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); } } } }
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); }
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); }
private void sinkCyclic(long timer) { if (KPIHarvestInterval == 0) { return; } if (timer % KPIHarvestInterval != 0) { return; } if (TheThing.GetSafePropertyBool(MyBaseThing, "EnableKPIs")) { TheCDEKPIs.ToThingProperties(MyBaseThing, true); } }
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); }
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); }
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 }
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))); } } } }
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) { } }
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); }
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 }
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); } }
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); }
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); }
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; }
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); }
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); }