Ejemplo n.º 1
0
        void OnDeletedThing(ICDEThing pThing, object pPara)
        {
            TheThing tThing = pPara as TheThing;

            if (tThing != null && tThing.IsInit())
            {
                var tThingObj = (tThing.GetObject() as TheConnectionBase);
                if (tThingObj != null)
                {
                    tThingObj.Disconnect(true);
                }
            }
        }
Ejemplo n.º 2
0
 private void OnStorageReady(ICDEThing pThing, object para)
 {
     MyLogFiles = new TheStorageMirror <TheBackupDefinition>(TheCDEngines.MyIStorageService)
     {
         CacheTableName     = MyLogFilesTableName,
         IsRAMStore         = true,
         IsCachePersistent  = false,
         CacheStoreInterval = 0
     };
     MyLogFiles.RegisterEvent(eStoreEvents.StoreReady, sinkStorageReady);
     MyLogFiles.RegisterEvent(eStoreEvents.DeleteRequested, sinkDeleteLog);
     MyLogFiles.RegisterEvent(eStoreEvents.ReloadRequested, sinkStorageReady);
     MyLogFiles.InitializeStore(false, false);
 }
Ejemplo n.º 3
0
        private void StartVerifier()
        {
            var thing = TheThingRegistry.GetThingByMID("*", TheCommonUtils.CGuid(this.ThingToVerify));

            if (thing != null)
            {
                thing.RegisterEvent(eThingEvents.PropertySet, OnThingUpdate);
                m_thingToVerify = thing;
                g_sw            = new System.Diagnostics.Stopwatch();
                g_sw.Start();
                MyBaseThing.StatusLevel = 1;
                IsStarted = true;
                MyBaseThing.LastMessage = "Verifier started";
            }
        }
Ejemplo n.º 4
0
        public override void HandleMessage(ICDEThing sender, object pIncoming)
        {
            TheProcessMessage pMsg = pIncoming as TheProcessMessage;

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

            switch (pMsg.Message.TXT)
            {
            default:
                base.HandleMessage(sender, pIncoming);
                break;
            }
        }
Ejemplo n.º 5
0
        public virtual void HandleMessage(ICDEThing sender, object pIncoming)
        {
            TheProcessMessage pMsg = pIncoming as TheProcessMessage;

            if (pMsg == null)
            {
                return;
            }

            string[] cmd = pMsg.Message.TXT.Split(':');
            switch (cmd[0])
            {
            default:
                break;
            }
        }
Ejemplo n.º 6
0
        void sinkFileReceived(ICDEThing pThing, object pFileName)
        {
            TheProcessMessage pMsg = pFileName as TheProcessMessage;

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

            var tb = new TheBitmapImage(null, this);

            TheThing.SetSafePropertyString(tb, "CurrentImage", pMsg.Message.TXT);
            tb.GetBaseThing().FriendlyName = pMsg.Message.TXT.Substring(pMsg.Message.TXT.IndexOf('\\') + 1);
            TheThingRegistry.RegisterThing(tb);
            TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", string.Format("###Image-File ({0}) received!###", pMsg.Message.TXT)));
        }
Ejemplo n.º 7
0
 private static void HandleMessage(ICDEThing arg1, object arg2)
 {
     if (!(arg2 is TheProcessMessage pMsg))
     {
         return;
     }
     if (pMsg?.Message != null)
     {
         string[] cmd = pMsg.Message.TXT.Split(':');
         switch (cmd[0])
         {
         case "HELLO_REPLY":
             Console.WriteLine("MyTestEngine received HELLO_REPLY " + (cmd.Length > 1 ? cmd[1] : ""));
             break;
         }
     }
 }
Ejemplo n.º 8
0
        /// <summary>
        /// Handles Messages sent from a host sub-engine to its clients
        /// </summary>
        /// <param name="Command"></param>
        /// <param name="pMessage"></param>
        public override void HandleMessage(ICDEThing sender, object pIncoming)
        {
            if (!(pIncoming is TheProcessMessage pMsg))
            {
                return;
            }
            try
            {
                string[] cmd = pMsg.Message.TXT.Split(':');

                switch (cmd[0]) //string 2 cases
                {
                case "CDE_INITIALIZED":
                    MyBaseEngine.SetInitialized(pMsg.Message);
                    return;

                case "GET_NODECPUINFO":
                    if (MyServiceHealth != null)
                    {
                        //MyServiceHealth.SendCPUInfo(pMsg.Message.GetOriginator());
                        MyServiceHealth.SendCPUInfo(pMsg.Message);
                    }
                    break;

                case "GET_NODEISMHEALTH":
                    if (MyServiceHealth != null)
                    {
                        //MyServiceHealth.SendHealthInfo(pMsg.Message.GetOriginator());
                        MyServiceHealth.SendHealthInfo(pMsg.Message);
                    }
                    break;

                case "REFRESH_DASH":
                    MyPCVitalsDashboard.Reload(pMsg, true);
                    break;

                default:
                    break;
                }
            }
            catch (Exception e)
            {
                TheBaseAssets.MySYSLOG.WriteToLog(8032, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(MyBaseEngine.GetEngineName(), "ProcessServiceMessage Error", eMsgLevel.l1_Error, e.ToString()));
            }
        }
Ejemplo n.º 9
0
        void sinkFileReceived(ICDEThing pThing, object pFileName)
        {
            TheProcessMessage pMsg = pFileName as TheProcessMessage;

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

            var tIm = TheThing.GetSafePropertyString(MyBaseThing, "CurrentImage");

            if (!string.IsNullOrEmpty(tIm) && tIm != pMsg.Message.TXT)
            {
                File.Delete(TheCommonUtils.cdeFixupFileName(tIm));
            }
            TheThing.SetSafePropertyString(MyBaseThing, "CurrentImage", pMsg.Message.TXT);
            TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", string.Format("Update to Image-File ({0}) received!", pMsg.Message.TXT)));
        }
Ejemplo n.º 10
0
 /********************************************************
  * BASIC MESSAGING EXAMPLE (without plugins)
  * Uncomment the "SinkTimer" method in MyTestHost to enable.
  *******************************************************/
 private static void HandleMessage(ICDEThing arg1, object arg2)
 {
     if (!(arg2 is TheProcessMessage pMsg))
     {
         return;
     }
     if (pMsg?.Message != null)
     {
         string[] cmd = pMsg.Message.TXT.Split(':');
         switch (cmd[0])
         {
         case "HELLO":
             Console.WriteLine("MyTestEngine2 received HELLO " + (cmd.Length > 1 ? cmd[1] : ""));
             TheCommCore.PublishCentral(new TSM("MyTestEngine", "HELLO_REPLY:" + (cmd.Length > 1 ? cmd[1] : ""), "MyTestPayload"));     // Send reply back
             break;
         }
     }
 }
Ejemplo n.º 11
0
        /// <summary>
        /// Handles Messages sent from a host sub-engine to its clients
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="pIncoming"></param>
        public void HandleMessage(ICDEThing sender, object pIncoming)
        {
            if (!(pIncoming is TheProcessMessage pMsg))
            {
                return;
            }

            string[] cmd = pMsg.Message.TXT.Split(':');
            switch (cmd[0])
            {
            case "CDE_INITIALIZED":
                MyBaseEngine.SetInitialized(pMsg.Message);
                break;

            default:
                break;
            }
        }
Ejemplo n.º 12
0
        void sinkFileReceived(ICDEThing pThing, object pFileName)
        {
            TheProcessMessage pMsg = pFileName as TheProcessMessage;

            if (pMsg?.Message == null)
            {
                return;
            }
            try
            {
                LoadXMLDefinition(pMsg.Message.TXT);
                TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", string.Format("Modbus Definition File ({0}) received - Creating UX", pMsg.Message.TXT)));
                mMyDashboard.Reload(pMsg, true);
            }
            catch (Exception)
            {
                TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_ERROR", $"Modbus Definition File ({pMsg.Message.TXT}) received but creating UX failed!"));
            }
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Handles Messages sent from a host sub-engine to its clients
        /// </summary>
        public override void HandleMessage(ICDEThing sender, object pIncoming)
        {
            TheProcessMessage pMsg = pIncoming as TheProcessMessage;

            if (pMsg == null)
            {
                return;
            }
            string[] cmd = pMsg.Message.TXT.Split(':');
            switch (cmd[0])
            {
            case "CDE_INITIALIZED":
                MyBaseEngine.SetInitialized(pMsg.Message);
                break;

            case "CDE_INITIALIZE":
                if (MyBaseEngine.GetEngineState().IsService&& MyBaseEngine.GetEngineState().IsLiveEngine)
                {
                    if (!MyBaseEngine.GetEngineState().IsEngineReady)
                    {
                        MyBaseEngine.SetEngineReadiness(true, null);
                    }
                }
                MyBaseEngine.ReplyInitialized(pMsg.Message);
                break;

            case "REFFRESHME":
                InitServers();
                if (MyDash != null)
                {
                    MyDash.Reload(pMsg, false);
                }
                break;

            case "SET_LAST_MSG":
                SetLastMessage(TheScopeManager.GetTokenFromScrambledScopeID(pMsg.Message.SID), pMsg.Message.PLS);
                break;

            case "GET_LAST_MSG":
                TheCommCore.PublishToOriginator(pMsg.Message, new TSM(MyBaseEngine.GetEngineName(), "SET_LAST_MSG", ReturnLastMessage()));
                break;
            }
        }
Ejemplo n.º 14
0
        public override void HandleMessage(ICDEThing sender, object pIncoming)
        {
            TheProcessMessage pMsg = pIncoming as TheProcessMessage;

            if (pMsg == null)
            {
                return;
            }

            string[] cmd = pMsg.Message.TXT.Split(':');

            switch (cmd[0])
            {
            case "UPDATE_VALUE":
                ScanAllServices();
                break;

            case "REFRESH_DASH":
                InitNetworkServices();
                mMyDashboard.Reload(pMsg, false);
                break;

            case "CDE_INITIALIZED":
                MyBaseEngine.SetInitialized(pMsg.Message);
                break;

            case "CDE_INITIALIZE":
                if (MyBaseEngine.GetEngineState().IsService)
                {
                    if (!MyBaseEngine.GetEngineState().IsEngineReady)
                    {
                        MyBaseEngine.SetEngineReadiness(true, null);
                    }
                    MyBaseEngine.ReplyInitialized(pMsg.Message);
                }
                break;

            default:
                TheThing tt = TheThingRegistry.GetThingByProperty(MyBaseEngine.GetEngineName(), Guid.Empty, "ID", pMsg.Message.PLS);
                tt?.HandleMessage(sender, pMsg);
                break;
            }
        }
Ejemplo n.º 15
0
 private void StorageHasStarted(ICDEThing sender, object pReady)
 {
     if (pReady != null)
     {
         if (MyVisitorLogStore == null)
         {
             MyVisitorLogStore = new TheStorageMirror <TheVisitorLogData>(TheCDEngines.MyIStorageService);
             MyVisitorLogStore.RegisterEvent(eStoreEvents.StoreReady, StoreIsUp);
         }
         MyVisitorLogStore.IsRAMStore = TheCDEngines.MyIStorageService == null || TheCDEngines.MyIStorageService.GetBaseEngine().GetEngineState().IsSimulated;
         if (MyVisitorLogStore.IsRAMStore)
         {
             MyVisitorLogStore.IsCachePersistent = true;
             MyVisitorLogStore.CacheTableName    = "VisitorLog";
             MyVisitorLogStore.SetRecordExpiration(1000000, null);
         }
         MyVisitorLogStore.CreateStore(TheBaseAssets.MyServiceHostInfo.ApplicationName + ": The Visitor Log", "Logs all visitors to the Site " + TheBaseAssets.MyServiceHostInfo.ApplicationName, null, true, false);
     }
 }
Ejemplo n.º 16
0
        void sinkThingWasRegistered(ICDEThing sender, object pPara)
        {
            if (TheBaseAssets.MyServiceHostInfo.IsCloudService)
            {
                return;                                                //TODO: Allow Cloud Rules
            }
            TheThing pThing = sender as TheThing;

            if (pThing != null && TheThing.GetSafePropertyString(pThing, "DeviceType") == eKnownDeviceTypes.TheThingRule)
            {
                TheRule tRule = new TheRule(pThing, this)
                {
                    Parent = MyBaseThing.ID
                };
                tRule.RegisterEvent(eEngineEvents.ThingUpdated, sinkUpdated);
                RegisterRule(tRule);
                ActivateRules();
            }
        }
Ejemplo n.º 17
0
        //void sinkRulesUpdatedThing(ICDEThing pThing, object pData)
        //{
        //    if (m_Tag == null) return;
        //    cdeP tPro = pData as cdeP;
        //    if (tPro != null && tPro.HasChanged)
        //    {
        //        string tOPCPropVal = PropertyOPCToString(tPro);
        //        TheThing.SetSafePropertyString(MyBaseThing, "QValue", tOPCPropVal);
        //        if ((tOPCPropVal != 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(tPro.Value)));
        //            //System.Diagnostics.Debug.WriteLine(string.Format("CDE: WriteTag:{0} to ({1})", MyBaseThing.FriendlyName,tPro.ToString()));
        //        }
        //    }
        //}
        void sinkRulesUpdatedThing(ICDEThing pThing, object pData)
        {
            if (m_Tag == null)
            {
                return;
            }
            cdeP tPro = pData as cdeP;

            if (tPro != null && tPro.HasChanged)
            {
                var    value       = tPro.GetValue();
                string tOPCPropVal = PropertyOPCToString((ePropertyTypes)tPro.cdeT, value);
                TheThing.SetSafePropertyString(MyBaseThing, "QValue", tOPCPropVal);
                if ((tOPCPropVal != 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(value)));
                    //System.Diagnostics.Debug.WriteLine(string.Format("CDE: WriteTag:{0} to ({1})", MyBaseThing.FriendlyName,tPro.ToString()));
                }
            }
        }
Ejemplo n.º 18
0
        void sinkFileReceived(ICDEThing pThing, object pFileName)
        {
            TheProcessMessage pMsg = pFileName as TheProcessMessage;

            if (pMsg?.Message == null)
            {
                return;
            }
            try
            {
                string tGuid = $"THH{Guid.NewGuid()}";
                //File.Copy(TheCommonUtils.cdeFixupFileName(pMsg.Message.TXT), TheCommonUtils.cdeFixupFileName($"/cache/{tGuid}"));
                CreateTHHUx(tGuid, TheCommonUtils.cdeFixupFileName(pMsg.Message.TXT));
                TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", string.Format("KPI File ({0}) received - Creating UX", pMsg.Message.TXT)));
                MyPCVitalsDashboard.Reload(pMsg, true);
            }
            catch (Exception)
            {
                TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_ERROR", $"KPI File ({pMsg.Message.TXT}) received but creating UX failed!"));
            }
        }
Ejemplo n.º 19
0
        public void HandleMessage(ICDEThing sender, object pIncoming)
        {
            TheProcessMessage pMsg = pIncoming as TheProcessMessage;

            if (pMsg == null)
            {
                return;
            }

            string[] cmd = pMsg.Message.TXT.Split(':');
            switch (cmd[0])
            {
            case "CDE_INITIALIZED":
                MyBaseEngine.SetInitialized(pMsg.Message);          //Sets the Service to "Ready". ProcessInitialized() internally contains a call to this Handler and allows for checks right before SetInitialized() is called.
                break;

            case "REFFRESHME":
                InitServices();
                mMyDashboard.Reload(pMsg, false);
                break;
            }
        }
Ejemplo n.º 20
0
        private void WriteAggregatedConditionsToProperty(ICDEThing tEventHost, DateTimeOffset time)
        {
            var currentConditionsAsJson = TheCommonUtils.SerializeObjectToJSONString(_currentConditionsByConditionId.Values.OrderByDescending(evnt =>
            {
                if (evnt.TryGetValue("Time", out var evntTime))
                {
                    return(evntTime);
                }
                return(null);
            }).ToList());

            if (TheThing.GetSafePropertyString(tEventHost.GetBaseThing(), DisplayName) != currentConditionsAsJson)
            {
                TheBaseAssets.MySYSLOG.WriteToLog(78102, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(MyOPCServer.GetBaseThing().EngineName, $"Updated current events {_currentConditionsByConditionId.Count} - {currentConditionsAsJson}", eMsgLevel.l6_Debug, $"{DisplayName} {GetNodeIdForLogs()} {EventInfo.AggregateRetainedConditions}"));
                // Using publish time because the event timestamps could be way in the past (i.e. when a recent event just was removed)
                tEventHost.GetBaseThing().SetProperty(DisplayName, currentConditionsAsJson, time);
            }
            else
            {
                TheBaseAssets.MySYSLOG.WriteToLog(78102, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(MyOPCServer.GetBaseThing().EngineName, $"No change to current events {_currentConditionsByConditionId.Count} - {currentConditionsAsJson}", eMsgLevel.l6_Debug, $"{DisplayName} {GetNodeIdForLogs()} {EventInfo.AggregateRetainedConditions}"));
            }
        }
Ejemplo n.º 21
0
 /// <summary>
 /// Probes if a rule with the given ID exists
 /// </summary>
 /// <param name="pRuleID">ID to probe for</param>
 /// <returns></returns>
 public static bool HasRuleID(Guid pRuleID)
 {
     InitRR();
     if (MyRulesRegistry != null)
     {
         ICDEThing pRule = TheThingRegistry.GetThingByID(eEngineName.ThingService, pRuleID.ToString());
         if (pRule != null)
         {
             try
             {
                 if (pRule.GetBaseThing().GetObject() is TheThingRule tRule)
                 {
                     return(true);
                 }
             }
             catch
             {
                 //ignored
             }
         }
     }
     return(false);
 }
Ejemplo n.º 22
0
        private void OnThingDeleted(ICDEThing t, object o)
        {
            // TODO: Close any network connections or free up any other resources held
            List <TheThing> tDevList = TheThingRegistry.GetThingsOfEngine(MyBaseThing.EngineName);

            if (tDevList.Count > 0)
            {
                foreach (TheThing tDev in tDevList)
                {
                    if (tDev.DeviceType != "IBaseEngine")
                    {
                        //TheThingClass tS = null;
                        //if (!tDev.HasLiveObject)
                        //{
                        //    try
                        //    {
                        //        tDev.OnThingDeleted(t, o); // Only needed if the thing needs to free up any resources
                        //    }
                    }
                }
            }
            MyBaseEngine.SetStatusLevel(-1); //Calculates the current statuslevel of the service/engine
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Primary event handler for incoming messages from CD-Engine
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="Para"></param>
        static void sinkIncoming(ICDEThing sender, object Para)
        {
            //Cast returned message to make strongly typed
            TheProcessMessage tProc = Para as TheProcessMessage;

            if (tProc == null)
            {
                return;
            }

            ////Skip ContentService messages for now
            //if (tProc.Message.ENG == eEngineName.ContentService)
            //{
            //    return;
            //}

            //Parse message text into command
            string[] tCmd = tProc.Message.TXT.Split(':');
            switch (tCmd[0])
            {
            default:
                break;
            }
        }
Ejemplo n.º 24
0
        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)));
                    }
                }
            }
        }
Ejemplo n.º 25
0
        void sinkRuleIncoming(ICDEThing sender, object pIncoming)
        {
            TheProcessMessage pMsg = pIncoming as TheProcessMessage;

            if (pMsg == null || pMsg.Message == null)
            {
                return;
            }
            //System.Diagnostics.Debug.WriteLine(string.Format("{0} {1} {2}", pMsg.Message.ENG, pMsg.Message.TXT, pMsg.Message.PLS));
            List <TheThing> tList = TheThingRegistry.GetThingsByFunc("*", s => TheThing.GetSafePropertyString(s, "TriggerObject") == pMsg.Message.ENG);

            if (tList != null)
            {
                foreach (TheThing tThing in tList)
                {
                    TheRule tRule = tThing.GetObject() as TheRule;
                    if (tRule == null || !tRule.IsRuleActive)
                    {
                        continue;
                    }
                    if (tRule.TriggerStartTime > DateTimeOffset.Now)
                    {
                        continue;
                    }
                    if (tRule.TriggerEndTime < DateTimeOffset.Now)
                    {
                        RemoveTrigger(tRule, false);
                        continue;
                    }
                    if (pMsg.Message.TXT.StartsWith(tRule.TriggerProperty))
                    {
                        tRule.RuleTrigger(pMsg.Message.PLS);
                    }
                }
            }
        }
Ejemplo n.º 26
0
        /// <summary>
        /// Handles Messages sent from a host sub-engine to its clients
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="pIncoming"></param>
        public void HandleMessage(ICDEThing sender, object pIncoming)
        {
            TheProcessMessage pMsg = pIncoming as TheProcessMessage;

            if (pMsg == null)
            {
                return;
            }

            string[] cmd = pMsg.Message.TXT.Split(':');
            switch (cmd[0])
            {
            case "CDE_INITIALIZED":
                MyBaseEngine.SetInitialized(pMsg.Message);
                break;

            case nameof(MsgMileRecordHolder):
                if (g_EnableMeshDataResponse)
                {
                    // Request from another node for mile record holder information.
                    var request     = TheCommRequestResponse.ParseRequestMessageJSON <MsgMileRecordHolder>(pMsg.Message);
                    var MsgResponse = new MsgMileRecordHolderResponse();
                    if (request != null)
                    {
                        MsgResponse.data = TheRecordHolder.QueryRecordHolder(request.id);
                    }
                    TheCommRequestResponse.PublishResponseMessageJson(pMsg.Message, MsgResponse);

                    MsgResponse = null;       // Prevent legacy response handler for being sent.
                }
                break;

            default:
                break;
            }
        }
Ejemplo n.º 27
0
 void sinkUpdateControls(ICDEThing pThing, object para)
 {
     UpdateUx();
 }
Ejemplo n.º 28
0
 public void HandleMessage(ICDEThing sender, object pMsg)
 {
 }
Ejemplo n.º 29
0
 public virtual void FireEvent(string eventName, ICDEThing sender, object parameter, bool fireAsync)
 {
     TheThing?.FireEvent(eventName, sender, parameter, fireAsync);
 }
Ejemplo n.º 30
0
 private void OnPreShutdown(ICDEThing sender, object msg)
 {
     ShutdownService();
 }