Home Site Map Search Contact Us About Us About Us
Copyright © 2000
JavaScript Realtime


/**************************************************************************
 *
 * Script  : Main.js
 *
 * Purpose : All scripts are run from here.
 *
 **************************************************************************
 * Revision History
 *
 *      V1.0.0  03/07/2000  James Bischoff 
 *         Created  
 *
 **************************************************************************/

/**************************************************************************
 * Function : OnLoad
 * Purpose  : Instantiate all heavy duty objects required by this script.
 *            The objects must be assigned to global variables.
 **************************************************************************/
function OnLoad() {

   var strFunction = "OnLoad";

   try {
      gobjLocalMessenger = new LocalMessenger(
                                  gcstrAppname,
                                  gclngTraceLevel,
                                  gcstrMessengerDebugFile,
                                  gcstrMessengerMessageFile,
                                  gcstrMessengerErrorFile);

      gobjLocalMessenger.SendDebug(strFunction + " {Start}");
 
      glngStatus = 0;
      
      LocalOnload();
      
      gobjLocalMessenger.SendDebug(strFunction + " {End}");
      return(true);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" + 
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      glngStatus = 1;
      return(false);
   }
}

/**************************************************************************
 * Function : OnUnload
 * Purpose  : Destroy all heavy duty global objects created by OnLoad.
 **************************************************************************/
function OnUnload() {

   var strFunction = "OnUnload";

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start}");

      LocalOnunload();

      gobjLocalMessenger.SendDebug(strFunction + " {End}");
      
      gobjLocalMessenger = "";
      return(true);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" + 
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      glngStatus = 1;
      return(false);
   }
}

/**************************************************************************
 * Function : OnTimer
 * Purpose  : The main procedure.
 **************************************************************************/
function OnTimer() {

   var strFunction = "OnTimer";

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start}");

      LocalMain();

      gobjLocalMessenger.SendDebug(strFunction + " {End}");      
      return(true);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" + 
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      glngStatus = 1;
      return(false);
   }
}

/**************************************************************************
 *
 * Script  : RealTimeMain.js
 *
 * Purpose : Generic Galaxy realtime main script.
 *
 * Inputs  : None
 *
 **************************************************************************
 * Revision History
 *
 *      V1.0.0  05/08/2000  James Bischoff 
 *         Created
 *
 **************************************************************************/

/**************************************************************************
 * Galaxy script engine include files
 **************************************************************************/
//<include="D:\\galaxy\\config\\common\\adojavas.inc">
//<include="D:\\galaxy\\config\\common\\Message.js">
//<include="D:\\galaxy\\config\\common\\Database.js">
//<include="D:\\galaxy\\config\\common\\Utility.js">
//<include="D:\\galaxy\\config\\common\\Math.js">
//<include="D:\\galaxy\\config\\common\\TagData.js">
//<include="D:\\galaxy\\config\\common\\Main.js">

/**************************************************************************
 * Generic Constants
 **************************************************************************/
var gclngFileTraceLevel = 10;
var gcstrOPCEngine = "OPC.Galaxy.2";

/**************************************************************************
 * Generic Global Variables
 **************************************************************************/
var glngStatus;
var gobjLocalMessenger;

/**************************************************************************
 * Application Global Variables
 **************************************************************************/
var g;               //Tags Object - 1 character for calculation readability
var gobjCalcEngine;
var gblnFirstPass = true;
var gobjFakeOPC;
var gintSecond;
var gintMinute;
var gintHour;
var gintMonth;
var gintDay;
var gintWeekDay;
var gintYear;

/**************************************************************************
 * WScript Execution Check
 **************************************************************************/
try {
   if (typeof(WScript) == "object") {
      if (!OnLoad())
         WScript.Quit(glngStatus);
      if (!OnTimer())
         WScript.Quit(glngStatus);
      OnUnload();
      WScript.Quit(glngStatus);
   }
}
catch(objError) {
}

/**************************************************************************
 * The Main Application
 **************************************************************************/
function LocalMain() {

   var strFunction = "LocalMain";
   var objCurDate = "";

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start}");

      objCurDate  = new Date();
      gintSecond  = objCurDate.getSeconds();
      gintMinute  = objCurDate.getMinutes();
      gintHour    = objCurDate.getHours();
      gintMonth   = objCurDate.getMonth() + 1; //For VBScript compatibility;
      gintDay     = objCurDate.getDate();
      gintWeekDay = objCurDate.getDay() + 1;   //For VBScript compatibility
      gintYear    = objCurDate.getFullYear();      
      
      gobjLocalMessenger.SendMessage(strFunction + " {Begin Run on [" + objCurDate + "]}")
      objCurDate  = "";

      if (gblnFirstPass) {
         CustomCalcs();
         gblnFirstPass = false;
      }   
         
      g.UpdateValues(2);      
      CustomCalcs();
      g.UpdateValues(2);
      
      objCurDate  = new Date();
      gobjLocalMessenger.SendMessage(strFunction + " {End Run on [" + objCurDate + "]}")
      objCurDate  = "";      
      
      gobjLocalMessenger.SendDebug(strFunction + " {End}");
      return(true);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" +
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      throw(objError);
   }
}

/**************************************************************************
 * Heavy duty objects are created here
 **************************************************************************/
function LocalOnload() {

   var strFunction = "LocalOnload";

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start}");
            
      gobjLocalMessenger.SendDebug(strFunction + " {Create Calc Engine}");            
      gobjCalcEngine = new ActiveXObject("CalcEngine.CalcObject");

      gobjLocalMessenger.SendDebug(strFunction + " {Create Tags Object}");            
      g = new Tags();

      gobjFakeOPC = new FakeOPC();

      gobjLocalMessenger.SendDebug(strFunction + " {End}");
      return(true);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" +
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      throw(objError);
   }
}

/**************************************************************************
 * Heavy duty objects are destroyed here
 **************************************************************************/
function LocalOnunload() {

   var strFunction = "LocalOnunload";

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start}");

      gobjLocalMessenger.SendDebug(strFunction + " {Destroy Tags Object}");
      g = "";
      
      gobjLocalMessenger.SendDebug(strFunction + " {Destroy Calc Engine}");      
      gobjCalcEngine = "";
      
      gobjFakeOPC = "";

      gobjLocalMessenger.SendDebug(strFunction + " {End}");
      return(true);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" +
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      throw(objError);
   }
}

/**************************************************************************
 *
 * Script  : Math.js
 *
 * Purpose : Common math functions.
 *
 **************************************************************************
 * Revision History
 *
 *      V1.0.0  03/07/2000  James Bischoff 
 *         Created  
 *
 **************************************************************************/

/**************************************************************************
 * Function : SafeRatio
 * Purpose  : Calculate ratio of 2 values with divide by 0 protection.
 **************************************************************************/
function SafeRatio(x, y) {

   var strFunction = "SafeRatio";
   var dblRatio = 0.0;

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start x=[" + x + "] y=[" + y + "]}");
      
      if (y != 0.0)
         dblRatio = (x / y); 
      
      gobjLocalMessenger.SendDebug(strFunction + " {End dblRatio=[" + dblRatio + "]}");
      return(dblRatio);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" + 
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      return(0.0);
   }
}

/**************************************************************************
 * Function : SafeLog
 * Purpose  : Calculate log with <= 0 protection.
 **************************************************************************/
function SafeLog(x) {

   var strFunction = "SafeLog";
   var dblLog = 0.0;

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start x=[" + x + "]}");
      
      if (x > 0.0)
         dblLog = Math.log(x); 
      
      gobjLocalMessenger.SendDebug(strFunction + " {End dblLog=[" + dblLog + "]}");
      return(dblLog);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" + 
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      return(0.0);
   }
}

/**************************************************************************
 * Function : SafeSqr
 * Purpose  : Calculate log with <= 0 protection.
 **************************************************************************/
function SafeSqr(x) {

   var strFunction = "SafeSqr";
   var dblSqr = 0.0;

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start x=[" + x + "]}");
      
      if (x >= 0.0)
         dblSqr = Math.sqrt(x); 
      
      gobjLocalMessenger.SendDebug(strFunction + " {End dblSqr=[" + dblSqr + "]}");
      return(dblSqr);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" + 
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      return(0.0);
   }
}

/**************************************************************************
 * Function : GasComp
 * Purpose  : Calculate a single gas compensation.
 * Note     : The temperatures and pressures can be either tag names
 *            or numeric values.
 **************************************************************************/
function GasComp(
            strCompTag,
            strRawTag,
            vntActTemp,
            vntActPres,
            vntDesTemp,
            vntDesPres) {

   var strFunction = "GasComp";
   var lngStatus = Number.NaN;
   var dblActTemp = Number.NaN;
   var dblActPres = Number.NaN;
   var dblDesTemp = Number.NaN;
   var dblDesPres = Number.NaN;
   var lngErr = 0;

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start}");
      
      lngStatus = g.s(strRawTag);
      
      if (typeof(vntActTemp) == "string") {
         lngStatus += g.s(vntActTemp);
         dblActTemp = g.v(vntActTemp);
      } else
         dblActTemp = vntActTemp;
         
      if (typeof(vntActPres) == "string") {
         lngStatus += g.s(vntActPres);
         dblActPres = g.v(vntActPres);
      } else
         dblActPres = vntActPres;
      
      if (typeof(vntDesTemp) == "string") {
         lngStatus += g.s(vntDesTemp);
         dblDesTemp = g.v(vntDesTemp);
      } else
         dblDesTemp = vntDesTemp;
         
      if (typeof(vntDesPres) == "string") {
         lngStatus += g.s(vntDesPres);
         dblDesPres = g.v(vntDesPres);
      } else
         dblDesPres = vntDesPres;

      g.wv(strCompTag).Value = g.v(strRawTag) * 
         gobjCalcEngine.gascor(dblActTemp, dblActPres, dblDesTemp, dblDesPres, lngErr);
   
      g.ws(strCompTag).Value = ((lngStatus == 0) ? 0 : 1);
       
      gobjLocalMessenger.SendDebug(strFunction + " {End}");
      return(true);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" + 
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      gobjLocalMessenger.SendError(strFunction + 
         " {Unable to calculate gas compensation for meter [" + strCompTag + "]}");
      g.ws(strCompTag).Value = 1;   
      return(false);
   }
}

/**************************************************************************
 * Function : SteamComp
 * Purpose  : Calculate a single steam compensation.
 * Note     : The temperatures and pressures can be either tag names
 *            or numeric values.
 **************************************************************************/
function SteamComp(
            strCompTag,
            strRawTag,
            vntActTemp,
            vntActPres,
            vntDesTemp,
            vntDesPres) {

   var strFunction = "SteamComp";
   var lngStatus  = Number.NaN;
   var dblActTemp = Number.NaN;
   var dblActPres = Number.NaN;
   var dblDesTemp = Number.NaN;
   var dblDesPres = Number.NaN;
   var lngErr = 0;

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start}");
      
      lngStatus = g.s(strRawTag);
      
      if (typeof(vntActTemp) == "string") {
         lngStatus += g.s(vntActTemp);
         dblActTemp = g.v(vntActTemp);
      } else
         dblActTemp = vntActTemp;
         
      if (typeof(vntActPres) == "string") {
         lngStatus += g.s(vntActPres);
         dblActPres = g.v(vntActPres);
      } else
         dblActPres = vntActPres;
      
      if (typeof(vntDesTemp) == "string") {
         lngStatus += g.s(vntDesTemp);
         dblDesTemp = g.v(vntDesTemp);
      } else
         dblDesTemp = vntDesTemp;
         
      if (typeof(vntDesPres) == "string") {
         lngStatus += g.s(vntDesPres);
         dblDesPres = g.v(vntDesPres);
      } else
         dblDesPres = vntDesPres;

      g.wv(strCompTag).Value = g.v(strRawTag) * 
         gobjCalcEngine.stmcor(dblActTemp, dblActPres, dblDesTemp, dblDesPres, lngErr);
   
      g.ws(strCompTag).Value = ((lngStatus == 0) ? 0 : 1);
       
      gobjLocalMessenger.SendDebug(strFunction + " {End}");
      return(true);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" + 
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      gobjLocalMessenger.SendError(strFunction + 
         " {Unable to calculate steam compensation for meter [" + strCompTag + "]}");
      g.ws(strCompTag).Value = 1;   
      return(false);
   }
}

/**************************************************************************
 * Function : LiquidComp
 * Purpose  : Calculate a single liquid compensation.
 * Note     : The temperatures and pressures can be either tag names
 *            or numeric values.
 **************************************************************************/
function LiquidComp(
            strCompTag,
            strRawTag,
            vntActTemp,
            vntActGrav,
            vntDesTemp,
            vntDesGrav60,
            vntDesGrav) {

   var strFunction  = "LiquidComp";
   var lngStatus    = Number.NaN;
   var dblActTemp   = Number.NaN;
   var dblActGrav   = Number.NaN;
   var dblDesTemp   = Number.NaN;
   var dblDesGrav60 = Number.NaN;
   var dblDesGrav   = Number.NaN;
   var lngErr = 0;

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start}");
      
      lngStatus = g.s(strRawTag);
      
      if (typeof(vntActTemp) == "string") {
         lngStatus += g.s(vntActTemp);
         dblActTemp = g.v(vntActTemp);
      } else
         dblActTemp = vntActTemp;
         
      if (typeof(vntActGrav) == "string") {
         lngStatus += g.s(vntActGrav);
         dblActGrav = g.v(vntActGrav);
      } else
         dblActGrav = vntActGrav;
      
      if (typeof(vntDesTemp) == "string") {
         lngStatus += g.s(vntDesTemp);
         dblDesTemp = g.v(vntDesTemp);
      } else
         dblDesTemp = vntDesTemp;
         
      if (typeof(vntDesGrav60) == "string") {
         lngStatus += g.s(vntDesGrav60);
         dblDesGrav60 = g.v(vntDesGrav60);
      } else
         dblDesGrav60 = vntDesGrav60;

      if (typeof(vntDesGrav) == "string") {
         lngStatus += g.s(vntDesGrav);
         dblDesGrav = g.v(vntDesGrav);
      } else
         dblDesGrav = vntDesGrav;

      g.wv(strCompTag).Value = g.v(strRawTag) * 
         gobjCalcEngine.liqcor(dblActTemp, dblActGrav, dblDesTemp, dblDesGrav60, dblDesGrav, lngErr);
   
      g.ws(strCompTag).Value = ((lngStatus == 0) ? 0 : 1);
       
      gobjLocalMessenger.SendDebug(strFunction + " {End}");
      return(true);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" + 
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      gobjLocalMessenger.SendError(strFunction + 
         " {Unable to calculate liquid compensation for meter [" + strCompTag + "]}");
      g.ws(strCompTag).Value = 1;   
      return(false);
   }
}

/**************************************************************************
 *
 * Script  : Database.js
 *
 * Purpose : Common database functions.
 *
 **************************************************************************
 * Revision History
 *
 *      V1.0.0  03/07/2000  James Bischoff
 *         Created  
 *
 **************************************************************************/

/**************************************************************************
 * Function : CreateADOConnection
 * Purpose  : Create and open an ADO connection object.
 **************************************************************************/
function OpenADOConnection( 
            strDSN,
            strUser, 
            strPass,
            objADOConnection) {

   var strFunction = "OpenADOConnection";

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start}");            
      
      objADOConnection.Open( 
         strDSN, 
         strUser, 
         strPass);  
      
      gobjLocalMessenger.SendDebug(strFunction + " {End}");
      return(true);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" + 
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      ProcessADOError(objADOConnection);
      throw(objError);
   }
}

/**************************************************************************
 * Function : DestroyADOConnection
 * Purpose  : Close and destroy an ADO connection object.
 **************************************************************************/
function DestroyADOConnection(objADOConnection) {

   var strFunction = "DestroyADOConnection";

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start}");
      
      if (typeof(objADOConnection) == "object") {
         if (objADOConnection.ConnectionString != "")
            objADOConnection.Close();
         objADOConnection = "";
      }
      
      gobjLocalMessenger.SendDebug(strFunction + " {End}");
      return(true);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" + 
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      ProcessADOError(objADOConnection);
      throw(objError);
   }
}

/**************************************************************************
 * Function : ShowADOVersion
 * Purpose  : Display the database engine name and version.
 **************************************************************************/
function ShowADOVersion(objADOConnection) {

   var strFunction = "ShowADOVersion";

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start}");
      
      if (typeof(objADOConnection) == "object") {
         if (objADOConnection.ConnectionString != "") {
            gobjLocalMessenger.SendDebug(strFunction + " {" + 
                                         objADOConnection.Properties("DBMS Name") +  
                                         objADOConnection.Properties("DBMS Version") + "}");                     
         }            
      }
            
      gobjLocalMessenger.SendDebug(strFunction + " {End}");
      return(true);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" + gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      ProcessADOError(objADOConnection);
      throw(objError);
   }
}            

/**************************************************************************
 * Function : ProcessADOError
 * Purpose  : Process ADO object errors.
 **************************************************************************/
function ProcessADOError(objADOObjectWithError) {

   var strFunction = "ProcessADOError";
   
   var objEnumerator = null;

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start}");
      
      objEnumerator = new Enumerator(objADOObjectWithError.Errors);
      
      for ( ; !objEnumerator.atEnd(); objEnumerator.moveNext())
      {
         gobjLocalMessenger.SendError(strFunction + " {" + 
            gobjLocalMessenger.BuildErrorMessage(objEnumerator.item()) + "}");
      }
      
      gobjLocalMessenger.SendDebug(strFunction + " {End}");
      return(true);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" + 
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      throw(objError);
   }
}

/**************************************************************************
 *
 * Script  : Message.js
 *
 * Purpose : All script messages are routed here.  
 *           The JScript LocalMessenger object is the intended interface,
 *           thus, the functions should only be called as methods of this
 *           object.
 *
 **************************************************************************
 * Revision History
 *
 *      V1.0.0  03/07/2000  James Bischoff 
 *         Created  
 *
 **************************************************************************/

/**************************************************************************
 * Main Message Object
 **************************************************************************/
function LocalMessenger( 
   strAppname,
   lngTraceLevel,
   strDebugFile,
   strMessageFile,
   strErrorFile) {

   var strFunction = "LocalMessenger";

   try {

      this.SendDebug = SendDebug;
      this.SendMessage = SendMessage;
      this.SendError = SendError;
      this.SetTraceLevel = SetTraceLevel;
      this.BuildErrorMessage = BuildErrorMessage;
      this.objLocalMessenger = new ActiveXObject("Galaxy.LocalMessenger.1");
      
      if (typeof(strAppname) == "undefined") 
         strAppname = "UndefinedApplication";
      this.strAppname = strAppname;
      
      if (typeof(lngTraceLevel) == "undefined") 
         lngTraceLevel = 0;
      this.lngTraceLevel = lngTraceLevel;
   
      if (ValidateFilePath(strDebugFile))
         this.objLocalMessenger.SetDebugFile(strDebugFile);
      else
         this.SendError(strFunction + " {" + strDebugFile + " cannot be created}");
           
      if (ValidateFilePath(strMessageFile))
         this.objLocalMessenger.SetMessageFile(strMessageFile);
      else
         this.SendError(strFunction + " {" + strMessageFile + " cannot be created}");

      if (ValidateFilePath(strErrorFile))
         this.objLocalMessenger.SetErrorFile(strErrorFile);
      else
         this.SendError(strFunction + " {" + strErrorFile + " cannot be created}");
      
      return(true);
   }
   catch(objError) {
      return(false);
   }
}

/**************************************************************************
 * Function : ValidateFilePath()
 * Purpose  : Create a directory if it does not already exist for a given 
 *            file path.
 **************************************************************************/
function ValidateFilePath(strFilePath) {

   var strFunction = "ValidateFilePath";

   var objFileSystem = new ActiveXObject("Scripting.FileSystemObject");
   var strFolderName = "";
   var strDriveName = "";
   var arrPathParts = null;
   var i = null;

   try {

      if (typeof(strFilePath) == "undefined")
         throw "strFilePath is undefined";

      strFolderName = objFileSystem.GetParentFolderName(strFilePath);
      strDriveName = objFileSystem.GetDriveName(strFilePath);

      if (!objFileSystem.FolderExists(strFolderName)) {
         arrPathParts = strFolderName.split("\\");
         for (i = 1; i < arrPathParts.length; i++) { 
            if (arrPathParts[i] == "")
               i += 3;  // Skip UNC portion if there
            strDriveName += "\\" + arrPathParts[i];
            if (!objFileSystem.FolderExists(strDriveName))
               objFileSystem.CreateFolder(strDriveName);
         }
      }   

      objFileSystem = "";
      return(true);
   }
   catch(objError) {
      objFileSystem = "";      
      return(false);
   }   
}

/**************************************************************************
 * Function : SetTraceLevel()
 * Purpose  : Set the debug trace level.
 **************************************************************************/
function SetTraceLevel(lngTraceLevel) {

   var strFunction = "SetTraceLevel";

   try {   
      if (this.lngTraceLevel < 1)
         this.lngTraceLevel = 1;
         
      this.SendDebug(strFunction + " {Trace Level set to [" + lngTraceLevel + "]}");
      this.lngTraceLevel = lngTraceLevel;
   }
   catch(objError) {
   }
}

/**************************************************************************
 * Function : SendDebug, SendError, SendMessage
 * Purpose  : Output messages using the LocalMessenger object.
 *
 *            SendLocalMessage takes the following string parameters:
 *
 *               Type    = Error, Warning, Message, Debug
 *               Channel = File, Debug, Event, All
 *               AppName = Application Name
 *               Message = The Message
 *
 **************************************************************************/

/**************************************************************************
 * Debug Only
 **************************************************************************/
function SendDebug(strMessage) {

   try {
      if (this.lngTraceLevel > 0) {
         this.objLocalMessenger.SendLocalMessage(
            "Debug", 
            "Debug", 
            this.strAppname,
            strMessage);
         if (this.lngTraceLevel >= gclngFileTraceLevel) {
            this.objLocalMessenger.SendLocalMessage(
            "Debug", 
            "File", 
            this.strAppname,
            strMessage);
         }   
      }   
      return(true);
   }
   catch(objError) {
      return(false);
   }      
}

/**************************************************************************
 * File Only
 **************************************************************************/
function SendMessage(strMessage) {

   try {
      this.objLocalMessenger.SendLocalMessage(
         "Message", 
         "File", 
         this.strAppname,
         strMessage);
      return(true);   
   }
   catch(objError) {
      return(false);
   }
}

/**************************************************************************
 * Debug, File, and Event Log
 **************************************************************************/
function SendError(strMessage) {

   try {
      this.objLocalMessenger.SendLocalMessage(
         "Error", 
         "All", 
         this.strAppname,
         strMessage);
      this.objLocalMessenger.SendLocalMessage(
         "Error", 
         "Debug", 
         this.strAppname,
         strMessage);
      return(true);   
   }
   catch(objError) {
      return(false);
   }
}

/**************************************************************************
 * Function : mobjLocalMessenger.BuildErrorMessage()
 * Purpose  : Create a complete error message string from the error object.
 **************************************************************************/
function BuildErrorMessage(objError) {

   return( (objError.number & 0xFFFF) + " - " + objError + " - " + objError.description )

}


/**************************************************************************
 * Function : OnRestart
 * Purpose  : Pass in trace level.  Initially called right after OnLoad.
 **************************************************************************/
function OnRestart(lngTraceLevel) {

   var strFunction = "OnRestart";

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start}");

      gobjLocalMessenger.SendMessage(strFunction + " {Set trace level to [" + lngTraceLevel + "]}");
      gobjLocalMessenger.SetTraceLevel(lngTraceLevel);

      gobjLocalMessenger.SendDebug(strFunction + " {End}");      
      return(true);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" + 
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      glngStatus = 1;
      return(false);
   }
}

/**************************************************************************
 *
 * Script  : TagData.js
 *
 * Purpose : Read and write values using the global OPC Engine
 *
 **************************************************************************
 * Revision History
 *
 *      V1.0.0  03/07/2000  James Bischoff 
 *         Created  
 *
 **************************************************************************/

/**************************************************************************
 * Object  : Tags
 * Purpose : This object hosts the Galaxy OPC Engine objects that read and
 *           write shared memory data and statuses, and read timestamps.
 *           There are methods to get values, and return a reference to a 
 *           writable object as well as onbe to update all of the values
 *           in all of the objects in these collections.
 **************************************************************************/
function Tags() {

   var strFunction = "Tags Constructor";

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start}");

      this.v = v;
      this.s = s;
      this.d = d;
      this.wv = wv;
      this.ws = ws;
      this.UpdateValues = UpdateValues;
      
      //These collections contain the Galaxy Engine objects for each tag
      this.colValues = new ActiveXObject("Scripting.Dictionary");
      this.colStatuses = new ActiveXObject("Scripting.Dictionary");
      this.colCTimes = new ActiveXObject("Scripting.Dictionary");
      
      gobjLocalMessenger.SendDebug(strFunction + " {Create OPC Engine}");
      this.objOPCEngine = new ActiveXObject("GalaxyEngine.Data.1");

      gobjLocalMessenger.SendDebug(strFunction + " {Initialize OPC Engine}");      
      this.objOPCEngine.OpenOPCServer(gcstrOPCEngine);
            
      gobjLocalMessenger.SendDebug(strFunction + " {End}");      
      return(true);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" +
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      throw(objError);
   }
}

/**************************************************************************
 * Function : v()
 * Purpose  : See if there is an engine tag object for this tag's value.  
 *            If there is not, then create one and return the value.
 **************************************************************************/
function v(strOPCName) {

   var strFunction = "v";
   var objValue = "";
   var objTag = "";

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start strOPCName=[" + strOPCName + "]}");            

      objTag = new Tag(strOPCName);     
      
      if (!this.colValues.Exists(objTag.OPCName)) {         
         gobjLocalMessenger.SendDebug(strFunction + " {Create OPCEngine Tag Object}");         
         objValue = this.objOPCEngine.CreateTag(objTag.TagName, objTag.AccessPath);          
         this.colValues.add(objTag.OPCName, objValue);         
         objValue = "";          
         if (!gblnFirstPass)
            this.objOPCEngine.Update(1);
      }

      if (gblnFirstPass)
         return(1);
      
      gobjLocalMessenger.SendDebug(strFunction + " {Get Tag Value}");
      objTag.v = this.colValues.Item(objTag.OPCName).Value;
            
      gobjLocalMessenger.SendDebug(strFunction + 
                                   " {OPCName=[" + objTag.OPCName + 
                                   "] Value=[" + objTag.v + "]}");      
      
      if (typeof(objTag.v) != "number")
         throw(new Error(0,"Unable to retrieve numeric data for [" + objTag.OPCName + "]}"));
      
      gobjLocalMessenger.SendDebug(strFunction + " {End}");
      return(objTag.v);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" + 
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      throw(objError);
   }
}

/**************************************************************************
 * Function : s()
 * Purpose  : See if there is an engine tag object for this tag's status.  
 *            If there is not, then create one and return the value.
 **************************************************************************/
function s(strOPCName) {

   var strFunction = "s";
   var objStatus = "";
   var objTag = "";

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start strOPCName=[" + strOPCName + "]}");            

      objTag = new Tag(strOPCName);     
      
      if (!this.colStatuses.Exists(objTag.OPCName)) {         
         gobjLocalMessenger.SendDebug(strFunction + " {Create OPCEngine Tag Object}");         
         objStatus = this.objOPCEngine.CreateTag(objTag.TagName + ".sta", objTag.AccessPath);          
         this.colStatuses.add(objTag.OPCName, objStatus);         
         objStatus = "";          
         if (!gblnFirstPass)
            this.objOPCEngine.Update(1);
      }

      if (gblnFirstPass)
         return(1);
      
      gobjLocalMessenger.SendDebug(strFunction + " {Get Tag Status}");
      objTag.s = this.colStatuses.Item(objTag.OPCName).Value;
            
      gobjLocalMessenger.SendDebug(strFunction + 
                                   " {OPCName=[" + objTag.OPCName + 
                                   "] Status=[" + objTag.s + "]}");      
                  
      if (typeof(objTag.s) != "number")
         throw(new Error(0,"Unable to retrieve numeric data for [" + objTag.OPCName + "]}"));

      gobjLocalMessenger.SendDebug(strFunction + " {End}");
      return(objTag.s);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" + 
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      throw(objError);
   }
}

/**************************************************************************
 * Function : d()
 * Purpose  : See if there is an engine tag object for this tag's Date/Time.  
 *            If there is not, then create one and return the value.
 **************************************************************************/
function d(strOPCName) {

   var strFunction = "d";
   var objCTime = "";
   var objTag = "";

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start strOPCName=[" + strOPCName + "]}");            

      objTag = new Tag(strOPCName);     
      
      if (!this.colCTimes.Exists(objTag.OPCName)) {         
         gobjLocalMessenger.SendDebug(strFunction + " {Create OPCEngine Tag Object}");         
         objCTime = this.objOPCEngine.CreateTag(objTag.TagName + ".ctime", objTag.AccessPath);          
         this.colCTimes.add(objTag.OPCName, objCTime);         
         objCTime = "";          
         if (!gblnFirstPass)
            this.objOPCEngine.Update(1);
      }

      if (gblnFirstPass)
         return(1);
      
      gobjLocalMessenger.SendDebug(strFunction + " {Get Tag CTime}");
      
      if (typeof(this.colCTimes.Item(objTag.OPCName).Value) != "number")
         throw(new Error(0,"Unable to retrieve numeric data for [" + objTag.OPCName + "]}"));      
      
      objTag.d = new Date(this.colCTimes.Item(objTag.OPCName).Value * 1000);
            
      gobjLocalMessenger.SendDebug(strFunction + 
                                   " {OPCName=[" + objTag.OPCName + 
                                   "] Date=[" + objTag.d + "]}");      
                  
      gobjLocalMessenger.SendDebug(strFunction + " {End}");
      return(objTag.d);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" + 
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      throw(objError);
   }
}

/**************************************************************************
 * Function : wv()
 * Purpose  : See if there is an engine tag object for this tag's value.  
 *            If there is not, then create one and return a reference
 *            to the engine object so it can be written to.
 **************************************************************************/
function wv(strOPCName) {

   var strFunction = "wv";
   var objValue = "";
   var objTag = "";

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start strOPCName=[" + strOPCName + "]}");            

      objTag = new Tag(strOPCName);     
      
      if (!this.colValues.Exists(objTag.OPCName)) {         
         gobjLocalMessenger.SendDebug(strFunction + " {Create OPCEngine Tag Object}");         
         objValue = this.objOPCEngine.CreateTag(objTag.TagName, objTag.AccessPath);          
         this.colValues.add(objTag.OPCName, objValue);         
         objValue = "";          
         if (!gblnFirstPass)
            this.objOPCEngine.Update(1);
      }
      
      if (gblnFirstPass)
         return(gobjFakeOPC);

      gobjLocalMessenger.SendDebug(strFunction + " {Get Tag Value}");
      objTag.v = this.colValues.Item(objTag.OPCName).Value;
            
      gobjLocalMessenger.SendDebug(strFunction + 
                                   " {OPCName=[" + objTag.OPCName + 
                                   "] Value=[" + objTag.v + "]}");      

      if (typeof(objTag.v) != "number")
         throw(new Error(0,"Unable to retrieve numeric data for [" + objTag.OPCName + "]}"));
                  
      gobjLocalMessenger.SendDebug(strFunction + " {End}");
      return(this.colValues.Item(objTag.OPCName));
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" + 
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      throw(objError);
   }
}

/**************************************************************************
 * Function : ws()
 * Purpose  : See if there is an engine tag object for this tag's status.  
 *            If there is not, then create one and return a reference
 *            to the engine object so it can be written to.
 * Note     : Do not throw bad tags here since we do not want to stop
 *            a big function just because we can't write a bad status
 *            for a tag that probably doesn't exist anyway.
 **************************************************************************/
function ws(strOPCName) {

   var strFunction = "ws";
   var objStatus = "";
   var objTag = "";

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start strOPCName=[" + strOPCName + "]}");            

      objTag = new Tag(strOPCName);     
      
      if (!this.colStatuses.Exists(objTag.OPCName)) {         
         gobjLocalMessenger.SendDebug(strFunction + " {Create OPCEngine Tag Object}");         
         objStatus = this.objOPCEngine.CreateTag(objTag.TagName + ".sta", objTag.AccessPath);          
         this.colStatuses.add(objTag.OPCName, objStatus);         
         objStatus = "";          
         if (!gblnFirstPass)
            this.objOPCEngine.Update(1);
      }
      
      if (gblnFirstPass)
         return(gobjFakeOPC);

      gobjLocalMessenger.SendDebug(strFunction + " {Get Tag Status}");
      objTag.s = this.colStatuses.Item(objTag.OPCName).Value;
            
      gobjLocalMessenger.SendDebug(strFunction + 
                                   " {OPCName=[" + objTag.OPCName + 
                                   "] Status=[" + objTag.s + "]}");      
                  
      if (typeof(objTag.s) != "number")
         gobjLocalMessenger.SendError(strFunction + " {Unable to retrieve numeric data for [" + objTag.OPCName + "]}");

      gobjLocalMessenger.SendDebug(strFunction + " {End}");
      return(this.colStatuses.Item(objTag.OPCName));
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" + 
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      throw(objError);
   }
}

/**************************************************************************
 * Function : UpdateValues()
 * Purpose  : Update all OPC engine values and do not throw errors.
 **************************************************************************/
function UpdateValues(lngSeconds) {

   var strFunction = "UpdateValues";

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start}");            
      
      this.objOPCEngine.Update(lngSeconds);
      
      gobjLocalMessenger.SendDebug(strFunction + " {End}");
      return(true);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" + 
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      return(false);
   }
}

/**************************************************************************
 * Object  : Tag
 * Purpose : This object host is used by the Tags object methods as a
 *           utility object to parse OPC names and to temporarily store
 *           values, statuses, and timestamps.  It could also be used as
 *           a general tag object.
 **************************************************************************/
function Tag(strOPCName) {

   var strFunction = "Tag Constructor";
   var arrPathParts = "";
   var strTagName = "";
   var strAccessPath = "";

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start}");

      if (strOPCName.indexOf("/") == -1)
         this.OPCName = gcstrDefaultAccessPath + "/" + strOPCName;          
      else
         this.OPCName = strOPCName;
  
      gobjLocalMessenger.SendDebug(strFunction + " {OPCName = [" + this.OPCName + "]}");
      
      arrPathParts = this.OPCName.split("/");
      strTagName = arrPathParts[4];
      strAccessPath = "//" + arrPathParts[2] + "/" + arrPathParts[3];
      
      gobjLocalMessenger.SendDebug(strFunction + " {TagName = [" + strTagName + "]}");
      gobjLocalMessenger.SendDebug(strFunction + " {AccessPath = [" + strAccessPath + "]}");
      
      this.TagName = strTagName;
      this.AccessPath = strAccessPath;
      
      this.v = "";
      this.s = "";
      this.d = "";
                        
      gobjLocalMessenger.SendDebug(strFunction + " {End}");      
      return(true);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" +
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      throw(objError);
   }
}

/**************************************************************************
 * Object  : FakeOPC
 * Purpose : This object host is used on the first pass to disable writes
 *           while the OPC group list is being established.
 **************************************************************************/
function FakeOPC() {

   var strFunction = "FakeOPC Constructor";

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start}");
      
      this.Value = "";
                        
      gobjLocalMessenger.SendDebug(strFunction + " {End}");      
      return(true);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" +
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      throw(objError);
   }
}


 /**************************************************************************
 *
 * Script  : DcrHycCalc1.inc
 *
 * Purpose : DCR HYC realtime calculations
 *
 **************************************************************************
 * Revision History
 *
 *    V2.0.0  05/08/2000  James Bischoff - Port to JScript
 *
 **************************************************************************/

/**************************************************************************
 * Application Constants
 **************************************************************************/
var gclngTraceLevel = 0;
var gcstrDefaultAccessPath = "//DCR/HYC"
var gcstrAppname = "dcrhyccalc1";
var gcstrMessengerDebugFile   = "D:\\Galaxy\\Tmp\\"     + gcstrAppname + ".bug";
var gcstrMessengerMessageFile = "D:\\Galaxy\\Message\\" + gcstrAppname + ".txt";
var gcstrMessengerErrorFile   = "D:\\Galaxy\\Error\\"   + gcstrAppname + ".err";

/**************************************************************************
 * Unit Specific Calculations
 **************************************************************************/
function CustomCalcs() {

   var strFunction = "CustomCalcs";

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start}");
      
      //Uncomment to start debugger here when running under wsh      
      //debugger;
            
      //////////////////////////////////////////////////////////////////////
      //                       Gas Meter Compensation
      //////////////////////////////////////////////////////////////////////
      //       CompMtr      RawMtr      ActTmp      ActPrs   DesTmp DesPrs
      //////////////////////////////////////////////////////////////////////
      GasComp("36FI109Z",  "36FI109",  "36TI594",  "36PC357", 167., 2814.);
      GasComp("36FI110Z",  "36FI110",  "36TI594",  "36PC357", 167., 2814.);
      GasComp("36FI124Z",  "36FI124",  "36TI573",  "36PC346", 118.,  300.);
      GasComp("36FI128Z",  "36FI128",  "36TC582",  "36PC353", 127., 2540.);
      GasComp("36FC132Z",  "36FC132",  "36TI594",  "36PC357", 167., 2814.);
      GasComp("36FI135Z",  "36FI135",  "36TI594",  "36PC357", 167., 2814.);
      GasComp("36FI146Z",  "36FI146",  "36TI641",  "36PI395", 127.,  225.);
      GasComp("36FC164Z",  "36FC164",  "37TI542",  "36PI1340", 60.,   50.);
      GasComp("36FI177Z",  "36FI177",  "21TI4515", "36PI459",  60.,   50.);
      GasComp("36FI213Z",  "36FI213",  "36TI589",  "36PC353", 150., 2540.);
      GasComp("36FI2100Z", "36FI2100", "37TI629",  "37PI418", 240., 2500.);
      GasComp("37FI101Z",  "37FI101",  "24TI3500", "37PI306", 115.,  162.);
      GasComp("37FC105Z",  "37FC105",  "37TI1531", "37PI411", 100.,  700.);
      GasComp("37FC113Z",  "37FC113",  "37TI520",  "37PC325",  60.,  332.);
      GasComp("37FC134Z",  "37FC134",  "37TI529",  "37PI333", 400.,  255.);
      GasComp("37FI160Z",  "37FI160",  "37TI604",  "37PC401", 100.,  140.);
      GasComp("37FC161Z",  "37FC161",  "37TI1531", "37PI411", 100.,  700.);
      GasComp("37FI162Z",  "37FI162",  "37TI629",  "37PI418", 220., 2600.);
      GasComp("37FI168Z",  "37FI168",  "37TI629",  "37PI418", 220., 2600.);
      GasComp("37FC207Z",  "37FC207",  "37TI518",  "37PC311", 110.,  300.);
      GasComp("37FI217Z",  "37FI217T", "37TI1531", "37PI411", 120.,  725.);
      GasComp("37FI217MZ", "37FI217M", "37TI1531", "37PI411", 120.,  725.);

      //////////////////////////////////////////////////////////////////////
      //                      Steam Meter Compensation
      //////////////////////////////////////////////////////////////////////
      //         CompMtr      RawMtr      ActTmp       ActPrs  DesTmp DesPrs
      //////////////////////////////////////////////////////////////////////
      SteamComp("37FI179Z",  "37FI179T",  "37TI531",  "36PI469", 750., 600.);
      SteamComp("36FI127Z",  "36FI127",         750,  "36PI469", 750., 600.);
      SteamComp("37FI181Z",  "37FI181",         287,  "36PI454", 287.,  40.);
      SteamComp("37FI102Z",  "37FI102",         750,  "36PI469", 750., 600.);
      SteamComp("37FI176Z",  "37FI176",         287,  "36PI454", 287.,  40.);
      SteamComp("37FI178Z",  "37FI178M",        545,  "36PI456", 378., 175.);
      SteamComp("36FI174Z",  "36FI174",         287,  "36PI454", 300.,  40.);
      SteamComp("36FI175Z",  "36FI175",         545,  "36PI456", 545., 175.);
      
      ////////////////////////////////////////////////////////////////////////////////////
      //                      Liquid Meter Compensation
      ////////////////////////////////////////////////////////////////////////////////////
      //          CompMtr      RawMtr      ActTmp          ActGrv   DesTmp DesGrv60 DesGrv
      ////////////////////////////////////////////////////////////////////////////////////
      LiquidComp("36FI167Z",  "36FI167",  "36TI1505", "36LB006APIX", 150., 0.887, 0.850);
      LiquidComp("36FC101Z",  "36FC101",  "36TI506",  "36LB011APIX", 450., 1.011, 0.894);
      LiquidComp("36FC117Z",  "36FC117",  "36TI579",  "36LB011APIX", 450., 1.011, 0.894);
      LiquidComp("36FI154Z",  "36FI154",  "36TI660",           28.0, 644., 0.889, 0.665);
      LiquidComp("36FI157Z",  "36FI157",  "36TI677",  "36LB004APIX", 100., 0.681, 0.661);
      LiquidComp("36FC158Z",  "36FC158",  "36TI680",  "36LB005APIX", 100., 0.816, 0.797);
      LiquidComp("36FI165Z",  "36FI165",  "36TI697",  "36LB007APIX", 690., 0.891, 0.663);
      LiquidComp("36FC166Z",  "36FC166",  "36TI698",  "36LB006APIX", 350., 0.887, 0.770);
      LiquidComp("36FI215Z",  "36FI215",  "36TI1501", "36LB006APIX", 312., 0.887, 0.850);
      LiquidComp("37FI139Z",  "37FI139",  "36TI601",           10.0, 242., 1.000, 0.945);
      LiquidComp("37FC149Z",  "37FC149",  "37TI584",           10.0, 233., 1.250, 1.186);
      LiquidComp("37FC148Z",  "37FC148",  "37TC589",           10.0, 150., 1.022, 1.000);

      
      ////////////////////////////////////////////////////////////////////////////////////////////////
      //                                 Conversion Calculation
      //
      //         Conversion = 100 - ((100 - 36LB007P650X) * (36FI154 - 36FI167) / 36FC101)
      ////////////////////////////////////////////////////////////////////////////////////////////////
      try {
         if (g.v("36FC101") == 0.0) {  
            g.wv("36XIHCONV").Value = 0.0;
            g.ws("36XIHCONV").Value = 1;
         } else {
            g.wv("36XIHCONV").Value = 
               100 - ((100 - g.v("36LB007P650X")) * (g.v("36FI154") - g.v("36FI167")) / g.v("36FC101"));
            g.ws("36XIHCONV").Value = (((g.s("36LB007P650X") + g.s("36FI154") + g.s("36FI167") 
               + g.s("36FC101")) == 0) ? 0 : 1);  
         }
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 36XIHCON36XIHCONV}");
         g.ws("36XIHCONV").Value = 1;
      }

      try {
         g.wv("37XIPDFDRATZ").Value = SafeRatio(g.v("42FI1483"), g.v("42FC1864X"));
         g.ws("37XIPDFDRATZ").Value = (((g.s("42FI1483") + g.s("42FC1864X")) == 0) ? 0 : 1);
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37XIPDFDRATZ}");
         g.ws("37XIPDFDRATZ").Value = 1;
      }

      /////////////////////////////////////////////////////////////////////////////////////
      //                          Low Purity Hydrogen Balance
      /////////////////////////////////////////////////////////////////////////////////////
      try {
         var dblFILOPURBL = g.v("42FI1111") + (0.001 * g.v("25FI123A")) + (0.001 * g.v("31FI174")) + g.v("36FI213");
      
         g.wv("37FILOPURBLZ").Value = dblFILOPURBL - (0.001*(g.v("29FI111")) + g.v("29FI138") + g.v("29FI151") 
                                     + g.v("29FI174") + g.v("29FI203"));
                                  
         g.ws("37FILOPURBLZ").Value = (((g.s("42FI1111") + g.s("25FI123A") + g.s("31FI174") + g.s("36FI213") 
                                     + g.s("29FI111") + g.s("29FI138") + g.s("29FI151") + g.s("29FI174")
                                     + g.s("29FI203")) == 0) ? 0 : 1);       
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37FILOPURBL}");
         g.ws("37FILOPURBLZ").Value = 1;
      }                               
                               
      try {                         
         g.wv("37FI99H2IMPZ").Value = g.v("42FI1483") - g.v("37FC105") - 0.001*(g.v("31FI174") 
                                     + g.v("33FI141") + g.v("28FI263"));
         
         g.ws("37FI99H2IMPZ").Value = (((g.s("42FI1483") + g.s("37FC105") + g.s("31FI174") 
                                     + g.s("33FI141") + g.s("28FI263")) == 0) ? 0 : 1);
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37FI99H2IMP}");
         g.ws("37FI99H2IMPZ").Value = 1;
      }


      
      /////////////////////////////////////////////////////////////////////////////////////
      //                          Hydrogen Balance Calculation
      //
      //  If we do not import hydrogen, h2make shall be 37FI160 - e12 recycle(FI168)
      //  If we import h2, we have to back out the amount of import going into
      //        e12 recyle which is FI217-FC105-FC161
      //                                  ^toR7  ^go to 3rd stage           
      //  Buffer gas calculation obtained by the balance calc around K2
      //  The amount h2 going to 36 unit is FI162 + buffer gas to K1
      //
      //  use 36FI2100Z instead of calculated buffer gas, 9/10/96
      //
      /////////////////////////////////////////////////////////////////////////////////////
      try {
         g.wv("37FIH2PRODZ").Value = g.v("37FI160Z") - g.v("37FI217Z") + g.v("37FC105Z") + 
                                     g.v("37FC161Z") - g.v("37FI168Z");
         g.ws("37FIH2PRODZ").Value = (((g.s("37FI160Z") + g.s("37FI217Z") + g.s("37FC105Z") +
                                        g.s("37FC161Z") + g.s("37FI168Z")) == 0) ? 0 : 1);
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37FIH2PRODZ}");
         g.ws("37FIH2PRODZ").Value = 1;
      }       
       
      try { 
         g.wv("37FIH2BUFFZ").Value = g.v("37FI160Z") + g.v("37FC161Z") - g.v("37FI162Z") - g.v("37FI168Z");
         g.ws("37FIH2BUFFZ").Value = (((g.s("37FI160Z") + g.s("37FC161Z") + g.s("37FI162Z") + 
                                        g.s("37FI168Z")) == 0) ? 0 : 1);
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37FIH2BUFFZ}");
         g.ws("37FIH2BUFFZ").Value = 1;
      }
      
      try {
         g.wv("37FIH2TO36Z").Value = g.v("37FI162Z");
         g.ws("37FIH2TO36Z").Value = g.s("37FI162Z");
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37FIH2TO36Z}");
         g.ws("37FIH2TO36Z").Value = 1;
      }

      /////////////////////////////////////////////////////////////////////////////////////
      //                         Toggle Global Watch Dog In IA
      /////////////////////////////////////////////////////////////////////////////////////
      try {
         g.wv("36GLOBALWD").Value = ((g.v("36GLOBALWD") == 0) ? 1 : 0);
         g.ws("36GLOBALWD").Value = 0;
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 36GLOBALWD}");
         g.ws("36GLOBALWD").Value = 1;
      }

      /////////////////////////////////////////////////////////////////////////////////////
      //                         
      /////////////////////////////////////////////////////////////////////////////////////
      try {
         g.wv("37DPI353Z").Value = g.v("37PI353") - g.v("37PI347");
         g.ws("37DPI353Z").Value = (((g.s("37PI353") + g.s("37PI347")) == 0) ? 0 : 1);
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37DPI353Z}");
         g.ws("37DPI353Z").Value = 1;
      }

      try {
         g.wv("37DPI355Z").Value = g.v("37PI355") - g.v("37PI347");
         g.ws("37DPI355Z").Value = (((g.s("37PI355") + g.s("37PI347")) == 0) ? 0 : 1);
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37DPI355Z}");
         g.ws("37DPI355Z").Value = 1;
      }

      /////////////////////////////////////////////////////////////////////////////////////
      //                             CO2 Calculation
      //
      //   CO2 to MeOH = k4a+k4b+k5-recycle-to refinery
      //   do not need calculation, get 41FC116 from 41fi116 from methanol
      //   CO2toMeoh=37FI3104+37FI3105+37FI3113 - (37FI3103/1000.) - 37FI182
      //   41FC116=41FI116*0.001
      /////////////////////////////////////////////////////////////////////////////////////
      try {
         g.wv("41FC116").Value = 0;
         g.ws("41FC116").Value = 0;
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 41FC116}");
         g.ws("41FC116").Value = 1;
      }

      /////////////////////////////////////////////////////////////////////////////////////
      //     CO2 to Cardox and stack = total CO2 make - CO2 to Meoh - CO2 to refinery
      /////////////////////////////////////////////////////////////////////////////////////
      try {
         g.wv("37FICO2CRDXZ").Value = (g.v("37FICO2MAKX") / 58.0475)  - g.v("41FC116") - g.v("37FI182");
         g.ws("37FICO2CRDXZ").Value = (((g.s("37FICO2MAKX") + g.s("41FC116") + g.s("37FI182")) == 0) ? 0 : 1);
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37FICO2CRDXZ}");
         g.ws("37FICO2CRDXZ").Value = 1;
      }
      
      try {
         g.wv("37FICO2CRDXZ").Value = (g.v("37FICO2MAKX") / 58.0475)  - g.v("41FC116") - g.v("37FI182");
         g.ws("37FICO2CRDXZ").Value = (((g.s("37FICO2MAKX") + g.s("41FC116") + g.s("37FI182")) == 0) ? 0 : 1);
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37FICO2CRDXZ}");
         g.ws("37FICO2CRDXZ").Value = 1;
      }

      /////////////////////////////////////////////////////////////////////////////////////
      //                              all streams in tons/day
      /////////////////////////////////////////////////////////////////////////////////////
      try {
         g.wv("37FICO2CDXZ").Value = g.v("37FICO2CRDXZ") * 58.0475;
         g.ws("37FICO2CDXZ").Value = g.s("37FICO2CRDXZ");
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37FICO2CDXZ}");
         g.ws("37FICO2CDXZ").Value = 1;
      }

      try {
         g.wv("37FICO2REFZ").Value = g.v("37FI182") * 58.0475;
         g.ws("37FICO2REFZ").Value = g.s("37FI182");
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37FICO2REFZ}");
         g.ws("37FICO2REFZ").Value = 1;
      }

      try {
         g.wv("37FICO2MEOHZ").Value = g.v("41FC116") * 58.0475;
         g.ws("37FICO2MEOHZ").Value = g.s("41FC116");
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37FICO2MEOHZ}");
         g.ws("37FICO2MEOHZ").Value = 1;
      }


      /////////////////////////////////////////////////////////////////////////////////////
      //                         Control Loops Uptime Monitors
      //
      //   Clear Counter and percent uptime at midnight
      //   This percent uptime is the running average of the day
      //   Every time ,this runs, it increases counter by 1 and percent uptime
      //       by 100 then divide by counter to get the running average of percent
      //       uptime
      //       k = k + 1
      //       use ravg function for running average (*UPTRAZ for trend)
      //   There is another tag *UPTZ in historian and let historian averaging
      //   for report. If loop is on , this *UPTZ tag = 100.
      //               If loop is off, this *UPTZ tag = 0.
      //       use uptime function 
      //   Foxserv shall average 10 min. data and historian shall average this
      //   for the day. 10min historian lives 1 month,hourly lives 3 months
      /////////////////////////////////////////////////////////////////////////////////////  
      try {
         if ( (gintWeekDay = 1) && (gintHour = 0) && (gintMinute = 0)  && (gintSecond < 30) ) {
            g.wv("36CMPVARKZ").Value = 0;
            g.ws("36CMPVARKZ").Value = 0;
         }
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to update 36CMPVARKZ}");
         g.ws("36CMPVARKZ").Value = 1;
      }      
 
      try { 
         g.wv("36XI02UPTZ").Value  = (g.v("22TC3551LX")   == 1 ? 100 : 0);
         g.wv("36XI04UPTZ").Value  = (g.v("36UABH1041M")  == 1 ? 100 : 0);
         g.wv("36XI24UPTZ").Value  = (g.v("36UPDD6241M")  == 1 ? 100 : 0);
         g.wv("37XI51UPTZ").Value  = (g.v("37FC105L")     == 1 ? 100 : 0);
         g.wv("37XI521UPTZ").Value = (g.v("37FC119L")     == 1 ? 100 : 0);
         g.wv("37XI522UPTZ").Value = (g.v("37RF52CC1STA") == 1 ? 100 : 0);
         g.wv("37XI53NUPTZ").Value = (g.v("37UABH1531M")  == 1 ? 100 : 0);
         g.wv("37XI53SUPTZ").Value = (g.v("37UABH1532M")  == 1 ? 100 : 0);
         g.wv("37XI54EUPTZ").Value = (g.v("37HC914M")     == 1 ? 100 : 0);
         g.wv("37XI54WUPTZ").Value = (g.v("37HC915M")     == 1 ? 100 : 0);
         g.wv("37XI57UPTZ").Value  = (g.v("37TC569L")     == 1 ? 100 : 0);
         g.wv("37XI60UPTZ").Value  = (g.v("37FC113L")     == 1 ? 100 : 0);
         g.wv("36XIDMCUPTZ").Value = (g.v("36DMCONOFF")   == 1 ? 100 : 0);
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to update one or more Uptime Monitors}");
      } 

      /////////////////////////////////////////////////////////////////////////////////////  
      //                         10AM to 10AM ACCUM for 45FI200
      /////////////////////////////////////////////////////////////////////////////////////  
      try {
         g.wv("45SYNC8AMZ").Value = (( (Math.abs(gintHour - 10.00) < 0.001) && (gintMinute = 0) ) ? 1 : 0);
         g.ws("45SYNC8AMZ").Value = 0;
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 45SYNC8AMZ}");
         g.ws("45SYNC8AMZ").Value = 1;
      }
      
      /////////////////////////////////////////////////////////////////////////////////////  
      //                              Misc Calc for RCM
      /////////////////////////////////////////////////////////////////////////////////////  
      try {
         g.wv("36TI1560DX").Value = g.v("36TI1559CX") + g.v("36TI1560CX");
         g.ws("36TI1560DX").Value = (((g.s("36TI1559CX") + g.s("36TI1560CX")) == 0) ? 0 : 1);
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 36TI1560DX}");
         g.ws("36TI1560DX").Value = 1;
      }

      try {
         g.wv("36TI1562DX").Value = (g.v("36TI1561CX") + g.v("36TI1562CX"));
         g.ws("36TI1562DX").Value = (((g.s("36TI1561CX") + g.s("36TI1562CX")) == 0) ? 0 : 1);
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 36TI1562DX}");
         g.ws("36TI1562DX").Value = 1;
      }

      try {
         g.wv("37TIR6DLTZ").Value = g.v("37TI592") - g.v("37TI598A");
         g.ws("37TIR6DLTZ").Value = (((g.s("37TI592") + g.s("37TI598A")) == 0) ? 0 : 1);
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37TIR6DLTZ}");
         g.ws("37TIR6DLTZ").Value = 1;
      }

      /////////////////////////////////////////////////////////////////////////////////////  
      //                    Fuel gas total for Refinery fuel gas balance
      ///////////////////////////////////////////////////////////////////////////////////// 
      try {
         g.wv("36FIFGTOTZ").Value = g.v("37FI123X") + (g.v("36FI177") / 1000.0);
         g.ws("36FIFGTOTZ").Value = (((g.s("37FI123X") + g.s("36FI177")) == 0) ? 0 : 1);
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 36FIFGTOTZ}");
         g.ws("36FIFGTOTZ").Value = 1;
      }

      /////////////////////////////////////////////////////////////////////////////////////  
      //                           Steam Balance Calculation
      //                      Not using complex (In-Out)/Plot egde
      //                              Using (In/Out)*100
      /////////////////////////////////////////////////////////////////////////////////////  

      /////////////////////////////////////////////////////////////////////////////////////  
      //                                  275# Calc
      /////////////////////////////////////////////////////////////////////////////////////  
      try {
         g.wv("37FIE4STM").Value = (g.v("37FI132") - g.v("37FI127")) * 8.34 * 60.0 / 1000.0;
         g.ws("37FIE4STM").Value = (((g.s("37FI132") + g.s("37FI127")) == 0) ? 0 : 1);
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 36FIFGTOTZ}");
         g.ws("37FIE4STM").Value = 1;
      }

      try {
         var dblIn275 = g.v("37FI102") + g.v("37P4BSTM") + g.v("37P4ASTM") + g.v("37FIE4STM") + 
                        g.v("37P2BSTM") + g.v("37P11BSTM");
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate dblIn275}");
         dblIn275 = 0;
      }

      try {
         var dbl37FV119A = (888.58 * ((g.v("37FC119O") - 50.0) * 2.0) - 0.22727) / 1000.0;
         dbl37FV119A = ((dbl37FV119A < 0.0) ? 0 : dbl37FV119A);  
         g.wv("37FV119A").Value = dbl37FV119A;
         g.ws("37FV119A").Value = g.s("37FC119O");
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37FV119A}");
         g.ws("37FV119A").Value = 1;
      }      
      
      // if (Z37FC119O > 50.0)  Z37FV119B=2.127 * 50.0
      // ignore valve calculation for FV119B, use FV119A valve
      // meaning FC119 - FV119A      
      try {         
         var dbl37FV119B = g.v("37FC119") - dbl37FV119A;    
         g.wv("37FV119B").Value = dbl37FV119B;
         g.ws("37FV119B").Value = (((g.s("37FC119") + g.s("37FC119O")) == 0) ? 0 : 1);
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37FV119B}");
         g.ws("37FV119B").Value = 1;
      }

      try {
         var dblOut275 = g.v("37PV334") + dbl37FV119B;
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate dblOut275}");
         dblOut275 = 0;
      }

      try {         
         g.wv("37UCL275STM").Value = SafeRatio(dblIn275, dblOut275) * 100.0;         
         g.ws("37UCL275STM").Value = (((g.s("37FC119") + g.s("37FC119O") + g.s("37PV334")) == 0) ? 0 : 1);
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37UCL275STM}");
         g.ws("37UCL275STM").Value = 1;
      }

      try {         
         g.wv("37K1LEAK").Value = ((g.v("37FI102") > 5.0) ? 1.276 : 0);
         g.ws("37K1LEAK").Value = g.s("37FI102");
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37K1LEAK}");
         g.ws("37K1LEAK").Value = 1;
      }

      try {         
         g.wv("37PV334LEAK").Value = ((g.v("37PV334") > 1.0) ? 0 : Math.abs(dblIn275 - dblOut275));
         g.ws("37PV334LEAK").Value = g.s("37PV334");
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37PV334LEAK}");
         g.ws("37PV334LEAK").Value = 1;
      }

      /////////////////////////////////////////////////////////////////////////////////////  
      //                                  175# Calc
      /////////////////////////////////////////////////////////////////////////////////////  
      try {
         g.wv("37PV334").Value = 0.676 * g.v("37PC334O");
         g.ws("37PV334").Value = g.s("37PC334O");
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37PV334}");
         g.ws("37PV334").Value = 1;
      }

      // Take PV334LEAK out of in175. Test and there is no leak. 11/21/95
      try {
         var dblIn175 = g.v("37FI154") + g.v("37PV334") + (g.v("37FI137") / 1000.0) + g.v("37FI178T");
         var dblOut175 = g.v("37FI178M") + g.v("37P19BSTM") + g.v("37P20BSTM") + g.v("37P5ASTM") + g.v("37P1BSTM");
         g.wv("37UCL175STM").Value = ((dblOut175 <= 0) ? 0 : (dblIn175 / dblOut175 * 100.0));
         g.ws("37UCL175STM").Value = (((g.s("37PV334") + g.s("37FI137") + g.s("37FI178T") + 
                                        g.s("37FI178M") + g.s("37P19BSTM") + g.s("37P20BSTM") + 
                                        g.s("37P5ASTM") + g.s("37P1BSTM")) == 0) ? 0 : 1);
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37UCL175STM}");
         g.ws("37UCL175STM").Value = 1;
      }
     
      /////////////////////////////////////////////////////////////////////////////////////  
      //                                  40# Calc
      /////////////////////////////////////////////////////////////////////////////////////  
      try {
         var dblIn40 = g.v("37P1BSTM") + g.v("37P5ASTM") + g.v("37FI181T") + g.v("37K1LEAK") + 
                       g.v("37P4LEAK") + g.v("37P2BLEAK") + g.v("37P11BLEAK");
         var dblOut40 = g.v("37FI176") + g.v("37FI181M");
         g.wv("37UCL40STM").Value = ((dblOut40 <= 0) ? 0 : (dblIn40 / dblOut40 * 100.0));
         g.ws("37UCL40STM").Value = (((g.s("37P1BSTM") + g.s("37P5ASTM") + g.s("37FI181T") + 
                                       g.s("37K1LEAK") + g.s("37P4LEAK") + g.s("37P2BLEAK") + 
                                       g.s("37P11BLEAK") + g.s("37FI176") + g.s("37FI181M")) == 0) ? 0 : 1);
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37UCL40STM}");
         g.ws("37UCL40STM").Value = 1;
      }
     
      /////////////////////////////////////////////////////////////////////////////////////  
      //                                  600# Calc
      /////////////////////////////////////////////////////////////////////////////////////  
      try {
         var dblIn600  = g.v("37FI126") + g.v("37FI179T");
         var dblOut600 = g.v("37FI102") + g.v("37FC114") + g.v("37FV119A") + g.v("37P4ASTM") + 
                         g.v("37P4BSTM") + g.v("37P2BSTM") + g.v("37P11BSTM") + g.v("37FI179M");
         g.wv("37UCL600STM").Value = ((dblOut600 <= 0) ? 0 : (dblIn600 / dblOut600 * 100.0));
         g.ws("37UCL600STM").Value = (((g.s("37FI126") + g.s("37FI179T") + g.s("37FI102") + g.s("37FC114") +
                                        g.s("37FV119A") + g.s("37P4ASTM") + g.s("37P4BSTM") + g.s("37P2BSTM") +  
                                        g.s("37P11BSTM") + g.s("37FI179M")) == 0) ? 0 : 1);
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37UCL600STM}");
         g.ws("37UCL600STM").Value = 1;
      }
     
      /////////////////////////////////////////////////////////////////////////////////////  
      //                                  36 Unit Calc
      /////////////////////////////////////////////////////////////////////////////////////  
      try {
         var dbl36FIE12STM = (g.v("36FC166") + (g.v("36FI215") * 1000.0)) * 31.735 / 10757.0;
         g.wv("36FIE12STM").Value = dbl36FIE12STM;
         g.ws("36FIE12STM").Value = (((g.s("36FC166") + g.s("36FI215")) == 0) ? 0 : 1);
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 36FIE12STM}");
         g.ws("36FIE12STM").Value = 1;
      }

      try {
         var dblIn40_36  = g.v("36P29BSTM") + dbl36FIE12STM;
         var dblOut40_36 = g.v("36FI174");
         g.wv("36UCL40STM").Value = ((dblOut40_36 <= 0) ? 0 : (dblIn40_36 / dblOut40_36 * 100.0));
         g.ws("36UCL40STM").Value = (((g.s("36P29BSTM") + g.s("36FI174") + g.s("36FC166") + 
                                       g.s("36FI215")) == 0) ? 0 : 1);
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 36UCL40STM}");
         g.ws("36UCL40STM").Value = 1;
      }

      try {
         var dblIn175_36  = g.v("36FI127");
         var dblOut175_36 = g.v("36FI175") + 0.045;
         g.wv("36UCL175STM").Value = ((dblOut175_36 <= 0) ? 0 : (dblIn175_36 / dblOut175_36 * 100.0));
         g.ws("36UCL175STM").Value = (((g.s("36P29BSTM") + g.s("36FI174") + g.s("36FC166") + 
                                       g.s("36FI215")) == 0) ? 0 : 1);
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 36UCL175STM}");
         g.ws("36UCL175STM").Value = 1;
      }

      /////////////////////////////////////////////////////////////////////////////////////  
      //                          Date And Time Targets Last Updated
      /////////////////////////////////////////////////////////////////////////////////////  
      try {
         if (g.v("36TGNEW") == 1) {
            g.wv("36TGMM").Value   = gintMonth;
            g.wv("36TGDD").Value   = gintDay;
            g.wv("36TGYY").Value   = gintYear;
            g.wv("36TGHH").Value   = gintHour;
            g.wv("36TGMIMI").Value = gintMinute;
         }
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to update one or more unit 36 target time tags}");
      }

      try {
         if (g.v("37TGNEW") == 1) {
            g.wv("37TGMM").Value   = gintMonth;
            g.wv("37TGDD").Value   = gintDay;
            g.wv("37TGYY").Value   = gintYear;
            g.wv("37TGHH").Value   = gintHour;
            g.wv("37TGMIMI").Value = gintMinute;
         }
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to update one or more unit 37 target time tags}");
      }

      /////////////////////////////////////////////////////////////////////////////////////  
      //                           Mass Balance Calc for 36 unit
      /////////////////////////////////////////////////////////////////////////////////////  

      // Correct Meters For Molecular Weight Changes

      try {
         var dbl36Mwt = (g.v("36LB003H2") * 0.02016) + (g.v("36LB003C1") * 0.16042) + (g.v("36LB003C2") * 0.3007) +
                        (g.v("36LB003C3") * 0.44097) + ((g.v("36LB003IC4") + g.v("36LB003NC4")) * 0.58124) +
                        (g.v("36LB003BTM") * 0.86178) + ((g.v("36LB003IC5") + g.v("36LB003NC5")) * 0.72151);
         if (dbl36Mwt != 0) {         
            g.wv("36FI128Z").Value = g.v("36FI128Z") * SafeSqr(3.47 / dbl36Mwt);
            g.wv("36FI213Z").Value = g.v("36FI213Z") * SafeSqr(3.47 / dbl36Mwt);
         }
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 36FI128Z and 36FI213Z}");
      }

      // use special sample's result for D5 and D6
      // was 18.2091 now use 17.8 per Paul Dewaele, 2/22/2000
      try {         
         g.wv("36FI124Z").Value = g.v("36FI124Z") * SafeSqr(17.85 / 17.8) * 100.0;         
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 36FI124Z}");
      }
      
      // was 56.91 now use 36.5 per Paul Dewaele, 2/22/2000
      try {         
         g.wv("36FI146Z").Value = g.v("36FI146Z") * SafeSqr(41.77 / 36.5) * 100.0;         
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 36FI146Z}");
      }

      try {
         g.UpdateValues(2);   //Refresh calcs before we do this to get latest values
         var dblD4gas  = dbl36Mwt * (g.v("36FI128Z") + g.v("36FI213Z")) * 1000000 / (379 * 24);
         var dblD5gas  = 17.8 * g.v("36FI124Z") * 1000000 / (379 * 24);
         var dblD6gas  = 36.5 * g.v("36FI146Z") * 1000000 / (379 * 24);      
         var dblLtgaso = g.v("36FI157Z") * (141.5 / (131.5 + g.v("36LB004APIX"))) * 14595;
         var dblHygaso = g.v("36FC158Z") * (141.5 / (131.5 + g.v("36LB005APIX"))) * 14595;
         var dblNo2    = g.v("36FI167Z") * (141.5 / (131.5 + g.v("36LB006APIX"))) * 14595;
         var dblVacBtm = g.v("36FI165Z") * (141.5 / (131.5 + g.v("36LB007APIX"))) * 14595;
         var dblTotalOut36 = dblD4gas + dblD5gas + dblD6gas + dblLtgaso + dblHygaso + dblNo2 + dblVacBtm;
         var dblLiqChg = g.v("36FC101Z") * (141.5 / (131.5 + g.v("36LB011APIX"))) * 14595;
         var dblH2fr37 = 2.29 *  g.v("37FIH2TO36Z") * 1000000 / (379 * 24);
         var dblK1buff = 2.29 *  g.v("36FI2100Z")   * 1000000 / (379 * 24);
         var dblTotalIn36 = dblLiqChg + dblH2fr37 + dblK1buff;
         g.wv("36XIMASSBALZ").Value = SafeRatio(dblTotalOut36, dblTotalIn36) * 100;
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 36XIMASSBALZ}");
      }

      /////////////////////////////////////////////////////////////////////////////////////  
      //                           Mass Balance Calc for 37 unit
      /////////////////////////////////////////////////////////////////////////////////////  

      // Correct Meters For Molecular Weight Changes

      try {
         var dbl37Mwt = (g.v("22A30211H2X") * 0.02016) + (g.v("22A30211C1X") * 0.16042) + 
                        (g.v("22A30211C2X") * 0.3007) + (g.v("22A30211C3X") * 0.44097) + 
                        ((g.v("22A30211IC4X") + g.v("22A30211NC4X")) * 0.58124) +
                        (g.v("22A30211C3EX") * 0.42078) + (g.v("22A30211C5X") * 0.72151) + 
                        (g.v("22A30211C4EX") * 0.56104);
         if (dbl37Mwt != 0) {         
            g.wv("37FC207Z").Value = g.v("37FC207Z") * SafeSqr(0.6483 * 28.964 / dbl37Mwt);
         }
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37FC207Z}");
      }

      // Use PSA Hydrogen Analysis For Import Hydrogen
      try {
         var dblH2Mwt = (g.v("42LB032H2") * 0.02016) + (g.v("42LB032C1") * 0.16042);
         if (dblH2Mwt != 0) {         
            g.wv("37FI217Z").Value = g.v("37FI217Z") * SafeSqr(0.069 * 28.964 / dblH2Mwt);
            g.wv("37FI217MZ").Value = g.v("37FI217MZ") * SafeSqr(0.069 * 28.964 / dblH2Mwt);
         }
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37FI217Z and 37FI217MZ}");
      }

      // For Every  Mole Of CO2 Made, Two Mole Of Steam Was Used
      try {
         g.wv("37FISTMPROCZ").Value = (g.v("37FC207Z") + g.v("37FC113Z")) * 1000 * 2.0 * 18.016 / (379 * 24);
         g.ws("37FISTMPROCZ").Value = (((g.s("37FC207Z") + g.s("37FC113Z")) == 0) ? 0 : 1);
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37FISTMPROCZ}");
         g.ws("37FISTMPROCZ").Value = 1;
      }

      try {
         g.UpdateValues(2);   //Refresh calcs before we do this to get latest values
         var dblco2      = (g.v("37FC207Z") + g.v("37FC113Z")) * 1000000 * 44.01 / (379 * 24);         
         var dblBuff     = 2.29 * g.v("36FI2100Z") * 1000000 / (379 * 24);         
         var dblExport   = dblH2Mwt * g.v("37FI217MZ") * 1000000 / (379 * 24);            
         var dblTotalOut37 = dblH2fr37 + dblco2 + dblBuff + dblExport;
         var dblCokerGas = (g.v("37FC207Z") - g.v("37FC105Z")) * 1000000 / (379 * 24);         
         var dblNatGas   = 17.0239 *  g.v("37FC113Z") * 1000000 / (379 * 24);         
         var dblImport   = dblH2Mwt *  g.v("37FI217Z") * 1000000 / (379 * 24);         
         var dblTotalIn37 = dblCokerGas + dblNatGas + dblImport + (g.v("37FISTMPROCZ") * 1000.0);
         g.wv("37XIMASSBALZ").Value = SafeRatio(dblTotalOut37, dblTotalIn37) * 100;
      } catch(objError) {
         gobjLocalMessenger.SendError(strFunction + " {Unable to calculate 37XIMASSBALZ}");
      }

      gobjLocalMessenger.SendDebug(strFunction + " {End}");
      return(true);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" +
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      return(false);
   }
}

/**************************************************************************
 *
 * Script  : Utility.js
 *
 * Purpose : Common utility functions.
 *
 **************************************************************************
 * Revision History
 *
 *      V1.0.0  03/07/2000  James Bischoff 
 *         Created  
 *
 **************************************************************************/

/**************************************************************************
 * Function : ListToDictionary
 * Purpose  : Convert a list like "a,b,c" into a dictionary object with
 *            one string element for each list item.
 **************************************************************************/
function ListToDictionary(strList, objDictionary) {

   var strFunction = "ListToDictionary";
   
   var arrList = null;
   var lngElement = null;

   try {
      gobjLocalMessenger.SendDebug(strFunction + " {Start}");
      
      arrList = strList.split(",");
      objDictionary.RemoveAll();
      
      for (lngElement in arrList) {
         objDictionary.add(arrList[lngElement] + "",arrList[lngElement] + "");
         gobjLocalMessenger.SendDebug(strFunction + " {Add Element [" + arrList[lngElement] + "]}");
      }
      
      gobjLocalMessenger.SendDebug(strFunction + " {End}");
      return(true);
   }
   catch(objError) {
      gobjLocalMessenger.SendError(strFunction + " {" + 
         gobjLocalMessenger.BuildErrorMessage(objError) + "}");
      throw(objError);
   }
}