void sinkRegisterIsos()
        {
            var tEngs = TheThingRegistry.GetBaseEnginesAsThing(false, true);

            foreach (var t in tEngs)
            {
                if (TheThing.GetSafePropertyBool(t, "IsIsolated"))
                {
                    IBaseEngine tBase = TheThingRegistry.GetBaseEngine(t, true);
                    if (tBase != null && tBase.GetISOLater() != null)
                    {
                        TheThing tT   = TheThingRegistry.GetThingByFunc(MyBaseEngine.GetEngineName(), s => s.DeviceType == TheISOlaterKPIs.eDeviceType && TheThing.GetSafePropertyString(s, "ISOLaterName") == t.EngineName);
                        var      tKPI = new TheISOlaterKPIs(tT, this, t.EngineName);
                        TheThingRegistry.RegisterThing(tKPI);
                    }
                }
            }
            List <TheThing> tDevList = TheThingRegistry.GetThingsByProperty(MyBaseEngine.GetEngineName(), Guid.Empty, "DeviceType", TheKPIReport.eDeviceType);

            if (tDevList.Count > 0)
            {
                foreach (TheThing tDev in tDevList)
                {
                    if (tDev.GetObject() == null)
                    {
                        TheKPIReport cs = new TheKPIReport(tDev, this);
                        TheThingRegistry.RegisterThing(cs);
                    }
                }
            }
        }
Beispiel #2
0
        void SendRuleTSM(bool serviceOnly)
        {
            string engine  = TheCommonUtils.CStr(GetProperty("TSMEngine", false));
            string text    = TheCommonUtils.CStr(GetProperty("TSMText", false));
            string payload = TheCommonUtils.CStr(GetProperty("TSMPayload", false));

            //payload = payload.Replace("%DTO%", TheCommonUtils.CStr(DateTimeOffset.Now));
            //text = text.Replace("%DTO%", TheCommonUtils.CStr(DateTimeOffset.Now));
            ICDEThing triggerThing = TheThingRegistry.GetThingByMID("*", TheCommonUtils.CGuid(TriggerObject)) as ICDEThing;
            string    escPayload   = TheCommonUtils.GenerateFinalStr(payload, triggerThing);

            escPayload = TheCommonUtils.GenerateFinalStr(escPayload, MyBaseThing);
            string escText = TheCommonUtils.GenerateFinalStr(text, triggerThing);

            escText = TheCommonUtils.GenerateFinalStr(escText, MyBaseThing);

            if (!string.IsNullOrEmpty(engine) && !string.IsNullOrEmpty(text))
            {
                TSM customTSM = new TSM(engine, escText, escPayload);
                if (serviceOnly)
                {
                    customTSM.SetToServiceOnly(true);
                }
                TheCommCore.PublishCentral(customTSM, true);
            }
            if (IsRuleLogged)
            {
                LogEvent(escPayload);
            }
            if (TheThing.GetSafePropertyBool(MyBaseThing, "IsEVTLogged"))
            {
                TheLoggerFactory.LogEvent(eLoggerCategory.RuleEvent, TheCommonUtils.GenerateFinalStr(MyBaseThing.FriendlyName, MyBaseThing), eMsgLevel.l4_Message, TheBaseAssets.MyServiceHostInfo.GetPrimaryStationURL(false), escText, escPayload);
            }
        }
        public virtual bool Init()
        {
            if (mIsInitCalled)
            {
                return(false);
            }
            mIsInitCalled = true;

            if (string.IsNullOrEmpty(MyBaseThing.ID))
            {
                MyBaseThing.ID = Guid.NewGuid().ToString();
                this.Gen_Config_StatsUpdateInterval = 5000;
            }
            MyBaseThing.Value = "0";
            TheThing.SetSafePropertyBool(MyBaseThing, "IsActive", true);
            MyBaseThing.GetProperty(nameof(Gen_Config_PropertyUpdateInterval), true).RegisterEvent(eThingEvents.PropertyChanged, OnChangeTimer);
            MyBaseThing.GetProperty(nameof(Gen_Config_NumberOfActiveProperties), true).RegisterEvent(eThingEvents.PropertyChanged, OnChangeTimer);
            MyBaseThing.StatusLevel = 0;
            if (TheThing.GetSafePropertyBool(MyBaseThing, "AutoStart"))
            {
                OnChangeTimer(null);
            }
            mIsInitialized = true;
            return(true);
        }
        public override bool Init()
        {
            if (!mIsInitStarted)
            {
                mIsInitStarted = true;
                MyBaseEngine.RegisterEvent(eEngineEvents.ShutdownEvent, OnShutdown);
                TheThing.SetSafePropertyBool(MyBaseThing, "IsConnected", false);

                IBaseEngine tBase = TheThingRegistry.GetBaseEngine(TheThing.GetSafePropertyString(MyBaseThing, "ISOLaterName"), true);
                if (tBase != null)
                {
                    MyIsolator = tBase.GetISOLater() as Process;
                    if (MyIsolator == null)
                    {
                        MyBaseThing.LastMessage = "Engine not isolated";
                        MyBaseThing.StatusLevel = 3;
                        mIsInitCompleted        = true;
                        return(true);
                    }
                    MyBaseThing.LastMessage = "KPIs monitor ready";
                    MyBaseThing.StatusLevel = 1;
                    if (TheThing.GetSafePropertyBool(MyBaseThing, "AutoConnect"))
                    {
                        Connect();
                    }
                }
                else
                {
                    MyBaseThing.LastMessage = "Base Engine cloud not be located";
                    MyBaseThing.StatusLevel = 3;
                }
                mIsInitCompleted = true;
            }
            return(true);
        }
Beispiel #5
0
        private void SetCtrlType()
        {
            if (CountBar == null)
            {
                return;
            }
            string     tControl  = ThePropertyBag.PropBagGetValue(CountBar.PropertyBag, "ControlType", "=");
            eFieldType tCtrlType = eFieldType.SingleEnded;

            if (!string.IsNullOrEmpty(tControl) && TheCommonUtils.CInt(tControl) == 0 && tControl.Length > 0)
            {
                TheControlType tType = TheNMIEngine.GetControlTypeByType(tControl);
                if (tType != null)
                {
                    ThePropertyBag.PropBagUpdateValue(CountBar.PropertyBag, "EngineName", "=", tType.BaseEngineName);
                }
                tCtrlType = eFieldType.UserControl;
            }
            else
            {
                tCtrlType = (eFieldType)TheCommonUtils.CInt(tControl);
            }
            CountBar.Type        = tCtrlType;
            CountBar.Flags       = TheCommonUtils.CInt(ThePropertyBag.PropBagGetValue(CountBar.PropertyBag, "Flags", "="));
            CountBar.PropertyBag = new TheNMIBaseControl {
                ParentFld = 1
            };
            CountBar.UpdateUXProperties(Guid.Empty);
            CountBar.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "click", (sener, para) => {
                TheThing.SetSafePropertyBool(MyBaseThing, "ClickState", !TheThing.GetSafePropertyBool(MyBaseThing, "ClickState"));
            });
        }
 void sinkTimer(long timer)
 {
     if ((timer % 5) == 0)
     {
         if (TheThing.GetSafePropertyBool(MyBaseThing, "LogKPIs"))
         {
             TheBaseAssets.MySYSLOG.WriteToLog(23099, new TSM(MyBaseEngine.GetEngineName(), TheCDEKPIs.GetKPIs(true), eMsgLevel.l4_Message));
         }
     }
 }
 public TheDataVerifier(TheThing pThing, IBaseEngine pEngine)
 {
     MyBaseThing            = pThing ?? new TheThing();
     MyBaseEngine           = pEngine;
     MyBaseThing.DeviceType = eVThings.eDataVerifier;
     MyBaseThing.EngineName = pEngine.GetEngineName();
     MyBaseThing.SetIThingObject(this);
     if (TheThing.GetSafePropertyBool(MyBaseThing, "AutoStart"))
     {
         StartVerifier();
     }
 }
        void sinkUpdateUX2(cdeP prop)
        {
            string Plotband;

            if (TheThing.GetSafePropertyBool(MyBaseThing, "IsLowAlarm"))
            {
                Plotband = $"SubTitle={TheThing.GetSafePropertyString(MyBaseThing, "StateSensorUnit")}:;:PlotBand=[{{ \"from\": {TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorMinValue")}, \"to\": {TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorAverage")}, \"color\": \"#FF000088\" }}, {{ \"from\": {TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorAverage")}, \"to\": {TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorMaxValue")}, \"color\": \"#00FF0044\" }}]";
            }
            else
            {
                Plotband = $"SubTitle={TheThing.GetSafePropertyString(MyBaseThing, "StateSensorUnit")}:;:PlotBand=[{{ \"from\": {TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorMinValue")}, \"to\": {TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorAverage")}, \"color\": \"#00FF0088\" }}, {{ \"from\": {TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorAverage")}, \"to\": {TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorMaxValue")}, \"color\": \"#FF000044\" }}]";
            }
            GaugeFld?.SetUXProperty(Guid.Empty, Plotband);
        }
Beispiel #9
0
 private void sinkCyclic(long timer)
 {
     if (KPIHarvestInterval == 0)
     {
         return;
     }
     if (timer % KPIHarvestInterval != 0)
     {
         return;
     }
     if (TheThing.GetSafePropertyBool(MyBaseThing, "EnableKPIs"))
     {
         TheCDEKPIs.ToThingProperties(MyBaseThing, true);
     }
 }
Beispiel #10
0
        public override bool Init()
        {
            if (mIsInitCalled)
            {
                return(false);
            }
            mIsInitCalled = true;

            MyBaseThing.RegisterStatusChanged(sinkStatChanged);
            MyBaseThing.StatusLevel = 4;
            MyBaseThing.Value       = "0";
            MyBaseThing.RegisterEvent(eEngineEvents.IncomingMessage, HandleMessage);
            MyBaseEngine.RegisterEvent(eEngineEvents.ThingDeleted, OnThingDeleted);
            MyBaseEngine.RegisterEvent(eEngineEvents.ThingRegistered, OnThingRegisterd);

            if (!TheBaseAssets.MyServiceHostInfo.IsCloudService && !TheThing.GetSafePropertyBool(MyBaseThing, "RanBefore"))
            {
                TheThing.SetSafePropertyBool(MyBaseThing, "RanBefore", true);
                string tAutoPing = TheBaseAssets.MySettings.GetSetting("AutoPing");
                if (!string.IsNullOrEmpty(tAutoPing))
                {
                    TheThing tThing = new TheThing();
                    tThing.EngineName   = MyBaseEngine.GetEngineName();
                    tThing.DeviceType   = eNetworkServiceTypes.PingService;
                    tThing.Address      = tAutoPing;
                    tThing.FriendlyName = tAutoPing;
                    TheThing.SetSafePropertyBool(tThing, "AllowRTT", true);
                    TheThing.SetSafePropertyBool(tThing, "AutoConnect", true);
                    TheThingRegistry.RegisterThing(tThing);
                }
            }

            if (MyBaseEngine.GetEngineState().IsService)
            {
                TheCommonUtils.cdeRunAsync("Init Networkers", true, (o) =>
                {
                    InitNetworkServices();
                    mIsInitialized = true;
                    FireEvent(eThingEvents.Initialized, this, true, true);
                    MyBaseEngine.ProcessInitialized();
                });
            }
            return(false);
        }
Beispiel #11
0
        public static bool CopyStateSensorInfo(TheThing pBaseThing)
        {
            if (pBaseThing == null)
            {
                return(false);
            }
            var t = TheThingRegistry.GetThingByMID("*", TheThing.GetSafePropertyGuid(pBaseThing, "RealSensorThing"));

            if (t != null && TheThing.GetSafePropertyBool(t, "IsStateSensor"))
            {
                if (string.IsNullOrEmpty(TheThing.GetSafePropertyString(pBaseThing, "StateSensorType")))
                {
                    TheThing.SetSafePropertyString(pBaseThing, "StateSensorType", TheThing.GetSafePropertyString(t, "StateSensorType"));
                }
                if (string.IsNullOrEmpty(TheThing.GetSafePropertyString(pBaseThing, "StateSensorUnit")))
                {
                    TheThing.SetSafePropertyString(pBaseThing, "StateSensorUnit", TheThing.GetSafePropertyString(t, "StateSensorUnit"));
                }
                if (string.IsNullOrEmpty(TheThing.GetSafePropertyString(pBaseThing, "StateSensorValueName")))
                {
                    TheThing.SetSafePropertyString(pBaseThing, "StateSensorValueName", TheThing.GetSafePropertyString(t, "StateSensorValueName"));
                }
                if (pBaseThing.GetProperty("StateSensorAverage") == null)
                {
                    TheThing.SetSafePropertyNumber(pBaseThing, "StateSensorAverage", TheThing.GetSafePropertyNumber(t, "StateSensorAverage"));
                }
                if (pBaseThing.GetProperty("StateSensorMinValue") == null)
                {
                    TheThing.SetSafePropertyNumber(pBaseThing, "StateSensorMinValue", TheThing.GetSafePropertyNumber(t, "StateSensorMinValue"));
                }
                if (pBaseThing.GetProperty("StateSensorMaxValue") == null)
                {
                    TheThing.SetSafePropertyNumber(pBaseThing, "StateSensorMaxValue", TheThing.GetSafePropertyNumber(t, "StateSensorMaxValue"));
                }
                if (string.IsNullOrEmpty(TheThing.GetSafePropertyString(pBaseThing, "StateSensorIcon")))
                {
                    TheThing.SetSafePropertyString(pBaseThing, "StateSensorIcon", TheThing.GetSafePropertyString(t, "StateSensorIcon"));
                }
                return(true);
            }
            return(false);
        }
Beispiel #12
0
        public override void Connect(TheProcessMessage pMsg)
        {
            if (IsConnected)
            {
                return;
            }
            IsConnected             = true;
            MyBaseThing.StatusLevel = 1;
            MyBaseThing.LastMessage = $"Connected to Logger at {DateTimeOffset.Now}";

            mLogFilePath    = Address;
            mMaxLogFileSize = (int)TheThing.GetSafePropertyNumber(MyBaseThing, "MaxLogFileSize");
            mWriteToConsole = TheThing.GetSafePropertyBool(MyBaseThing, "WriteToConsole");
            MyCurLog        = TheThing.GetSafePropertyString(MyBaseThing, "LogFilePath");
            mLogFileDate    = TheThing.GetSafePropertyDate(MyBaseThing, "LogFileDate");
            if (string.IsNullOrEmpty(MyCurLog) || (mLogFileDate != DateTimeOffset.MinValue && mLogFileDate.Day != DateTimeOffset.Now.Day))
            {
                LogFilePath = MyCurLog = TheCommonUtils.cdeFixupFileName(mLogFilePath + string.Format("\\LOG_{0:yyyMMdd_HHmmss}.txt", DateTime.Now));
                LogFileDate = mLogFileDate = DateTimeOffset.Now;
            }
            TheCommonUtils.CreateDirectories(MyCurLog);
            TheCDEngines.MyContentEngine.RegisterEvent(eEngineEvents.NewEventLogEntry, sinkNewEvent);

#if !CDE_NET4 && !CDE_NET35
            if (TheBaseAssets.MyCmdArgs?.ContainsKey("CreateEventLog") != true)
            {
                // CODE REVIEW: What is the purpose of this export?
                var pipelineConfig = MyBaseThing.GetThingPipelineConfigurationAsync(false).Result;
                if (pipelineConfig != null)
                {
                    var tWrite = TheCommonUtils.SerializeObjectToJSONString(pipelineConfig);
                    TheCommonUtils.CreateDirectories(TheCommonUtils.cdeFixupFileName($"\\ConfigTemplates\\{MyBaseThing.FriendlyName}.cdeConfig"));
                    using (System.IO.StreamWriter fs = new System.IO.StreamWriter(TheCommonUtils.cdeFixupFileName($"\\ConfigTemplates\\{MyBaseThing.FriendlyName}.cdeConfig"), false))
                    {
                        fs.Write(tWrite);
                    }
                }
            }
#endif
        }
Beispiel #13
0
        public override bool DoInit()
        {
            MyBaseThing.StatusLevel = 0;
            MyBaseThing.LastMessage = "Timer Ready";
            IsActive = false;

            if (string.IsNullOrEmpty(MyBaseThing.ID))
            {
                MyBaseThing.ID = Guid.NewGuid().ToString();
                TheThing.SetSafePropertyBool(MyBaseThing, "IsStateSensor", true);
                TheThing.SetSafePropertyString(MyBaseThing, "StateSensorType", "analog");
                TheThing.SetSafePropertyString(MyBaseThing, "StateSensorUnit", "ticks");
                TheThing.SetSafePropertyNumber(MyBaseThing, "StateSensorMaxValue", 60000);
                TheThing.SetSafePropertyNumber(MyBaseThing, "StateSensorAverage", 1000);
                TheThing.SetSafePropertyNumber(MyBaseThing, "StateSensorMinValue", 0);
            }
            if (TheThing.GetSafePropertyBool(MyBaseThing, "AutoStart"))
            {
                sinkTriggered(null);
            }
            return(true);
        }
        void sinkUXUpdatedThing(ICDEThing pThing, object pData)
        {
            cdeP tProp = pData as cdeP;

            if (tProp != null && m_Tag != null)
            {
                if (!DontMonitor && tProp != null && tProp.HasChanged && tProp.Name == "Value")
                {
                    var value = tProp.GetValue();
                    if (value != null && tProp.cdeT == 4 && TheThing.GetSafePropertyBool(MyBaseThing, "StoreArrayInProperties"))
                    {
                        byte[] bytes = (byte[])value;
                        for (int ii = 0; ii < bytes.Length; ii++)
                        {
                            TheThing.SetSafePropertyNumber(MyBaseThing, $"Value{ii}", bytes[ii]);
                        }
                    }
                    if (PropertyOPCToString((ePropertyTypes)tProp.cdeT, value) != m_Tag.MyLastValue.ToString()) //CODE-REVIEW: Racing can happen here! Both functions can take too long and change during the ToString operation (so far only seen in debugger!)
                    {
                        m_Tag.WriteTag(new DataValue(new Variant(tProp.Value)));
                    }
                }
            }
        }
Beispiel #15
0
        public override bool DoInit()
        {
            if (Frequency < 100)
            {
                Frequency = 100;
            }

            GetProperty(nameof(StartValue), true).RegisterEvent(eThingEvents.PropertyChanged, sinkTriggered);
            GetProperty(nameof(StartValue), true).RegisterEvent(eThingEvents.PropertyChanged, sinkStartValueChanged);
            GetProperty("Value", true).RegisterEvent(eThingEvents.PropertyChanged, sinkValueReset);

            this.MyBaseThing.DeclareSensorProperty("Value", ePropertyTypes.TNumber, new cdeP.TheSensorMeta {
                RangeMax = 100, RangeMin = 0, Units = "ticks",
            });

            if (!TheThing.GetSafePropertyBool(MyBaseThing, "IsStateSensor"))
            {
                TheThing.SetSafePropertyBool(MyBaseThing, "IsStateSensor", true);
                TheThing.SetSafePropertyString(MyBaseThing, "StateSensorType", "analog");
                TheThing.SetSafePropertyString(MyBaseThing, "StateSensorUnit", "ticks");
                TheThing.SetSafePropertyNumber(MyBaseThing, "StateSensorMaxValue", 100);
                TheThing.SetSafePropertyNumber(MyBaseThing, "StateSensorAverage", 50);
                TheThing.SetSafePropertyNumber(MyBaseThing, "StateSensorMinValue", 0);
            }
            if (!IsActive)
            {
                IsActive = false;
                MyBaseThing.StatusLevel = 0;
                MyBaseThing.LastMessage = "Countdown ready";
                if (AutoStart && mTimer == null)
                {
                    sinkTriggered(this.GetProperty("Value", false));
                }
            }
            return(true);
        }
        private void RemoveTrigger(TheRule tRule, bool DoForce)
        {
            if (TheCDEngines.MyThingEngine == null || !TheBaseAssets.MasterSwitch)
            {
                return;
            }
            if (tRule.IsRuleActive || DoForce)
            {
                if (TheThingRegistry.HasThingsWithFunc(MyBaseEngine.GetEngineName(), s => s.cdeMID != tRule.GetBaseThing().cdeMID&&
                                                       TheThing.GetSafePropertyString(s, "TriggerObject") == tRule.TriggerObject && TheThing.GetSafePropertyBool(s, "IsRuleActive")))
                {
                    return;
                }
                switch (tRule.TriggerObjectType)
                {
                default:
                    TheThing tTriggerThing = TheThingRegistry.GetThingByMID("*", TheCommonUtils.CGuid(tRule.TriggerObject));
                    if (tTriggerThing != null)
                    {
                        cdeP tProp = tTriggerThing.GetProperty(tRule.TriggerProperty);
                        if (tProp != null)
                        {
                            tProp.UnregisterEvent(eThingEvents.PropertyChanged, sinkRuleAction);
                        }
                    }
                    break;

                case "CDE_ENGINE":
                    TheThing tBase = TheThingRegistry.GetBaseEngineAsThing(tRule.TriggerObject);
                    if (tBase != null)
                    {
                        tBase.UnregisterEvent(eEngineEvents.IncomingMessage, sinkRuleIncoming);
                    }
                    break;

                case "CDE_EVENTFIRED":
                    TheThing tBaseE = TheThingRegistry.GetThingByID("*", tRule.TriggerObject);
                    if (tBaseE != null)
                    {
                        tBaseE.UnregisterEvent(tRule.TriggerProperty, sinkRuleThingEvent);
                    }
                    break;
                }
                tRule.IsRuleActive  = false;
                tRule.IsRuleRunning = false;
                tRule.IsRuleWaiting = true;
            }
        }
        void GenerateStressThingData(object stressThingObj)
        {
            if (!TheBaseAssets.MasterSwitch)
            {
                m_Timer?.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
                m_Timer?.Dispose();
                m_Timer = null;
                return;
            }
            var sw = new System.Diagnostics.Stopwatch();

            sw.Start();
            var now = DateTimeOffset.UtcNow;

            for (int i = 1; i <= this.Gen_Config_NumberOfActiveProperties; i++)
            {
                var value = (double)valueCounter++; //r.Next(0, 1000);
                if (valueCounter % 25 == 0)
                {
                    value = double.NaN;
                }
                var propName = String.Format("Gen_Prop{0:D4}", i);
                if (bFirstRun && this.MyBaseThing.GetProperty(propName, false)?.IsSensor != true)
                {
                    this.MyBaseThing.DeclareSensorProperty(propName, ePropertyTypes.TNumber, new cdeP.TheSensorMeta {
                    });
                }
                this.MyBaseThing.SetProperty(propName, value, now);

                var newCount = System.Threading.Interlocked.Increment(ref propGenerateCounter);
            }
            bFirstRun = false;

            if (TheThing.GetSafePropertyBool(MyBaseThing, "Gen_Config_35Running"))
            {
                MyBaseThing.SetProperties(new Dictionary <string, object>
                {
                    { "35.Running", b35_Running },
                    { "35.Ended", !b35_Running },
                    { "35.Aborted", false },
                    { "35.StoppedOperator", false },
                    { "35.StoppedMalfunction", false },
                }, now);
                b35_Running = !b35_Running;
            }

            if (g_sw.ElapsedMilliseconds > this.Gen_Config_StatsUpdateInterval)
            {
                long elapsed = 0;
                lock (g_sw)
                {
                    elapsed = g_sw.ElapsedMilliseconds;
                    if (elapsed > this.Gen_Config_StatsUpdateInterval)
                    {
                        g_sw.Restart();
                    }
                }
                if (elapsed > this.Gen_Config_StatsUpdateInterval)
                {
                    var newCount = System.Threading.Interlocked.Exchange(ref propGenerateCounter, 0);
                    this.Gen_Stats_PropertyCounter    += newCount;
                    this.Gen_Stats_PropertiesPerSecond = newCount / (elapsed / 1000.0);
                    this.Gen_Stats_UpdateTime          = DateTimeOffset.Now;
                    TheBaseAssets.MySYSLOG.WriteToLog(700, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("Data Generator", "Generate", eMsgLevel.l6_Debug, String.Format("Generate Rate: {0,11:N2} properties/s", this.Gen_Stats_PropertiesPerSecond)));
                }
            }
            sw.Stop();
            long newDueTime = this.Gen_Config_PropertyUpdateInterval - sw.ElapsedMilliseconds;

            if (newDueTime < 0)
            {
                TheBaseAssets.MySYSLOG.WriteToLog(700, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("Data Generator", "Generate", eMsgLevel.l6_Debug, String.Format("Falling behing by {0} ms", -newDueTime)));
                newDueTime = 0;
            }
            try
            {
                if (m_Timer != null)
                {
                    m_Timer.Change(newDueTime, System.Threading.Timeout.Infinite);
                }
            }
            catch (Exception)
            {
            }
        }
Beispiel #18
0
        public override void HandleMessage(ICDEThing sender, object pIncoming)
        {
            TheProcessMessage pMsg = pIncoming as TheProcessMessage;

            if (pMsg == null || pMsg.Message == null)
            {
                return;
            }

            var cmd = pMsg.Message.TXT.Split(':');

            switch (cmd[0])
            {
            case "CALL_METHOD":
            case nameof(MsgOPCUAMethodCall):
                string error         = "Unexpected";
                string exceptionText = "";

                MsgOPCUAMethodCall callInfo        = null;
                byte[]             largeOutput     = null;
                string             outParamsAsJson = null;
                IList <object>     outputArguments = null;
                if (m_Method == null)
                {
                    error = "Method meta data not initialized";
                }
                else if (m_Method.MyOPCServer == null)
                {
                    error = "Method not inititialized";
                }
                else if (m_Method.MyOPCServer.m_session == null)
                {
                    error = "OPC UA session not created";
                }
                else
                {
                    try
                    {
                        if (TheCommonUtils.cdeIsLocked(m_Method))
                        {
                            TheBaseAssets.MySYSLOG.WriteToLog(78401, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM(MyBaseThing.EngineName, String.Format("[{0}] Method called concurrently", m_Method.MyOPCServer.GetLogAddress()), eMsgLevel.l4_Message, String.Format("{0}", MyBaseThing.Address)));
                        }
                        lock (m_Method)
                        {
                            if (m_Method.Args == null)
                            {
                                var browseError = m_Method.MyOPCServer.MethodBrowser(m_Method.TagRef, m_Method.DisplayName, m_Method);
                                if (!string.IsNullOrEmpty(browseError))
                                {
                                    error = "Unable to retrieve method metadata from server: " + browseError;
                                }
                            }
                            if (m_Method.Args == null)
                            {
                                error = "Unable to retrieve method metadata from server";
                            }
                            else
                            {
                                if (!string.IsNullOrEmpty(pMsg.Message.PLS))
                                {
                                    if (cmd[0] == nameof(MsgOPCUAMethodCall))
                                    {
                                        callInfo = TheCommRequestResponse.ParseRequestMessageJSON <MsgOPCUAMethodCall>(pMsg.Message);
                                        foreach (var argument in callInfo.Arguments)
                                        {
                                            TheThing.SetSafeProperty(this, argument.Key, argument.Value, ePropertyTypes.NOCHANGE);
                                        }
                                    }
                                    else
                                    {
                                        var tLst = TheCommonUtils.cdeSplit(pMsg.Message.PLS, ":;:", true, true).ToList();
                                        foreach (string t in tLst)
                                        {
                                            TheThing.SetPropertyFromBagItem(this, t);
                                        }
                                    }
                                }
                                object[] tArgs = new object[InputArgCnt];
                                for (int i = 0; i < InputArgCnt; i++)
                                {
                                    tArgs[i] = TheOPCTag.GetOPCValueFromCDEValue(InputArgs[i].cdeProperty == null ? null : InputArgs[i].cdeProperty.Value, InputArgs[i].OPCType);
                                }
#if OLD_UA
                                outputArguments = m_Method.MyOPCServer.m_session.CallWithTimeout(m_Method.ParentId, m_Method.TagRef, MethodCallTimeout, tArgs);
#else
                                outputArguments = m_Method.MyOPCServer.m_session.Call(m_Method.ParentId, m_Method.TagRef, tArgs);     //CM: C-labs extension: .CallWithTimeout(m_Method.ParentId, m_Method.TagRef, MethodCallTimeout, tArgs);
#endif
                                if (cmd[0] != nameof(MsgOPCUAMethodCall))
                                {
                                    if (TheThing.GetSafePropertyBool(this, "ReturnOutputAsJson"))
                                    {
                                        outParamsAsJson = TheCommonUtils.SerializeObjectToJSONString(outputArguments);
                                        //TheThing.SetSafePropertyString(this, "OutputAsJson", outParamsAsJson);
                                    }
                                    else
                                    {
                                        if (outputArguments != null && outputArguments.Count > 0)
                                        {
                                            for (int i = 0; i < outputArguments.Count; i++)
                                            {
                                                if (i < OutputArgs.Count)
                                                {
                                                    object value;
                                                    if (outputArguments[i] is byte[] && (outputArguments[i] as byte[]).Length > 4096 && largeOutput == null)
                                                    {
                                                        largeOutput = outputArguments[i] as byte[];
                                                        value       = "";
                                                    }
                                                    else
                                                    {
                                                        value = outputArguments[i];
                                                    }

                                                    cdeP tP = OutputArgs[i].cdeProperty;
                                                    if (tP != null)
                                                    {
                                                        //TheOPCTag.UpdateValueProperty(outputArguments[i] as DataValue, tP, outputArguments[i] as DataValue);
                                                        tP.Value = value;
                                                        // tP.SetValue(outputArguments[i], pMsg.Message.GetOriginator().ToString()); // CODE REVIEW: Why did we set the originator here? It's only really needed for remote things to break update cycles...
                                                    }
                                                }
                                                else
                                                {
                                                    TheBaseAssets.MySYSLOG.WriteToLog(78402, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM(MyBaseThing.EngineName, String.Format("[{0}] Error processing method response for OPC Server", m_Method.MyOPCServer.GetLogAddress()), eMsgLevel.l2_Warning, String.Format("{0}: too many out parameters in method", MyBaseThing.Address)));
                                                }
                                            }
                                        }
                                    }
                                    MyBaseThing.LastUpdate = DateTimeOffset.Now;
                                    LastMessage            = string.Format("Success at {0}", MyBaseThing.LastUpdate);
                                }
                                error = "";
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        error         = "Method Call failed: " + e.Message;
                        exceptionText = e.ToString();
                        LastMessage   = error;
                        TheBaseAssets.MySYSLOG.WriteToLog(78403, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(MyBaseThing.EngineName, String.Format("[{0}] Method Call failed", m_Method.MyOPCServer.GetLogAddress()), eMsgLevel.l1_Error, String.Format("{0}:{1}", MyBaseThing.Address, e.ToString())));
                    }
                }
                if (cmd[0] == nameof(MsgOPCUAMethodCall))
                {
                    if (callInfo?.ReturnRawJSON == true)
                    {
                        TheCommRequestResponse.PublishResponseMessageJson(pMsg.Message, new MsgOPCUAMethodCallResponse {
                            OutputArguments = new List <object> {
                                TheCommonUtils.SerializeObjectToJSONString(outputArguments)
                            }, Error = error
                        });
                    }
                    else
                    {
                        TheCommRequestResponse.PublishResponseMessageJson(pMsg.Message, new MsgOPCUAMethodCallResponse {
                            OutputArguments = (List <object>)outputArguments, Error = error
                        });
                    }
                }
                else
                {
                    TSM tTSN = new TSM(MyBaseThing.EngineName, string.Format(String.IsNullOrEmpty(error) ? "CALL_METHOD_RESPONSE:{0}:{1}" : "CALL_METHOD_RESPONSE:{0}:{1}:{2}:{3}", MyBaseThing.ID, cmd[1], error.Replace(":", " "), exceptionText.Replace(":", " ")));
                    if (largeOutput != null && String.IsNullOrEmpty(error))
                    {
                        tTSN.PLB = largeOutput;
                    }
                    if (outParamsAsJson != null && String.IsNullOrEmpty(error))
                    {
                        tTSN.PLS = outParamsAsJson;
                    }
                    if (pMsg.LocalCallback != null)
                    {
                        pMsg.LocalCallback(tTSN);
                    }
                    else
                    {
                        TheCommCore.PublishToOriginator(pMsg.Message, tTSN);
                    }
                }
                break;
            }

            base.HandleMessage(this, pMsg);
        }
Beispiel #19
0
        static protected TheThing StartOPCServer(bool disableSecurity)
        {
#if OPCUASERVER
            // TODO Actually use our own OPC Server for the unit test
            var opcServerThing = TheThingRegistry.GetThingsOfEngine("CDMyOPCUAServer.cdeMyOPCServerService").FirstOrDefault();
            Assert.IsNotNull(opcServerThing, $"Unable to obtain OPC Server thing: error loading plug-in or server not yet initialized?");

            lock (opcServerStartupLock)
            {
                if (!TheThing.GetSafePropertyBool(opcServerThing, "IsRunning"))
                {
                    TheThing.SetSafePropertyBool(opcServerThing, "DisableSecurity", disableSecurity);
                    TheThing.SetSafePropertyBool(opcServerThing, "NoServerCertificate", disableSecurity);

                    var theOpcThing = new TheThing();
                    theOpcThing.EngineName = "OPCTestEng";
                    theOpcThing.DeviceType = "OPCTestDT";
                    theOpcThing.Address    = "OPCTestAddress";
                    theOpcThing.SetProperty("OpcProp01", "0001");
                    theOpcThing.SetProperty("OpcProp02", "0002");
                    theOpcThing.SetProperty("OpcProp03", "0003");
                    theOpcThing.SetProperty("OpcProp04", "0004");
                    theOpcThing.SetProperty("OpcProp05", "0005");
                    theOpcThing.SetProperty("OpcProp06", "0006");
                    theOpcThing.SetProperty("OpcProp07", "0007");
                    theOpcThing.SetProperty("OpcProp08", "0008");
                    theOpcThing.SetProperty("OpcProp09", "0009");
                    theOpcThing.SetProperty("OpcProp10", "0010");
                    var tThing = TheThingRegistry.RegisterThing(theOpcThing);
                    Assert.IsNotNull(tThing);

                    var addThingResponse = TheCommRequestResponse.PublishRequestJSonAsync <MsgAddThingsToServer, MsgAddThingsToServerResponse>(myContentService, opcServerThing, new MsgAddThingsToServer
                                                                                                                                               (
                                                                                                                                                   new TheThingToAddToServer
                    {
                        cdeMID = Guid.NewGuid(),
                        ReplaceExistingThing = false,
                        ThingMID             = TheCommonUtils.cdeGuidToString(theOpcThing.cdeMID),
                    }
                                                                                                                                               ), new TimeSpan(0, 0, 30)).Result;

                    Assert.IsNotNull(addThingResponse, "No reply to OPC Server MsgAddThingToServer");
                    Assert.IsTrue(string.IsNullOrEmpty(addThingResponse.Error), $"Error adding thing to OPC Server: '{addThingResponse.Error}'.");
                    Assert.AreEqual(1, addThingResponse.ThingStatus.Count, $"Error adding thing to OPC Server.");
                    Assert.IsTrue(string.IsNullOrEmpty(addThingResponse.ThingStatus[0].Error), $"Error adding thing to OPC Server: '{addThingResponse.ThingStatus[0].Error}'.");

                    MsgStartStopServerResponse responseStart;
                    int retryCount = 1;
                    do
                    {
                        responseStart = TheCommRequestResponse.PublishRequestJSonAsync <MsgStartStopServer, MsgStartStopServerResponse>(myContentService, opcServerThing,
                                                                                                                                        new MsgStartStopServer
                        {
                            Restart = true,
                        },
                                                                                                                                        new TimeSpan(0, 0, 30)).Result;
                        retryCount--;
                    } while (retryCount >= 0 && responseStart == null);

                    Assert.IsNotNull(responseStart, "Failed to send MsgStartStopServer message to restart OPC UA Server");
                    Assert.IsTrue(string.IsNullOrEmpty(responseStart.Error), $"Error restarting OPC Server: '{addThingResponse.Error}'.");
                    Assert.IsTrue(responseStart.Running, $"OPC Server not running after MsgStartStopServer Restart message");
                }
            }
            return(opcServerThing);
#else
            return(null);
#endif
        }
Beispiel #20
0
        public override void OnNewEvent(TheProcessMessage timer, object unused)
        {
            TheEventLogEntry tEntry = timer?.Cookie as TheEventLogEntry;

            if (tEntry == null)
            {
                return;
            }
            if (!string.IsNullOrEmpty(MyBaseThing.Address) && tEntry?.Message?.TXT?.Contains(MyBaseThing.Address) == true) //Avoid recursive
            {
                return;
            }
            var t = new TheGELFLogEntry()
            {
                version = "1.1",
                host    = TheBaseAssets.MyServiceHostInfo.GetPrimaryStationURL(false),
                level   = (int)tEntry.Message?.LVL,
#if CDE_NET45 || CDE_NET4 || CDE_NET35
                timestamp = TheCommonUtils.CDbl($"{(tEntry.Message.TIM.Subtract(new DateTime(1970, 1, 1))).TotalSeconds}.{tEntry.Message.TIM.Millisecond}"),
#else
                timestamp = TheCommonUtils.CDbl($"{tEntry.Message.TIM.ToUnixTimeSeconds()}.{tEntry.Message.TIM.Millisecond}"),
#endif
                full_message  = tEntry.Message?.PLS,
                short_message = tEntry.Message?.TXT,
                _log_id       = tEntry.EventID,
                _serial_no    = tEntry.Serial,
                _engine       = tEntry.Message.ENG,
                _device_id    = tEntry.Message.GetOriginator().ToString()
            };

            try
            {
                if (!string.IsNullOrEmpty(MyBaseThing.Address))
                {
                    var pData = new TheRequestData()
                    {
                        RequestUri       = new Uri($"{MyBaseThing.Address}/gelf"),
                        ResponseMimeType = "application/json",
                        PostData         = TheCommonUtils.CUTF8String2Array(TheCommonUtils.SerializeObjectToJSONString <TheGELFLogEntry>(t)),
                        DontCompress     = true
                    };

                    MyRest.PostRESTAsync(pData, (okData) =>
                    {
                        MyBaseThing.StatusLevel = 1;
                    }, (errData) =>
                    {
                        MyBaseThing.LastMessage = $"Post to Log Error: {errData.ErrorDescription}";
                        MyBaseThing.StatusLevel = 2;
                    });
                }
            }
            catch (Exception e)
            {
                MyBaseThing.LastMessage = $"Cannot Post to Log Error: {e.Message}";
                MyBaseThing.StatusLevel = 2;
            }

            if (TheThing.GetSafePropertyBool(MyBaseThing, "ToConsole"))
            {
                Console.WriteLine(TheCommonUtils.SerializeObjectToJSONString <TheGELFLogEntry>(t));
            }
        }
        void sinkPrePro(cdeP pProp)
        {
            if (TheThing.GetSafePropertyString(MyBaseThing, "StateSensorType") != "analog")
            {
                SetProperty("Value", pProp.Value);
                return;
            }
            int    prepro     = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(MyBaseThing, "PrePro"));
            int    preprotime = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(MyBaseThing, "PreProTime"));
            double valScale   = TheCommonUtils.CDbl(TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorScaleFactor"));


            var pPropString = TheCommonUtils.CStr(pProp);

            if (!string.IsNullOrEmpty(ValueFilterPattern))
            {
                try
                {
                    if (ValueFilterPattern != filterPattern || filterRegex == null)
                    {
#if !CDE_NET4
                        filterRegex = new Regex(ValueFilterPattern, RegexOptions.Compiled | RegexOptions.CultureInvariant, new TimeSpan(0, 0, 5));
#else
                        filterRegex = new Regex(ValueFilterPattern, RegexOptions.Compiled | RegexOptions.CultureInvariant);
#endif
                        filterPattern = ValueFilterPattern;
                    }
                    pPropString = filterRegex.Match(pPropString).Value;
                }
                catch (Exception e)
                {
                    LastMessage = $"Error applying filter pattern: {e.Message}";
                    return; // CODE REVIEW: Or ist it better to treat this as 0, so other time processing doesn not get confused?
                }
            }

            double pValue;

            if (!string.IsNullOrEmpty(ValueMatchPattern))
            {
                try
                {
                    if (ValueMatchPattern != matchPattern || matchRegex == null)
                    {
#if !CDE_NET4
                        matchRegex = new Regex(ValueMatchPattern, RegexOptions.Compiled | RegexOptions.CultureInvariant, new TimeSpan(0, 0, 5));
#else
                        matchRegex = new Regex(ValueMatchPattern, RegexOptions.Compiled | RegexOptions.CultureInvariant);
#endif
                        matchPattern = ValueMatchPattern;
                    }
                    if (matchRegex.IsMatch(pProp.ToString()))
                    {
                        pValue = 1;
                    }
                    else
                    {
                        pValue = 0;
                    }
                }
                catch (Exception e)
                {
                    LastMessage = $"Error applying match pattern: {e.Message}";
                    return; // CODE REVIEW: Or ist it better to treat this as 0, so other time processing doesn not get confused?
                }
            }
            else
            {
                pValue = TheCommonUtils.CDbl(pPropString);
            }
            if (valScale != 0)
            {
                pValue /= valScale;
            }
            if (pValue < 0 && TheThing.GetSafePropertyBool(MyBaseThing, "StateSensorIsAbs"))
            {
                pValue = Math.Abs(pValue);
            }
            if (preprotime > 0 && prepro > 0)
            {
                if (pValue < min)
                {
                    min = pValue;
                }
                if (pValue > max)
                {
                    max = pValue;
                }
                ave += pValue;
                aveCnt++;
                if (DateTimeOffset.Now.Subtract(lastWrite).TotalSeconds < preprotime)
                {
                    return;
                }
                lastWrite = DateTimeOffset.Now;
                switch (prepro)
                {
                case 1:
                    if (min == double.MaxValue)
                    {
                        return;
                    }
                    pValue = min;
                    min    = double.MaxValue;
                    break;

                case 2:
                    if (max == double.MinValue)
                    {
                        return;
                    }
                    pValue = max;
                    min    = double.MinValue;
                    break;

                case 3:
                    if (aveCnt == 0)
                    {
                        return;
                    }
                    pValue = ave / aveCnt;
                    ave    = 0;
                    aveCnt = 0;
                    break;
                }
            }
            if (GetProperty("StateSensorDigits", false) != null)
            {
                int tDigits = (int)TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorDigits");
                SetProperty("Value", decimal.Round((decimal)pValue, tDigits, MidpointRounding.AwayFromZero));
            }
            else
            {
                SetProperty("Value", pValue);
            }
        }
Beispiel #22
0
        internal static TheScreenInfo GenerateLiveScreen(Guid pScreenId, TheClientInfo tClientInfo) // Guid pUserGuid, int lcid, int pFlag)
        {
            if (TheCDEngines.MyNMIService == null)
            {
                return(null);
            }

            TheScreenInfo tInfo = new TheScreenInfo
            {
                cdeMID          = pScreenId,
                MyDashboard     = null,
                MyStorageInfo   = new List <TheFormInfo>(),
                MyStorageMeta   = new cdeConcurrentDictionary <string, TheFormInfo>(),
                MyStorageMirror = new List <object>(),
                MyDashPanels    = new List <TheDashPanelInfo>()
            };

            TheThing tLiveForm = TheThingRegistry.GetThingByMID("*", pScreenId);

            if (tLiveForm == null || !TheUserManager.HasUserAccess(tClientInfo.UserID, tLiveForm.cdeA))
            {
                return(null); //V3.1: BUG 126 - could lead to racing condition. TODO: Revisit later
                //TheFormInfo tI = new TheFormInfo(tLiveForm) { FormTitle = (tLiveForm == null ? "Form not Found!" : "Access Denied!") };
                //tI.TargetElement = pScreenId.ToString();
                //tI.AssociatedClassName = pScreenId.ToString();
                //tInfo.MyStorageInfo.Add(tI);
                //tI.FormFields = new List<TheFieldInfo>();
                //TheFieldInfo tFldInfo = new TheFieldInfo(null, null, 10, 0, 0);
                //tFldInfo.Type = eFieldType.SmartLabel;
                //tFldInfo.Header = (tLiveForm == null ? "This Form was defined but has not Meta-Data associated with it." : "You do not have the required access permissions!");
                //tI.FormFields.Add(tFldInfo);
                //return tInfo;
            }
            string          tFormName = TheThing.GetSafePropertyString(tLiveForm, "FriendlyName");
            List <TheThing> tFields   = TheThingRegistry.GetThingsByFunc("*", s => s.cdeO == TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID && TheThing.GetSafePropertyString(s, "FormName") == tFormName && TheThing.GetSafePropertyBool(s, "IsLiveTag") && (s.UID == Guid.Empty || s.UID == tClientInfo.UserID));

            if (tFields != null && tFields.Any())
            {
                string tFormTitle = TheThing.GetSafePropertyString(tLiveForm, "FormTitle");
                if (string.IsNullOrEmpty(tFormTitle))
                {
                    tFormTitle = tFormName;
                }
                TheFormInfo tI = new TheFormInfo(tLiveForm)
                {
                    FormTitle           = tFormTitle,
                    TargetElement       = pScreenId.ToString(),
                    DefaultView         = eDefaultView.Form,
                    TileWidth           = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(tLiveForm, "TileWidth")),
                    TileHeight          = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(tLiveForm, "TileHeight")),
                    IsUsingAbsolute     = TheThing.GetSafePropertyBool(tLiveForm, "IsAbsolute"),
                    AssociatedClassName = pScreenId.ToString()
                };
                tInfo.MyStorageInfo.Add(tI);
                tI.FormFields = new List <TheFieldInfo>();
                int fldNo = 10;
                foreach (TheThing tTh in tFields)
                {
                    int tfldNo = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(tTh, "FldOrder"));
                    if (tfldNo == 0)
                    {
                        tfldNo = fldNo;
                    }
                    int          tFlags   = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(tTh, "Flags"));
                    cdeP         ValProp  = tTh.GetProperty("Value");
                    bool         IsNewFld = true;
                    TheFieldInfo tFldInfo = TheNMIEngine.GetFieldById(TheThing.GetSafePropertyGuid(tTh, "FldID"));
                    if (tFldInfo == null)
                    {
                        tFldInfo = new TheFieldInfo(tTh, "Value", tfldNo, tFlags & 0xFFBF, tTh.GetBaseThing().cdeA);
                    }
                    else
                    {
                        tFldInfo.FldOrder = tfldNo;
                        tFldInfo.Flags    = tFlags;
                        IsNewFld          = false;
                    }
                    if (tFldInfo.PropertyBag == null)
                    {
                        tFldInfo.PropertyBag = new ThePropertyBag();
                    }
                    ThePropertyBag.PropBagUpdateValue(tFldInfo.PropertyBag, "IsOnTheFly", "=", "True");
                    ThePropertyBag.PropBagUpdateValue(tFldInfo.PropertyBag, "UXID", "=", $"{tTh.cdeMID}");
                    tFldInfo.Header = tTh.FriendlyName;
                    RegisterNMISubscription(tClientInfo, "Value", tFldInfo);

                    string tControlType = TheThing.GetSafePropertyString(tTh, "ControlType");
                    if (TheCommonUtils.CInt(tControlType) == 0 && !TheCommonUtils.IsNullOrWhiteSpace(tControlType))
                    {
                        tFldInfo.Type = eFieldType.UserControl;
                        RegisterFieldEvents(tTh, ValProp, IsNewFld, tFldInfo, tControlType);
                    }
                    else
                    {
                        tFldInfo.Type = (eFieldType)TheCommonUtils.CInt(tControlType);
                    }
                    tFldInfo.DefaultValue = ValProp?.ToString();
                    tFldInfo.TileWidth    = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(tTh, "TileWidth"));
                    tFldInfo.TileHeight   = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(tTh, "TileHeight"));

                    foreach (cdeP prop in tTh.GetNMIProperties())
                    {
                        ThePropertyBag.PropBagUpdateValue(tFldInfo.PropertyBag, prop.Name, "=", prop.ToString());
                    }
                    if (tFldInfo.Type == eFieldType.TileButton)
                    {
                        tTh.DeclareNMIProperty("IsDown", ePropertyTypes.TBoolean);
                        ThePropertyBag.PropBagUpdateValue(tFldInfo.PropertyBag, "EnableTap", "=", "True");
                        tFldInfo.RegisterUXEvent(tTh, eUXEvents.OnPropertyChanged, "IsDown", (pThing, pObj) =>
                        {
                            if (!(pObj is TheProcessMessage pMsg) || pMsg.Message == null)
                            {
                                return;
                            }
                            TheThing.SetSafePropertyBool(pThing, "IsDown", TheCommonUtils.CBool(pMsg.Message.PLS));
                        });
        public bool ActivateRules()
        {
            if (TheCDEngines.MyThingEngine == null || TheBaseAssets.MyServiceHostInfo.IsCloudService || TheCommonUtils.cdeIsLocked(LockRules) || !mIsInitialized)
            {
                return(false);
            }

            lock (LockRules)
            {
                if (mIsInitialized)
                {
                    InitRules();
                }
                //List<TheRule> tList = MyRulesStore.MyMirrorCache.GetEntriesByFunc(s => s.IsRuleActive && !s.IsRuleRunning && s.IsRuleWaiting);
                List <TheThing> tList = TheThingRegistry.GetThingsByFunc("*", s =>
                                                                         TheThing.GetSafePropertyString(s, "Parent").Equals(MyBaseThing.ID) && //TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID) &&
                                                                         TheThing.GetSafePropertyBool(s, "IsRuleActive") &&
                                                                         !TheThing.GetSafePropertyBool(s, "IsRuleRunning") &&
                                                                         TheThing.GetSafePropertyBool(s, "IsRuleWaiting"));
                if (tList != null && tList.Count > 0)
                {
                    foreach (TheThing tThing in tList)
                    {
                        TheRule tRule = tThing.GetObject() as TheRule;
                        if (tRule == null)
                        {
                            continue;
                        }
                        if (string.IsNullOrEmpty(tRule.TriggerProperty))
                        {
                            tRule.IsIllegal     = true;
                            tRule.IsRuleWaiting = false;
                            continue;
                        }
                        if (tRule.TriggerStartTime > DateTimeOffset.Now)
                        {
                            continue;
                        }
                        if (tRule.TriggerEndTime < DateTimeOffset.Now)
                        {
                            RemoveTrigger(tRule, false);
                            continue;
                        }
                        switch (tRule.TriggerObjectType)
                        {
                        case "CDE_ENGINE":
                            TheThing tBase = TheThingRegistry.GetBaseEngineAsThing(tRule.TriggerObject);
                            if (tBase != null)
                            {
                                tBase.RegisterEvent(eEngineEvents.IncomingMessage, sinkRuleIncoming);
                                tRule.IsRuleWaiting        = false;
                                tRule.IsRuleRunning        = true;
                                tRule.IsTriggerObjectAlive = true;
                                TheSystemMessageLog.WriteLog(4445, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(eKnownDeviceTypes.TheThingRule, $"Rule {tRule.FriendlyName} started with TriggerType: {tRule.TriggerObjectType}"), false);
                            }
                            break;

                        case "CDE_EVENTFIRED":
                            TheThing tBaseE = TheThingRegistry.GetBaseEngineAsThing(tRule.TriggerObject);
                            if (tBaseE != null)
                            {
                                tBaseE.RegisterEvent(tRule.TriggerProperty, sinkRuleThingEvent);
                                tRule.IsRuleWaiting        = false;
                                tRule.IsRuleRunning        = true;
                                tRule.IsTriggerObjectAlive = true;
                                TheSystemMessageLog.WriteLog(4445, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(eKnownDeviceTypes.TheThingRule, $"Rule {tRule.FriendlyName} started with TriggerType: {tRule.TriggerObjectType}"), false);
                            }
                            break;

                        default:
                            TheThing tTriggerThing = TheThingRegistry.GetThingByMID("*", TheCommonUtils.CGuid(tRule.TriggerObject));
                            if (tTriggerThing != null)
                            {
                                //if (tTriggerThing.GetObject() == null) continue;  //TODO: Verify if this can stay removed
                                //if (tTriggerThing.GetProperty("FriendlyName").Value.ToString().Contains("Motion")) continue;
                                cdeP tProp = tTriggerThing.GetProperty(tRule.TriggerProperty, true);
                                if (tProp != null)
                                {
                                    tProp.UnregisterEvent(eThingEvents.PropertyChanged, sinkRuleAction);
                                    tProp.RegisterEvent(eThingEvents.PropertyChanged, sinkRuleAction);
                                }
                                tRule.IsRuleWaiting        = false;
                                tRule.IsRuleRunning        = true;
                                tRule.IsTriggerObjectAlive = true;
                                tRule.RuleTrigger(tProp.ToString(), true);
                                TheSystemMessageLog.WriteLog(4445, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(eKnownDeviceTypes.TheThingRule, $"Rule {tRule.FriendlyName} started with TriggerType: {tRule.TriggerObjectType}"), false);
                            }
                            break;
                        }
                    }
                }
            }
            return(true);
        }
Beispiel #24
0
        public override bool CreateUX()
        {
            if (mIsUXInitCalled)
            {
                return(false);
            }
            mIsUXInitCalled = true;

            bool readOnly = TheThing.GetSafePropertyBool(MyBaseThing, TheThingRegistry.eOwnerProperties.cdeReadOnly);
            int  writeEnableFlag;

            if (!readOnly)
            {
                writeEnableFlag = 2;
            }
            else
            {
                writeEnableFlag = 0;
            }

            //NUI Definition for All clients


            TheThing.SetSafePropertyString(MyBaseThing, "StateSensorUnit", "Live Tags");
            TheThing.SetSafePropertyString(MyBaseThing, "StateSensorIcon", "/Images/OPCLogo.png");
            var tFlds = TheNMIEngine.AddStandardForm(MyBaseThing, "FACEPLATE", null, 0, new nmiStandardForm {
                MaxTileWidth = 24, UseMargin = true
            });
            var tMyForm = tFlds["Form"] as TheFormInfo;

            var tSBlock = TheNMIEngine.AddStatusBlock(MyBaseThing, tMyForm, 10);

            tSBlock["Group"].SetParent(1);

            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, 20, 0, 0x0, "Live Tags:", "LiveTagCnt", new nmiCtrlNumber()
            {
                ParentFld = tSBlock["Group"].FldOrder
            });
            //TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, 30, 0, 0x0, "Browsed Tags:", "BrowsedTagCnt", new nmiCtrlNumber() { ParentFld = tSBlock["Group"].FldOrder });

            var tCBlock = TheNMIEngine.AddConnectivityBlock(MyBaseThing, tMyForm, 100, (m, c) =>
            {
                if (c)
                {
                    Connect(false);
                }
                else
                {
                    Disconnect(false, false, "Disconnect due to user/NMI request");
                }
            });

            tCBlock["Group"].SetParent(1);

            CreateConfigurationSection(writeEnableFlag, tMyForm, 500, 1);

            //TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.TextArea, 13, 0, 0, "Last-Msg", "LastMessage", new ThePropertyBag() { "TileHeight=2", "TileWidth=6" });

#if USE_CSVIMPORT
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.CollapsibleGroup, 400, 2, 0xc0, "Tag import...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup()
            {
                ParentFld = 1, DoClose = true, IsSmall = true, TileWidth = 6
            }));
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.DropUploader, 410, 2, 0xC0, "Drop a CSV or JSON file with tags", null, new nmiCtrlDropUploader {
                NoTE = true, TileHeight = 4, TileWidth = 3, ParentFld = 400, EngineName = MyBaseEngine.GetEngineName(), MaxFileSize = 52428800
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 420, 2, 0xC0, "Replace existing tags", nameof(ReplaceAllTagsOnUpload), new nmiCtrlSingleCheck {
                TileHeight = 1, TileWidth = 3, ParentFld = 400
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 425, 2, 0xC0, "Bulk apply tags", nameof(BulkApplyOnUpload), new nmiCtrlSingleCheck {
                TileHeight = 1, TileWidth = 3, ParentFld = 400
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.TileButton, 430, writeEnableFlag, 0xF0, "Export Tags", null, new nmiCtrlTileButton()
            {
                ClassName = "cdeGoodActionButton", TileWidth = 3, TileHeight = 1, ParentFld = 400, NoTE = true
            })
            .RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "EXPORTTAGS", ExportTags);
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 435, 2, 0xC0, "Export As CSV", nameof(ExportAsCSV), new nmiCtrlSingleCheck {
                TileHeight = 1, TileWidth = 3, ParentFld = 400
            });
#endif

            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.CollapsibleGroup, 615, 2, 0xC0, "Security...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup()
            {
                ParentFld = 100, UseMargin = false, DoClose = true, IsSmall = true, TileWidth = 6
            }));
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleEnded, 620, writeEnableFlag, 0xC0, "User Name", "UserName", new nmiCtrlSingleEnded {
                ParentFld = 615, TileWidth = 6, TileHeight = 1
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Password, 630, writeEnableFlag | 1, 0xC0, "Password", "Password", new nmiCtrlPassword()
            {
                ParentFld = 615, HideMTL = true
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 640, writeEnableFlag, 0xC0, "Disable Security", "DisableSecurity", new nmiCtrlSingleCheck()
            {
                ParentFld = 615, TileWidth = 3
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 650, writeEnableFlag, 0xC0, "Accept Untrusted Cert", "AcceptUntrustedCertificate", new nmiCtrlSingleCheck {
                ParentFld = 615, TileWidth = 3, TileHeight = 1
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 660, writeEnableFlag, 0xC0, "Disable Domain Check", "DisableDomainCheck", new ThePropertyBag()
            {
                "ParentFld=615", "TileWidth=3", "TileHeight=1"
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 670, writeEnableFlag, 0xC0, "Accept Invalid Cert", "AcceptInvalidCertificate", new ThePropertyBag()
            {
                "ParentFld=615", "TileWidth=3", "TileHeight=1"
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 680, writeEnableFlag, 0xC0, "Anonymous", "Anonymous", new ThePropertyBag()
            {
                "ParentFld=615", "TileWidth=3", "TileHeight=1"
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleEnded, 690, writeEnableFlag, 0xC0, "Client Cert Subject Name", "AppCertSubjectName", new ThePropertyBag()
            {
                "ParentFld=615", "TileWidth=6", "TileHeight=1"
            });


#if USE_ADVANCED
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.CollapsibleGroup, 600, 2, 0xC0, "Advanced Configurations...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup()
            {
                ParentFld = 1, DoClose = true, IsSmall = true                                                                                                                                                                                    /*, MaxTileWidth=18*/
            }));

            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.CollapsibleGroup, 695, 2, 0xC0, "Reconnects and Timeouts...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup()
            {
                ParentFld = 600, DoClose = true, IsSmall = true, TileWidth = 6
            }));
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, 700, writeEnableFlag, 0xC0, "Reconnect Delay", "ReconnectPeriod", new ThePropertyBag()
            {
                "ParentFld=695", "TileWidth=6", "TileHeight=1"
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, 710, writeEnableFlag, 0xC0, "Keep-Alive Interval", nameof(KeepAliveInterval), new ThePropertyBag()
            {
                "ParentFld=695", "TileWidth=6", "TileHeight=1"
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, 715, writeEnableFlag, 0xC0, "Keep-Alive Timeout", nameof(KeepAliveTimeout), new ThePropertyBag()
            {
                "ParentFld=695", "TileWidth=6", "TileHeight=1"
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, 720, writeEnableFlag, 0xC0, "Publishing Interval", nameof(PublishingInterval), new ThePropertyBag()
            {
                "ParentFld=695", "TileWidth=6", "TileHeight=1"
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, 730, writeEnableFlag, 0xC0, "Operation Timeout", "OperationTimeout", new ThePropertyBag()
            {
                "ParentFld=695", "TileWidth=6", "TileHeight=1"
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, 740, writeEnableFlag, 0xC0, "Session Timeout", "SessionTimeout", new ThePropertyBag()
            {
                "ParentFld=695", "TileWidth=6", "TileHeight=1"
            });

            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.CollapsibleGroup, 745, 2, 0xC0, "Status info and data formats...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup()
            {
                ParentFld = 600, DoClose = true, IsSmall = true, TileWidth = 6
            }));
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 750, writeEnableFlag, 0xC0, "Send Status Code", nameof(SendStatusCode), new ThePropertyBag()
            {
                "ParentFld=745", "TileWidth=3", "TileHeight=1"
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 755, writeEnableFlag, 0xC0, "Use Local Timestamp", nameof(UseLocalTimestamp), new ThePropertyBag()
            {
                "ParentFld=745", "TileWidth=3", "TileHeight=1"
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 760, writeEnableFlag, 0xC0, "Send Server Timestamp", nameof(SendServerTimestamp), new ThePropertyBag()
            {
                "ParentFld=745", "TileWidth=3", "TileHeight=1"
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 770, writeEnableFlag, 0xC0, "Send Pico Seconds", nameof(SendPicoSeconds), new ThePropertyBag()
            {
                "ParentFld=745", "TileWidth=3", "TileHeight=1"
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 772, writeEnableFlag, 0xC0, "Send OPC Data Type", nameof(SendOpcDataType), new ThePropertyBag()
            {
                "ParentFld=745", "TileWidth=3", "TileHeight=1"
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 775, writeEnableFlag, 0xC0, "Send Sequence Number", nameof(SendSequenceNumber), new ThePropertyBag()
            {
                "ParentFld=745", "TileWidth=3", "TileHeight=1"
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 778, writeEnableFlag, 0xC0, "Use OPC Sequence Number for Thing sequence", nameof(UseSequenceNumberForThingSequence), new ThePropertyBag()
            {
                "ParentFld=745", "TileWidth=3", "TileHeight=1"
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 780, writeEnableFlag, 0xC0, "Do not use sub-properties ", nameof(DoNotUsePropsOfProps), new ThePropertyBag()
            {
                "ParentFld=745", "TileWidth=3", "TileHeight=1"
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 790, writeEnableFlag, 0xC0, "Do not write array properties", nameof(DoNotWriteArrayElementsAsProperties), new ThePropertyBag()
            {
                "ParentFld=745", "TileWidth=3", "TileHeight=1"
            });

            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.CollapsibleGroup, 795, 2, 0xC0, "Browsing and logging...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup()
            {
                ParentFld = 600, DoClose = true, IsSmall = true, TileWidth = 6
            }));
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 800, writeEnableFlag, 0xC0, "Do Not Use Parent Path", nameof(DoNotUseParentPath), new ThePropertyBag()
            {
                "ParentFld=795", "TileWidth=3", "TileHeight=1"
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 810, writeEnableFlag, 0xC0, "Show Tags in Properties", nameof(ShowTagsInProperties), new ThePropertyBag()
            {
                "ParentFld=795", "TileWidth=3", "TileHeight=1"
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 820, writeEnableFlag, 0xC0, "Enable Data Logging", nameof(EnableOPCDataLogging), new ThePropertyBag()
            {
                "ParentFld=795", "TileWidth=3", "TileHeight=1"
            });
#endif
            mIsUXInitialized = true;
            return(true);
        }
Beispiel #25
0
 void UpdateStatus()
 {
     if (IsRuleRunning)
     {
         if (IsTriggerObjectAlive)
         {
             MyBaseThing.StatusLevel = 1;
         }
         else
         {
             MyBaseThing.StatusLevel = 2;
         }
     }
     else
     {
         MyBaseThing.StatusLevel = 0;
     }
     MyBaseThing.LastMessage = $"Running:{IsRuleRunning} TrigerAlive:{IsTriggerObjectAlive} LastFired:{TheThing.GetSafePropertyBool(MyBaseThing, "LastTriggered")} Owner:{MyBaseThing.cdeO}";
     MyBaseThing.LastUpdate  = DateTimeOffset.Now;
 }
Beispiel #26
0
        internal void FireAction(bool FireNow)
        {
            if (TheCDEngines.MyThingEngine == null || !TheBaseAssets.MasterSwitch)
            {
                return;
            }
            if (!FireNow)
            {
                int tDelay = ActionDelay;
                if (tDelay > 0)
                {
                    Timer tTimer = GetDelayTimer();
                    if (tTimer != null)
                    {
                        tTimer.Dispose();
                        tTimer = null;
                    }
                    tTimer = new Timer(sinkFireOnTimer, this, tDelay * 1000, Timeout.Infinite);
                    SetDelayTimer(tTimer);
                    return;
                }
            }
            switch (ActionObjectType)
            {
            case "CDE_PUBLISHCENTRAL":
                SendRuleTSM(false);
                break;

            case "CDE_PUBLISH2SERVICE":
                SendRuleTSM(true);
                break;

            default:     //case "CDE_THING":
                TheThing tActionThing = TheThingRegistry.GetThingByMID("*", TheCommonUtils.CGuid(ActionObject));
                if (tActionThing != null)
                {
                    string tActionValue = ActionValue;
                    if (!string.IsNullOrEmpty(tActionValue))
                    {
                        ICDEThing triggerThing = TheThingRegistry.GetThingByMID("*", TheCommonUtils.CGuid(TriggerObject)) as ICDEThing;
                        tActionValue = TheCommonUtils.GenerateFinalStr(tActionValue, triggerThing);
                        tActionValue = tActionValue.Replace("%OldValue%", TriggerOldValue);
                        tActionValue = TheCommonUtils.GenerateFinalStr(tActionValue, MyBaseThing);
                    }

                    ICDEThing tObject = tActionThing.GetObject() as ICDEThing;
                    if (tObject != null)
                    {
                        tObject.SetProperty(ActionProperty, tActionValue);
                    }
                    else
                    {
                        tActionThing.SetProperty(ActionProperty, tActionValue);
                    }
                    if (IsRuleLogged)
                    {
                        LogEvent(tActionValue);
                    }
                    if (TheThing.GetSafePropertyBool(MyBaseThing, "IsEVTLogged"))
                    {
                        TheLoggerFactory.LogEvent(eLoggerCategory.RuleEvent, TheCommonUtils.GenerateFinalStr(MyBaseThing.FriendlyName, MyBaseThing), eMsgLevel.l4_Message, TheBaseAssets.MyServiceHostInfo.GetPrimaryStationURL(false), TriggerObject, tActionValue);
                    }
                }
                break;
            }
            TheThing.SetSafePropertyDate(MyBaseThing, "LastAction", DateTimeOffset.Now);
            FireEvent("RuleFired", this, this, true);
        }
Beispiel #27
0
        public virtual bool MonitorTag(Subscription subscription, out string error, bool bApplySubscription = true, bool bReadInitialValue = true)
        {
            error = null;
            if (subscription == null || subscription.Session == null)
            {
                error = "Error: No OPC session.";
                return(false);
            }

            lock (subscription.MonitoredItems)
            {
                if (MyMonitoredItem != null && !subscription.MonitoredItems.Contains(MyMonitoredItem))
                {
                    // Monitored item was removed: recreate from scratch. Otherwise modify in place
                    MyMonitoredItem = null;
                }


                if (!this.IsSubscribedAsThing && !this.IsSubscribedAsProperty)
                {
                    // Nothing to be monitored
                    error = "Error: Nothing to be monitored";
                    return(false);
                }

                if (TheThing.GetSafePropertyBool(MyBaseThing, "DontMonitor") || SampleRate < -1)
                {
                    return(false);
                }
                // can only subscribe to local variables.
                //if (TagRef == null || TagRef.NodeId.IsAbsolute || TagRef.NodeClass != NodeClass.Variable)
                var resolvedNodeId = GetResolvedNodeIdName();
                if (resolvedNodeId == null) // || NodeId.IsAbsolute || TagRef.NodeClass != NodeClass.Variable)
                {
                    error = "Error: No or invalid NodeId";
                    return(false);
                }


                var previousMonitoredItem = subscription.MonitoredItems.FirstOrDefault(mi => mi.Handle == this || this.RefersToSamePropertyAndTag(mi.Handle));
                if (previousMonitoredItem != null)
                {
                    if (!previousMonitoredItem.StartNodeId.Equals(resolvedNodeId))
                    {
                        TheBaseAssets.MySYSLOG.WriteToLog(78201, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("OPC", $"[{MyOPCServer.GetLogAddress()}] Internal Error - monitored item {previousMonitoredItem.StartNodeId} replaced with {resolvedNodeId}. Change will not take effect!", eMsgLevel.l4_Message));
                    }
                    MyMonitoredItem = previousMonitoredItem;
                }
                else
                {
                    MyMonitoredItem = new MonitoredItem(subscription.DefaultItem);
                }
                //MyMonitoredItem.StartNodeId = (NodeId)TagRef.NodeId;
                MyMonitoredItem.StartNodeId    = resolvedNodeId;
                MyMonitoredItem.AttributeId    = Attributes.Value;
                MyMonitoredItem.DisplayName    = DisplayName; // Utils.Format("{0}", TagRef);
                MyMonitoredItem.MonitoringMode = MonitoringMode.Reporting;
                if ((!this.HistoryStartTime.HasValue || this.HistoryStartTime.Value == DateTimeOffset.MinValue) && MyOPCServer.DefHistoryStartTime != DateTimeOffset.MinValue)
                {
                    this.HistoryStartTime = MyOPCServer.DefHistoryStartTime;
                }

                if (this.HistoryStartTime.HasValue && this.HistoryStartTime.Value != DateTimeOffset.MinValue)
                {
                    MyMonitoredItem.Filter = new AggregateFilter()
                    {
                        StartTime          = this.HistoryStartTime.Value.UtcDateTime,
                        ProcessingInterval = this.SampleRate,
                        AggregateType      = ObjectIds.AggregateFunction_Interpolative,
                    };
                    MyMonitoredItem.QueueSize        = uint.MaxValue;
                    MyMonitoredItem.SamplingInterval = 0;
                }
                else
                {
                    DataChangeFilter filter = null;
                    // TODO Remove this special case: pass parameters for deadband filters and StatusValueTimestamp (this breaks P08!!!)
                    if (this.DeadbandFilterValue != 0)
                    {
                        filter = new DataChangeFilter
                        {
                            DeadbandType  = (uint)(this.DeadbandFilterValue > 0 ? DeadbandType.Absolute : DeadbandType.Percent),
                            DeadbandValue = Math.Abs(this.DeadbandFilterValue)
                        };
                    }

                    if (ChangeTrigger != 1)
                    {
                        if (filter == null)
                        {
                            filter = new DataChangeFilter();
                        }
                        filter.Trigger = (DataChangeTrigger)ChangeTrigger;
                    }

                    if (filter != null)
                    {
                        MyMonitoredItem.Filter = filter;
                    }
                    MyMonitoredItem.SamplingInterval = SampleRate;

                    // For Events, the sample rate should be 0 (per spec), but is really ignored and thus should not affect the aggregate sample rate for the server
                    // All other sample rates are at least 50ms per other checks

                    if (SampleRate <= subscription.PublishingInterval * 2 && SampleRate > 0)
                    {
                        // 3.220: PublishingInterval is now independent of the sample rate: it only affects the frequency of the traffic from the server, not the content
                        //MyOPCServer.Subscription.PublishingInterval = SampleRate;

                        // Request the QueueSize to be 50 times the expected data points, so that no data is lost in normal operation
                        MyMonitoredItem.QueueSize = (uint)Math.Ceiling((((double)subscription.PublishingInterval) / SampleRate) * 50);
                        if (MyMonitoredItem.QueueSize < 50)
                        {
                            MyMonitoredItem.QueueSize = 50;
                        }
                    }
                    else
                    {
                        MyMonitoredItem.QueueSize = 50; // Request at least 50
                    }
                }
                MyMonitoredItem.DiscardOldest = true;

                MyMonitoredItem.Notification -= MonitoredItem_Notification;
                MyMonitoredItem.Notification += MonitoredItem_Notification;

                TheOPCMonitoredItemBase previousTag = null;
                if (previousMonitoredItem != null && previousMonitoredItem.Handle != this)
                {
                    previousTag = previousMonitoredItem.Handle as TheOPCMonitoredItemBase;
                    if (previousTag != null)
                    {
                        previousTag.ReleaseMonitoredItem();
                    }
                }

                MyMonitoredItem.Handle = this;

                InitializeMonitoredItem(previousTag);

                if (previousMonitoredItem == null)
                {
                    subscription.AddItem(MyMonitoredItem);
                }
            }
            if (bApplySubscription)
            {
#if OLD_UA
                var items = subscription.ApplyChanges();
                if (!items.Contains(MyMonitoredItem))
#else
                subscription.ApplyChanges();
                if (!subscription.MonitoredItems.Contains(MyMonitoredItem))
#endif
                {
                    TheBaseAssets.MySYSLOG.WriteToLog(78201, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("OPC", $"[{MyOPCServer.GetLogAddress()}] Internal Error: Monitored item not found after applying changes {GetNodeIdForLogs()}. Actual values: Sampling {MyMonitoredItem.Status.SamplingInterval}, Queue {MyMonitoredItem.Status.QueueSize}", eMsgLevel.l1_Error));
                    error = "Error: Monitored item not found after applying changes";
                    return(false);
                }
                else
                {
                    TheBaseAssets.MySYSLOG.WriteToLog(78201, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("OPC", $"[{MyOPCServer.GetLogAddress()}] Added monitored item {GetNodeIdForLogs()}. Actual values: Sampling {MyMonitoredItem.Status.SamplingInterval}, Queue {MyMonitoredItem.Status.QueueSize}", eMsgLevel.l4_Message));
                }
            }

            if (ServiceResult.IsBad(MyMonitoredItem.Status.Error))
            {
                TheThing.SetSafePropertyString(MyBaseThing, "LastMessage", MyMonitoredItem.Status.Error.StatusCode.ToString());
                TheBaseAssets.MySYSLOG.WriteToLog(78201, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("OPC", $"[{MyOPCServer.GetLogAddress()}] Error adding monitored item {GetNodeIdForLogs()}", eMsgLevel.l4_Message, MyMonitoredItem.Status.Error.ToString()));
                error = "Error: " + MyMonitoredItem.Status.Error.ToString();
                return(false);
            }
            else
            {
                MyOPCServer.RegisterEvent("DisconnectComplete", sinkDisconnected);
            }

            TheThing.SetSafePropertyBool(MyBaseThing, "IsActive", true);
            return(true);
        }