public void HandleMessage(ICDEThing sender, object pIncoming) { TheProcessMessage pMsg = pIncoming as TheProcessMessage; if (pMsg == null) { return; } var tCmd = pMsg.Message.TXT.Split(':'); switch (tCmd[0]) { case "CDE_NODETOPICS": sinkServiceInfo(pMsg?.Message); break; case "ADD_FOOTPRINT": var Tf = TheCommonUtils.DeserializeJSONStringToObject <NodeTypeScript>(pMsg.Message.PLS); if (Tf?.NodeTypes != null && Tf.NodeTypes.Count > 0) { MyFootPrints.AddItems(Tf.NodeTypes, null); } TheCommCore.PublishToOriginator(pMsg.Message, new TSM(pMsg.Message.ENG, $"{tCmd[0]}_RESPONSE{(tCmd.Length>1?$":{tCmd[1]}":"")}", "{\"RESPONSE\":\"SUCCESS\"}"), true); break; } }
private void OnDownloadClick(ICDEThing pThing, object pPara) { TheProcessMessage pMSG = pPara as TheProcessMessage; if (pMSG == null || pMSG.Message == null) { return; } string[] cmd = pMSG.Message.PLS.Split(':'); if (cmd.Length > 2) { TheThing tThing = TheThingRegistry.GetThingByMID("*", TheCommonUtils.CGuid(cmd[2]), true); if (tThing == null) { return; } TSM tFilePush = new TSM(eEngineName.ContentService, string.Format("CDE_FILE:{0}.JSON:application/zip", tThing.FriendlyName)) { SID = pMSG.Message.SID, PLS = "bin", PLB = TheCommonUtils.CUTF8String2Array(TheCommonUtils.SerializeObjectToJSONString(tThing)) }; TheCommCore.PublishToOriginator(pMSG.Message, tFilePush); } }
private void ShowKPI(int pFldOrder, string pLabel, string pUpdName, int MaxVal = 100, int AveVal = 50, string pUnits = "bytes") { TheNMIEngine.AddSmartControl(MyBaseThing, mMyForm, eFieldType.TileGroup, pFldOrder, 0, 0, null, null, new nmiCtrlTileGroup { ParentFld = 300, TileWidth = 6 }); TheNMIEngine.AddSmartControl(MyBaseThing, mMyForm, eFieldType.SmartLabel, pFldOrder + 1, 0, 0, null, null, new nmiCtrlSmartLabel { ParentFld = pFldOrder, Text = pLabel, NoTE = true, TileFactorY = 2, TileHeight = 1, TileWidth = 5, ClassName = "cdeTileGroupHeaderSmall" }); var tBut = TheNMIEngine.AddSmartControl(MyBaseThing, mMyForm, eFieldType.TileButton, pFldOrder + 2, 2, 0, "V-Tise", null, new nmiCtrlTileButton { ParentFld = pFldOrder, NoTE = true, TileFactorY = 2, TileHeight = 1, TileWidth = 1, ClassName = "cdeGlassButton" }); tBut.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, $"But{pUpdName}", (sender, para) => { TheThing tT = TheThingRegistry.GetThingByID(MyBaseEngine.GetEngineName(), $"ISO{MyBaseThing.cdeMID}:{pUpdName}"); if (tT == null) { TheKPIReport tRep = new TheKPIReport(null, MyPlugin); TheThing.SetSafePropertyGuid(tRep, "RealSensorThing", MyBaseThing.cdeMID); tRep.GetBaseThing().ID = $"ISO{MyBaseThing.cdeMID}:{pUpdName}"; MyBaseThing.GetProperty(pUpdName, true); TheThing.SetSafePropertyString(tRep, "RealSensorProperty", pUpdName); TheThing.SetSafePropertyNumber(tRep, "StateSensorMaxValue", MaxVal); TheThing.SetSafePropertyNumber(tRep, "StateSensorAverage", AveVal); TheThing.SetSafePropertyNumber(tRep, "StateSensorSteps", MaxVal / 15); TheThing.SetSafePropertyString(tRep, "StateSensorValueName", pLabel); TheThing.SetSafePropertyString(tRep, "StateSensorUnit", pUnits); TheThing.SetSafePropertyString(tRep, "FriendlyName", MyBaseThing.FriendlyName); TheThing.SetSafePropertyString(tRep, "ReportName", $"ISO-KPI: {MyBaseThing.FriendlyName} - {pLabel}"); TheThing.SetSafePropertyString(tRep, "ReportCategory", "ISO KPI Reports"); ThePluginInfo tI = MyPlugin.GetBaseEngine().GetPluginInfo(); if (tI != null) { TheThing.SetSafePropertyString(tRep, "SerialNumber", TheCommonUtils.CStr(tI.CurrentVersion)); TheThing.SetSafePropertyString(tRep, "VendorName", TheCommonUtils.CStr(tI.Developer)); TheThing.SetSafePropertyString(tRep, "ProductName", TheCommonUtils.CStr(tI.ServiceDescription)); TheThing.SetSafePropertyString(tRep, "ProductText", TheCommonUtils.CStr(tI.LongDescription)); TheThing.SetSafePropertyString(tRep, "VendorText", TheCommonUtils.CStr(tI.DeveloperUrl)); TheThing.SetSafePropertyString(tRep, "ProductID", TheCommonUtils.CStr(tI.cdeMID)); } TheThingRegistry.RegisterThing(tRep); MyBaseEngine.ProcessMessage(new TheProcessMessage(new TSM(MyBaseEngine.GetEngineName(), "REFRESH_DASH"))); } else { TheCommCore.PublishToOriginator((para as TheProcessMessage).Message, new TSM(eEngineName.NMIService, "NMI_TTS", tT.cdeMID.ToString())); } }); TheNMIEngine.AddSmartControl(MyBaseThing, mMyForm, eFieldType.SmartLabel, pFldOrder + 3, 0, 0, null, pUpdName, new nmiCtrlSingleEnded { ParentFld = pFldOrder, TileWidth = 2 }); TheNMIEngine.AddSmartControl(MyBaseThing, mMyForm, eFieldType.BarChart, pFldOrder + 4, 0, 0, null, pUpdName, new nmiCtrlBarChart() { ParentFld = pFldOrder, MaxValue = MaxVal, TileWidth = 4, NoTE = true, Foreground = "blue" }); }
/// <summary> /// If this is a service the SimplexProc event will be called when the C-DEngine receives a new event sent by a subscriber to this service /// </summary> /// <param name="pMsg">The Message to be Processed</param> private void ProcessServiceMessage(TheProcessMessage pMsg) { string[] cmd = pMsg.Message.TXT.Split(':'); switch (cmd[0]) //string 2 cases { case "WEBRELAY_RESPONSE": TheRequestData tState = TheCommonUtils.DeserializeJSONStringToObject <TheRequestData>(pMsg.Message.PLS); if (pMsg.Message.PLB != null && pMsg.Message.PLB.Length > 0) { tState.ResponseBuffer = pMsg.Message.PLB; } tState.RequestUri = new Uri(tState.RequestUriString); //tState.SessionState = new TheSessionState() { SScopeID = pMsg.SID }; sinkResults(tState); break; case "WEBRELAY_REQUEST": TheRequestData tData = TheCommonUtils.DeserializeJSONStringToObject <TheRequestData>(pMsg.Message.PLS); if (tData != null) { tData.RequestUri = new Uri(tData.RequestUriString); //tData.SessionState = new TheSessionState() { SScopeID = pMsg.SID }; if (pMsg.Message.PLB != null && pMsg.Message.PLB.Length > 0) { tData.PostData = pMsg.Message.PLB; } tData.CookieObject = pMsg.Message; ReadHttpPage(tData, tData.SessionState.ARApp, null, sinkProcessResponse); //InterceptHttpRequest(tData,tData.SessionState.ARApp); } break; case "WEBRELAY_REQUESTWRA": TSM tTSM = new TSM(); List <TheThing> webApps = TheThingRegistry.GetThingsOfEngine(MyBaseEngine.GetEngineName()); foreach (TheThing tApp in webApps) { if (tApp.Address.Equals(pMsg.Message.PLS)) { tTSM.PLS = $"/CDEWRA{tApp.cdeMID}" + TheThing.GetSafePropertyString(tApp, "HomePage"); break; } } if (!string.IsNullOrEmpty(tTSM.PLS)) { string[] org = pMsg.Message.ORG.Split(':'); TheThing senderThing = TheThingRegistry.GetThingByMID(TheCommonUtils.CGuid(org[1]), true); IBaseEngine senderEngine = TheThingRegistry.GetBaseEngine(senderThing, true); tTSM.ENG = senderEngine.GetEngineName(); tTSM.TXT = "RESPONSEWRA"; TheCommCore.PublishToOriginator(pMsg.Message, tTSM, true); } break; } }
void CreateScriptEditTemplate() { MSE = new TheFormInfo(new Guid("{00000000-6AD1-45AE-BE61-96AF02329613}"), eEngineName.NMIService, "Script Editor", null) { DefaultView = eDefaultView.Form, IsNotAutoLoading = true, PropertyBag = new nmiCtrlFormTemplate { TableReference = $"{TheThing.GetSafeThingGuid(MyBaseThing, "SCRIPT_TABLE")}", TileWidth = 12 } }; TheNMIEngine.AddFormToThingUX(MyBaseThing, MSE, "CMyForm", "Script Editor", 100, 3, 0xF0, null, null, new ThePropertyBag() { "Visibility=false" }); TheNMIEngine.AddSmartControl(MyBaseThing, MSE, eFieldType.SingleEnded, 50, 0, 0, "Script Name", "ScriptName", new nmiCtrlSingleEnded() { TileWidth = 12 }); TheNMIEngine.AddSmartControl(MyBaseThing, MSE, eFieldType.TextArea, 60, 2, 0, null, "ScriptRaw", new nmiCtrlTextArea() { NoTE = true, TileWidth = 12, TileHeight = 12 }); TheNMIEngine.AddSmartControl(MyBaseThing, MSE, eFieldType.TextArea, 110, 0, 0, "Last Error", "ScriptError", new nmiCtrlTextArea() { TileWidth = 12, TileHeight = 3 }); var but = TheNMIEngine.AddSmartControl(MyBaseThing, MSE, eFieldType.TileButton, 100, 2, 0, "Save Script", null, new nmiCtrlTileButton() { TileWidth = 6, NoTE = true, TileHeight = 1, ClassName = "cdeGoodActionButton" }); but.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "SaveScript", (sender, pPara) => { if (!(pPara is TheProcessMessage pMSG) || pMSG.Message == null) { return; } var tP = pMSG.Message.PLS.Split(':'); var t = MyScriptTableStorage.MyMirrorCache.GetEntryByID(TheCommonUtils.CGuid(tP[2])); try { var Res = TheCommonUtils.DeserializeJSONStringToObject <TheScript>(t.ScriptRaw); t.ScriptError = "ok"; MSE.Reload(pMSG, true); } catch (Exception ee) { t.ScriptError = ee.ToString(); MSE.Reload(pMSG, true); return; } File.WriteAllText(t.FileName, t.ScriptRaw); TheCommCore.PublishToOriginator(pMSG.Message, new TSM(eEngineName.NMIService, "NMI_TTS", TheThing.GetSafeThingGuid(MyBaseThing, "SCRIPT_TABLE").ToString())); //This is the same as the TTS:.. from above...but with an additional roundtrip to the Relay });
private void sinkProcessResponse(TheRequestData pRequest) { if (pRequest.StatusCode >= 400 && pRequest.ResponseBuffer == null && !string.IsNullOrEmpty(pRequest.ErrorDescription)) { pRequest.ResponseBuffer = TheCommonUtils.CUTF8String2Array(pRequest.ErrorDescription); } if (pRequest.ResponseBuffer == null && string.IsNullOrEmpty(pRequest.ResponseBufferStr)) { pRequest.ResponseBuffer = TheCommonUtils.CUTF8String2Array("EMPTY"); } if (pRequest.ResponseMimeType.StartsWith("text/html") || pRequest.ResponseMimeType.Contains("javascript")) //OK { pRequest.ResponseBufferStr = TheCommonUtils.CArray2UTF8String(pRequest.ResponseBuffer); } string tReqUri = pRequest.RequestUri.Host; if (pRequest.RequestUri.Port != 80) { tReqUri += ":" + pRequest.RequestUri.Port; } if (!string.IsNullOrEmpty(pRequest.ResponseBufferStr) && (pRequest.ResponseMimeType.StartsWith("text/html") || pRequest.ResponseMimeType.Contains("javascript")) && pRequest.ResponseBufferStr.IndexOf(tReqUri, StringComparison.CurrentCultureIgnoreCase) >= 0) { if (pRequest.SessionState.ARApp != Guid.Empty) { TheRelayAppInfo tMyApp = TheThingRegistry.GetThingObjectByMID(MyBaseEngine.GetEngineName(), pRequest.SessionState.ARApp) as TheRelayAppInfo; //MyRelayApps.MyMirrorCache.GetEntryByFunc(s => s.cdeMID.Equals(pRequest.SessionState.ARApp)); if (tMyApp != null) { Uri tCloudUri = new Uri(pRequest.RequestUriString); //pRequest.ResponseBufferStr = pRequest.ResponseBufferStr.Replace(pRequest.RequestUri.Host + ":" + pRequest.RequestUri.Port, new Uri(tMyApp.CloudUrl).Host + ":" + new Uri(tMyApp.CloudUrl).Port); pRequest.ResponseBufferStr = pRequest.ResponseBufferStr.Replace(pRequest.RequestUri.Scheme + "://" + tReqUri, tCloudUri.Scheme + "://" + tCloudUri.Host + ":" + tCloudUri.Port); pRequest.ResponseBuffer = TheCommonUtils.CUTF8String2Array(pRequest.ResponseBufferStr); } } } TheBaseAssets.MySYSLOG.WriteToLog(400, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseEngine.GetEngineName(), string.Format("Response Bytes:{1} For Page:{0} Sent", pRequest.cdeRealPage, pRequest.ResponseBuffer != null ? pRequest.ResponseBuffer.Length : 0), eMsgLevel.l3_ImportantMessage)); if (pRequest.ResponseBuffer != null) { //TheCommonUtils.SleepOneEye(5000, 100); TSM message3 = new TSM(MyBaseEngine.GetEngineName(), "WEBRELAY_RESPONSE") { PLB = pRequest.ResponseBuffer }; pRequest.ResponseBuffer = null; pRequest.ResponseBufferStr = null; pRequest.RequestUriString = pRequest.RequestUri.ToString(); TSM tMSG = pRequest.CookieObject as TSM; pRequest.CookieObject = null; pRequest.PostData = null; message3.PLS = TheCommonUtils.SerializeObjectToJSONString(pRequest); TheCommCore.PublishToOriginator(tMSG, message3); } }
public override bool DoCreateUX() { return(true); //TODO: Make much better UX here...Remove Controls first then create (see OPC DA Plugin) #pragma warning disable CS0162 MyStatusForm = TheNMIEngine.AddForm(new TheFormInfo(MyBaseThing) { FormTitle = MyBaseThing.FriendlyName, DefaultView = eDefaultView.Form }); SummaryForm = TheNMIEngine.AddFormToThingUX(MyBaseThing, MyStatusForm, "CMyForm", MyBaseThing.FriendlyName, 3, 1, 0x0, "OPC UA Methods", "FriendlyName", new ThePropertyBag() { }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.SingleEnded, 1, 0, MyBaseThing.cdeA, "OPC UA Method Name", "FriendlyName"); TheFieldInfo mSendbutton = TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.TileButton, 2, 0x82, 0, "Call", false, "", null, new ThePropertyBag() { "PreventDefault", "TileWidth=2", "TileHeight=1", "Style=background-image:url('GlasButton.png');" }); mSendbutton.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "", (pThing, pObj) => { TheProcessMessage pMsg = pObj as TheProcessMessage; if (m_Method == null || m_Method.MyOPCServer == null || !m_Method.MyOPCServer.IsConnected) { TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", "Server not connected - please connect first")); return; } HandleMessage(this, new TheProcessMessage(new TSM(MyBaseThing.EngineName, "CALL_METHOD:" + TheCommonUtils.cdeGuidToString(Guid.NewGuid())))); }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.TextArea, 3, 0, 0xC0, "Last MSG", false, "LastMessage", null, new ThePropertyBag() { "TileWidth=6", "TileHeight=3" }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.SmartLabel, 100, 0, MyBaseThing.cdeA, "", false, null, null, new ThePropertyBag() { "Format=Input Arguments", "Style=font-size:20px;text-align: left;float:none;clear:left;background-color:black;color:white;" }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.SmartLabel, 200, 0, MyBaseThing.cdeA, "", false, null, null, new ThePropertyBag() { "Format=Output Arguments", "Style=font-size:20px;text-align: left;float:none;clear:left;background-color:black;color:white;" }); CreateDynUX(false); return(true); #pragma warning restore CS0162 }
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))); }
public void SendCPUInfo(TSM message) { Guid originator = message.GetOriginator(); if (originator == Guid.Empty) { SendCPUInfo(originator); } else { GetCPUInfo(TheBaseAssets.MyServiceHostInfo.GetPrimaryStationURL(false)); TSM tMsg = new TSM(MyEngineName, "CPUINFO", TheCommonUtils.SerializeObjectToJSONString <TheCPUInfo>(MyCPUInfoData)); tMsg.SetNoDuplicates(true); TheCommCore.PublishToOriginator(message, tMsg, true); TheBaseAssets.MySYSLOG.WriteToLog(8003, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : tMsg); } }
public void SendHealthInfo(TSM message) { Guid originator = message.GetOriginator(); if (originator == Guid.Empty) { SendHealthInfo(originator); } else { GetISMHealthData(); TSM tMsg = new TSM(MyEngineName, "ISMHEALTH", TheCommonUtils.SerializeObjectToJSONString <TheServiceHealthData>(MyHealthData)); tMsg.SetNoDuplicates(true); TheCommCore.PublishToOriginator(message, tMsg, true); eventNewHealthData?.Invoke(MyHealthData); TheBaseAssets.MySYSLOG.WriteToLog(8004, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : tMsg); } }
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))); }
/// <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; } }
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!")); } }
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!")); } }
public virtual bool DoCreateUX() { MyEditorForm = new TheFormInfo(MyBaseThing) { DefaultView = eDefaultView.Form, PropertyBag = new ThePropertyBag { "MaxTileWidth=6", "HideCaption=true", "AllowDrag=true" } }; MyEditorForm.ModelID = "NMIEditor"; TheDashboardInfo tDash = TheNMIEngine.GetDashboardById(TheNMIHtml5RT.eNMIDashboard); MyEditorDashIcon = TheNMIEngine.AddFormToThingUX(tDash, MyBaseThing, MyEditorForm, "CMyForm", "NMI Control Editor", 1, 0x89, 0x80, "NMI", null, new ThePropertyBag() { "RenderTarget=cdeInSideBarRight", "NeverHide=true" }); //"mAllowDrag=true", "nVisibility=false", MySampleControl = TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.SingleEnded, 3, 2, MyBaseThing.cdeA, "CurrentValue", "Value", null); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.TileGroup, 9, 0, 0, null, null, new nmiCtrlTileGroup { TileWidth = 7, TileHeight = 1, TileFactorY = 2 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.TileButton, 10, 2, 0, "Basic", null, new nmiCtrlTileButton { ParentFld = 9, OnClick = "GRP:NMIP:Basic", TileWidth = 1, TileHeight = 1, TileFactorY = 2, NoTE = true, ClassName = "cdeTransitButton" }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.TileButton, 20, 2, 0, "Screen", null, new nmiCtrlTileButton { ParentFld = 9, OnClick = "GRP:NMIP:Screen", TileWidth = 1, TileHeight = 1, TileFactorY = 2, NoTE = true, ClassName = "cdeTransitButton" }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.TileButton, 30, 2, 0, "All", null, new nmiCtrlTileButton { ParentFld = 9, OnClick = "GRP:NMIP:All", TileWidth = 1, TileHeight = 1, TileFactorY = 2, NoTE = true, ClassName = "cdeTransitButton" }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.TileButton, 40, 2, 0, "Source", null, new nmiCtrlTileButton { ParentFld = 9, OnClick = "GRP:NMIP:Source", TileWidth = 1, TileHeight = 1, TileFactorY = 2, NoTE = true, ClassName = "cdeTransitButton" }); //TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.TileButton, 50, 2, 0, "Compounds", null, new nmiCtrlTileButton { OnClick = "GRP:Cate:5", TileWidth = 2, TileHeight = 1, TileFactorY = 2, NoTE = true, ClassName = "cdeTransitButton" }); //TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.TileButton, 60, 2, 0, "Gauges", null, new nmiCtrlTileButton { OnClick = "GRP:Cate:6", TileWidth = 2, TileHeight = 1, TileFactorY = 2, NoTE = true, ClassName = "cdeTransitButton" }); TheFieldInfo mSendbutton = TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.TileButton, 70, 2, 0x80, "Reload", false, "", null, new nmiCtrlTileButton() { ParentFld = 9, TileWidth = 2, NoTE = true, TileFactorY = 2, ClassName = "cdeGoodActionButton" }); mSendbutton.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "", (pThing, pPara) => { TheProcessMessage pMsg = pPara as TheProcessMessage; if (pMsg?.Message == null) { return; } UpdateUx(pThing.GetBaseThing()); MyEditorForm.Reload(pMsg, tDash.cdeMID, true); }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.TileGroup, 1000, 2, 0x80, null, null, new nmiCtrlTileGroup() { Group = "NMIP:Basic" }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.ComboBox, 1010, 2, 0x80, "Control Type", "ControlType", new ThePropertyBag() { "Options=%RegisteredControlTypes%", "ParentFld=1000" }); GetProperty("ControlType", true).RegisterEvent(eThingEvents.PropertyChanged, (p) => { UpdateUx(MyBaseThing); }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.Number, 1020, 2, 0, "Tile Width", "TileWidth", new nmiCtrlNumber() { ParentFld = 1000, TileHeight = 1, TileFactorY = 1, DefaultValue = "6", TileWidth = 3 }); GetProperty("TileWidth", true).RegisterEvent(eThingEvents.PropertyChanged, (p) => { MySampleControl.SetUXProperty(Guid.Empty, "TileWidth= " + p.ToString()); }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.Number, 1030, 2, 0, "Tile Height", "TileHeight", new nmiCtrlNumber() { ParentFld = 1000, TileHeight = 1, TileFactorY = 1, DefaultValue = "1", TileWidth = 3 }); GetProperty("TileHeight", true).RegisterEvent(eThingEvents.PropertyChanged, (p) => { MySampleControl.SetUXProperty(Guid.Empty, "TileHeight= " + p.ToString()); }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.ComboBox, 1040, 2, 0, "Horizontal Alignment", "HorizontalAlignment", new nmiCtrlComboBox() { ParentFld = 1000, Options = ";left;center;right" }); GetProperty("HorizontalAlignment", true).RegisterEvent(eThingEvents.PropertyChanged, (p) => { MySampleControl.SetUXProperty(Guid.Empty, "HorizontalAlignment= " + p.ToString()); }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.ComboBox, 1050, 2, 0, "Class Name", "ClassName", new nmiCtrlComboBox() { ParentFld = 1000, Options = ";BlueWhite;GreenYellow;RedWhite" }); GetProperty("ClassName", true).RegisterEvent(eThingEvents.PropertyChanged, (p) => { MySampleControl.SetUXProperty(Guid.Empty, "ClassName= " + p.ToString()); }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.SingleEnded, 1060, 2, 0, "HelpText", "HelpText", new nmiCtrlSingleEnded() { ParentFld = 1000 }); GetProperty("HelpText", true).RegisterEvent(eThingEvents.PropertyChanged, (p) => { MySampleControl.SetUXProperty(Guid.Empty, "HelpText= " + p.ToString()); }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.ComboBox, 1070, 2, 0, "Opacity", "Opacity", new nmiCtrlComboBox() { ParentFld = 1000, Options = ";0.1;0.3;0.5;0.7;0.9;1.0" }); GetProperty("Opacity", true).RegisterEvent(eThingEvents.PropertyChanged, (p) => { MySampleControl.SetUXProperty(Guid.Empty, "Opacity= " + p.ToString()); }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.SingleCheck, 1080, 2, 0, "No TE", "NoTE", new nmiCtrlSingleCheck() { ParentFld = 1000 }); GetProperty("NoTE", true).RegisterEvent(eThingEvents.PropertyChanged, (p) => { MySampleControl.SetUXProperty(Guid.Empty, "NoTE= " + p.ToString()); }); //Screen Properties TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.TileGroup, 3000, 2, 0x80, null, null, new nmiCtrlTileGroup() { Group = "NMIP:Screen", Visibility = false }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.ComboOption, 3010, 2, 0x80, "NMI Screen", "FormName", new ThePropertyBag() { "Options=%GetLiveScreens%", "TileWidth=6", "TileHeight=1", "ParentFld=3000" }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.CheckField, 3020, 2, 0x80, "Flags", "Flags", new ThePropertyBag() { "Bits=6", "TileHeight=6", "TileFactorY=2", "ImageList=<span class='fa-stack'><i class='fa fa-stack-1x'></i><i class='fa fa-stack-2x'> </i></span>," + "<span class='fa-stack'><i class='fa fa-stack-1x'></i><i class='fa fa-stack-2x'> </i></span>," + "<span class='fa-stack'><i class='fa fa-stack-1x'></i><i class='fa fa-stack-2x text-danger' style='opacity:0.5'></i></span>," + "<span class='fa-stack'><i class='fa fa-stack-1x'></i><i class='fa fa-stack-2x text-danger' style='opacity:0.5'></i></span>," + "<span class='fa-stack'><i class='fa fa-stack-1x'></i><i class='fa fa-stack-2x text-danger' style='opacity:0.5'></i></span>," + "<span class='fa-stack'><i class='fa fa-stack-1x'></i><i class='fa fa-stack-2x text-danger' style='opacity:0.5'></i></span>", "ParentFld=3000" }).FldWidth = 1; //ALL Properties TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.TileGroup, 2000, 2, 0x80, null, null, new nmiCtrlTileGroup() { TileWidth = 6, Group = "NMIP:All", Visibility = false }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.Table, 2010, 0xA2, 0x80, "All Properties", "mypropertybag;1", new ThePropertyBag() { "NoTE=true", "TileHeight=4", "TileLeft=9", "TileTop=3", "TileWidth=6", "FldWidth=6", "ParentFld=2000" }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.SingleEnded, 2020, 0x0A, 0, "New Property Name", "ScratchName", new nmiCtrlSingleEnded() { ParentFld = 2000 }); TheFieldInfo tBut = TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.TileButton, 2040, 0x0A, 0, "Add Property", false, null, null, new nmiCtrlTileButton() { ParentFld = 2000, NoTE = true, ClassName = "cdeGoodActionButton" }); tBut.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "AddProp", (pThing, pObj) => { TheProcessMessage pMsg = pObj as TheProcessMessage; if (pMsg?.Message == null) { return; } string[] parts = pMsg.Message.PLS.Split(':'); TheThing tOrg = pThing.GetBaseThing(); // TheThingRegistry.GetThingByMID(MyBaseEngine.GetEngineName(), TheCommonUtils.CGuid(parts[2])); //if (tOrg == null) return; string tNewPropName = TheThing.GetSafePropertyString(tOrg, "ScratchName"); if (string.IsNullOrEmpty(tNewPropName)) { TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", "Please specify a new property name")); } else { if (tOrg.GetProperty(tNewPropName) != null) { TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", "Property already exists")); } else { tOrg.DeclareNMIProperty(tNewPropName, ePropertyTypes.TString); TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", "Property Added")); MyEditorForm.Reload(pMsg, false); } tOrg.SetProperty("ScratchName", ""); } }); //THING Connector TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.TileGroup, 5000, 2, 0x80, null, null, new nmiCtrlTileGroup() { TileWidth = 6, Group = "NMIP:Source", Visibility = false }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.ThingPicker, 5010, 2, 0x80, "Source Thing", "Address", new nmiCtrlThingPicker() { ParentFld = 5000, IncludeEngines = true }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.PropertyPicker, 5020, 2, 0x80, "Source Property", "SourceProp", new nmiCtrlPropertyPicker() { ParentFld = 5000, ThingFld = 5010 }); TheFieldInfo mSendbutton2 = TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.TileButton, 5050, 2, 0x80, "Engage", false, "", null, new nmiCtrlTileButton() { NoTE = true, TileWidth = 6, ClassName = "cdeGoodActionButton", ParentFld = 5000 }); mSendbutton2.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "", (pThing, pPara) => { TheProcessMessage pMsg = pPara as TheProcessMessage; if (pMsg?.Message == null) { return; } UpdateUx(pThing.GetBaseThing()); }); UpdateUx(MyBaseThing); return(true); }
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); }
// KPIs in UI //public long PropertiesSent //{ // get { return (long) TheThing.GetSafePropertyNumber(MyBaseThing, "PropertiesSent"); } // set { TheThing.SetSafePropertyNumber(MyBaseThing, "PropertiesSent", value); } //} //public long PropertiesSentSinceStart //{ // get { return (long)TheThing.GetSafePropertyNumber(MyBaseThing, "PropertiesSentSinceStart"); } // set { TheThing.SetSafePropertyNumber(MyBaseThing, "PropertiesSentSinceStart", value); } //} //public double PropertiesPerSecond //{ // get { return TheThing.GetSafePropertyNumber(MyBaseThing, "PropertiesPerSecond"); } // set { TheThing.SetSafePropertyNumber(MyBaseThing, "PropertiesPerSecond", value); } //} //public double DataSentKBytesPerSecond //{ // get { return TheThing.GetSafePropertyNumber(MyBaseThing, "DataSentKBytesPerSecond"); } // set { TheThing.SetSafePropertyNumber(MyBaseThing, "DataSentKBytesPerSecond", value); } //} //public double DataSentKBytesSinceStart //{ // get { return TheThing.GetSafePropertyNumber(MyBaseThing, "DataSentKBytesSinceStart"); } // set { TheThing.SetSafePropertyNumber(MyBaseThing, "DataSentKBytesSinceStart", value); } //} //public double EventsPerSecond //{ // get { return TheThing.GetSafePropertyNumber(MyBaseThing, "EventsPerSecond"); } // set { TheThing.SetSafePropertyNumber(MyBaseThing, "EventsPerSecond", value); } //} //public long EventsSent //{ // get { return (long)TheThing.GetSafePropertyNumber(MyBaseThing, "EventsSent"); } // set { TheThing.SetSafePropertyNumber(MyBaseThing, "EventsSent", value); } //} //public long EventsSentSinceStart //{ // get { return (long)TheThing.GetSafePropertyNumber(MyBaseThing, "EventsSentSinceStart"); } // set { TheThing.SetSafePropertyNumber(MyBaseThing, "EventsSentSinceStart", value); } //} //public long PendingEvents //{ // get { return (long) TheThing.GetSafePropertyNumber(MyBaseThing, "PendingEvents"); } // set { TheThing.SetSafePropertyNumber(MyBaseThing, "PendingEvents", value); } //} //public DateTimeOffset KPITime //{ // get { return TheThing.GetSafePropertyDate(MyBaseThing, "KPITime"); } // set { TheThing.SetSafePropertyDate(MyBaseThing, "KPITime", value); } //} //public DateTimeOffset LastReceiveTime //{ // get { return TheThing.GetSafePropertyDate(MyBaseThing, nameof(LastReceiveTime)); } // set { TheThing.SetSafePropertyDate(MyBaseThing, nameof(LastReceiveTime), value); } //} #endregion 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 "MESHSENDER_DATA": if (IsConnected || AutoConnect) { //TheBaseAssets.MySYSLOG.WriteToLog(180001, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("Mesh Receiver", $"Received TSM with TXT MESHSENDER_DATA {this.MyBaseThing.FriendlyName}: {pMsg.Message.ToString()}", eMsgLevel.l6_Debug)); bool bSuccess = false; //bool bSendAck = true; string error = ""; bool bIsTargeted = pMsg.Topic.StartsWith("CDE_SYSTEMWIDE"); string correlationToken = null; if (cmd.Length >= 2) { correlationToken = cmd[1]; } string eventConverterName = null; if (cmd.Length >= 3) { eventConverterName = cmd[2]; } //if (EnableDataLogging) //{ // try // { // lock (dataLoggerLock) // { // System.IO.File.AppendAllText("meshreceiverdata.log", $"{{\"TimeReceived\":\"{DateTimeOffset.Now:O}\", \"PLS\": {pMsg.Message.PLS},\"TXT\":{pMsg.Message.TXT}}},\r\n"); // } // } // catch (Exception e) // { // TheBaseAssets.MySYSLOG.WriteToLog(180003, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("Mongo Writer", $"Unable to log data to file: {this.MyBaseThing.FriendlyName}", eMsgLevel.l3_ImportantMessage, e.ToString())); // } //} bSuccess = ProcessMessage(correlationToken, eventConverterName, pMsg.Message.TIM, pMsg.Message.PLS, pMsg.Message.ORG, bIsTargeted, out error, out var bSendAck); if (bSendAck) { TSM response = new TSM(MyBaseEngine.GetEngineName(), $"MESHSENDER_DATA_ACK:{correlationToken}:{bSuccess}:{error}"); response.QDX = pMsg.Message.QDX; TheBaseAssets.MySYSLOG.WriteToLog(180001, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("Mesh Receiver", $"Sending ACK for {this.MyBaseThing.FriendlyName} to ORG '{pMsg.Message.ORG}'", eMsgLevel.l1_Error, response.TXT)); TheCommCore.PublishToOriginator(pMsg.Message, response, true); if (!bIsTargeted) { var notification = new TSM(MyBaseEngine.GetEngineName(), $"MESHRECEIVER_ACK_NOTIFY:;:{correlationToken}:;:{pMsg.Message.ORG}:;:{bIsTargeted}"); TheCommCore.PublishCentral(notification, false); } } } break; case "MESHRECEIVER_ACK_NOTIFY": { var ackNotifyParts = TheCommonUtils.cdeSplit(pMsg.Message.TXT, ":;:", false, false); if (ackNotifyParts.Length >= 4) { string correlationToken = ackNotifyParts[1]; string sourceORG = ackNotifyParts[2]; bool bIsTargeted = TheCommonUtils.CBool(ackNotifyParts[3]); _nodeOwnerManager.RegisterOwnerCandidate(correlationToken, sourceORG, pMsg.Message.ORG, bIsTargeted); } break; } case "MESHSENDER_PING": case "MESHSENDER_PING_ALL": { string correlationToken = "nocorrelationtoken"; if (cmd.Length > 1) { correlationToken = cmd[1]; } // MyBaseThing.LastMessage = DateTimeOffset.Now + String.Format(": {0} from {1}. Token {2}", cmd[0], TheCommonUtils.cdeGuidToString(pMsg.Message.GetOriginator()), correlationToken); MyBaseThing.LastMessage = $"{DateTimeOffset.Now}: {cmd[0]} from {TheCommonUtils.cdeGuidToString(pMsg.Message.GetOriginator())}. Token {correlationToken}"; //TSM response = new TSM(MyBaseEngine.GetEngineName(), String.Format("{0}_ACK:{1}", cmd[0], correlationToken), // String.Format("{0}:{1}:{2}:{3}", TheCommonUtils.cdeGuidToString(MyBaseThing.cdeMID), ++PingCounter, MyBaseThing.FriendlyName, IsConnected)); TSM response = new TSM(MyBaseEngine.GetEngineName(), $"{cmd[0]}_ACK:{correlationToken}", $"{TheCommonUtils.cdeGuidToString(MyBaseThing.cdeMID)}:{++PingCounter}:{MyBaseThing.FriendlyName}:{IsConnected}"); TheCommCore.PublishToOriginator(pMsg.Message, response, true); } break; default: base.HandleMessage(sender, pIncoming); break; } }
/// <summary> /// Creates the basic NMI User Interface /// </summary> /// <returns></returns> public override bool CreateUX() { if (mIsUXInitCalled) { return(false); } mIsUXInitCalled = true; if (!MyBaseEngine.GetEngineState().IsService) { mIsUXInitialized = true; return(true); } UserPrefID = new Guid("{E15AE1F2-69F3-42DC-97E8-B0CC2A8526A6}").ToString().ToLower(); UserManID = TheThing.GetSafeThingGuid(MyBaseThing, "USEMAN").ToString().ToLower(); AddDashboard(MyBaseThing, new TheDashboardInfo(eNMIPortalDashboard, "-HIDE") { FldOrder = 99999, PropertyBag = { "Category=NMI" } }); //Main Portal of Relay TheDashboardInfo tDash = AddDashboard(MyBaseThing, new TheDashboardInfo(eNMIDashboard, "NMI Admin Portal") { cdeA = 0x0, FldOrder = 9090, PropertyBag = new nmiDashboard() { Category = "NMI", ForceLoad = true, Thumbnail = "FA5:f06c", Caption = "###NMI Admin###" } }); if (!TheBaseAssets.MyServiceHostInfo.IsIsolated) { TheFormInfo tInf = new TheFormInfo(new Guid("{6EE8AC31-7395-4A80-B01C-D49BE174CFC0}"), eEngineName.NMIService, "###Service Overview###", "HostEngineStates") { IsNotAutoLoading = true, PropertyBag = new nmiCtrlTableView { ShowFilterField = true } }; AddFormToThingUX(tDash, MyBaseThing, tInf, "CMyTable", "###Service Overview###", 1, 0x0F, 128, "###NMI Administration###", null, new ThePropertyBag { "TileThumbnail=FA5:f05a" }); var tDisButName = "DISPLUG"; var tDisBut = AddSmartControl(MyBaseThing, tInf, eFieldType.TileButton, 1, 0x42, 0x80, null, "DisableText", new nmiCtrlTileButton() { MID = new Guid("{7C67925E-7C2D-4460-9E61-6166494E9328}"), TableHeader = "###Is Enabled###", TileHeight = 1, TileWidth = 1, FldWidth = 1, ClassName = "cdeTableButton" }); tDisBut.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, tDisButName, (sender, para) => { if (para is TheProcessMessage pMsg && pMsg.Message != null) { var tCmd = pMsg.Message.PLS?.Split(':'); if (tCmd != null && tCmd.Length > 2) { if (tCmd[1] != tDisButName) { return; } var estate = TheCDEngines.MyServiceStates.GetEntryByID(tCmd[2]); if (estate != null) { var tBase = TheThingRegistry.GetBaseEngine(estate.ClassName); if (tBase != null) { if (tBase.HasCapability(eThingCaps.Internal)) { TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", TheNMIEngine.LocNMI(pMsg, "###Not allowed on internal engines###"))); return; } if (tBase.HasCapability(eThingCaps.MustBePresent)) { TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", TheNMIEngine.LocNMI(pMsg, "###Not allowed on engines that must be present###"))); return; } } estate.IsDisabled = !estate.IsDisabled; estate.IsUnloaded = estate.IsDisabled; SetUXProperty(Guid.Empty, tDisBut.cdeMID, $"Caption={estate.DisableText}", pMsg.Message.PLS.Split(':')[2]); TheBaseAssets.RecordServices(); } } } });
public virtual bool CreateUX() { if (mIsUXInitCalled) { return(false); } mIsUXInitCalled = true; var tFlds = TheNMIEngine.AddStandardForm(MyBaseThing, null, 12, null, "Value"); MyStatusForm = tFlds["Form"] as TheFormInfo; SummaryForm = tFlds["DashIcon"] as TheDashPanelInfo; SummaryForm.PropertyBag = new ThePropertyBag() { string.Format("Format={0}<br>{{0}} Properties", MyBaseThing.FriendlyName) }; SummaryForm.RegisterPropertyChanged(sinkStatChanged); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.Number, 21, 0, 0x0, "###CDMyVThings.TheVThings#CountOfProperties598472#Count of Properties###", "Value", new nmiCtrlNumber() { ParentFld = 1 }); TheFieldInfo mSendbutton = TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.TileButton, 22, 2, 0, "###CDMyVThings.TheVThings#Reload598472#Reload###", false, "", null, new nmiCtrlTileButton() { ParentFld = 1, NoTE = true, ClassName = "cdeGoodActionButton" }); mSendbutton.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "", (pThing, pPara) => { TheProcessMessage pMsg = pPara as TheProcessMessage; if (pMsg?.Message == null) { return; } sinkStatChanged(null, null); MyStatusForm.Reload(pMsg, true); }); PropTable = TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.Table, 40, 0xA0, 0x80, "All Properties", "mypropertybag;0", new TheNMIBaseControl() { NoTE = true, ParentFld = 1, TileWidth = 12, TileHeight = 16 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.SingleEnded, 30, 0x0A, 0, "New Property Name", "ScratchName", new nmiCtrlSingleEnded() { ParentFld = 1 }); TheFieldInfo tBut = TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.TileButton, 35, 0x0A, 0, "Add Property", false, null, null, new nmiCtrlTileButton() { ParentFld = 1, NoTE = true }); tBut.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "AddProp", (pThing, pObj) => { TheProcessMessage pMsg = pObj as TheProcessMessage; if (pMsg?.Message == null) { return; } string[] parts = pMsg.Message.PLS.Split(':'); TheThing tOrg = TheThingRegistry.GetThingByMID(MyBaseEngine.GetEngineName(), TheCommonUtils.CGuid(parts[2])); if (tOrg == null) { return; } string tNewPropName = TheThing.GetSafePropertyString(tOrg, "ScratchName"); if (string.IsNullOrEmpty(tNewPropName)) { TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", "Please specify a new property name")); } else { if (tOrg.GetProperty(tNewPropName) != null) { TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", "Property already exists")); } else { tOrg.DeclareNMIProperty(tNewPropName, ePropertyTypes.TString); TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", "Property Added")); MyStatusForm.Reload(pMsg, false); } } tOrg.RemoveProperty("ScratchName"); }); mIsUXInitialized = true; return(true); }
private void CreateLogTable(int StartFld, int pParentFld) { TheFormInfo tBackup = TheNMIEngine.AddForm(new TheFormInfo(TheThing.GetSafeThingGuid(MyBaseThing, "BKUPFORM"), eEngineName.NMIService, "Log Files", MyLogFilesTableName) { GetFromServiceOnly = true, TileWidth = -1, OrderBy = "BackupTime desc", TileHeight = 4 }); TheNMIEngine.AddFields(tBackup, new List <TheFieldInfo> { { new TheFieldInfo() { FldOrder = 11, DataItem = "BackupTime", Flags = 0, Type = eFieldType.DateTime, Header = "Log Create Date", FldWidth = 2 } }, { new TheFieldInfo() { FldOrder = 12, DataItem = "Title", Flags = 0, Type = eFieldType.SingleEnded, Header = "Log Name", FldWidth = 7 } }, { new TheFieldInfo() { FldOrder = 13, DataItem = "BackupSize", Flags = 0, Type = eFieldType.SingleEnded, Header = "Log Size", FldWidth = 2 } }, { new TheFieldInfo() { FldOrder = 100, DataItem = "CDE_DELETE", Flags = 2, cdeA = 0x80, Type = eFieldType.TileButton, TileWidth = 1, TileHeight = 1 } }, }); TheFieldInfo btnDownload = TheNMIEngine.AddSmartControl(MyBaseThing, tBackup, eFieldType.TileButton, 1, 2, 0x0, "<i class='fa fa-3x'></i>", "", new nmiCtrlTileButton() { ClassName = "cdeTableButton", TileHeight = 1, TileWidth = 1 }); btnDownload.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "DOWNLOAD", (pThing, pObj) => { TheProcessMessage pMsg = pObj as TheProcessMessage; if (pMsg?.Message == null) { return; } string[] pCmds = pMsg.Message.PLS.Split(':'); if (pCmds.Length > 2) { TheBackupDefinition tFile = MyLogFiles.GetEntryByID(TheCommonUtils.CGuid(pCmds[2])); if (tFile != null) { TSM tFilePush = new TSM(eEngineName.ContentService, string.Format("CDE_FILE:{0}.txt:text/text", tFile.Title)); try { using (FileStream fr = new FileStream(tFile.FileName, FileMode.Open)) { using (BinaryReader br = new BinaryReader(fr)) { tFilePush.PLB = br.ReadBytes((int)fr.Length); } } } catch (Exception) { } if (tFilePush.PLB == null) { TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", "Log cannot be downloaded...")); } else { TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", "Log is downloading. Please wait")); tFilePush.SID = pMsg.Message.SID; tFilePush.PLS = "bin"; TheCommCore.PublishToOriginator(pMsg.Message, tFilePush); } } } }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.CollapsibleGroup, StartFld, 2, 0x0, "Logs on Node...", null, new nmiCtrlCollapsibleGroup { TileWidth = 12, IsSmall = true, DoClose = true, ParentFld = pParentFld, AllowHorizontalExpand = true, MaxTileWidth = 12 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.Table, StartFld + 1, 0, 0, null, tBackup.cdeMID.ToString(), new nmiCtrlTableView { TileWidth = -1, IsDivOnly = true, ParentFld = StartFld, NoTE = true, TileHeight = -1, MID = TheThing.GetSafeThingGuid(MyBaseThing, "LOGMID"), MainClassName = "cdeInFormTable" }); }
public override bool CreateUX() { if (mIsUXInitCalled) { return(false); } mIsUXInitCalled = true; //NUI Definition for All clients mMyDashboard = TheNMIEngine.AddDashboard(MyBaseThing, new TheDashboardInfo(MyBaseEngine, "OPC UA Client") { PropertyBag = new nmiDashboardTile() { Category = " Connectivity", Thumbnail = "opcLarge.png;1;cdeLargeIcon", TileWidth = 3, TileHeight = 4, ClassName = "cdeLiveTile cdeLargeTile" } }); var tFlds = TheNMIEngine.AddStandardForm(MyBaseThing, "OPC General Settings", "OPCD", 0, new nmiStandardForm { MaxTileWidth = 12, UseMargin = true, Category = TheNMIEngine.GetNodeForCategory() }); TheFormInfo tMyForm = tFlds["Form"] as TheFormInfo; TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.CollapsibleGroup, 5, 2, 0xc0, "GLS Discovery Service", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup() { DoClose = false, IsSmall = true, TileWidth = 6, ParentFld = 1 })); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleEnded, 10, 2, 0, "GLS Address", "Address", new nmiCtrlSingleEnded() { ParentFld = 5 }); TheFieldInfo tBut = TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.TileButton, 11, 2, 0, "Scan for Servers", null, new nmiCtrlTileButton() { ParentFld = 5, ClassName = "cdeGoodActionButton" }); tBut.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "SCAN", (pThing, pObj) => { TheProcessMessage pMsg = pObj as TheProcessMessage; if (pMsg != null) { TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", "Scanning...")); GetEndpoints(); mMyDashboard.Reload(pMsg, false); } }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.CollapsibleGroup, 15, 2, 0xc0, "Tracing (all clients)...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup() { DoClose = false, TileWidth = 6, IsSmall = true, ParentFld = 1 })); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 16, 2, 0, "OPC Client File Tracing", nameof(EnableTracing), new nmiCtrlSingleCheck { TileWidth = 3, ParentFld = 15 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 17, 2, 0, "OPC Client Trace to Log", nameof(EnableTracingToLog), new nmiCtrlSingleCheck { TileWidth = 3, ParentFld = 15 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, 18, 2, 0, "OPC Client Trace Mask", nameof(OPCTraceMask), new nmiCtrlNumber { TileWidth = 6, ParentFld = 15, HelpText = "1=Err,2=Info,4=Stk,8=Svc,16=SvcDtl,32=Op,64=OpDtl,128=Start,256=Ext,512=Sec" }); TheFormInfo tAllOPCUASrvs = new TheFormInfo(MyBaseEngine) { cdeMID = TheThing.GetSafeThingGuid(MyBaseThing, "OPCS"), defDataSource = string.Format("TheThing;:;0;:;True;:;DeviceType={1};EngineName={0}", MyBaseEngine.GetEngineName(), eOPCDeviceTypes.OPCRemoteServer), FormTitle = "Discovered OPC-UA Servers", AddButtonText = "Add a Server" }; TheNMIEngine.AddFormToThingUX(MyBaseThing, tAllOPCUASrvs, "CMyTable", "All OPC-UA Remote Servers", 1, 0x0F, 0xC0, TheNMIEngine.GetNodeForCategory(), null, new ThePropertyBag() { "Thumbnail=OPCLogo.png;1.0" }); var tOpcs = TheNMIEngine.AddCommonTableColumns(MyBaseThing, tAllOPCUASrvs); tOpcs["Address"].Header = "Server URL"; tOpcs["Address"].PropertyBag = new nmiCtrlSingleEnded { TileWidth = 4, FldWidth = 4 }; TheNMIEngine.AddField(tAllOPCUASrvs, new TheFieldInfo() { FldOrder = 5, cdeA = 0xC0, Flags = 2, Type = eFieldType.SingleCheck, Header = "Auto-Connect", DataItem = "MyPropertyBag.AutoConnect.Value" }); TheNMIEngine.AddField(tAllOPCUASrvs, new TheFieldInfo() { FldOrder = 6, cdeA = 0xC0, Flags = 2, Type = eFieldType.SingleCheck, Header = "Connected", DataItem = "MyPropertyBag.IsConnected.Value", PropertyBag = new nmiCtrlSingleCheck { AreYouSure = "Are you sure you want to connect/disconnect?" } }); // TheNMIEngine.AddField(tAllOPCUASrvs, new TheFieldInfo() { FldOrder = 13, Flags = 2, cdeA = 0xFF, Type = eFieldType.SingleEnded, Header = "Friendly Name", DataItem = "MyPropertyBag.FriendlyName.Value", PropertyBag = new ThePropertyBag() { "FldWidth=3" } }); //TheNMIEngine.AddField(tAllOPCUASrvs, new TheFieldInfo() { FldOrder = 14, Flags = 2, cdeA = 0xC0, Type = eFieldType.SingleEnded, Header = "Server URL", DataItem = "MyPropertyBag.Address.Value", PropertyBag = new ThePropertyBag() { "FldWidth=5" } }); TheNMIEngine.AddField(tAllOPCUASrvs, new TheFieldInfo() { FldOrder = 50, cdeA = 0xFF, Type = eFieldType.DateTime, Header = "Last Update", DataItem = "MyPropertyBag.LastUpdate.Value", PropertyBag = new ThePropertyBag() { "FldWidth=3" } }); TheNMIEngine.AddField(tAllOPCUASrvs, new TheFieldInfo() { FldOrder = 55, cdeA = 0xFF, Type = eFieldType.DateTime, Header = "Last Receive", DataItem = "MyPropertyBag.LastDataReceivedTime.Value", PropertyBag = new ThePropertyBag() { "FldWidth=3" } }); //TheNMIEngine.AddTableButtons(tAllOPCUASrvs); TheThingRegistry.UpdateEngineUX(MyBaseEngine.GetEngineName()); TheNMIEngine.AddLiveTagTable(MyBaseThing, eOPCDeviceTypes.OPCLiveTag, "UA Live Tags", TheNMIEngine.GetNodeForCategory()); TheNMIEngine.AddLiveTagTable(MyBaseThing, eOPCDeviceTypes.OPCMethod, "UA Methods", TheNMIEngine.GetNodeForCategory()); TheNMIEngine.AddTileBreak(MyBaseThing, mMyDashboard, "..A"); TheNMIEngine.AddAboutButton(MyBaseThing, true, "REFRESH_DASH", 0xc0); TheNMIEngine.RegisterEngine(MyBaseEngine); CreateOPCWizard(); mIsUXInitialized = true; return(true); }
public override bool CreateUX() { if (!mIsUXInitStarted) { mIsUXInitStarted = true; // Creates a "portal" for each rule. This is how we create // a tile for each rule on the rules engine's main page. mThisFormFields = TheNMIEngine.AddStandardForm(MyBaseThing, MyBaseThing.FriendlyName, 18); // Update our status. TheFormInfo tFormGuid = mThisFormFields["Form"] as TheFormInfo; tFormGuid.RegisterEvent2(eUXEvents.OnShow, (pMSG, para) => { UpdateStatus(); }); // Create "Rule Status" settings group // Field Order = 10 // Parent = 1 (main form) // Get standard Status Block. var tstFlds = TheNMIEngine.AddStatusBlock(MyBaseThing, tFormGuid, idGroupStatus); tstFlds["Group"].SetParent(idForm); tstFlds["Group"].Header = "Rule Status"; // tstFlds["Group"].PropertyBag = new ThePropertyBag { "DoClose=true" }; tstFlds["FriendlyName"].Header = "Rule Name"; // When the Friendly Name changes, propogate to the other UI elements that use it. tstFlds["FriendlyName"].RegisterUXEvent(MyBaseThing, eUXEvents.OniValueChanged, null, (psender, pPara) => { (mThisFormFields["Header"] as TheFieldInfo).SetUXProperty(Guid.Empty, $"Title={MyBaseThing.FriendlyName}"); (mThisFormFields["DashIcon"] as TheDashPanelInfo).SetUXProperty(Guid.Empty, $"Caption={MyBaseThing.FriendlyName}"); }); // Add fields to Status Block that are specific to this plugin. TheNMIEngine.AddSmartControl(MyBaseThing, tFormGuid, eFieldType.SingleCheck, 60, 2, 0, "Activate Rule", "IsRuleActive", new nmiCtrlSingleCheck { ParentFld = idGroupStatus, TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, tFormGuid, eFieldType.SingleCheck, 70, 2, 0, "Log Action", "IsRuleLogged", new nmiCtrlSingleCheck { ParentFld = idGroupStatus, TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, tFormGuid, eFieldType.SingleCheck, 75, 2, 0, "Log Action to Eventlog", "IsEVTLogged", new nmiCtrlSingleCheck { ParentFld = idGroupStatus, TileWidth = 3 }); TheFieldInfo tTriggerBut = TheNMIEngine.AddSmartControl(MyBaseThing, tFormGuid, eFieldType.TileButton, 65, 2, 0xC0, "Trigger Now", null, new nmiCtrlTileButton { ParentFld = idGroupStatus, ClassName = "cdeGoodActionButton", NoTE = true, TileWidth = 3 }); tTriggerBut.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "TriggerNow", (psender, pPara) => { TheProcessMessage pMSG = pPara as TheProcessMessage; if (pMSG == null || pMSG.Message == null) { return; } string[] cmd = pMSG.Message.PLS.Split(':'); if (cmd.Length > 2) { TheThing tThing = TheThingRegistry.GetThingByMID("*", TheCommonUtils.CGuid(cmd[2])); if (tThing == null) { return; } TheRule tRule = tThing.GetObject() as TheRule; if (tRule != null) { //FireAction(tRule, true); tRule.FireAction(true); MyBaseEngine.ProcessMessage(new TheProcessMessage(new TSM(MyBaseEngine.GetEngineName(), "FIRE_RULE", MyBaseThing.cdeMID.ToString()))); TheCommCore.PublishToOriginator(pMSG.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", string.Format("Rule {0} triggered", tRule.GetBaseThing().FriendlyName))); } } }); // Create "Trigger Object" settings group (Field Order = idGroupTriggerObject (100), Parent = 1) TheNMIEngine.AddSmartControl(MyBaseThing, tFormGuid, eFieldType.CollapsibleGroup, idGroupTriggerObject, 2, 0, "Trigger Object", null, new nmiCtrlCollapsibleGroup { ParentFld = idForm, TileWidth = 6, IsSmall = true }); // Create "Action Settings" settings group (Field Order = idGroupActionSettings (500), Parent = 1) TheNMIEngine.AddSmartControl(MyBaseThing, tFormGuid, eFieldType.CollapsibleGroup, idGroupActionSettings, 2, 0, "Action Settings", null, new nmiCtrlCollapsibleGroup { ParentFld = idForm, TileWidth = 6, IsSmall = true }); // Create "Thing Property Action" settings group (Field Order = idGroupThingPropAction (550), Parent = 500) TheNMIEngine.AddSmartControl(MyBaseThing, tFormGuid, eFieldType.CollapsibleGroup, idGroupThingPropAction, 2, 0, "Thing/Property Action", null, new nmiCtrlCollapsibleGroup { ParentFld = idGroupActionSettings, TileWidth = 6, IsSmall = true }); // Create "TSM Action" settings group (Field Order = idGroupTSMAction (600), Parent = 500) TheNMIEngine.AddSmartControl(MyBaseThing, tFormGuid, eFieldType.CollapsibleGroup, idGroupTSMAction, 2, 0, "TSM Action", null, new nmiCtrlCollapsibleGroup { ParentFld = idGroupActionSettings, TileWidth = 6, IsSmall = true, DoClose = true }); // Create all other (non-group header) fields. TheNMIEngine.AddFields(tFormGuid, new List <TheFieldInfo> { /* Trigger Object Group */ { new TheFieldInfo() { FldOrder = 140, DataItem = "MyPropertyBag.TriggerObject.Value", Flags = 2, Type = eFieldType.ThingPicker, Header = "Trigger Object", PropertyBag = new nmiCtrlThingPicker() { ParentFld = idGroupTriggerObject, HelpText = "If this objects...", IncludeEngines = true } } }, { new TheFieldInfo() { FldOrder = 150, DataItem = "MyPropertyBag.TriggerProperty.Value", Flags = 2, Type = eFieldType.PropertyPicker, Header = "Trigger Property", DefaultValue = "Value", PropertyBag = new nmiCtrlPropertyPicker() { ParentFld = idGroupTriggerObject, HelpText = "...property is...", ThingFld = 140 } } }, { new TheFieldInfo() { FldOrder = 160, DataItem = "MyPropertyBag.TriggerCondition.Value", Flags = 2, Type = eFieldType.ComboBox, Header = "Trigger Condition", DefaultValue = "2", PropertyBag = new nmiCtrlComboBox() { ParentFld = idGroupTriggerObject, HelpText = "... then this value, this rule will fire...", DefaultValue = "2", Options = "Fire:0;State:1;Equals:2;Larger:3;Smaller:4;Not:5;Contains:6;Set:7;StartsWith:8;EndsWith:9;Flank:10" } } }, { new TheFieldInfo() { FldOrder = 170, DataItem = "MyPropertyBag.TriggerValue.Value", Flags = 2, Type = eFieldType.SingleEnded, Header = "Trigger Value", PropertyBag = new ThePropertyBag() { "ParentFld=100", "HelpText=...this objects..." } } }, /* Action Settings Group */ { new TheFieldInfo() { FldOrder = 505, DataItem = "MyPropertyBag.ActionObjectType.Value", Flags = 2, Type = eFieldType.ComboBox, Header = "Action Object Type", PropertyBag = new nmiCtrlComboBox() { ParentFld = idGroupActionSettings, Options = "Set Property on a Thing:CDE_THING;Publish Central:CDE_PUBLISHCENTRAL;Publish to Service:CDE_PUBLISH2SERVICE", DefaultValue = "CDE_THING" } } }, { new TheFieldInfo() { FldOrder = 506, DataItem = "MyPropertyBag.ActionDelay.Value", Flags = 2, Type = eFieldType.Number, Header = "Delay", DefaultValue = "0", PropertyBag = new ThePropertyBag() { "ParentFld=500", "HelpText=...after a delay of these seconds..." } } }, /* Thing / Property Action Sub-Group */ { new TheFieldInfo() { FldOrder = 560, DataItem = "MyPropertyBag.ActionObject.Value", Flags = 2, Type = eFieldType.ThingPicker, Header = "Action Object", PropertyBag = new nmiCtrlThingPicker() { ParentFld = 550, HelpText = "...this objects...", IncludeEngines = true } } }, { new TheFieldInfo() { FldOrder = 562, DataItem = "MyPropertyBag.ActionProperty.Value", Flags = 2, Type = eFieldType.PropertyPicker, Header = "Action Property", DefaultValue = "Value", PropertyBag = new nmiCtrlPropertyPicker() { ParentFld = idGroupThingPropAction, HelpText = "...property will change to...", ThingFld = 560 } } }, { new TheFieldInfo() { FldOrder = 563, DataItem = "MyPropertyBag.ActionValue.Value", Flags = 2, Type = eFieldType.SingleEnded, Header = "Action Value", PropertyBag = new nmiCtrlSingleEnded { ParentFld = idGroupThingPropAction, HelpText = "...this value", Style = "text-overflow:ellipsis;overflow:hidden; max-width:400px" } } }, /* TSM Action Sub-Group */ { new TheFieldInfo() { FldOrder = 630, DataItem = "MyPropertyBag.TSMEngine.Value", Flags = 2, Type = eFieldType.ThingPicker, Header = "TSM Engine", PropertyBag = new nmiCtrlThingPicker() { ParentFld = 600, ValueProperty = "EngineName", IncludeEngines = true, Filter = "DeviceType=IBaseEngine" } } }, { new TheFieldInfo() { FldOrder = 631, DataItem = "MyPropertyBag.TSMText.Value", Flags = 2, Type = eFieldType.SingleEnded, Header = "TSM Text", PropertyBag = new ThePropertyBag() { "ParentFld=600", "HelpText=Command of the TSM" } } }, { new TheFieldInfo() { FldOrder = 632, DataItem = "MyPropertyBag.TSMPayload.Value", Flags = 2, Type = eFieldType.TextArea, Header = "TSM Payload", PropertyBag = new nmiCtrlTextArea() { ParentFld = idGroupTSMAction, TileHeight = 2, HelpText = "Body of the TSM" } } }, }); mIsUXInitCompleted = true; } return(true); }
virtual void HandleMessage(ICDEThing sender, object pIncoming) { TheProcessMessage pMsg = pIncoming as TheProcessMessage; if (pMsg == null || pMsg.Message == null) { return; } var cmd = TheCommonUtils.cdeSplit(pMsg.Message.TXT, ":", false, false); switch (cmd[0]) { case "RUREADY": if (cmd.Length > 1 && cmd[1] == TheCommonUtils.cdeGuidToString(MyBaseThing.cdeMID)) { TheCommCore.PublishToOriginator(pMsg.Message, new TSM(pMsg.Message.ENG, "IS_READY:" + TheCommonUtils.cdeGuidToString(MyBaseThing.cdeMID), mIsInitialized.ToString()) { FLG = 8 }, true); } break; case "CONNECT_SERVER": Connect(); break; case nameof(MsgConnectDisconnect): { var request = TheCommRequestResponse.ParseRequestMessageJSON <MsgConnectDisconnect>(pMsg.Message); var responseMsg = new MsgConnectDisconnectResponse(); if (request == null) { responseMsg.Error = "Error parsing request message"; } else { try { if (request.Connect.HasValue && request.Reconnect.HasValue) { responseMsg.Error = "Can specify at most one of Connect Reconnect"; } else if (!request.Connect.HasValue && !request.Reconnect.HasValue && !request.AutoConnect.HasValue) { responseMsg.Error = "Must specify at least one of Connect Reconnect AutoConnect"; } else { if (request.Connect.HasValue) { if (request.Connect == true) { Connect(); } else { Disconnect(true); } } if (request.Reconnect.HasValue) { Disconnect(true); if (request.WaitTimeBeforeReconnect.HasValue) { try { #if !NET40 await TheCommonUtils.TaskDelayOneEye(request.WaitTimeBeforeReconnect.Value, 100).ConfigureAwait(false); #else TheCommonUtils.TaskDelayOneEye(request.WaitTimeBeforeReconnect.Value, 100).Wait(); #endif } catch (System.Threading.Tasks.TaskCanceledException) { } } Connect(); } if (request.AutoConnect.HasValue) { AutoConnect = request.AutoConnect.Value; } responseMsg.Connected = IsConnected; } } catch (Exception e) { responseMsg.Error = e.Message; } } TheCommRequestResponse.PublishResponseMessageJson(pMsg.Message, responseMsg); } break; } }
private void CreateConfigurationSection(int writeEnableFlag, TheFormInfo tMyForm, int pStartFld, int pParentFld) { UseTree = TheCommonUtils.CBool(TheBaseAssets.MySettings.GetSetting("UseTreeView")); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.CollapsibleGroup, pStartFld, 2, 0xc0, "Tag Management...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup() { DoClose = !UseTree, IsSmall = true, ParentFld = pParentFld, TileWidth = UseTree ? 18 : 6 })); if (!UseTree) { TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleEnded, pStartFld + 1, writeEnableFlag, 0xC0, "Browse Branch", "BrowseBranch", new nmiCtrlSingleEnded() { ParentFld = pStartFld }); } #if USE_WEBIX else { var stringCols = TheCommonUtils.SerializeObjectToJSONString(new List <TheWXColumn> { { new TheWXColumn() { TileWidth = 6, Header = "Node Name", ID = "DisplayName", FilterType = "textFilter", Template = "{common.treetable()}{common.treecheckbox()} <strong>#DisplayName#</strong>" } }, //{ new TheWXColumn() { TileWidth = 2, Header = "Host Property", ID = "HostPropertyNameOverride", SortType = "string", Flags=2 } }, { new TheWXColumn() { TileWidth = 1, Header = "Sample-Rate", ID = "SampleRate", SortType = "int", Flags = 2 } }, { new TheWXColumn() { TileWidth = 1, Header = "Deadband-Filter", ID = "DeadbandFilterValue", SortType = "int", Flags = 2 } }, { new TheWXColumn() { TileWidth = 1, Header = "Trigger", ID = "ChangeTrigger", SortType = "int", Flags = 2 } }, { new TheWXColumn() { TileWidth = 6, Header = "Node ID", ID = "NodeIdName", FilterType = "textFilter", SortType = "int" } } }); OpcTagTree = TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.UserControl, pStartFld + 6, 2, 0, "Sample Tree", "SelectedIs", new nmiCtrlWXTreeTable() { ParentFld = pStartFld, TileWidth = 12, TileHeight = 12, NoTE = true, RootNode = "Objects", TreeNode = "Parent", NameNode = "DisplayName", SelectNode = "HasActiveHostThing", LeftSplit = 1, OpenAllBranches = false, SplitCharacter = ".", Columns = stringCols }); OpcTagTree.RegisterEvent2("NMI_FIELD_EVENT", (pMSG, para) => { var tUpdate = TheCommonUtils.DeserializeJSONStringToObject <TheWXFieldEvent>(pMSG.Message.PLS); if (tUpdate != null) { var MyTag = MyTags.MyMirrorCache.GetEntryByID(tUpdate.cdeMID); if (MyTag != null) { switch (tUpdate.Name) { case "SampleRate": MyTag.SampleRate = TheCommonUtils.CInt(tUpdate.Value); break; case "DeadbandFilterValue": MyTag.DeadbandFilterValue = TheCommonUtils.CDbl(tUpdate.Value); break; case "ChangeTrigger": MyTag.ChangeTrigger = TheCommonUtils.CInt(tUpdate.Value); break; } } } }); } #endif // BROWSE Button TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.TileButton, pStartFld + 2, writeEnableFlag, 0xC0, "Browse", null, new nmiCtrlTileButton() { ParentFld = pStartFld, ClassName = "cdeGoodActionButton", TileWidth = 3, NoTE = true }) .RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "BROWSE", (pThing, pObj) => { TheProcessMessage pMsg = pObj as TheProcessMessage; if (pMsg == null || pMsg.Message == null) { return; } if (ConnectionState != ConnectionStateEnum.Connected) { TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", "Server not connected - please connect first")); } else { TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", "Browsing...")); LastMessage = "Browsing Started at " + DateTimeOffset.Now.ToString(); BrowsedTagCnt = 0; Browser(currentRoot, currentRoot.ToString(), true, false, null); var dataModelJson = TheCommonUtils.SerializeObjectToJSONString( MyTags.MyMirrorCache.TheValues .Where(t => t.HostPropertyNameOverride?.Contains("].[") != true) // Filter out any DataValue sub-properties (i.e. engineering units), as the tree view doesn't seem to handle nodes under leaf-nodes (or inner nodes with data) yet .ToList()); OpcTagTree?.SetUXProperty(pMsg.Message.GetOriginator(), $"DataModel={dataModelJson}", true); LastMessage += " - Browsing done at " + DateTimeOffset.Now.ToString(); TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", LastMessage)); } }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, pStartFld + 3, 0, 0x0, "Browsed Tags:", "BrowsedTagCnt", new nmiCtrlNumber() { ParentFld = pStartFld, TileWidth = 3 }); ///Browsed TAGS Form { var tDataSource = "TheOPCTags"; if (MyTags != null) { tDataSource = MyTags.StoreMID.ToString(); } var tOPCTagForm = new TheFormInfo(TheThing.GetSafeThingGuid(MyBaseThing, "TAGLIST_ID"), eEngineName.NMIService, "OPC-UA Server Tags", $"{tDataSource};:;1000") { IsNotAutoLoading = true, AddButtonText = "Add new Tag", PropertyBag = new nmiCtrlTableView { ShowFilterField = true } }; TheNMIEngine.AddFormToThingUX(MyBaseThing, tOPCTagForm, "CMyTable", "Tag List", 1, 3, 0xF0, null, null, new ThePropertyBag() { "Visibility=false" }); TheNMIEngine.AddFields(tOPCTagForm, new List <TheFieldInfo> { // 1: Thing subscription { new TheFieldInfo() { FldOrder = 3, DataItem = "IsSubscribedAsThing", Flags = 0, Type = eFieldType.SingleCheck, Header = "Has Tag Thing", FldWidth = 1 } }, { new TheFieldInfo() { FldOrder = 11, DataItem = "Parent", Flags = 0, Type = eFieldType.SingleEnded, Header = "Parent", FldWidth = 4 } }, { new TheFieldInfo() { FldOrder = 12, DataItem = "DisplayName", Flags = 0, Type = eFieldType.SingleEnded, Header = "Name", FldWidth = 3 } }, { new TheFieldInfo() { FldOrder = 13, DataItem = nameof(TheOPCTag.HostPropertyNameOverride), Flags = writeEnableFlag, Type = eFieldType.SingleEnded, Header = "Host Property Name", FldWidth = 3 } }, { new TheFieldInfo() { FldOrder = 14, DataItem = "HostThingMID", Flags = writeEnableFlag, Type = eFieldType.ThingPicker, Header = "Host Thing", FldWidth = 3 } }, { new TheFieldInfo() { FldOrder = 15, DataItem = nameof(TheOPCTag.ChangeTrigger), Flags = writeEnableFlag, Type = eFieldType.ComboBox, Header = "Change Trigger", FldWidth = 1, PropertyBag = new nmiCtrlComboBox { Options = "Status:0;Value:1;Value & Timestamp:2" } } }, { new TheFieldInfo() { FldOrder = 16, DataItem = nameof(TheOPCTag.SampleRate), Flags = writeEnableFlag, Type = eFieldType.Number, Header = "Sample Rate (ms)", FldWidth = 1 } }, { new TheFieldInfo() { FldOrder = 17, DataItem = nameof(TheOPCTag.DeadbandFilterValue), Flags = writeEnableFlag, Type = eFieldType.Number, Header = "Deadband", FldWidth = 1 } }, { new TheFieldInfo() { FldOrder = 18, DataItem = "NodeIdName", Flags = 2, Type = eFieldType.SingleEnded, Header = "NodeId", FldWidth = 6 } }, // 30: Property subscription { new TheFieldInfo() { FldOrder = 19, DataItem = nameof(TheOPCTag.HistoryStartTime), Flags = writeEnableFlag, Type = eFieldType.SingleEnded, Header = "History Start", FldWidth = 3 } }, //{ new TheFieldInfo() { FldOrder=13,DataItem="PropAttr.7.Value.Value",Flags=0,Type=eFieldType.SingleEnded,Header="Value",FldWidth=5 }}, //{ new TheFieldInfo() { FldOrder=14,DataItem="PropAttr.7.DataType",Flags=0,Type=eFieldType.SingleEnded,Header="Type",FldWidth=5 }}, }); TheNMIEngine.AddTableButtons(tOPCTagForm, false, 100, 0); // Button Subscribe as Thing TheNMIEngine.AddSmartControl(MyBaseThing, tOPCTagForm, eFieldType.TileButton, 1, writeEnableFlag, 0xC0, "Create Tag Thing", null, new nmiCtrlTileButton() { ClassName = "cdeGoodActionButton", TileHeight = 1 }) .RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "SUBSCRIBE", (tThing, pMsg) => SubscribeAsThing(tThing, pMsg, MyTags)); // Button: Subscribe property into host thing TheNMIEngine.AddSmartControl(MyBaseThing, tOPCTagForm, eFieldType.TileButton, 5, writeEnableFlag, 0xC0, "Monitor as Property", null, new nmiCtrlTileButton() { ClassName = "cdeGoodActionButton", TileHeight = 1 }) .RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "SUBSCRIBEPROP", (tThing, pMsg) => SubscribeAsProperty(tThing, pMsg, MyTags)); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.TileButton, pStartFld + 4, writeEnableFlag, 0xF0, "Show Tag List", null, new nmiCtrlTileButton() { OnClick = $"TTS:{tOPCTagForm.cdeMID}", ParentFld = pStartFld, ClassName = "cdeTransitButton", TileWidth = 3, NoTE = true }); } TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, pStartFld + 5, writeEnableFlag, 0xC0, "Default Sample Rate", nameof(DefSampleRate), new nmiCtrlNumber() { ParentFld = pStartFld, TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.ThingPicker, pStartFld + 6, writeEnableFlag, 0xC0, "Thing for Property Subs", "TagHostThingForSubscribeAll", new nmiCtrlThingPicker() { NoTE = true, ParentFld = pStartFld, TileWidth = 4 }); // SUBSCRIBE all tags as Properties TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.TileButton, pStartFld + 7, writeEnableFlag, 0xC0, $"Subscribe {(UseTree ? "selected" : "all")} in properties", null, new nmiCtrlTileButton() { ParentFld = pStartFld, ClassName = "cdeGoodActionButton", TileWidth = 2, NoTE = true }) .RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "ALLTAGS", (pThing, pObj) => { TheProcessMessage pMsg = pObj as TheProcessMessage; if (pMsg == null || pMsg.Message == null) { return; } if (ConnectionState != ConnectionStateEnum.Connected) { TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", "Server not connected - please connect first")); } else { var tHostThing = TheThingRegistry.GetThingByMID("*", TheCommonUtils.CGuid(this.TagHostThingForSubscribeAll)); if (tHostThing == null) { TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", "Host Thing not specified or invalid")); return; } TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", "Subscribing...")); if (MyTags.MyMirrorCache.Count == 0 && !UseTree) { // Clear all previous subscription in either MyTags (tag as thing) oder HostThing (tag as property) MyTags.MyMirrorCache.Reset(); // TODO Figure out how to clean up subscribed things in properties. // - Can't just delete as a customer may have hand picked certain properties via browse paths etc. // - Allow customer to use multiple host things? //var tThing = TheThingRegistry.GetThingByMID("*", TheCommonUtils.CGuid(TagHostThing)); //if (tThing != null) //{ // foreach (var prop in tThing.GetPropertiesMetaStartingWith("OPCUA:")) // { // tThing.RemoveProperty(prop.Name); // } //} LastMessage = "Subscribing started at " + DateTimeOffset.Now.ToString(); BrowsedTagCnt = 0; Browser(currentRoot, currentRoot.ToString(), true, true, tHostThing, CreateIDFilter()); LastMessage += " - Subscribing done at " + DateTimeOffset.Now.ToString(); TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", LastMessage)); } else { // Previously browsed: use those tags to do the subscriptions LastMessage = "Subscribing started at " + DateTimeOffset.Now.ToString(); var subscription = GetOrCreateSubscription(0); var pFilterIDs = CreateIDFilter(); int count = 0; //var results = new List<Opc.Ua.Client.MonitoredItem>();//CM: removed as Nothing is done with "results" foreach (var tag in MyTags.TheValues) { string tagNameForFilter; if (tag.DisplayName == "EngineeringUnits" || tag.DisplayName == "EURange") { tagNameForFilter = tag.Parent; } else { tagNameForFilter = $"{tag.Parent}.{tag.DisplayName}"; } if (pFilterIDs != null && pFilterIDs.Contains(tagNameForFilter)) { tag.HostThingMID = TheCommonUtils.cdeGuidToString(tHostThing.cdeMID); var childTags = tag.GetChildTags(); if (childTags?.Any() == true) { foreach (var childTag in childTags) { childTag.HostThingMID = tag.HostThingMID; } } if (!RegisterAndMonitorTagInHostThing(subscription, tag, out string error, false, true, false) || !string.IsNullOrEmpty(error)) { // error }
public override bool CreateUX() { if (TheBaseAssets.MyServiceHostInfo.IsCloudService) { mIsUXInitialized = true; return(true); } if (!TheNMIEngine.IsInitialized()) { return(false); } if (mIsUXInitCalled) { return(false); } mIsUXInitCalled = true; MyDash = TheNMIEngine.AddDashboard(MyBaseThing, new TheDashboardInfo(MyBaseEngine, "Rules Engine") { FldOrder = 5000, cdeA = 0xC0, PropertyBag = new ThePropertyBag { "Caption=Rules Engine", "Thumbnail=FA5:f546", "Category=Services" } }); TheFormInfo tFormGuid = new TheFormInfo(new Guid("{6C34871C-D49B-4D7A-84E0-35E25B1F18B0}") /*TheThing.GetSafeThingGuid(MyBaseThing, "RULESREG")*/, eEngineName.NMIService, "The Rules Registry", $"TheThing;:;0;:;True;:;DeviceType={eKnownDeviceTypes.TheThingRule};EngineName={MyBaseEngine.GetEngineName()}") { GetFromFirstNodeOnly = true, IsNotAutoLoading = true, AddButtonText = "Add Rule", AddTemplateType = "44444444-6AD1-45AE-BE61-96AF02329613" }; //TheNMIEngine.AddForm(tFormGuid); TheNMIEngine.AddFormToThingUX(MyDash, MyBaseThing, tFormGuid, "CMyTable", "Rules Registry", 5, 9, 128, TheNMIEngine.GetNodeForCategory(), null, new ThePropertyBag { "Thumbnail=FA5:f07b" }); TheNMIEngine.AddFields(tFormGuid, new List <TheFieldInfo> { { new TheFieldInfo() { FldOrder = 10, DataItem = "MyPropertyBag.IsRuleActive.Value", Flags = 2, Type = eFieldType.SingleCheck, Header = "Active", FldWidth = 1, TileLeft = 2, TileTop = 6, TileWidth = 4, TileHeight = 1 } }, { new TheFieldInfo() { FldOrder = 20, DataItem = "MyPropertyBag.IsRuleLogged.Value", Flags = 2, Type = eFieldType.SingleCheck, Header = "Logged", FldWidth = 1, TileLeft = 6, TileTop = 6, TileWidth = 4, TileHeight = 1 } }, { new TheFieldInfo() { FldOrder = 30, DataItem = "MyPropertyBag.FriendlyName.Value", Flags = 2, Type = eFieldType.SingleEnded, Header = "Rule Name", FldWidth = 3, TileLeft = 0, TileTop = 1, TileWidth = 11, TileHeight = 1, PropertyBag = new nmiCtrlSingleEnded() { HelpText = "Give this rule a friendly name" } } }, { new TheFieldInfo() { FldOrder = 137, DataItem = "cdeO", Flags = 16, Type = eFieldType.SingleEnded, Header = "Status", FldWidth = 3, Format = "<span style='font-size:xx-small'>Running:%MyPropertyBag.IsRuleRunning.Value%<br>TrigerAlive:%MyPropertyBag.IsTriggerObjectAlive.Value%</span>" } }, }); TheNMIEngine.AddSmartControl(MyBaseThing, tFormGuid, eFieldType.StatusLight, 35, 0x40, 0x0, "Status", "StatusLevel", new TheNMIBaseControl() { FldWidth = 1 }); TheNMIEngine.AddTableButtons(tFormGuid, true, 1000, 0xA2); TheFieldInfo tTriggerBut = TheNMIEngine.AddSmartControl(MyBaseThing, tFormGuid, eFieldType.TileButton, 5, 2, 0xC0, "Trigger Now", null, new nmiCtrlTileButton { ClassName = "cdeGoodActionButton", TileLeft = 1, TileTop = 6, TileWidth = 1, TileHeight = 1, NoTE = true }); tTriggerBut.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "TriggerNow", (psender, pPara) => { TheProcessMessage pMSG = pPara as TheProcessMessage; if (pMSG == null || pMSG.Message == null) { return; } string[] cmd = pMSG.Message.PLS.Split(':'); if (cmd.Length > 2) { TheThing tThing = TheThingRegistry.GetThingByMID("*", TheCommonUtils.CGuid(cmd[2])); if (tThing == null) { return; } TheRule tRule = tThing.GetObject() as TheRule; if (tRule != null) { tRule.FireAction(true); TheCommCore.PublishToOriginator(pMSG.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", string.Format("Rule {0} triggered", tRule.FriendlyName))); } } }); TheNMIEngine.AddAboutButton4(MyBaseThing, MyDash, null, true, false, "REFRESH_DASH"); AddRulesWizard(); mIsUXInitialized = true; return(true); }
public override bool DoCreateUX() { MyBaseThing.RegisterProperty("ClickState"); var tFlds = TheNMIEngine.AddStandardForm(MyBaseThing, null, 24, null, "Value"); MyStatusForm = tFlds["Form"] as TheFormInfo; //MyStatusForm.PropertyBag = new ThePropertyBag { "TileWidth=6" }; MyStatusForm.RegisterEvent2(eUXEvents.OnShow, (pmse, sen) => { UpdateUx(); }); SummaryForm = tFlds["DashIcon"] as TheDashPanelInfo; SummaryForm.PropertyBag = new nmiDashboardTile() { Format = $"{MyBaseThing.FriendlyName}<br>{{0}}", Caption = MyBaseThing.FriendlyName }; CountBar = TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.SingleEnded, 5, 2, MyBaseThing.cdeA, "CurrentValue", "Value", null); ChangeTimestampField = TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.DateTime, 6, 0, MyBaseThing.cdeA, "Last Change", nameof(ValueChangeTimestamp), new nmiCtrlDateTime { ParentFld = 1, Visibility = ShowChangeTimestamp }); TimestampField = TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.DateTime, 7, 0, MyBaseThing.cdeA, "Timestamp", nameof(ValueTimestamp), new nmiCtrlDateTime { ParentFld = 1, Visibility = ShowChangeTimestamp }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.CollapsibleGroup, 800, 2, 0x80, "Configuration...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup() { ParentFld = 1, DoClose = true, IsSmall = true })); var ts = TheNMIEngine.AddStatusBlock(MyBaseThing, MyStatusForm, 810); ts["Group"].SetParent(800); ts["Group"].PropertyBag = new nmiCtrlCollapsibleGroup { DoClose = true }; TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.CollapsibleGroup, 1000, 2, 0x80, "NMI Settings...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup() { ParentFld = 800, DoClose = true, IsSmall = true, TileWidth = 6 })); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.CollapsibleGroup, 3000, 2, 0x80, "Advanced NMI Settings...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup() { ParentFld = 1000, DoClose = true, IsSmall = true, TileWidth = 6 })); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.ComboOption, 3010, 2, 0x80, "NMI Screen", "FormName", new ThePropertyBag() { "Options=%GetLiveScreens%", "TileWidth=6", "TileHeight=1", "ParentFld=3000" }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.CheckField, 3020, 2, 0x80, "Flags", "Flags", new ThePropertyBag() { "Bits=6", "TileHeight=6", "TileFactorY=2", "ImageList=<span class='fa-stack'><i class='fa fa-stack-1x'></i><i class='fa fa-stack-2x'> </i></span>," + "<span class='fa-stack'><i class='fa fa-stack-1x'></i><i class='fa fa-stack-2x'> </i></span>," + "<span class='fa-stack'><i class='fa fa-stack-1x'></i><i class='fa fa-stack-2x text-danger' style='opacity:0.5'></i></span>," + "<span class='fa-stack'><i class='fa fa-stack-1x'></i><i class='fa fa-stack-2x text-danger' style='opacity:0.5'></i></span>," + "<span class='fa-stack'><i class='fa fa-stack-1x'></i><i class='fa fa-stack-2x text-danger' style='opacity:0.5'></i></span>," + "<span class='fa-stack'><i class='fa fa-stack-1x'></i><i class='fa fa-stack-2x text-danger' style='opacity:0.5'></i></span>", "ParentFld=3000" }).FldWidth = 1; TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.ComboBox, 1500, 2, 0x80, "Control Type", "ControlType", new ThePropertyBag() { "Options=%RegisteredControlTypes%", "ParentFld=1000" }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.CollapsibleGroup, 2000, 2, 0x80, "All Properties...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup() { NoTE = true, ParentFld = 1000, DoClose = true, IsSmall = true, TileWidth = 6 })); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.Table, 2010, 0xA2, 0x80, "All Properties", "mypropertybag;1", new ThePropertyBag() { "NoTE=true", "TileHeight=4", "TileLeft=9", "TileTop=3", "TileWidth=6", "FldWidth=6", "ParentFld=2000" }); TheNMIEngine.AddFields(MyStatusForm, new List <TheFieldInfo> { { new TheFieldInfo() { FldOrder = 2020, DataItem = "MyPropertyBag.ScratchName.Value", Flags = 0x0A, Type = eFieldType.SingleEnded, Header = "New Property Name", TileWidth = 6, TileHeight = 1, PropertyBag = new ThePropertyBag() { "ParentFld=2000" } } }, }); TheFieldInfo tBut = TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.TileButton, 2040, 0x0A, 0, "Add Property", false, null, null, new nmiCtrlTileButton() { ParentFld = 2000, NoTE = true, ClassName = "cdeGoodActionButton" }); tBut.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "AddProp", (pThing, pObj) => { TheProcessMessage pMsg = pObj as TheProcessMessage; if (pMsg?.Message == null) { return; } string[] parts = pMsg.Message.PLS.Split(':'); TheThing tOrg = TheThingRegistry.GetThingByMID(MyBaseEngine.GetEngineName(), TheCommonUtils.CGuid(parts[2])); if (tOrg == null) { return; } string tNewPropName = TheThing.GetSafePropertyString(tOrg, "ScratchName"); if (string.IsNullOrEmpty(tNewPropName)) { TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", "Please specify a new property name")); } else { if (tOrg.GetProperty(tNewPropName) != null) { TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", "Property already exists")); tOrg.SetProperty("ScratchName", ""); } else { tOrg.DeclareNMIProperty(tNewPropName, ePropertyTypes.TString); TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", "Property Added")); tOrg.SetProperty("ScratchName", ""); MyStatusForm.Reload(pMsg, false); } } }); TheFieldInfo mSendbutton = TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.TileButton, 1550, 2, 0x80, "Reload", false, "", null, new nmiCtrlTileButton() { TileWidth = 6, NoTE = true, ClassName = "cdeGoodActionButton", ParentFld = 1000 }); mSendbutton.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "", (pThing, pPara) => { TheProcessMessage pMsg = pPara as TheProcessMessage; if (pMsg?.Message == null) { return; } UpdateUx(); MyStatusForm.Reload(pMsg, true); //TheNMIEngine.GetEngineDashBoardByThing(MyBaseEngine.GetBaseThing()).Reload(pMsg, true); }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.CollapsibleGroup, 5000, 2, 0x80, "Source...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup() { DoClose = true, IsSmall = true, ParentFld = 800, TileWidth = 6 })); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.ThingPicker, 5010, 2, 0x80, "Source Thing", "Address", new nmiCtrlThingPicker() { ParentFld = 5000, IncludeEngines = true, IncludeRemotes = true }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.PropertyPicker, 5020, 2, 0x80, "Source Property", "SourceProp", new nmiCtrlPropertyPicker() { ParentFld = 5000, ThingFld = 5010 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.SingleCheck, 5030, 2, 0x80, "Show Timestamp", nameof(ShowTimestamp), new nmiCtrlSingleCheck { ParentFld = 5000, TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.SingleCheck, 5040, 2, 0x80, "Show Change Time", nameof(ShowChangeTimestamp), new nmiCtrlSingleCheck { ParentFld = 5000, TileWidth = 3 }); TheFieldInfo mSendbutton2 = TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.TileButton, 5050, 2, 0x80, "Engage", false, "", null, new nmiCtrlTileButton() { NoTE = true, TileWidth = 6, ClassName = "cdeGoodActionButton", ParentFld = 5000 }); mSendbutton2.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "", (pThing, pPara) => { TheProcessMessage pMsg = pPara as TheProcessMessage; if (pMsg?.Message == null) { return; } UpdateUx(); }); UpdateUx(); return(true); }
public override void HandleMessage(ICDEThing sender, object pIncoming) { TheProcessMessage pMsg = pIncoming as TheProcessMessage; if (pMsg == null || pMsg.Message == null) { return; } string[] tCmd = pMsg.Message.TXT.Split(':'); switch (tCmd[0]) //string 2 cases { case "CDE_INITIALIZED": MyBaseEngine.SetInitialized(pMsg.Message); break; case "CDE_INITIALIZE": if (!MyBaseEngine.GetEngineState().IsEngineReady) { MyBaseEngine.SetInitialized(pMsg.Message); } MyBaseEngine.ReplyInitialized(pMsg.Message); break; case "CDE_REGISTERRULE": TheRule tRule = TheCommonUtils.DeserializeJSONStringToObject <TheRule>(pMsg.Message.PLS); if (tRule != null) { RegisterRule(tRule); } break; case "CLAIM_RULES": List <TheThing> tList = TheThingRegistry.GetThingsByFunc(eEngineName.ThingService, s => TheThing.GetSafePropertyString(s, "DeviceType").Equals(eKnownDeviceTypes.TheThingRule)); if (tList != null && tList.Count > 0) { foreach (TheThing tThing in tList) { tThing.Parent = MyBaseThing.ID; tThing.EngineName = MyBaseEngine.GetEngineName(); } } ActivateRules(); MyDash.Reload(null, false); TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", $"{tList.Count} New Rules claimed")); break; case "REFRESH_DASH": ActivateRules(); MyDash.Reload(null, false); break; case "FIRE_RULE": var t = TheThingRegistry.GetThingByMID(MyBaseEngine.GetEngineName(), TheCommonUtils.CGuid(pMsg?.Message?.PLS)); if (t != null) { TheRule tR = t.GetObject() as TheRule; if (tR != null) { tR.RuleTrigger(tR.TriggerOldValue, true); } } break; } }