예제 #1
0
 private void sinkLoopChanged(cdeP pProp)
 {
     int tTime = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(this, "MsToTrigger"));
     //if (tTime > 0)
     {
         int tPeriod = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(this, "LoopPeriod"));
         if (tPeriod == 0)
         {
             tPeriod = -1;
         }
         if (tPeriod > 0 && tPeriod < 10)
         {
             tPeriod = 10;
         }
         MyBaseThing.Value = "0";
         if (mTimer != null)
         {
             mTimer.Change(tTime, tPeriod);
         }
         else
         {
             mTimer = new Timer(sinkTriggerTimeout, null, tTime, tPeriod);
         }
         IsActive = true;
         MyBaseThing.StatusLevel = 1;
         MyBaseThing.LastMessage = $"Timer started at {DateTimeOffset.Now}";
         SummaryForm?.SetUXProperty(Guid.Empty, string.Format("Background=green"));
     }
 }
예제 #2
0
 void sinkTriggerTimeout(object state)
 {
     if (TheCommonUtils.cdeIsLocked(tLock))
     {
         return;
     }
     if (!TheBaseAssets.MasterSwitch)
     {
         mTimer?.Dispose();
         mTimer = null;
         return;
     }
     if (IsDisabled)
     {
         if (MyBaseThing.StatusLevel != 0)
         {
             MyBaseThing.StatusLevel = 0;
             MyBaseThing.LastMessage = "Timer disabled";
         }
         return;
     }
     else if (MyBaseThing.StatusLevel == 0)
     {
         MyBaseThing.StatusLevel = 1;
         MyBaseThing.LastMessage = "Timer enabled";
     }
     lock (tLock)
     {
         cdeP pV = MyBaseThing.SetProperty("Value", (TheCommonUtils.CInt(MyBaseThing.Value) + 1));
         pV.cdeE = 2;
     }
 }
예제 #3
0
 private void sinkTriggered(cdeP pProp)
 {
     if (TheCommonUtils.cdeIsLocked(TriggerLock) || IsDisabled)
     {
         return;
     }
     lock (TriggerLock)
     {
         if (pProp == null)
         {
             return;
         }
         int tTime = TheCommonUtils.CInt(pProp.ToString());
         if (tTime <= 0 || mTimer != null)
         {
             return;
         }
         mTimer?.Dispose();
         if (Frequency < 100)
         {
             Frequency = 100;
         }
         mTimer            = new Timer(sinkTriggerTimeout, null, 0, Frequency);
         MyBaseThing.Value = tTime.ToString();
         IsActive          = true;
         CountBar?.SetUXProperty(Guid.Empty, $"MaxValue={tTime}");
         tGauge?.SetUXProperty(Guid.Empty, $"MaxValue={tTime}");
         MyBaseThing.LastMessage = "Countdown started: " + MyBaseThing.FriendlyName;
         MyBaseThing.StatusLevel = 1;
     }
 }
예제 #4
0
 private void SinkValueReset(cdeP pProp)
 {
     if (_mTimer == null)
     {
         SetProperty("StartValue", pProp.ToString());
     }
 }
예제 #5
0
 private void sinkValueReset(cdeP pProp)
 {
     if (mTimer == null && TheCommonUtils.CInt(pProp.ToString()) > 0)
     {
         this.SetProperty(nameof(StartValue), pProp.ToString());
     }
 }
예제 #6
0
 private void onPingTimeoutChanged(cdeP obj)
 {
     MyBaseThing.DeclareSensorProperty(nameof(RoundTripTime), ePropertyTypes.TNumber, new cdeP.TheSensorMeta {
         RangeMin = 0, RangeMax = PingTimeOut, Units = "ms"
     });
     //MyBaseThing.DeclareSensorProperty(nameof(MyBaseThing.Value), ePropertyTypes.TNumber, new cdeP.TheSensorMeta { RangeMin = 0, RangeMax = PingTimeOut, Units = "ms" });
 }
예제 #7
0
        public TheVTimer(TheThing pThing, IBaseEngine pEngine)
            : base(pThing)
        {
            if (pThing != null)
            {
                MyBaseThing = pThing;
            }
            else
            {
                MyBaseThing = new TheThing();
            }

            cdeP tfirstTrigger = MyBaseThing.DeclareNMIProperty("MsToTrigger", ePropertyTypes.TNumber);

            tfirstTrigger.RegisterEvent(eThingEvents.PropertySet, sinkLoopChanged);

            cdeP tLoop = MyBaseThing.DeclareNMIProperty("LoopPeriod", ePropertyTypes.TNumber);

            tLoop.RegisterEvent(eThingEvents.PropertySet, sinkLoopChanged);
            cdeP tTrigger = MyBaseThing.DeclareNMIProperty("TriggerTimer", ePropertyTypes.TString);

            tTrigger.RegisterEvent(eThingEvents.PropertySet, sinkTriggered);

            MyBaseEngine           = pEngine;
            MyBaseThing.DeviceType = eVThings.eVTimer;
            MyBaseThing.EngineName = pEngine.GetEngineName();
            MyBaseThing.SetIThingObject(this);
        }
예제 #8
0
        public void StartPropertyUpdateLoop()
        {
            testThing = new TheThing()
            {
                FriendlyName = "MyTestSensor"
            };
            TheThingRegistry.RegisterThing(testThing);
            Random rand = new Random(); // Used for generating "fake" sensor values

            cdeP[] props = new cdeP[propertyCount];

            // Run the loop on another thread
            TheCommonUtils.cdeRunAsync("PropertyUpdateLoop", true, (o) =>
            {
                while (TheBaseAssets.MasterSwitch)
                {
                    // Set the properties and log
                    props[0] = testThing.SetProperty(properties[0], rand.Next(25, 51));
                    props[1] = testThing.SetProperty(properties[1], rand.NextDouble());
                    props[2] = testThing.SetProperty(properties[2], rand.Next(10000, 50000));
                    LogChanges(false, props);

                    // Wait timeout of 1 second between property updates
                    TheCommonUtils.SleepOneEye(1000, 500);
                }
            });
        }
예제 #9
0
        void sinkUpdateUX(cdeP pProp)
        {
            int i = MyBaseThing.StatusLevel; //Optimizing that GetProperty is not called 3 times

            SummaryForm?.SetUXProperty(Guid.Empty, string.Format("Background={0}", TheNMIEngine.GetStatusColor(i)));

            MyBaseEngine.ProcessMessage(new TheProcessMessage(new TSM(MyBaseEngine.GetEngineName(), "UPDATE_VALUE")));
        }
예제 #10
0
 private void OnSendAttempt(cdeP notUsed)
 {
     if (KPILogIntervalInMinutes > 0 && DateTimeOffset.Now - lastKPILogTime > new TimeSpan(0, 0, KPILogIntervalInMinutes, 0))
     {
         lastKPILogTime = DateTimeOffset.Now - new TimeSpan(0, 0, 0, 5);  // Give a few seconds leeway so the next timer doesn't miss the window
         LogKPIs();
     }
 }
예제 #11
0
        public override bool Init()
        {
            if (!mIsInitStarted)
            {
                mIsInitStarted          = true;
                MyBaseThing.StatusLevel = 4;
                MyBaseThing.LastMessage = "Logger Service has started";

                MyBaseThing.RegisterEvent(eEngineEvents.IncomingMessage, HandleMessage);
                MyBaseEngine.RegisterEvent(eEngineEvents.ThingDeleted, OnThingDeleted);

                cdeP tP = null;
                if (TheBaseAssets.MyServiceHostInfo.DisableConsole)
                {
                    TheThing.SetSafePropertyBool(MyBaseThing, "DisableStandardLog", TheBaseAssets.MyServiceHostInfo.DisableConsole);
                }
                else
                {
                    tP = GetProperty("DisableStandardLog", true);
                }
                tP.RegisterEvent(eThingEvents.PropertyChanged, sinkDisableChanged);
                if (TheCommonUtils.CBool(tP.ToString()))
                {
                    TheBaseAssets.MyServiceHostInfo.DisableConsole = true;
                }

                if (TheBaseAssets.MyServiceHostInfo.UseGELFLoggingFormat)
                {
                    tP = TheThing.SetSafePropertyBool(MyBaseThing, "UseGELF", TheBaseAssets.MyServiceHostInfo.UseGELFLoggingFormat);
                }
                else
                {
                    tP = GetProperty("UseGELF", true);
                }
                tP.RegisterEvent(eThingEvents.PropertyChanged, sinkGELF);
                if (TheCommonUtils.CBool(tP.ToString()))
                {
                    TheBaseAssets.MyServiceHostInfo.UseGELFLoggingFormat = true;
                }

                bool DoLogKPIs = TheCommonUtils.CBool(TheBaseAssets.MySettings.GetSetting("LogKPIs"));
                if (DoLogKPIs)
                {
                    TheThing.SetSafePropertyBool(MyBaseThing, "LogKPIs", true);
                }

                TheQueuedSenderRegistry.RegisterHealthTimer(sinkTimer);
                // If not lengthy initialized you can remove cdeRunasync and call this synchronously
                TheCommonUtils.cdeRunAsync(MyBaseEngine.GetEngineName() + " Init Services", true, (o) =>
                {
                    // Perform any long-running initialization (i.e. network access, file access) here
                    InitServices();
                    MyBaseEngine.ProcessInitialized(); //Set the status of the Base Engine according to the status of the Things it manages
                    mIsInitCompleted = true;
                });
            }
            return(false);
        }
예제 #12
0
 private void sinkOnTraceLogDirectoryChanged(cdeP obj)
 {
     if (watcher != null)
     {
         watcher.Path = IISFailedReqTraceFolderPath;
     }
     else
     {
         StartFolderWatch();
     }
 }
예제 #13
0
        public override bool DoInit()
        {
            base.DoInit();
            IsActive = false;
            TheThing.SetSafePropertyBool(MyBaseThing, "IsStateSensor", true);
            MyBaseThing.StatusLevel = 4;
            if (string.IsNullOrEmpty(MyBaseThing.ID))
            {
                MyBaseThing.ID = Guid.NewGuid().ToString();

                TheThing.SetSafePropertyString(MyBaseThing, "StateSensorType", "analog");
                TheThing.SetSafePropertyString(MyBaseThing, "StateSensorUnit", "units");
                TheThing.SetSafePropertyNumber(MyBaseThing, "StateSensorMaxValue", 100);
                TheThing.SetSafePropertyNumber(MyBaseThing, "StateSensorAverage", 50);
                TheThing.SetSafePropertyNumber(MyBaseThing, "StateSensorMinValue", 0);
                TheThing.SetSafePropertyNumber(MyBaseThing, "Interval", 500);
            }
            TheThing.SetSafePropertyString(MyBaseThing, "StateSensorIcon", "/P066/Images/iconVThingsRest.png");
            GetProperty("FriendlyName", true).RegisterEvent(eThingEvents.PropertyChanged, sinkNameChanged);
            cdeP tRW = GetProperty("RawValue", true);

            tRW.RegisterEvent(eThingEvents.PropertyChanged, sinkPrePro);
            cdeP.SetSafePropertyBool(tRW, "IsStateSensor", true);
            cdeP.SetSafePropertyString(tRW, "StateSensorType", "analog");
            cdeP.SetSafePropertyString(tRW, "StateSensorUnit", "&#176;F");
            cdeP.SetSafePropertyNumber(tRW, "StateSensorMaxValue", 100);
            cdeP.SetSafePropertyNumber(tRW, "StateSensorAverage", 50);
            cdeP.SetSafePropertyNumber(tRW, "StateSensorMinValue", 0);

            if (!string.IsNullOrEmpty(TheThing.GetSafePropertyString(MyBaseThing, "RealSensorThing")) && !string.IsNullOrEmpty(TheThing.GetSafePropertyString(MyBaseThing, "RealSensorProperty")))
            {
                EngageMapper();
            }

            GetProperty("IsGlobal", true).RegisterEvent(eThingEvents.PropertyChanged, (p) =>
            {
                if (TheCommonUtils.CBool(p.ToString()))
                {
                    TheThingRegistry.RegisterThingGlobally(MyBaseThing);
                }
                else
                {
                    TheThingRegistry.UnregisterThingGlobally(MyBaseThing);
                }
            });
            GetProperty("Interval", true).RegisterEvent(eThingEvents.PropertyChanged, (p) =>
            {
                changeInterval(TheCommonUtils.CInt(p.ToString()));
            });
            MyBaseThing.SetPublishThrottle((int)TheThing.GetSafePropertyNumber(MyBaseThing, "Interval"));

            //TheQueuedSenderRegistry.RegisterHealthTimer(checkMapperHealth);
            return(true);
        }
예제 #14
0
        private void sinkPropChanged(cdeP pPara)
        {
            cdeP tProp = pPara as cdeP;

            if (tProp != null && tProp.Name == nameof(IsConnected))
            {
                if (_bIsConnected != TheCommonUtils.CBool(tProp.Value))
                {
                    TheThing.SetSafePropertyBool(MyBaseThing, nameof(IsConnected), _bIsConnected);
                }
            }
        }
예제 #15
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="property"></param>
        /// <returns>Empty string if tag is properly registered. null if tag is not known at all. Error string if registration has failed or not occurred.</returns>
        public string CheckTagStatus(cdeP property)
        {
            TagRegistration registration;

            if (!_TagRegistrations.TryGetValue(property.Name, out registration))
            {
                return(null);
            }
            if (String.IsNullOrEmpty(registration.Error))
            {
                return("");
            }
            return(registration.Error);
        }
예제 #16
0
        public override bool DoInit()
        {
            if (MyBaseThing.StatusLevel != 1)
            {
                MyBaseThing.LastMessage = "Tag Ready";
                MyBaseThing.StatusLevel = 0;
            }
            cdeP Mon = MyBaseThing.GetProperty("DontMonitor", true);

            Mon.RegisterEvent(eThingEvents.PropertyChanged, sinkPChanged);
            MyBaseThing.RegisterEvent(eThingEvents.PropertyChanged, sinkUXUpdatedThing);
            MyBaseThing.RegisterEvent(eThingEvents.ValueChanged, sinkRulesUpdatedThing);
            return(true);
        }
예제 #17
0
        public override cdeP SetProperty(string pName, object pValue)
        {
            cdeP tProp = base.SetProperty(pName, pValue);

            if (pName == nameof(StartValue))
            {
                sinkTriggered(tProp);
            }
            if (pName == "Value")
            {
                sinkValueReset(tProp);
            }
            return(tProp);
        }
예제 #18
0
 private void sinkTriggered(cdeP pProp)
 {
     if (mTimer != null)
     {
         mTimer.Dispose();
     }
     mTimer = null;
     if (pProp != null && pProp.ToString().Equals("stop", StringComparison.OrdinalIgnoreCase))
     {
         StopTimer();
         return;
     }
     sinkLoopChanged(pProp);
 }
예제 #19
0
        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);
        }
예제 #20
0
        private void SinkTriggered(cdeP pProp)
        {
            _index = 0;
            _mTimer?.Dispose();

            _mTimer           = new Timer(SinkTriggerTimeout, null, 0, Frequency);
            MyBaseThing.Value = _index.ToString();
            IsActive          = true;

            var xMax = GetProperty(nameof(Amplitude), false);

            CountBar?.SetUXProperty(Guid.Empty, $"MaxValue={xMax}");
            MyGauge?.SetUXProperty(Guid.Empty, $"MaxValue={xMax}");
            MyBaseThing.LastMessage = "Countdown started: " + MyBaseThing.FriendlyName;
        }
예제 #21
0
        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;
            }
        }
예제 #22
0
        void sinkPChanged(cdeP prop)
        {
            if (MyBaseEngine.GetEngineState().IsSimulated || !IsConnected)
            {
                return;
            }
            var field = MyModFieldStore.MyMirrorCache.GetEntryByFunc(s => s.PropertyName == prop.Name);

            if (field == null)
            {
                return;
            }

            var error = OpenModBus();

            if (!string.IsNullOrEmpty(error))
            {
                MyBaseThing.LastMessage = $"{DateTime.Now} - Modbus Device could not be opened: {error}";
                TheBaseAssets.MySYSLOG.WriteToLog(10000, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseThing.EngineName, MyBaseThing.LastMessage, eMsgLevel.l1_Error));
                return;
            }
            try
            {
                ushort tMainOffset   = (ushort)(TheThing.GetSafePropertyNumber(MyBaseThing, "Offset") + field.SourceOffset);
                byte   tSlaveAddress = (byte)TheThing.GetSafePropertyNumber(MyBaseThing, "SlaveAddress");
                int    tReadWay      = (int)TheThing.GetSafePropertyNumber(MyBaseThing, "ConnectionType");
                switch (tReadWay)
                {
                case 1:
                    MyModMaster.WriteSingleCoil(tSlaveAddress, tMainOffset, TheCommonUtils.CBool(prop.ToString()));
                    break;

                default:
                    MyModMaster.WriteSingleRegister(tSlaveAddress, tMainOffset, TheCommonUtils.CUShort(prop.ToString()));
                    break;
                }
            }
            catch (Exception e)
            {
                MyBaseThing.LastMessage = $"{DateTime.Now} - Failure during write of modbus property: {e.Message}";
                TheBaseAssets.MySYSLOG.WriteToLog(10000, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseThing.EngineName, MyBaseThing.LastMessage, eMsgLevel.l1_Error, e.ToString()));
            }
            if (!KeepOpen) // races with reader thread, but reader thread will retry/reopen so at most one data point is lost
            {
                CloseModBus();
            }
        }
예제 #23
0
 public bool RegisterEvent(cdeP property, string nodeId, TheEventSubscription subscriptionInfo)
 {
     if (property.GetThing()?.GetBaseThing() == null)
     {
         return(false);
     }
     return(_EventRegistrations.TryAdd(property.Name, new EventRegistration
     {
         PropertyName = property.Name,
         EventInfo = new MsgOPCUACreateTags.EventInfo
         {
             DisplayName = property.Name,
             NodeId = nodeId,
             Subscription = subscriptionInfo.Clone(),
             HostThing = property.GetThing().GetBaseThing(),
         },
         Error = "Not subscribed",
     }));
 }
예제 #24
0
        void sinkUpdateUX(cdeP prop)
        {
            if (prop.Name == "StateSensorValueName")
            {
                ValueField?.SetUXProperty(Guid.Empty, $"Title={TheThing.GetSafePropertyString(MyBaseThing, "StateSensorValueName")}");
            }
            if (prop.Name == "StateSensorMaxValue" || prop.Name == "StateSensorMinValue" || prop.Name == "StateSensorSteps")
            {
                LiveChartFld?.SetUXProperty(Guid.Empty, $"MaxValue={TheThing.GetSafePropertyString(MyBaseThing, "StateSensorMaxValue")}:;:MinValue={TheThing.GetSafePropertyString(MyBaseThing, "StateSensorMinValue")}");
                GaugeFld?.SetUXProperty(Guid.Empty, $"MaxValue={TheThing.GetSafePropertyString(MyBaseThing, "StateSensorMaxValue")}:;:MinValue={TheThing.GetSafePropertyString(MyBaseThing, "StateSensorMinValue")}");

                if (mBucket != null)
                {
                    mBucket = new TheBucketChart <T>((int)TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorMinValue"), (int)TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorMaxValue"), (int)TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorSteps"), true);
                    BucketChartFld?.SetUXProperty(Guid.Empty, $"XAxis={{ \"categories\": {mBucket.GetBuckets()} }}");
                    TheThing.SetSafePropertyString(MyBaseThing, "BucketChart", mBucket.GetBucketArray());
                }
            }
        }
예제 #25
0
        /// <summary>
        /// Initializes the Live Tag
        /// </summary>
        /// <returns></returns>
        public override bool Init()
        {
            if (mIsInitCalled)
            {
                return(false);
            }
            mIsInitCalled = true;

            TheThing.SetSafePropertyBool(MyBaseThing, "IsLiveTag", true);
            MyBaseThing.FireEvent("OnInitialized", this, new TSM(MyBaseThing.cdeMID.ToString(), "Was Init"), false);
            cdeP tThrot = GetProperty("Throttle", true);

            tThrot.RegisterEvent(eThingEvents.PropertyChanged, sinkThrottleChanged);
            mIsInitialized = DoInit();
            if (string.IsNullOrEmpty(MyBaseThing.ID))
            {
                MyBaseThing.ID = Guid.NewGuid().ToString();
            }
            return(mIsInitialized);
        }
예제 #26
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()));
                }
            }
        }
예제 #27
0
        //public static void Browse() { }

        //public async Task<string> RegisterAndReadTagAsync(cdeP property, string nodeId, int samplingInterval = 1000, ChangeTrigger changeTrigger = ChangeTrigger.Value, double deadbandvalue = 0) { return false; }

        public bool RegisterTag(cdeP property, string nodeId, int samplingInterval = 1000, ChangeTrigger changeTrigger = ChangeTrigger.Value, double deadbandvalue = 0)
        {
            if (property.GetThing()?.GetBaseThing() == null)
            {
                return(false);
            }
            return(_TagRegistrations.TryAdd(property.Name, new TagRegistration
            {
                PropertyName = property.Name,
                TagInfo = new MsgOPCUACreateTags.TagInfo
                {
                    DisplayName = property.Name,
                    NodeId = nodeId,
                    SamplingInterval = samplingInterval,
                    ChangeTrigger = changeTrigger,
                    DeadbandValue = deadbandvalue,
                    HostThingAddress = property.GetThing().GetBaseThing(),
                },
                Error = "Not subscribed",
            }));
        }
예제 #28
0
        /// <summary>
        /// The possible types of WeMo devices that can be detected
        /// </summary>
        #endregion

        public bool Init()
        {
            if (mIsInitCalled)
            {
                return(false);
            }
            mIsInitCalled          = true;
            MyBaseThing.EngineName = eEngineName.NMIService;
            MyBaseThing.DeviceType = "NMI Editor";
            TheThing.SetSafePropertyBool(MyBaseThing, "IsLiveTag", true);
            MyBaseThing.FireEvent("OnInitialized", this, new TSM(MyBaseThing.cdeMID.ToString(), "Was Init"), false);
            cdeP tThrot = GetProperty("Throttle", true);

            tThrot.RegisterEvent(eThingEvents.PropertyChanged, sinkThrottleChanged);
            mIsInitialized = DoInit();    //we have to follow your design to have mIsINitialzed called at the end. This can lead to problems for live tags
            if (string.IsNullOrEmpty(MyBaseThing.ID))
            {
                MyBaseThing.ID = Guid.NewGuid().ToString();
            }
            return(mIsInitialized);
        }
예제 #29
0
        void CreateDynUX(bool ForceAdd)
        {
            return; //TODO: Make much better UX here...Remove Controls first then create (see OPC DA Plugin)

#pragma warning disable CS0162
            if (mIsUXInitCalled && (!IsDynUXCreated || ForceAdd))
            {
                if (m_Method == null)
                {
                    return;
                }
                IsDynUXCreated = true;
                int i = 0;
                foreach (TheOPCProperties tOPC in InputArgs)
                {
                    cdeP tP = tOPC.cdeProperty;
                    if (tP == null)
                    {
                        IsDynUXCreated = false;
                        return;
                    }
                    TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, TheNMIEngine.GetCtrlTypeFromCDET((ePropertyTypes)tP.cdeT), 101 + i, 2, MyBaseThing.cdeA, tP.Name, tP.Name);
                    i++;
                }
                i = 0;
                foreach (TheOPCProperties tOPC in OutputArgs)
                {
                    cdeP tP = tOPC.cdeProperty;
                    if (tP == null)
                    {
                        IsDynUXCreated = false;
                        return;
                    }
                    TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, TheNMIEngine.GetCtrlTypeFromCDET((ePropertyTypes)tP.cdeT), 201 + i, 0, MyBaseThing.cdeA, tP.Name, tP.Name);
                    i++;
                }
                //HandleMessage(new TheProcessMessage(new TSM(MyBaseThing.EngineName, "CALL_METHOD:"+TheCommonUtils.cdeGuidToString(Guid.NewGuid()))));
            }
#pragma warning restore CS0162
        }
예제 #30
0
        private void SinkStatChanged(TheDashPanelInfo tDas, cdeP prop)
        {
            var i = (prop != null)
                ? TheCommonUtils.CInt(prop.ToString())
                : TheCommonUtils.CInt(MyBaseThing.Value);

            var tCol   = i < 3 ? "orange" : "green";
            var tLevel = i < 3 ? 2 : 1;

            if (i == 0)
            {
                tCol   = "gray";
                tLevel = 0;
            }

            SummaryForm.SetUXProperty(Guid.Empty, $"Background={tCol}");

            if (MyBaseThing.StatusLevel != tLevel)
            {
                MyBaseThing.StatusLevel = tLevel;
            }
        }