void sinkRuleThingEvent(ICDEThing sender, object pIncoming) { if (sender == null) { return; } TheThing tThing = TheThingRegistry.GetThingByProperty("*", Guid.Empty, "TriggerObject", TheThing.GetSafePropertyString(sender, "ID")); if (tThing != null) { TheRule tRule = tThing.GetObject() as TheRule; if (tRule == null || !tRule.IsRuleActive) { return; } if (tRule.TriggerStartTime > DateTimeOffset.Now) { return; } if (tRule.TriggerEndTime < DateTimeOffset.Now) { RemoveTrigger(tRule, false); return; } tRule.FireAction(false); } }
void sinkThingWasUpdated(ICDEThing sender, object pPara) { if (TheBaseAssets.MyServiceHostInfo.IsCloudService) { return; //TODO: Allow Cloud Rules } TheThing pThing = sender as TheThing; if (pThing != null && TheThing.GetSafePropertyString(pThing, "DeviceType") == eKnownDeviceTypes.TheThingRule) { TheRule tRule = pThing.GetObject() as TheRule; if (tRule == null) { tRule = new TheRule(pThing, this); tRule.RegisterEvent(eEngineEvents.ThingUpdated, sinkUpdated); RegisterRule(tRule); } { tRule.IsRuleWaiting = true; tRule.IsRuleRunning = false; TheSystemMessageLog.WriteLog(4445, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(eKnownDeviceTypes.TheThingRule, $"Rule {tRule.FriendlyName} stopped on Rule Update"), false); TheThingRegistry.UpdateThing(tRule, false); } ActivateRules(); } }
void sinkUpdated(ICDEThing sender, object inObj) { if (TheBaseAssets.MyServiceHostInfo.IsCloudService) { return; } TheThing pThing = sender.GetBaseThing(); if (pThing != null) { TheRule tRule = pThing.GetObject() as TheRule; if (tRule != null) { if (tRule.IsRuleActive) { ActivateRules(); } else { RemoveTrigger(tRule, true); } } } }
T CreateOrUpdateService <T>(TheThing tDevice, bool bRegisterThing) where T : TheNetworkServiceBase { T tServer; if (tDevice == null || !tDevice.HasLiveObject) { tServer = (T)Activator.CreateInstance(typeof(T), tDevice, this); if (bRegisterThing) { TheThingRegistry.RegisterThing(tServer); tServer.GetBaseThing().RegisterOnChange("DeviceType", OnServerDeviceTypeChanged); } } else { tServer = tDevice.GetObject() as T; if (tServer != null) { //tServer.InitServer(null); } else { tServer = (T)Activator.CreateInstance(typeof(T), tDevice, this); } } return(tServer); }
T CreateOrUpdateService <T>(TheThing tDevice, bool bRegisterThing) where T : TheLoggerBase { T tServer; if (tDevice == null || !tDevice.HasLiveObject) { tServer = (T)Activator.CreateInstance(typeof(T), tDevice, this); if (bRegisterThing) { TheThingRegistry.RegisterThing((ICDEThing)tServer); } } else { tServer = tDevice.GetObject() as T; if (tServer != null) { tServer.Connect(null); //Expose a Connect(TheProcessMessage) method on TheThing } else { tServer = (T)Activator.CreateInstance(typeof(T), tDevice, this); } } return(tServer); }
void OnDeletedThing(ICDEThing pThing, object pPara) { TheThing tThing = pPara as TheThing; if (tThing != null && tThing.IsInit()) { var tThingObj = (tThing.GetObject() as TheConnectionBase); if (tThingObj != null) { tThingObj.Disconnect(true); } } }
public TheNetworkServiceBase(TheThing tBaseThing, ICDEPlugin pPluginBase) { if (tBaseThing != null) { MyBaseThing = tBaseThing; // If we are changing objects due to DeviceType change, move the UX state over as we can't easily re-create it TheNetworkServiceBase previousInstance = MyBaseThing.GetObject() as TheNetworkServiceBase; if (previousInstance != null) { mIsUXInitialized = previousInstance.mIsUXInitialized; mIsInitialized = previousInstance.mIsInitialized; previousInstance.CloseServer(); } } else { MyBaseThing = new TheThing(); } MyBaseEngine = pPluginBase.GetBaseEngine(); MyBaseThing.SetIThingObject(this); }
T CreateOrUpdateService <T>(TheThing tDevice, bool bRegisterThing) where T : TheBitmapImage { T tServer; if (tDevice == null || !tDevice.HasLiveObject) { tServer = (T)Activator.CreateInstance(typeof(T), tDevice, this); if (bRegisterThing) { TheThingRegistry.RegisterThing((ICDEThing)tServer); } } else { tServer = tDevice.GetObject() as T; if (tServer == null) { tServer = (T)Activator.CreateInstance(typeof(T), tDevice, this); } } return(tServer); }
private static Image DrawStrip(Guid pThingGuid, DateTimeOffset now, TheFieldInfo pInfo) { int pixelWidth = 78 * TheCommonUtils.CInt(pInfo?.PropBagGetValue("TileWidth")); if (pixelWidth == 0) { pixelWidth = 78; } int Hours = TheCommonUtils.CInt(pInfo?.PropBagGetValue("Hours")); if (Hours == 0) { Hours = 1; } int pixelHeight = 1; Bitmap bmp = new Bitmap(pixelWidth, pixelHeight, PixelFormat.Format32bppArgb); int st = 0; string tColorString = pInfo?.PropBagGetValue("ChartColors"); string[] htmlColors = null; if (string.IsNullOrEmpty(tColorString)) { htmlColors = TheBaseAssets.MyServiceHostInfo.StatusColors.Split(';'); } else { htmlColors = tColorString.Split(';'); } Dictionary <int, SolidBrush> stateColorMapping = htmlColors.ToDictionary(x => st++, y => new SolidBrush(ColorTranslator.FromHtml(y))); TheThing tThing = TheThingRegistry.GetThingByMID("*", pThingGuid); if (tThing == null) { return(null); } cdeP pMSH = ((ICDEThing)tThing.GetObject())?.GetProperty("MachineStorageHistory", false); if (pMSH == null) { return(null); } List <TheMachineStateHistory> tList = TheCommonUtils.DeserializeJSONStringToObject <List <TheMachineStateHistory> >(pMSH.ToString()); if (tList == null) { return(null); } tList = tList.Where(s => now.Subtract(s.StateChangeTime).TotalHours < Hours).OrderBy(s => s.StateChangeTime).ToList(); cdeP LastDeletedEntry = tThing.GetProperty("LastDeletedEntry", false); TheMachineStateHistory lastState = null; if (LastDeletedEntry != null) { TheMachineStateHistory tHis = TheCommonUtils.DeserializeJSONStringToObject <TheMachineStateHistory>(LastDeletedEntry.ToString()); lastState = new TheMachineStateHistory() { State = tHis.State, StateChangeTime = now.Subtract(new TimeSpan(Hours, 0, 0)) }; } using (Graphics g = Graphics.FromImage(bmp)) { g.ScaleTransform((float)pixelWidth / (Hours * 60 * 60), 1.0f); List <KeyValuePair <int, RectangleF> > rectangles = new List <KeyValuePair <int, RectangleF> >(); foreach (var t in tList) { if (lastState != null && t.State != lastState.State) { float start = (float)now.Subtract(t.StateChangeTime).TotalSeconds; float size = (float)t.StateChangeTime.Subtract(lastState.StateChangeTime).TotalSeconds; rectangles.Add(new KeyValuePair <int, RectangleF>(lastState.State, new RectangleF(new PointF(start, 0), new SizeF(size, pixelHeight)))); lastState = t; } if (lastState == null) { lastState = t; } } if (lastState != null) { float size = (float)now.Subtract(lastState.StateChangeTime).TotalSeconds; rectangles.Add(new KeyValuePair <int, RectangleF>(lastState.State, new RectangleF(new PointF(0, 0), new SizeF(size, pixelHeight)))); } if (rectangles.Count > 0) { g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; // g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; for (int state = 0; state <= rectangles.Max(x => x.Key); state++) { if (stateColorMapping.ContainsKey(state)) { IEnumerable <RectangleF> rects = rectangles.Where(x => x.Key == state).Select(x => x.Value); var rectangleFs = rects as RectangleF[] ?? rects.ToArray(); if (rectangleFs.Any()) { if (state > stateColorMapping.Count) { g.FillRectangles(new SolidBrush(Color.Pink), rectangleFs.ToArray()); } else { g.FillRectangles(stateColorMapping[state], rectangleFs.ToArray()); } } } } } } if (TheCommonUtils.CBool(pInfo?.PropBagGetValue("DrawRightToLeft"))) { bmp.RotateFlip(RotateFlipType.RotateNoneFlipX); //draw right to left } return(bmp); }
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); }
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 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); }