//------------------------------------------------------------------------------ // Copyright (C) 2008 Invensys Systems Inc. All rights reserved. // // THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. //------------------------------------------------------------------------------ using System; using System.Runtime.InteropServices; using ArchestrA.Core; using ArchestrA.Toolkit; namespace ArchestrA.Toolkit.Watchdog { [Guid("85ca8612-8c40-4e51-b8b5-8588f2af5e59")] /// /// Summary description for Watchdog /// public class StatsRuntime : RuntimeBase { #region Attributes - Toolkit generated code // The following C# properties have been defined to simplify access to // attribute values - do not modify the contents of this region with // the code editor. private CMxTime LastTimeout { get { return InternalReferenceOnly.LastTimeout; } set { InternalReferenceOnly.LastTimeout.Set(value); } } private CMxInteger TimeoutCnt { get { return InternalReferenceOnly.TimeoutCnt; } set { InternalReferenceOnly.TimeoutCnt.Set(value); } } private CMxBoolean Reset { get { return InternalReferenceOnly.Reset; } set { InternalReferenceOnly.Reset.Set(value); } } private CMxElapsedTime DelayMax { get { return InternalReferenceOnly.DelayMax; } set { InternalReferenceOnly.DelayMax.Set(value); } } private CMxElapsedTime DelayAverage { get { return InternalReferenceOnly.DelayAverage; } set { InternalReferenceOnly.DelayAverage.Set(value); } } #endregion Attributes #region Internal Reference Only //Toolkit code required to access the attributes declared in the Object Class private Stats InternalReferenceOnly = null; #endregion Internal Reference Only #region Declarations //Declare Runtime Class Variables here. //Variables declared in this region are available to all methods //in the Runtime Class. bool m_PreviousTimeoutCondition; TimeSpan m_PreviousTimeSinceChange; TimeSpan m_DelayTotal; long m_ChangeDetectedCount; #endregion Declarations public StatsRuntime() { InternalReferenceOnly = new Stats(); this.AObjectInstance = InternalReferenceOnly; #region Runtime Event Registration - Toolkit generated code // Required region for Runtime Events - do not modify // the contents of this region with the code editor. base.RuntimeGetStatusDesc += new RuntimeGetStatusDescDelegate(StatsRuntime_RuntimeGetStatusDesc); base.RuntimeSetScanState += new RuntimeSetScanStateDelegate(StatsRuntime_RuntimeSetScanState); base.RuntimeExecute += new RuntimeExecuteDelegate(StatsRuntime_RuntimeExecute); base.RuntimeShutdown += new RuntimeShutdownDelegate(StatsRuntime_RuntimeShutdown); base.RuntimeStartup += new RuntimeStartupDelegate(StatsRuntime_RuntimeStartup); base.RuntimeDynamic += new RuntimeDynamicSetHandlerDelegate(StatsRuntime_RuntimeDynamic); base.RuntimeInitialize += new RuntimeInitializeDelegate(StatsRuntime_RuntimeInitialize); #endregion Runtime Event Registration #region Runtime Set Handler Registration – Toolkit generated code // Required method for Runtime SetHandlers. // Changes made using the code editor will appear in the Toolkit Editor. // // WARNING: Changes made to this region will result in a Shape Change. // TODO: Runtime SetHandler registration this.RegisterRuntimeSetHandler("Reset", new RuntimeSetHandlerDelegate(ResetSetHandler)); #endregion Runtime Set Handler Registration #region Primitive Wrapper Initialization - Toolkit generated code #endregion Primitive Wrapper Initialization #region Primitive Advise only Activate Registration - Toolkit generated code #endregion Primitive Advise only Activate Initialization } private void StatsRuntime_RuntimeInitialize(object sender) { //------------------------------------------------------------------------------ // TODO: Runtime - Initialize // // Do not read or write attribute values of this primitive during Initialize //------------------------------------------------------------------------------ } private void StatsRuntime_RuntimeExecute(object sender) { //------------------------------------------------------------------------------ // TODO: Runtime - Execute // // This is where the main logic of the object periodically executes when // the object is on scan. // // Read or write the attributes of this primitive using the generated // properties (Value, Quality). //------------------------------------------------------------------------------ #region Example code // // The lines below both increment the value of the attribute "Attribute1" by 1 // Example_001 ++; // Example_001 = Example_001 + 1; // // //Example_001 quality is set to Bad on Condition_001 being true. // Example_001.Quality = (Condition_001 ? DataQuality.DataQualityBad : DataQuality.DataQualityGood); // // // The attribute "ElapsedTime" contains the time elapsed since the last reset // ElapsedTime = GetScanTime() - TimeOfLastReset; // // // Increment the 3rd element of an array // FloatArray[3] ++; // // // Increment all the elements of an array // for( short counter = 1; counter <= FloatArray.Length; counter ++) // { // FloatArray[counter] ++; // } #endregion bool CurrentTimeoutCondition; GetBoolean("myparent.Timeout", out CurrentTimeoutCondition); if (!m_PreviousTimeoutCondition && CurrentTimeoutCondition) { TimeoutCnt++; LastTimeout = GetScanTime(); } //Compute the average delay by maintaining a sum/count of all the time elapsed between input changes, //(since the last reset) and dividing by the number input changes detected // TimeSpan CurrentTimeSinceChange; GetElapsedTime("myparent.TimeSinceChange", out CurrentTimeSinceChange); if (CurrentTimeSinceChange.Ticks == 0) //The input just changed { m_DelayTotal = m_DelayTotal + m_PreviousTimeSinceChange; DelayAverage = new TimeSpan(m_DelayTotal.Ticks / ++m_ChangeDetectedCount); } //Compute the maximum delay if (CurrentTimeSinceChange > DelayMax) { DelayMax = CurrentTimeSinceChange; } //Save these values for tests made during the next scan (see above) m_PreviousTimeoutCondition = CurrentTimeoutCondition; m_PreviousTimeSinceChange = CurrentTimeSinceChange; } private void StatsRuntime_RuntimeShutdown(object sender) { //------------------------------------------------------------------------------ // TODO: Runtime Event - Shutdown // // Clean up dynamic allocation, release open resources, etc. //------------------------------------------------------------------------------ // Activate marked attributes before shutting down AdviseOnlyActivateAttributes(); } private void StatsRuntime_RuntimeStartup(object sender, RuntimeStartupEventArgs e) { //------------------------------------------------------------------------------ // TODO: Runtime Event - Startup // // Cache attributes. Cache Primitive IDs of other known primitives. //------------------------------------------------------------------------------ // RestoreDynamicAttributes will recreate the Dynamic Attributes and restore the check pointed // values during failover startup. The Failover Support for Dynamic Attributes option must // be enabled via the Object Editor to support this function. To maintain the // Dynamic Attribute values the CheckpointDynamicAttributeData function must be called // when Dynamic Attribute values are modified (refer to the Dynamic Attribute Set Handler). //RestoreDynamicAttributes(); // Execute offscan code to initialize the object in its offscan state. SetScanState(false); // Suspend marked attributes at startup AdviseOnlySuspendAttributes(); } private void AdviseOnlySuspendAttributes() { // Required Method for Advise only Active. // Do not modify this method via the code editor. // // WARNING: Changes made to this method will be overwritten by the code generator. if (AdviseOnlyActiveEnabled) { } } private void AdviseOnlyActivateAttributes() { // Required Method for Advise only Active. // Do not modify this method via the code editor. // // WARNING: Changes made to this method will be overwritten by the code generator. if (AdviseOnlyActiveEnabled) { } } private void StatsRuntime_RuntimeSetScanState(object sender, RuntimeSetScanStateEventArgs e) { //------------------------------------------------------------------------------ // TODO: Runtime Event - SetScanState // // Perform actions when the object goes on or off scan. //------------------------------------------------------------------------------ } private void StatsRuntime_RuntimeGetStatusDesc(object sender, ref RuntimeGetStatusDescEventArgs e) { //------------------------------------------------------------------------------ // TODO: Runtime Event - GetStatusDesc // // This routine provides a String for an error code when a client requests it. // By default this method looks for an entry in the dictionary that has the // DetailedErrorCode as the PhraseID. // // You need to change this implmentation if you want to provide embedded values // within your messages, or you want to use string PhraseIDs instead of integer // PhraseIDs. //------------------------------------------------------------------------------ switch (e.detailedErrorCode) { default: e.status = GetText((int)e.detailedErrorCode); break; } } private void StatsRuntime_RuntimeDynamic(object sender, ref RuntimeSetHandlerEventArgs e) { string attrName = Get(e.attributeHandle.shAttributeId, e.attributeHandle.shPrimitiveId, EATTRIBUTEPROPERTY.idxAttribPropName); //------------------------------------------------------------------------------ // TODO: Runtime Event - Dynamic Set Handler // // Implement set handler code for any dynamic attributes you create with set handlers //------------------------------------------------------------------------------ // CheckpointDynamicAttributeData will update the checkpoint values for all Dynamic Attributes. // To recreate Dynamic Attributes and restore Dynamic Attribute values the RestoreDynamicAttributes // function must be called when starting up from failover (refer to the Startup method). //CheckpointDynamicAttributeData(); #region Example // if (attrName == "MyDynamic") // { // if (e.Value > 10) // { // LogWarning(string.Format("value for {0} must be less or equal to 10", attrName)); // } // else // { // SetValue(attrName, e.Value); // } // // // return; // } #endregion // if unhandled a warning is shown as a reminder SetValue(e.attributeHandle.shAttributeId, e.attributeHandle.shPrimitiveId, e.Value); LogWarning(string.Format("Uknown set handler for attribute '{0}'", attrName)); } private void ResetSetHandler(object sender, ref RuntimeSetHandlerEventArgs e) { TimeoutCnt = 0; LastTimeout = DateTime.MinValue; DelayAverage = new TimeSpan(0); DelayMax = new TimeSpan(0); m_ChangeDetectedCount = 0; m_DelayTotal = new TimeSpan(0); } } }