public override bool CreateUX() { if (!mIsUXInitCalled) { mIsUXInitCalled = true; TheNMIEngine.RegisterControlType(MyBaseEngine, "C3 Chart", "CDMyC3.ctrlC3Chart", "CDMyC3.ctrlC3Chart"); TheNMIEngine.RegisterControlType(MyBaseEngine, "Time Line Chart", "CDMyC3.ctrlTimeLineChart", "CDMyC3.ctrlTimeLineChart"); TheNMIEngine.RegisterControlType(MyBaseEngine, "Live Chart", "CDMyC3.ctrlProLiveChart"); TheNMIEngine.RegisterControlType(MyBaseEngine, "Stack Chart", "CDMyC3.ctrlC3StackChart"); TheNMIEngine.RegisterControlType(MyBaseEngine, "Cyto Chart", "CDMyC3.ctrlProCytoChart"); TheNMIEngine.RegisterControlType(MyBaseEngine, "Line Chart", "CDMyC3.ctrlC3Line"); //NUI Definition for All clients if (TheCommonUtils.CBool(TheBaseAssets.MySettings.GetSetting("ShowSamples"))) { mMyDashboard = TheNMIEngine.AddDashboard(MyBaseThing, new TheDashboardInfo(MyBaseEngine, "C3 Charts") { FldOrder = 7010, PropertyBag = new ThePropertyBag() { "Category=NMI Extensions", "HideShowAll=true", "Caption=<span style='font-size:64px'>C3</span><br>Charts" } }); TheFormInfo tMyForm = TheNMIEngine.AddForm(new TheFormInfo(MyBaseThing) { FormTitle = "C3 Samples Page", DefaultView = eDefaultView.Form }); TheNMIEngine.AddFormToThingUX(MyBaseThing, tMyForm, "CMyForm", "My Sample Form", 3, 3, 0, TheNMIEngine.GetNodeForCategory(), null, null); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.CollapsibleGroup, 10, 2, 0, "Value Tester", null, new nmiCtrlCollapsibleGroup { TileWidth = 6, ClassName = "AXGroup", IsSmall = true }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleEnded, 11, 2, 0, "My Sample Value Is", "SampleProperty", new nmiCtrlSingleEnded { ParentFld = 10 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.BarChart, 12, 2, 0, "My Sample Value Bar", "SampleProperty", new nmiCtrlBarChart() { ParentFld = 10, MaxValue = 255, TileHeight = 2 }); //TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.CollapsibleGroup, 29, 2, 0, "Pie Demo", null, new nmiCtrlCollapsibleGroup { /*TileHeight = 5, */TileWidth = 6, ClassName = "AXGroup", IsSmall = true }); //TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.UserControl, 30, 2, 0, "My Pie", "SampleProperty", new ctrlC3Chart { ChartType="pie", UpdateData = true, NoTE = true, ParentFld = 29, TileHeight = 4, TileWidth = 6, SetSeries = "[[\"Dogs\", 100],[\"Cats\", 20],[\"Birds\", 34]]" }); //TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.CollapsibleGroup, 34, 2, 0, "Pie Demo", null, new nmiCtrlCollapsibleGroup { /*TileHeight = 5, */TileWidth = 6, ClassName = "AXGroup", IsSmall = true }); //TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.UserControl, 35, 2, 0, "My Gauge", "SampleProperty", new ctrlC3Chart { ChartType="gauge", UpdateData = true, TileHeight = 4, ParentFld = 34, MaxValue = 255, TileWidth = 6, SetSeries = "[[\"Dogs\", 100]]" }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.CollapsibleGroup, 39, 2, 0, "Chart Demo", null, new nmiCtrlCollapsibleGroup { /*TileHeight = 5, */ TileWidth = 12, ClassName = "AXGroup", IsSmall = true }); ctrlC3Chart.AddC3Chart(MyBaseThing, tMyForm, 50, 39, true, new ctrlC3Chart { NoTE = true, TileHeight = 4, ParentFld = 39, ChartType = "bar", TileWidth = 12, SetSeries = "[[\"Dogs\", 100],[\"Cats\", 20],[\"Birds\", 34]]", Group = "[[\"Dogs\", \"Cats\"]]" }); TheNMIEngine.AddAboutButton(MyBaseThing); } TheNMIEngine.RegisterEngine(MyBaseEngine); mIsUXInitialized = true; } return(true); }
internal static string CreateCDEX(TheServicesMarketPlace tPlace, string tMetaFile, bool bForce, out string tCDEXFilePath) { tCDEXFilePath = null; try { tPlace.FileName = string.Format(CultureInfo.InvariantCulture, "{1} V{0:0.0000}.CDEX", tPlace.CurrentVersion, tPlace.ServiceName.Replace('.', '-')); string tTarget = Path.Combine(tMetaFile, tPlace.FileName); tCDEXFilePath = tTarget; if (!bForce && File.Exists(tTarget) && !TheCommonUtils.CBool(TheBaseAssets.MySettings.GetSetting("AlwaysCreateCDEXOnStartup"))) { return("Target Exists"); } TheCommonUtils.CreateDirectories(tTarget); if (File.Exists(tTarget)) { File.Delete(tTarget); } System.IO.Compression.ZipFile.CreateFromDirectory(tMetaFile + "new", tTarget, System.IO.Compression.CompressionLevel.Optimal, false); FileInfo f = new FileInfo(tTarget); tPlace.Size = f.Length; Directory.Delete(tMetaFile + "new", true); } catch (Exception e) { return($"Plugin {tPlace.ServiceName} with ID:{tPlace.PluginID} could not be created: {e}"); } return(null); }
public override bool Init() { if (!mIsInitStarted) { mIsInitStarted = true; MyBaseThing.StatusLevel = 4; MyBaseThing.LastMessage = "Logger Service has started"; MyBaseThing.RegisterEvent(eEngineEvents.IncomingMessage, HandleMessage); MyBaseEngine.RegisterEvent(eEngineEvents.ThingDeleted, OnThingDeleted); cdeP tP = null; if (TheBaseAssets.MyServiceHostInfo.DisableConsole) { TheThing.SetSafePropertyBool(MyBaseThing, "DisableStandardLog", TheBaseAssets.MyServiceHostInfo.DisableConsole); } else { tP = GetProperty("DisableStandardLog", true); } tP.RegisterEvent(eThingEvents.PropertyChanged, sinkDisableChanged); if (TheCommonUtils.CBool(tP.ToString())) { TheBaseAssets.MyServiceHostInfo.DisableConsole = true; } if (TheBaseAssets.MyServiceHostInfo.UseGELFLoggingFormat) { tP = TheThing.SetSafePropertyBool(MyBaseThing, "UseGELF", TheBaseAssets.MyServiceHostInfo.UseGELFLoggingFormat); } else { tP = GetProperty("UseGELF", true); } tP.RegisterEvent(eThingEvents.PropertyChanged, sinkGELF); if (TheCommonUtils.CBool(tP.ToString())) { TheBaseAssets.MyServiceHostInfo.UseGELFLoggingFormat = true; } bool DoLogKPIs = TheCommonUtils.CBool(TheBaseAssets.MySettings.GetSetting("LogKPIs")); if (DoLogKPIs) { TheThing.SetSafePropertyBool(MyBaseThing, "LogKPIs", true); } TheQueuedSenderRegistry.RegisterHealthTimer(sinkTimer); // If not lengthy initialized you can remove cdeRunasync and call this synchronously TheCommonUtils.cdeRunAsync(MyBaseEngine.GetEngineName() + " Init Services", true, (o) => { // Perform any long-running initialization (i.e. network access, file access) here InitServices(); MyBaseEngine.ProcessInitialized(); //Set the status of the Base Engine according to the status of the Things it manages mIsInitCompleted = true; }); } return(false); }
private static Image DrawStripHeader(DateTimeOffset now, TheFieldInfo pInfo) { bool drawRightToLeft = (TheCommonUtils.CBool(pInfo?.PropBagGetValue("DrawRightToLeft"))); 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 = 39; Bitmap bmp = new Bitmap(pixelWidth, pixelHeight, PixelFormat.Format32bppArgb); DateTimeOffset start = now.Subtract(new TimeSpan(drawRightToLeft ? Hours : 0, now.Minute, now.Second)); TimeSpan step = new TimeSpan(0, Hours * 5, 0); double scaling = (float)pixelWidth / (Hours * 60 * 60); using (Graphics g = Graphics.FromImage(bmp)) { Font drawFont = new Font("Arial", 10); SolidBrush drawBrush = new SolidBrush(Color.Black); // Color.FromArgb(179, 255, 255, 255)); DateTimeOffset currentTime = start; g.TextRenderingHint = TextRenderingHint.AntiAlias; for (int i = 0; i <= 12; i++) { string pattern = CultureInfo.CurrentCulture.DateTimeFormat.MonthDayPattern; pattern = pattern.Replace("MMMM", "MMM"); string timeValue = currentTime.DateTime.ToString(pattern) + "\n"; timeValue += currentTime.DateTime.ToShortTimeString(); SizeF size = g.MeasureString(timeValue, drawFont); double x = now.Subtract(currentTime).TotalSeconds *scaling - size.Width / 2; if (drawRightToLeft) { x = pixelWidth - x; } if (x >= -3 && x <= pixelWidth - size.Width + 3) { g.DrawString(timeValue, drawFont, drawBrush, new PointF((float)x, pixelHeight - size.Height - 5)); } if (drawRightToLeft) { currentTime = currentTime.Add(step); } else { currentTime = currentTime.Subtract(step); } } } return(bmp); }
public override bool DoInit() { base.DoInit(); IsActive = false; TheThing.SetSafePropertyBool(MyBaseThing, "IsStateSensor", true); MyBaseThing.StatusLevel = 4; if (string.IsNullOrEmpty(MyBaseThing.ID)) { MyBaseThing.ID = Guid.NewGuid().ToString(); TheThing.SetSafePropertyString(MyBaseThing, "StateSensorType", "analog"); TheThing.SetSafePropertyString(MyBaseThing, "StateSensorUnit", "units"); TheThing.SetSafePropertyNumber(MyBaseThing, "StateSensorMaxValue", 100); TheThing.SetSafePropertyNumber(MyBaseThing, "StateSensorAverage", 50); TheThing.SetSafePropertyNumber(MyBaseThing, "StateSensorMinValue", 0); TheThing.SetSafePropertyNumber(MyBaseThing, "Interval", 500); } TheThing.SetSafePropertyString(MyBaseThing, "StateSensorIcon", "/P066/Images/iconVThingsRest.png"); GetProperty("FriendlyName", true).RegisterEvent(eThingEvents.PropertyChanged, sinkNameChanged); cdeP tRW = GetProperty("RawValue", true); tRW.RegisterEvent(eThingEvents.PropertyChanged, sinkPrePro); cdeP.SetSafePropertyBool(tRW, "IsStateSensor", true); cdeP.SetSafePropertyString(tRW, "StateSensorType", "analog"); cdeP.SetSafePropertyString(tRW, "StateSensorUnit", "°F"); cdeP.SetSafePropertyNumber(tRW, "StateSensorMaxValue", 100); cdeP.SetSafePropertyNumber(tRW, "StateSensorAverage", 50); cdeP.SetSafePropertyNumber(tRW, "StateSensorMinValue", 0); if (!string.IsNullOrEmpty(TheThing.GetSafePropertyString(MyBaseThing, "RealSensorThing")) && !string.IsNullOrEmpty(TheThing.GetSafePropertyString(MyBaseThing, "RealSensorProperty"))) { EngageMapper(); } GetProperty("IsGlobal", true).RegisterEvent(eThingEvents.PropertyChanged, (p) => { if (TheCommonUtils.CBool(p.ToString())) { TheThingRegistry.RegisterThingGlobally(MyBaseThing); } else { TheThingRegistry.UnregisterThingGlobally(MyBaseThing); } }); GetProperty("Interval", true).RegisterEvent(eThingEvents.PropertyChanged, (p) => { changeInterval(TheCommonUtils.CInt(p.ToString())); }); MyBaseThing.SetPublishThrottle((int)TheThing.GetSafePropertyNumber(MyBaseThing, "Interval")); //TheQueuedSenderRegistry.RegisterHealthTimer(checkMapperHealth); return(true); }
private void sinkPropChanged(cdeP pPara) { cdeP tProp = pPara as cdeP; if (tProp != null && tProp.Name == nameof(IsConnected)) { if (_bIsConnected != TheCommonUtils.CBool(tProp.Value)) { TheThing.SetSafePropertyBool(MyBaseThing, nameof(IsConnected), _bIsConnected); } } }
void sinkPChanged(cdeP prop) { if (MyBaseEngine.GetEngineState().IsSimulated || !IsConnected) { return; } var field = MyModFieldStore.MyMirrorCache.GetEntryByFunc(s => s.PropertyName == prop.Name); if (field == null) { return; } var error = OpenModBus(); if (!string.IsNullOrEmpty(error)) { MyBaseThing.LastMessage = $"{DateTime.Now} - Modbus Device could not be opened: {error}"; TheBaseAssets.MySYSLOG.WriteToLog(10000, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseThing.EngineName, MyBaseThing.LastMessage, eMsgLevel.l1_Error)); return; } try { ushort tMainOffset = (ushort)(TheThing.GetSafePropertyNumber(MyBaseThing, "Offset") + field.SourceOffset); byte tSlaveAddress = (byte)TheThing.GetSafePropertyNumber(MyBaseThing, "SlaveAddress"); int tReadWay = (int)TheThing.GetSafePropertyNumber(MyBaseThing, "ConnectionType"); switch (tReadWay) { case 1: MyModMaster.WriteSingleCoil(tSlaveAddress, tMainOffset, TheCommonUtils.CBool(prop.ToString())); break; default: MyModMaster.WriteSingleRegister(tSlaveAddress, tMainOffset, TheCommonUtils.CUShort(prop.ToString())); break; } } catch (Exception e) { MyBaseThing.LastMessage = $"{DateTime.Now} - Failure during write of modbus property: {e.Message}"; TheBaseAssets.MySYSLOG.WriteToLog(10000, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseThing.EngineName, MyBaseThing.LastMessage, eMsgLevel.l1_Error, e.ToString())); } if (!KeepOpen) // races with reader thread, but reader thread will retry/reopen so at most one data point is lost { CloseModBus(); } }
/// <summary> /// Returns false if stores could not be initalized - IStorageService failed and will be shutdown /// </summary> /// <returns></returns> private bool InitializeStores() { bool bInitialized = CreateStorageDAT(); if (!bInitialized) { return(false); } bool Success = true; #if JCR_TESTSTORE if (MyTESTBASE == null) { MyTESTBASE = new TheStorageMirror <TheTestBase>(this); MyTESTBASE.IsRAMStore = MyBaseEngine.GetEngineState().IsSimulated; if (MyBaseEngine.GetEngineState().IsService) { MyTESTBASE.CreateStore(TheBaseAssets.MyServiceHostInfo.ApplicationName + ": Test Store", "Test Push and other test messages", null); } else { MyTESTBASE.InitializeStore(); } } #endif if (MyBaseEngine.GetEngineState().IsService&& TheBaseAssets.MyServiceHostInfo.StoreLoggedMessages) { EdgeDataCreateStore(typeof(TSM), null, TheBaseAssets.MyServiceHostInfo.ApplicationName + ": SystemMessageLog", "Log of all Application System Messages", false, null, null); } if (MyTimedCallbacks == null) { MyTimedCallbacks = new TheStorageMirror <TheTimedCallback>(TheCDEngines.MyIStorageService) { IsRAMStore = true }; MyTimedCallbacks.InitializeStore(true); MyTimedCallbacks.SetRecordExpiration(TheBaseAssets.MyServiceHostInfo.TO.ReceivedChunkTimeout, null); } if (TheCommonUtils.CBool(TheBaseAssets.MySettings.GetSetting("UseStorageForThingRegistry"))) { Success = CreateThingRegistryStore(); } return(Success); }
public static void ShutDown() { if (!TheBaseAssets.MasterSwitch) { return; } if (TheBaseAssets.MyApplication != null) { TheBaseAssets.MyApplication.Shutdown(false); } WasHereBefore = false; if (TheCommonUtils.CBool(System.Configuration.ConfigurationManager.AppSettings["AutoStartSite"])) { var client = new WebClient(); var url = MySite + "/cdeclean.aspx"; client.DownloadString(url); } }
internal static bool CheckAddPermission(cdeConcurrentDictionary <eWebPlatform, ThePropertyBag> pPlatBag, TheClientInfo pInfo) { cdeConcurrentDictionary <string, string> platPlat = null; if (pPlatBag.ContainsKey(pInfo.WebPlatform)) { platPlat = ThePropertyBag.GetDictionary(pPlatBag[pInfo.WebPlatform], "="); } if (pPlatBag.ContainsKey(eWebPlatform.Any)) { cdeConcurrentDictionary <string, string> tPlat = ThePropertyBag.GetDictionary(pPlatBag[eWebPlatform.Any], "="); if (tPlat.ContainsKey("HideAddButton") && TheCommonUtils.CBool(tPlat["HideAddButton"])) { if (platPlat == null || (platPlat.ContainsKey("ShowAddButton") && !TheCommonUtils.CBool(platPlat["ShowAddButton"]))) { return(false); } } if (tPlat.ContainsKey("RequireFirstNodeForAdd") && TheCommonUtils.CBool(tPlat["RequireFirstNodeForAdd"]) && !pInfo.IsFirstNode) { if (platPlat == null || (platPlat.ContainsKey("AllowAddOnAllNodes") && !TheCommonUtils.CBool(platPlat["AllowAddOnAllNodes"]))) { return(false); } } } else { if (platPlat != null) { if (platPlat.ContainsKey("HideAddButton") && TheCommonUtils.CBool(platPlat["HideAddButton"])) { return(false); } if (platPlat.ContainsKey("RequireFirstNodeForAdd") && TheCommonUtils.CBool(platPlat["RequireFirstNodeForAdd"]) && !pInfo.IsFirstNode) { return(false); } } } return(true); }
public bool Init() { if (mIsInitCalled) { return(false); } mIsInitCalled = true; MyBaseThing.StatusLevel = 1; MyBaseThing.Version = TheBaseAssets.MyAppInfo.CurrentVersion.ToString(CultureInfo.InvariantCulture); MyBaseThing.Capabilities = TheBaseAssets.MyAppInfo.Capabilities; MyBaseThing.Address = TheBaseAssets.MyServiceHostInfo.GetPrimaryStationURL(false); TheThing.SetSafePropertyString(MyBaseThing, "Description", TheBaseAssets.MyAppInfo.LongDescription); mIsInitialized = true; TheThing.SetSafePropertyBool(MyBaseThing, "EnableKPIs", TheCommonUtils.CBool(TheBaseAssets.MySettings.GetSetting("EnableKPIs"))); if (TheBaseAssets.MyServiceHostInfo.EnableTaskKPIs) { var taskKpiThread = new System.Threading.Thread(() => { TheSystemMessageLog.ToCo($"Tasks {DateTime.Now}: NodeHost starting Task KPI thread"); do { Thread.Sleep(1000); // Keeping it simple here, to minimize interference on task scheduler/thread scheduler etc. (Assumption: not used on production systems) // TheCommonUtils.SleepOneEye(1000, 1000); var kpis = TheCommonUtils.GetTaskKpis(null); TheSystemMessageLog.ToCo($"Tasks {DateTime.Now}: {TheCommonUtils.SerializeObjectToJSONString(kpis)}"); } while (TheBaseAssets.MasterSwitch && TheBaseAssets.MyServiceHostInfo.EnableTaskKPIs); TheSystemMessageLog.ToCo($"Tasks {DateTime.Now}: NodeHost ending Task KPI thread"); }); taskKpiThread.Start(); } KPIHarvestInterval = TheCommonUtils.CInt(TheBaseAssets.MySettings.GetAppSetting("KPIHarvestIntervalInSeconds", "5", false, true)); if (KPIHarvestInterval > 0) { TheQueuedSenderRegistry.RegisterHealthTimer(sinkCyclic); } return(true); }
/// <summary> /// Sets the Thread Name for debugging /// </summary> /// <param name="tName">Friendly name for the Thread</param> /// <param name="IsBackGround">If true, this thread is a designated background thread</param> public static void SetThreadName(string tName, bool IsBackGround) { if (EnableThreadDiag == null) { EnableThreadDiag = TheCommonUtils.CBool(TheBaseAssets.MySettings.GetSetting("EnableThreadDiagnostics")); } if (EnableThreadDiag == true) { if (IsBackGround) { System.Threading.Thread.CurrentThread.IsBackground = IsBackGround; } if (TheBaseAssets.MyServiceHostInfo.DebugLevel > eDEBUG_LEVELS.ESSENTIALS) { #if !CDE_STANDARD ThreadID = NativeMethods.GetCurrentThreadId(); #else System.Threading.Interlocked.Increment(ref ThreadID); #endif string t = System.Threading.Thread.CurrentThread.Name; if (string.IsNullOrEmpty(t)) { t = "cde" + tName; System.Threading.Thread.CurrentThread.Name = t; } else { if (!string.IsNullOrEmpty(tName) && !string.IsNullOrEmpty(t)) { t += ":cde" + tName; } } if (MyThreadNames != null && ThreadID < MAX_IDS) { MyThreadNames[ThreadID] = t; MyThreadStacks[ThreadID] = System.Threading.Thread.CurrentThread; // TheCommonUtils.GetStackInfo(new System.Diagnostics.StackTrace(true)); } } } }
public override bool CreateUX() { if (mIsUXInitCalled) { return(false); } mIsUXInitCalled = true; mMyDashboard = TheNMIEngine.AddDashboard(MyBaseThing, new TheDashboardInfo(MyBaseEngine, "Modbus Devices") { PropertyBag = new nmiDashboardTile { Thumbnail = "/Images/Modbus-Logo.png;0.5;cdeLargeIcon", Category = " Connectivity", TileWidth = 3, TileHeight = 4, ClassName = "cdeLiveTile cdeLargeTile" } }); var tFlds = TheNMIEngine.CreateEngineForms(MyBaseThing, TheThing.GetSafeThingGuid(MyBaseThing, "MYNAME"), "Modbus Devices", null, 20, 0x0F, 0xF0, TheNMIEngine.GetNodeForCategory(), "REFFRESHME", true, new eModbusType(), eModbusType.ModbusTCPDevice); TheFormInfo tForm = tFlds["Form"] as TheFormInfo; tForm.AddButtonText = "Add Modbus Device"; if (TheCommonUtils.CBool(TheBaseAssets.MySettings.GetSetting("AllowXMLUpload"))) { TheFormInfo tMyFormUp = TheNMIEngine.AddForm(new TheFormInfo(MyBaseThing) { cdeMID = TheThing.GetSafeThingGuid(MyBaseThing, "XMLUPLOAD"), FormTitle = "XML Modbus Definition Uploader", DefaultView = eDefaultView.Form }); TheNMIEngine.AddFormToThingUX(MyBaseThing, tMyFormUp, "CMyForm", "XML Definition Uploader", 3, 13, 0x80, TheNMIEngine.GetNodeForCategory(), null, null); TheNMIEngine.AddSmartControl(MyBaseThing, tMyFormUp, eFieldType.DropUploader, 3, 2, 128, "Drop a XML-file here", null, new nmiCtrlDropUploader { TileHeight = 6, NoTE = true, TileWidth = 6, EngineName = MyBaseEngine.GetEngineName(), MaxFileSize = 10000000 }); } AddConnectionWizard(); TheNMIEngine.RegisterEngine(MyBaseEngine); mIsUXInitialized = true; return(true); }
void sinkPChanged(cdeP tProp) { if (m_Tag != null && tProp != null && tProp.HasChanged && tProp.Name == "DontMonitor") { if (!TheCommonUtils.CBool(tProp.ToString())) { m_Tag.SampleRate = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(MyBaseThing, "SampleRate")); string error; TheBaseAssets.MySYSLOG.WriteToLog(78102, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM(MyBaseThing.EngineName, $"Monitoring tag due to DontMonitor property change {m_Tag}", eMsgLevel.l4_Message, "")); var subscription = m_Tag.MyOPCServer.GetOrCreateSubscription(m_Tag.SampleRate); if (subscription != null) { m_Tag.MonitorTag(subscription, out error); // TODO Handle error } } else { m_Tag.UnmonitorTag(); } } }
internal static bool RegisterNewNMINode(Guid pNodeID, Guid pID, Guid pOwner, string pDataItem, bool?pHasLiveSubs) { if (MyAliveNMINodes.ContainsKey(pNodeID)) { if (pID != Guid.Empty) { MyAliveNMINodes[pNodeID].cdeMID = pID; } if (pOwner != Guid.Empty) { MyAliveNMINodes[pNodeID].cdeO = pOwner; } if (!string.IsNullOrEmpty(pDataItem)) { MyAliveNMINodes[pNodeID].DataItem = pDataItem; } if (pHasLiveSubs != null) { MyAliveNMINodes[pNodeID].HasLiveSub = TheCommonUtils.CBool(pHasLiveSubs); } return(true); } else { var tsub = new TheNMISubscription() { cdeN = pNodeID, cdeO = pOwner, DataItem = pDataItem, HasLiveSub = TheCommonUtils.CBool(pHasLiveSubs), cdeMID = pID }; MyAliveNMINodes.TryAdd(pNodeID, tsub); if (pOwner != Guid.Empty) { MyAliveThings[pOwner] = tsub; } } return(false); }
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); }
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 }
internal static TheScreenInfo GenerateLiveScreen(Guid pScreenId, TheClientInfo tClientInfo) // Guid pUserGuid, int lcid, int pFlag) { if (TheCDEngines.MyNMIService == null) { return(null); } TheScreenInfo tInfo = new TheScreenInfo { cdeMID = pScreenId, MyDashboard = null, MyStorageInfo = new List <TheFormInfo>(), MyStorageMeta = new cdeConcurrentDictionary <string, TheFormInfo>(), MyStorageMirror = new List <object>(), MyDashPanels = new List <TheDashPanelInfo>() }; TheThing tLiveForm = TheThingRegistry.GetThingByMID("*", pScreenId); if (tLiveForm == null || !TheUserManager.HasUserAccess(tClientInfo.UserID, tLiveForm.cdeA)) { return(null); //V3.1: BUG 126 - could lead to racing condition. TODO: Revisit later //TheFormInfo tI = new TheFormInfo(tLiveForm) { FormTitle = (tLiveForm == null ? "Form not Found!" : "Access Denied!") }; //tI.TargetElement = pScreenId.ToString(); //tI.AssociatedClassName = pScreenId.ToString(); //tInfo.MyStorageInfo.Add(tI); //tI.FormFields = new List<TheFieldInfo>(); //TheFieldInfo tFldInfo = new TheFieldInfo(null, null, 10, 0, 0); //tFldInfo.Type = eFieldType.SmartLabel; //tFldInfo.Header = (tLiveForm == null ? "This Form was defined but has not Meta-Data associated with it." : "You do not have the required access permissions!"); //tI.FormFields.Add(tFldInfo); //return tInfo; } string tFormName = TheThing.GetSafePropertyString(tLiveForm, "FriendlyName"); List <TheThing> tFields = TheThingRegistry.GetThingsByFunc("*", s => s.cdeO == TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID && TheThing.GetSafePropertyString(s, "FormName") == tFormName && TheThing.GetSafePropertyBool(s, "IsLiveTag") && (s.UID == Guid.Empty || s.UID == tClientInfo.UserID)); if (tFields != null && tFields.Any()) { string tFormTitle = TheThing.GetSafePropertyString(tLiveForm, "FormTitle"); if (string.IsNullOrEmpty(tFormTitle)) { tFormTitle = tFormName; } TheFormInfo tI = new TheFormInfo(tLiveForm) { FormTitle = tFormTitle, TargetElement = pScreenId.ToString(), DefaultView = eDefaultView.Form, TileWidth = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(tLiveForm, "TileWidth")), TileHeight = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(tLiveForm, "TileHeight")), IsUsingAbsolute = TheThing.GetSafePropertyBool(tLiveForm, "IsAbsolute"), AssociatedClassName = pScreenId.ToString() }; tInfo.MyStorageInfo.Add(tI); tI.FormFields = new List <TheFieldInfo>(); int fldNo = 10; foreach (TheThing tTh in tFields) { int tfldNo = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(tTh, "FldOrder")); if (tfldNo == 0) { tfldNo = fldNo; } int tFlags = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(tTh, "Flags")); cdeP ValProp = tTh.GetProperty("Value"); bool IsNewFld = true; TheFieldInfo tFldInfo = TheNMIEngine.GetFieldById(TheThing.GetSafePropertyGuid(tTh, "FldID")); if (tFldInfo == null) { tFldInfo = new TheFieldInfo(tTh, "Value", tfldNo, tFlags & 0xFFBF, tTh.GetBaseThing().cdeA); } else { tFldInfo.FldOrder = tfldNo; tFldInfo.Flags = tFlags; IsNewFld = false; } if (tFldInfo.PropertyBag == null) { tFldInfo.PropertyBag = new ThePropertyBag(); } ThePropertyBag.PropBagUpdateValue(tFldInfo.PropertyBag, "IsOnTheFly", "=", "True"); ThePropertyBag.PropBagUpdateValue(tFldInfo.PropertyBag, "UXID", "=", $"{tTh.cdeMID}"); tFldInfo.Header = tTh.FriendlyName; RegisterNMISubscription(tClientInfo, "Value", tFldInfo); string tControlType = TheThing.GetSafePropertyString(tTh, "ControlType"); if (TheCommonUtils.CInt(tControlType) == 0 && !TheCommonUtils.IsNullOrWhiteSpace(tControlType)) { tFldInfo.Type = eFieldType.UserControl; RegisterFieldEvents(tTh, ValProp, IsNewFld, tFldInfo, tControlType); } else { tFldInfo.Type = (eFieldType)TheCommonUtils.CInt(tControlType); } tFldInfo.DefaultValue = ValProp?.ToString(); tFldInfo.TileWidth = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(tTh, "TileWidth")); tFldInfo.TileHeight = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(tTh, "TileHeight")); foreach (cdeP prop in tTh.GetNMIProperties()) { ThePropertyBag.PropBagUpdateValue(tFldInfo.PropertyBag, prop.Name, "=", prop.ToString()); } if (tFldInfo.Type == eFieldType.TileButton) { tTh.DeclareNMIProperty("IsDown", ePropertyTypes.TBoolean); ThePropertyBag.PropBagUpdateValue(tFldInfo.PropertyBag, "EnableTap", "=", "True"); tFldInfo.RegisterUXEvent(tTh, eUXEvents.OnPropertyChanged, "IsDown", (pThing, pObj) => { if (!(pObj is TheProcessMessage pMsg) || pMsg.Message == null) { return; } TheThing.SetSafePropertyBool(pThing, "IsDown", TheCommonUtils.CBool(pMsg.Message.PLS)); });
/// <summary> /// Checks if a property already matches a desired value. Sets the property and /// notifies listeners only when necessary. /// </summary> /// <typeparam name="T">Type of the property.</typeparam> /// <param name="storage">Reference to a property with both getter and setter.</param> /// <param name="value">Desired value for the property.</param> /// <param name="cdeT">Type of this property - important for comparison with old value</param> /// <param name="cdeE">Extended Flags of the value</param> /// <param name="propertyName">Name of the property used to notify listeners. This /// value is optional and can be provided automatically when invoked from compilers that /// support CallerMemberName.</param> /// <returns>True if the value was changed, false if the existing value matched the /// desired value.</returns> protected bool SetProperty <T>(ref T storage, T value, int cdeT, int cdeE, string propertyName = null) { if ((cdeE & 8) == 0) { if ((cdeE & 1) != 0) //Required in case the property is encrypted. { if (Equals(storage, value)) { return(false); } } else { switch (cdeT) { case 1: if (Math.Abs(TheCommonUtils.CDbl(storage) - TheCommonUtils.CDbl(value)) < Double.Epsilon && (storage == null && value == null || storage != null && value != null)) // 3.217: treat 0 and null as different { return(false); } break; case 2: if (TheCommonUtils.CBool(storage) == TheCommonUtils.CBool(value) && (storage == null && value == null || storage != null && value != null)) // 3.217: treat 0 and null as different { return(false); } value = (T)((object)TheCommonUtils.CBool(value)); break; case 3: if (storage != null && value != null && TheCommonUtils.CDate(storage) == TheCommonUtils.CDate(value)) { return(false); } break; case 4: //Binary Comparison - TODO:CODEREVIEW Could be very expensive to do Byte[] comparison if ((storage == null && value == null)) { return(false); // || ((storage as byte[]).GetHashCode() == (value as byte[]).GetHashCode())) return false; } break; case 5: //Function - Never Set it! return(false); case 6: if (TheCommonUtils.CGuid(storage) == TheCommonUtils.CGuid(value)) { return(false); } break; default: if (Equals(storage, value)) { return(false); } break; } } } storage = value; // CORE REVIEW Markus: SHould we clone the value here to prevent future modification? // CODE REVIEW: There is a race condition between setting mHasChanged and delivering the change notification. Should we raise the notification outside or is this mostly obsolete anyway (XAML only)? OnPropertyChanged(propertyName); return(true); }
/// <summary> /// Handles Messages sent from a host sub-engine to its clients /// </summary> /// <param name="Command"></param> /// <param name="pMessage"></param> public override void HandleMessage(ICDEThing sender, object pIncoming) { TheProcessMessage pMsg = pIncoming as TheProcessMessage; if (pMsg == null) { return; } string[] cmd = pMsg.Message.TXT.Split(':'); switch (cmd[0]) { case nameof(TheThing.MsgBrowseSensors): var browseRequest = TheCommRequestResponse.ParseRequestMessageJSON <TheThing.MsgBrowseSensors>(pMsg.Message); var browseResponse = new TheThing.MsgBrowseSensorsResponse { Error = "Internal error", Sensors = new List <TheThing.TheSensorSourceInfo>() }; foreach (FieldMapping fld in MyModFieldStore.TheValues) { browseResponse.Sensors.Add(new TheThing.TheSensorSourceInfo { SourceType = fld.SourceType, cdeType = ePropertyTypes.TNumber, SensorId = TheCommonUtils.CStr(fld.cdeMID), ExtensionData = new Dictionary <string, object> { { nameof(FieldMapping.SourceOffset), fld.SourceOffset }, { nameof(FieldMapping.SourceSize), fld.SourceSize }, { nameof(FieldMapping.AllowWrite), fld.AllowWrite } }, DisplayNamePath = new string[] { MyBaseEngine.GetEngineName(), MyBaseThing.FriendlyName, fld.PropertyName } }); } browseResponse.Error = null; TheCommRequestResponse.PublishResponseMessageJson(pMsg.Message, browseResponse); break; case nameof(TheThing.MsgSubscribeSensors): var subscribeRequest = TheCommRequestResponse.ParseRequestMessageJSON <TheThing.MsgSubscribeSensors>(pMsg.Message); var subscribeResponse = new TheThing.MsgSubscribeSensorsResponse { Error = "Internal error", SubscriptionStatus = new List <TheThing.TheSensorSubscriptionStatus>() }; if (subscribeRequest.ReplaceAll) { MyModFieldStore.RemoveAllItems(); } var subscriptionStatus = new List <TheThing.TheSensorSubscriptionStatus>(); foreach (TheThing.TheSensorSubscription sub in subscribeRequest.SubscriptionRequests) { FieldMapping fld = new FieldMapping() { PropertyName = sub.TargetProperty, cdeMID = TheCommonUtils.CGuid(sub.SensorId) }; if (fld.cdeMID == Guid.Empty) { fld.cdeMID = Guid.NewGuid(); } object sourceType; if (sub.ExtensionData != null) { if (sub.ExtensionData.TryGetValue(nameof(TheThing.TheSensorSourceInfo.SourceType), out sourceType)) { fld.SourceType = TheCommonUtils.CStr(sourceType); } object offset; if (sub.ExtensionData.TryGetValue("SourceOffset", out offset)) { fld.SourceOffset = TheCommonUtils.CInt(offset); } object size; if (sub.ExtensionData.TryGetValue("SourceSize", out size)) { fld.SourceSize = TheCommonUtils.CInt(size); } object allowWrite; if (sub.ExtensionData.TryGetValue("AllowWrite", out allowWrite)) { fld.AllowWrite = TheCommonUtils.CBool(allowWrite); } MyModFieldStore.AddAnItem(fld); subscriptionStatus.Add(CreateSubscriptionStatusFromFieldMapping(fld)); } else { subscriptionStatus.Add(new TheThing.TheSensorSubscriptionStatus { Error = "Missing source info", Subscription = sub, }); } } subscribeResponse.SubscriptionStatus = subscriptionStatus; subscribeResponse.Error = null; TheCommRequestResponse.PublishResponseMessageJson(pMsg.Message, subscribeResponse); break; case nameof(TheThing.MsgGetSensorSubscriptions): var getResponse = new TheThing.MsgGetSensorSubscriptionsResponse { Error = "Internal error" }; getResponse.Subscriptions = MyModFieldStore.TheValues.Select(fld => CreateSubscriptionStatusFromFieldMapping(fld).Subscription).ToList(); getResponse.Error = null; TheCommRequestResponse.PublishResponseMessageJson(pMsg.Message, getResponse); break; case nameof(TheThing.MsgUnsubscribeSensors): var unsubscribeRequest = TheCommRequestResponse.ParseRequestMessageJSON <TheThing.MsgUnsubscribeSensors>(pMsg.Message); var unsubscribeResponse = new TheThing.MsgUnsubscribeSensorsResponse { Error = "Internal error", Failed = new List <TheThing.TheSensorSubscriptionStatus>() }; if (unsubscribeRequest.UnsubscribeAll) { MyModFieldStore.RemoveAllItems(); if (MyModFieldStore.GetCount() > 0) { unsubscribeResponse.Failed = MyModFieldStore.TheValues.Select(fld => CreateSubscriptionStatusFromFieldMapping(fld)).ToList(); } } else { List <FieldMapping> toRemove = MyModFieldStore.TheValues.FindAll(fld => unsubscribeRequest.SubscriptionIds.Contains(fld.cdeMID)); MyModFieldStore.RemoveItems(toRemove, null); foreach (FieldMapping fld in MyModFieldStore.TheValues) { if (toRemove.Any(t => t.cdeMID == fld.cdeMID)) { unsubscribeResponse.Failed.Add(CreateSubscriptionStatusFromFieldMapping(fld)); } } } unsubscribeResponse.Error = null; TheCommRequestResponse.PublishResponseMessageJson(pMsg.Message, unsubscribeResponse); break; case nameof(TheThing.MsgExportConfig): var exportRequest = TheCommRequestResponse.ParseRequestMessageJSON <TheThing.MsgExportConfig>(pMsg.Message); var exportResponse = new TheThing.MsgExportConfigResponse { Error = "Internal error" }; // No custom config beyond config properties and subscriptions exportResponse.Error = null; TheCommRequestResponse.PublishResponseMessageJson(pMsg.Message, exportResponse); break; case nameof(TheThing.MsgApplyConfig): break; default: break; } TheThing.TheSensorSubscriptionStatus CreateSubscriptionStatusFromFieldMapping(FieldMapping fld) { return(new TheThing.TheSensorSubscriptionStatus { Subscription = new TheThing.TheSensorSubscription { TargetProperty = fld.PropertyName, SensorId = TheCommonUtils.CStr(fld.cdeMID), SubscriptionId = fld.cdeMID, ExtensionData = new Dictionary <string, object> { { nameof(FieldMapping.SourceType), fld.SourceType }, { nameof(FieldMapping.SourceOffset), fld.SourceOffset }, { nameof(FieldMapping.SourceSize), fld.SourceSize }, { nameof(FieldMapping.AllowWrite), fld.AllowWrite } }, TargetThing = new TheThingReference(MyBaseThing), SampleRate = (int?)this.Interval }, Error = null, }); } }
public override bool Init() { if (mIsInitCalled) { return(false); } mIsInitCalled = true; MyBaseThing.StatusLevel = 4; string temp; TheBaseAssets.MyCmdArgs.TryGetValue("IsHealthCollectionOff", out temp); if (!string.IsNullOrEmpty(temp)) { IsHealthCollectionOff = TheCommonUtils.CBool(temp); } if (HealthCollectionCycle == 0) { TheBaseAssets.MyCmdArgs.TryGetValue("HealthCollectionCycle", out temp); if (!string.IsNullOrEmpty(temp)) { HealthCollectionCycle = TheCommonUtils.CInt(temp); } if (HealthCollectionCycle == 0) { HealthCollectionCycle = 15; } } if (SensorDelay == 0) { TheBaseAssets.MyCmdArgs.TryGetValue("SensorDelay", out temp); if (!string.IsNullOrEmpty(temp)) { SensorDelay = TheCommonUtils.CInt(temp); } if (SensorDelay == 0) { SensorDelay = 500; } } if (SensorAccelDeadband < 1) { TheBaseAssets.MyCmdArgs.TryGetValue("SensorAccelDeadband", out temp); if (!string.IsNullOrEmpty(temp)) { SensorAccelDeadband = TheCommonUtils.CDbl(temp); } if (SensorAccelDeadband < 0.1) { SensorAccelDeadband = 3.0; } } int tBS = (int)TheThing.GetSafePropertyNumber(MyBaseThing, "ChartValues"); if (tBS < 10) { tBS = 1000; TheThing.SetSafePropertyNumber(MyBaseThing, "ChartValues", tBS); } tBS = (int)TheThing.GetSafePropertyNumber(MyBaseThing, "ChartSize"); if (tBS < 6) { tBS = 18; TheThing.SetSafePropertyNumber(MyBaseThing, "ChartSize", tBS); } TheUserManager.RegisterNewRole(new TheUserRole(new Guid("{0A254170-D4D4-4B2D-9E05-D471729BE739}"), "ComputerManager", 1, new Guid("{3FB56264-9AA8-4AC9-9208-A01F1142B153}"), true, "Person allowed to view Computer Details")); MyBaseThing.RegisterEvent(eEngineEvents.IncomingMessage, HandleMessage); //Event when C-DEngine has new Telegram for this service as a subscriber (Client Side) MyBaseThing.RegisterEvent("FileReceived", sinkFileReceived); MyBaseThing.RegisterEvent(eEngineEvents.ShutdownEvent, sinkEngineShutdown); StartEngineServices(); if (MyBaseThing.StatusLevel == 4) { MyBaseThing.StatusLevel = 1; } mIsInitialized = true; return(true); }
void sinkGELF(cdeP p) { TheBaseAssets.MyServiceHostInfo.UseGELFLoggingFormat = TheCommonUtils.CBool(p); }
public override bool CreateUX() { if (mIsUXInitCalled) { return(false); } mIsUXInitCalled = true; MyPCVitalsDashboard = TheNMIEngine.AddDashboard(MyBaseThing, new TheDashboardInfo(MyBaseEngine, "Node Vitals") { PropertyBag = new ThePropertyBag() { "Category=Diagnostics", "Caption=Node Vitals", "Thumbnail=FA5:f108", } }); TheFormInfo tMyConfForm = new TheFormInfo(TheThing.GetSafeThingGuid(MyBaseThing, "Config"), eEngineName.NMIService, "Setting", string.Format("TheThing;:;0;:;True;:;cdeMID={0}", MyBaseThing.cdeMID)) { DefaultView = eDefaultView.Form, PropertyBag = new ThePropertyBag { "TileWidth=6" } }; TheNMIEngine.AddFormToThingUX(MyBaseThing, tMyConfForm, "CMyForm", "Settings", 1, 9, 0xC0, TheNMIEngine.GetNodeForCategory(), null, null); TheNMIEngine.AddSmartControl(MyBaseThing, tMyConfForm, eFieldType.SingleCheck, 1, 2, 0xC0, "Disable Collection", "IsHealthCollectionOff"); //TheNMIEngine.AddSmartControl(MyBaseThing, tMyConfForm, eFieldType.SingleCheck, 2, 2, 0xC0, "Enable OHM", "EnableOHM"); TheNMIEngine.AddSmartControl(MyBaseThing, tMyConfForm, eFieldType.Number, 10, 2, 0xC0, "Health Collection Cycle", "HealthCollectionCycle"); TheNMIEngine.AddSmartControl(MyBaseThing, tMyConfForm, eFieldType.Number, 11, 2, 0xC0, "Sensor Delay", "SensorDelay"); TheNMIEngine.AddSmartControl(MyBaseThing, tMyConfForm, eFieldType.Number, 12, 2, 0xC0, "Sensor Deadband", "SensorAccelDeadband"); TheNMIEngine.AddSmartControl(MyBaseThing, tMyConfForm, eFieldType.Number, 13, 2, 0xC0, "Chart Values", "ChartValues", new nmiCtrlNumber { MinValue = 10 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyConfForm, eFieldType.Number, 14, 2, 0xC0, "Default Chart TileWidth", "ChartSize", new nmiCtrlNumber { MinValue = 6, MaxValue = 30 }); if (!TheCommonUtils.IsHostADevice()) { TheFormInfo tMyForm = new TheFormInfo() { cdeMID = new Guid("{A3765D29-8EFF-4F09-B5BC-E5CE4C7DEA6F}"), FormTitle = "CPU Details", defDataSource = "TheThing;:;0;:;True;:;DeviceType=CPUInfo" }; TheNMIEngine.AddFormToThingUX(MyBaseThing, tMyForm, "CMyTable", "CPUs", 2, 3, 0, "Live Tables", null, null); TheNMIEngine.AddField(tMyForm, new TheFieldInfo() { FldOrder = 5, FldWidth = 4, Flags = 2, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "Friendly Name", DataItem = "MyPropertyBag.FriendlyName.Value" }); TheNMIEngine.AddField(tMyForm, new TheFieldInfo() { FldOrder = 6, FldWidth = 2, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "HostURL", DataItem = "MyPropertyBag.HostUrl.Value" }); TheNMIEngine.AddField(tMyForm, new TheFieldInfo() { FldOrder = 11, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "Speed", DataItem = "MyPropertyBag.MaxClockSpeed.Value" }); TheNMIEngine.AddField(tMyForm, new TheFieldInfo() { FldOrder = 12, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "Cores", DataItem = "MyPropertyBag.NumberOfCores.Value" }); TheNMIEngine.AddField(tMyForm, new TheFieldInfo() { FldOrder = 13, FldWidth = 2, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "Manufacturer", DataItem = "MyPropertyBag.Manufacturer.Value" }); TheNMIEngine.AddField(tMyForm, new TheFieldInfo() { FldOrder = 14, Flags = 0, cdeA = 0xC0, Type = eFieldType.SingleEnded, Header = "Architecture", DataItem = "MyPropertyBag.AddressWidth.Value" }); TheNMIEngine.AddField(tMyForm, new TheFieldInfo() { FldOrder = 15, Flags = 0, cdeA = 0xC0, Type = eFieldType.SingleEnded, Header = "Rev", DataItem = "MyPropertyBag.Revision.Value" }); TheNMIEngine.AddField(tMyForm, new TheFieldInfo() { FldOrder = 16, Flags = 0, cdeA = 0xC0, Type = eFieldType.SingleEnded, Header = "L2 Cache", DataItem = "MyPropertyBag.L2CacheSize.Value" }); TheNMIEngine.AddField(tMyForm, new TheFieldInfo() { FldOrder = 17, Flags = 0, cdeA = 0xC0, Type = eFieldType.SingleEnded, Header = "Version", DataItem = "MyPropertyBag.Version.Value" }); TheNMIEngine.AddField(tMyForm, new TheFieldInfo() { FldOrder = 80, FldWidth = 2, cdeA = 0xFF, Type = eFieldType.DateTime, Header = "Last Update", DataItem = "MyPropertyBag.LastUpdate.Value" }); TheFormInfo tMyHForm = new TheFormInfo() { cdeMID = new Guid("{33170B1F-CA19-4DC6-A18F-15B5F7669E0A}"), FormTitle = "PC Health Details", defDataSource = "TheThing;:;0;:;True;:;DeviceType=PC-Health" }; TheNMIEngine.AddFormToThingUX(MyBaseThing, tMyHForm, "CMyTable", "PC Health", 3, 3, 0, "Live Tables", null, null); TheNMIEngine.AddField(tMyHForm, new TheFieldInfo() { FldOrder = 5, FldWidth = 3, Flags = 2, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "Friendly Name", DataItem = "MyPropertyBag.FriendlyName.Value" }); TheNMIEngine.AddField(tMyHForm, new TheFieldInfo() { FldOrder = 6, FldWidth = 2, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "HostAddress", DataItem = "MyPropertyBag.HostAddress.Value" }); TheNMIEngine.AddField(tMyHForm, new TheFieldInfo() { FldOrder = 7, FldWidth = 3, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "Host Version", DataItem = "MyPropertyBag.HostVersion.Value" }); //TheNMIEngine.AddField(tMyHForm, new TheFieldInfo() { FldOrder = 8, Flags = 0, cdeA = 0xC0, Type = eFieldType.SingleEnded, Header = "Station Roles", DataItem = "MyPropertyBag.StationRoles.Value" }); TheNMIEngine.AddField(tMyHForm, new TheFieldInfo() { FldOrder = 11, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "CPU Load", DataItem = "MyPropertyBag.CPULoad.Value" }); TheNMIEngine.AddField(tMyHForm, new TheFieldInfo() { FldOrder = 13, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "CPU Temp", DataItem = "MyPropertyBag.CPUTemp.Value" }); //TheNMIEngine.AddField(tMyHForm, new TheFieldInfo() { FldOrder = 14, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "Core Temps", DataItem = "MyPropertyBag.CoreTemps.Value" }); TheNMIEngine.AddField(tMyHForm, new TheFieldInfo() { FldOrder = 21, FldWidth = 2, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "RAM Available", DataItem = "MyPropertyBag.RAMAvailable.Value" }); TheNMIEngine.AddField(tMyHForm, new TheFieldInfo() { FldOrder = 22, FldWidth = 2, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "PC Uptime", DataItem = "MyPropertyBag.PCUptime.Value" }); TheNMIEngine.AddField(tMyHForm, new TheFieldInfo() { FldOrder = 23, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "Watts", DataItem = "MyPropertyBag.StationWatts.Value" }); TheNMIEngine.AddField(tMyHForm, new TheFieldInfo() { FldOrder = 31, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "cdeUptime", DataItem = "MyPropertyBag.cdeUptime.Value" }); TheNMIEngine.AddField(tMyHForm, new TheFieldInfo() { FldOrder = 32, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "cdeHandles", DataItem = "MyPropertyBag.cdeHandles.Value" }); TheNMIEngine.AddField(tMyHForm, new TheFieldInfo() { FldOrder = 33, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "cdeWorkingSetSize", DataItem = "MyPropertyBag.cdeWorkingSetSize.Value" }); TheNMIEngine.AddField(tMyHForm, new TheFieldInfo() { FldOrder = 34, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "cdeThreadCount", DataItem = "MyPropertyBag.cdeThreadCount.Value" }); TheNMIEngine.AddField(tMyHForm, new TheFieldInfo() { FldOrder = 35, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "EventTimeOuts", DataItem = "MyPropertyBag.TotalEventTimeouts.Value" }); TheNMIEngine.AddField(tMyHForm, new TheFieldInfo() { FldOrder = 36, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "QSenders", DataItem = "MyPropertyBag.QSenders.Value" }); TheNMIEngine.AddField(tMyHForm, new TheFieldInfo() { FldOrder = 37, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "TSM Inserts", DataItem = "MyPropertyBag.QSInserted.Value" }); TheNMIEngine.AddField(tMyHForm, new TheFieldInfo() { FldOrder = 38, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "TSM Sents", DataItem = "MyPropertyBag.QSSent.Value" }); TheNMIEngine.AddField(tMyHForm, new TheFieldInfo() { FldOrder = 80, FldWidth = 2, cdeA = 0xFF, Type = eFieldType.DateTime, Header = "Last Update", DataItem = "MyPropertyBag.LastUpdate.Value" }); } if (!TheBaseAssets.MyServiceHostInfo.IsCloudService) { int tBS = (int)TheThing.GetSafePropertyNumber(MyBaseThing, "ChartValues"); if (tBS < 10) { tBS = 10; } if (tBS > 10000) { tBS = 10000; } int tCS = (int)TheThing.GetSafePropertyNumber(MyBaseThing, "ChartSize"); if (tCS < 6) { tCS = 6; } TheNMIEngine.AddChartScreen(MyBaseThing, new TheChartDefinition(TheThing.GetSafeThingGuid(MyBaseThing, "CPUState"), "Computer CPU State", tBS, "TheHealthHistory", true, "", "PB.HostAddress", "PB.CPULoad;PB.CPUTemp;PB.RAMAvailable") { GroupMode = 0, IntervalInMS = 0 }, 2, 3, 0, TheNMIEngine.GetNodeForCategory(), false, new ThePropertyBag() { ".TileHeight=8", ".NoTE=true", $".TileWidth={tCS}", $"Header={TheNMIEngine.GetNodeForCategory()}" }); TheNMIEngine.AddChartScreen(MyBaseThing, new TheChartDefinition(TheThing.GetSafeThingGuid(MyBaseThing, "CDERes"), "CDE Resources", tBS, "TheHealthHistory", true, "", "PB.HostAddress", "PB.cdeHandles;PB.cdeWorkingSetSize") { GroupMode = 0, IntervalInMS = 0 }, 5, 3, 0, TheNMIEngine.GetNodeForCategory(), false, new ThePropertyBag() { ".TileHeight=8", ".NoTE=true", $".TileWidth={tCS}", $"Header={TheNMIEngine.GetNodeForCategory()}" }); TheNMIEngine.AddChartScreen(MyBaseThing, new TheChartDefinition(TheThing.GetSafeThingGuid(MyBaseThing, "CDEKPIs"), "CDE KPIs", tBS, "TheHealthHistory", true, "", "PB.HostAddress", "PB.QSenders;PB.QSLocalProcessed;PB.QSSent;PB.QKBSent;PB.QKBReceived;PB.QSInserted;PB.EventTimeouts;PB.TotalEventTimeouts;PB.CCTSMsRelayed;PB.CCTSMsReceived;PB.CCTSMsEvaluated;PB.HTCallbacks;PB.KPI1;PB.KPI2;PB.KPI3;PB.KPI4;PB.KPI5;PB.KPI10") { GroupMode = 0, IntervalInMS = 0 }, 5, 3, 0, TheNMIEngine.GetNodeForCategory(), false, new ThePropertyBag() { ".TileHeight=8", ".NoTE=true", $".TileWidth={tCS}", $"Header={TheNMIEngine.GetNodeForCategory()}" }); if (!TheCommonUtils.IsOnLinux()) { var tMyLiveForm = TheNMIEngine.AddStandardForm(MyBaseThing, "Live CPU Chart", 18, "CPULoad", null, 0, TheNMIEngine.GetNodeForCategory()); (tMyLiveForm["Header"] as TheFieldInfo).Header = $"{TheNMIEngine.GetNodeForCategory()} CPU Chart"; var tc = TheNMIEngine.AddSmartControl(MyBaseThing, tMyLiveForm["Form"] as TheFormInfo, eFieldType.UserControl, 22, 0, 0, "CPU Load", "LoadBucket", new ThePropertyBag() { "ParentFld=1", "ControlType=Line Chart", "Title=CPU Load", "SubTitle=" + GetProperty("HostAddress", true), "SeriesNames=[{ \"name\":\"CPU-Load\", \"lineColor\":\"rgba(0,255,0,0.39)\"}, { \"name\":\"CDE-Load\", \"lineColor\":\"rgba(0,0,255,0.39)\"}]", "TileHeight=4", "Speed=800", "Delay=0", "Background=rgba(0,0,0,0.01)", "MaxValue=100", "NoTE=true" }); tc.AddOrUpdatePlatformBag(eWebPlatform.Any, new nmiPlatBag { TileWidth = 18 }); tc.AddOrUpdatePlatformBag(eWebPlatform.Mobile, new nmiPlatBag { TileWidth = 6 }); tc.AddOrUpdatePlatformBag(eWebPlatform.HoloLens, new nmiPlatBag { TileWidth = 12 }); } } if (TheCommonUtils.CBool(TheBaseAssets.MySettings.GetSetting("PCVitalsMaster"))) { TheFormInfo tMyFormUp = TheNMIEngine.AddForm(new TheFormInfo(MyBaseThing) { cdeMID = TheThing.GetSafeThingGuid(MyBaseThing, "THHUPLOAD"), FormTitle = "PC Vitals Uploader", DefaultView = eDefaultView.Form }); TheNMIEngine.AddFormToThingUX(MyBaseThing, tMyFormUp, "CMyForm", "PC Vitals Uploader", 3, 13, 0x80, TheNMIEngine.GetNodeForCategory(), null, new nmiDashboardTile { TileThumbnail = "FA3:f093", }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyFormUp, eFieldType.DropUploader, 3, 2, 128, "Drop a TheHealthHistory-file here", null, new nmiCtrlDropUploader { TileHeight = 6, NoTE = true, TileWidth = 6, EngineName = MyBaseEngine.GetEngineName(), MaxFileSize = 10000000 }); FindTHHFiles(); } TheNMIEngine.AddPageDefinitions(new List <ThePageDefinition> { { new ThePageDefinition(new Guid("{7FED3369-AF7C-451F-9ED1-71131BB993F4}"), "/PCHEALTH", "Health Info", "", Guid.Empty) { WPID = 10, IncludeCDE = true, RequireLogin = false, PortalGuid = MyBaseEngine.GetDashboardGuid(), StartScreen = MyBaseEngine.GetDashboardGuid() } }, }); TheNMIEngine.AddAboutButton(MyBaseThing); TheNMIEngine.RegisterEngine(MyBaseEngine); mIsUXInitialized = true; return(true); }
public bool CreateUX() { if (!mIsUXInitStarted) { mIsUXInitStarted = true; //NUI Definition for All clients TheNMIEngine.AddDashboard(MyBaseThing, new TheDashboardInfo(MyBaseEngine, "Thing Provisioner") { PropertyBag = new nmiDashboardTile { Caption = "Thing Provisioner", Category = "Services", Thumbnail = "FA5Sf110", } }); if (TheCommonUtils.CBool(TheBaseAssets.MySettings.GetSetting("RedPill"))) { MyScriptTable = new TheFormInfo(TheThing.GetSafeThingGuid(MyBaseThing, "SCRIPT_TABLE"), eEngineName.NMIService, "Script Table", $"ScriptTableFields{MyBaseThing.ID}") { PropertyBag = new nmiCtrlFormView { TileWidth = 12, TileHeight = 10 } }; TheNMIEngine.AddFormToThingUX(MyBaseThing, MyScriptTable, "CMyTable", "Script Table", 1, 3, 0xF0, null, null, new ThePropertyBag() { "Visibility=true" }); TheNMIEngine.AddSmartControl(MyBaseThing, MyScriptTable, eFieldType.SingleCheck, 48, 2, 0, "Disabled", nameof(ScriptSnapshot.Disabled), new nmiCtrlSingleEnded() { TileWidth = 1, FldWidth = 1 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyScriptTable, eFieldType.SingleEnded, 50, 0, 0, "Script Name", nameof(ScriptSnapshot.ScriptName), new nmiCtrlSingleEnded() { TileWidth = 2, FldWidth = 2 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyScriptTable, eFieldType.Number, 55, 0, 0, "Script Step", nameof(ScriptSnapshot.ScriptStep), new nmiCtrlNumber() { TileWidth = 1, FldWidth = 1 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyScriptTable, eFieldType.SingleEnded, 60, 0, 0, "Step Status", nameof(ScriptSnapshot.ScriptStatus), new nmiCtrlSingleEnded() { TileWidth = 2, FldWidth = 2 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyScriptTable, eFieldType.SingleEnded, 65, 2, 0, "Step Name", nameof(ScriptSnapshot.StepName), new nmiCtrlSingleEnded() { TileWidth = 2, FldWidth = 2 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyScriptTable, eFieldType.DateTime, 67, 0, 0, "Time", nameof(ScriptSnapshot.LastUpdate), new nmiCtrlDateTime() { TileWidth = 1, FldWidth = 1 }); TheNMIEngine.AddTableButtons(MyScriptTable); if (TheCommonUtils.CBool(TheBaseAssets.MySettings.GetSetting("EnableDiagnostics"))) { CreateScriptEditTemplate(); var button = TheNMIEngine.AddSmartControl(MyBaseThing, MyScriptTable, eFieldType.TileButton, 45, 2, 0, "Replay", null, new nmiCtrlTileButton() { TileWidth = 1, TileHeight = 1, FldWidth = 1, ClassName = "cdeGoodActionButton" }); button.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "test", async(sender, pPara) => { try { if (!(pPara is TheProcessMessage pMSG) || pMSG.Message == null) { return; } string[] cmd = pMSG.Message.PLS.Split(':'); if (cmd.Length > 2) { var tScript = MyScriptTableStorage.GetEntryByID(TheCommonUtils.CGuid(cmd[2])); if (null != tScript) { if (string.IsNullOrEmpty(tScript.ScriptName)) { var script = LoadScript(tScript.FileName); await RunScriptAsync(script, tScript.Context, tScript.ScriptStep - 1, true); } //Rerun script step from snapshot. await RunScriptAsync(tScript.ContextScript, tScript.Context, tScript.ScriptStep - 1, true); } } } catch (Exception e) { MyBaseThing.LastMessage = $"Error replaying: {e.Message}"; } }); } } TheNMIEngine.AddAboutButton(MyBaseThing, false); mIsUXInitCompleted = true; } return(true); }
override protected void MonitoredItem_Notification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e) { try { var tEventTag = monitoredItem.Handle as TheOPCEvent; if (tEventTag == null) { TheBaseAssets.MySYSLOG.WriteToLog(78102, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyOPCServer.GetBaseThing().EngineName, $"Internal error: invalid monitored item handle in Event", eMsgLevel.l1_Error, $"{DisplayName} {GetNodeIdForLogs()} {EventInfo.AggregateRetainedConditions}")); return; } var tEventHost = tEventTag.GetHostThing(); if (tEventHost == null) { TheBaseAssets.MySYSLOG.WriteToLog(78102, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyOPCServer.GetBaseThing().EngineName, $"Event host thing not found", eMsgLevel.l1_Error, $"{DisplayName} {GetNodeIdForLogs()} {EventInfo.AggregateRetainedConditions}")); return; } EventFieldList notification = e.NotificationValue as EventFieldList; if (notification == null) { TheBaseAssets.MySYSLOG.WriteToLog(78102, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyOPCServer.GetBaseThing().EngineName, $"Internal error: notification is not an EventFieldList", eMsgLevel.l1_Error, $"{DisplayName} {GetNodeIdForLogs()} {EventInfo.AggregateRetainedConditions}")); return; } // check the type of event. NodeId eventTypeId = ClientUtils.FindEventType(monitoredItem, notification); if (MyOPCServer.EnableOPCDataLogging) { var logInfo = new Dictionary <string, object> { { "ReceiveTime", DateTimeOffset.Now }, { "TagId", DisplayName }, { "EventTypeId", eventTypeId }, { "Value", notification.EventFields.Aggregate("", (s, ef) => $"{s} [{ef.TypeInfo},{ef.Value}]") }, { "Server", notification.Message.PublishTime }, { "MonitoredItem", monitoredItem?.ClientHandle }, { "SequenceNumber", notification.Message?.SequenceNumber }, }; TheOPCTag.LogOPCData(logInfo, MyOPCServer.GetLogAddress(), $"{DisplayName} {GetNodeIdForLogs()} {EventInfo.AggregateRetainedConditions}"); } // ignore unknown events. if (NodeId.IsNull(eventTypeId)) { TheBaseAssets.MySYSLOG.WriteToLog(78102, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyOPCServer.GetBaseThing().EngineName, $"Unknown eventTypeId", eMsgLevel.l1_Error, $"{DisplayName} {GetNodeIdForLogs()} {EventInfo.AggregateRetainedConditions}: received {eventTypeId}")); return; } EventFilter filter = monitoredItem.Status.Filter as EventFilter; bool isRefreshEvent = false; var eventData = new Dictionary <string, object>(); DateTimeOffset sourceTime = DateTimeOffset.Now; string conditionId = null; bool? bRetain = null; int index = 0; foreach (var field in filter.SelectClauses) { var value = index < notification?.EventFields.Count ? notification?.EventFields[index].Value : null; if (value is ExtensionObject || value is ExtensionObject[]) { value = MyOPCServer.DecodeExtensionObjectToJson(value, out var ignored); } var name = field?.BrowsePath?.Count > 0 ? field.BrowsePath[0].Name : null; if (value is NodeId) { if (name == "EventType") { var eventType = value as NodeId; if (eventType == Opc.Ua.ObjectTypeIds.RefreshStartEventType) { TheBaseAssets.MySYSLOG.WriteToLog(78102, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(MyOPCServer.GetBaseThing().EngineName, $"Received Refresh Start event", eMsgLevel.l4_Message, $"{DisplayName} {GetNodeIdForLogs()} {EventInfo.AggregateRetainedConditions}")); _currentConditionsByConditionId.Clear(); if (_bRefreshing) { // Two overlapping refresh starts received TheBaseAssets.MySYSLOG.WriteToLog(78102, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyOPCServer.GetBaseThing().EngineName, $"Received more than one Refresh Start event", eMsgLevel.l2_Warning, $"{DisplayName} {GetNodeIdForLogs()} {EventInfo.AggregateRetainedConditions}")); } _bRefreshing = true; _lastRefreshStartTime = DateTimeOffset.Now; isRefreshEvent = true; } else if (eventType == Opc.Ua.ObjectTypeIds.RefreshEndEventType) { TheBaseAssets.MySYSLOG.WriteToLog(78102, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(MyOPCServer.GetBaseThing().EngineName, $"Received Refresh End event", eMsgLevel.l4_Message, $"{DisplayName} {GetNodeIdForLogs()} {EventInfo.AggregateRetainedConditions}")); if (!_bRefreshing) { TheBaseAssets.MySYSLOG.WriteToLog(78102, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyOPCServer.GetBaseThing().EngineName, $"Received Refresh End event without matching start event", eMsgLevel.l2_Warning, $"{DisplayName} {GetNodeIdForLogs()} {EventInfo.AggregateRetainedConditions}")); // refresh end received without refresh start } _bRefreshing = false; isRefreshEvent = true; if (EventInfo.AggregateRetainedConditions) { WriteAggregatedConditionsToProperty(tEventHost, TheCommonUtils.CDate(notification.Message.PublishTime)); } } } value = value.ToString(); } if (name == null) { if (field.TypeDefinitionId == Opc.Ua.ObjectTypeIds.BaseEventType) { name = "ConditionId"; } } if (name != null) { if (aliasMap.TryGetValue(index, out var alias)) { eventData[alias] = value; } else { eventData[name] = value; } switch (name) { case "ConditionId": conditionId = value?.ToString(); break; case "Retain": bRetain = TheCommonUtils.CBool(value); break; case "Time": sourceTime = TheCommonUtils.CDate(value); break; } } index++; } if (!isRefreshEvent) { var eventInfoProperties = EventInfo.GetPropertyNames(); var filteredEventProps = EventInfo.Properties?.Count > 0 ? eventData.Where(pk => !requiredEventFields.Contains(pk.Key) || eventInfoProperties.Contains(pk.Key)) //.Select(kv => //{ // if (aliasMap.TryGetValue(kv.Key, out var alias)) // { // return new KeyValuePair<string, object>(alias, kv.Value); // } // return kv; //}) .ToDictionary(kv => kv.Key, kv => kv.Value) : eventData; //if (_bRefreshing) //{ // filteredEventProps["Refresh"] = true; //} if (!EventInfo.AggregateRetainedConditions) { // Raw events // TODO avoid resending events due to a refresh? var eventAsJson = TheCommonUtils.SerializeObjectToJSONString(filteredEventProps); TheBaseAssets.MySYSLOG.WriteToLog(78102, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(MyOPCServer.GetBaseThing().EngineName, $"Received raw event {eventAsJson}", eMsgLevel.l6_Debug, $"{DisplayName} {GetNodeIdForLogs()} {EventInfo.AggregateRetainedConditions}")); tEventHost.GetBaseThing().SetProperty(DisplayName, eventAsJson, TheCommonUtils.CDate(notification.Message.PublishTime)); } else { // Aggregated Condition State if (conditionId != null) { if (bRetain == false) { TheBaseAssets.MySYSLOG.WriteToLog(78102, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(MyOPCServer.GetBaseThing().EngineName, $"Removed current event {conditionId}", eMsgLevel.l6_Debug, $"{DisplayName} {GetNodeIdForLogs()} {EventInfo.AggregateRetainedConditions}")); _currentConditionsByConditionId.RemoveNoCare(conditionId); } else { TheBaseAssets.MySYSLOG.WriteToLog(78102, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(MyOPCServer.GetBaseThing().EngineName, $"Added current event {conditionId}", eMsgLevel.l6_Debug, $"{DisplayName} {GetNodeIdForLogs()} {EventInfo.AggregateRetainedConditions}")); _currentConditionsByConditionId[conditionId] = filteredEventProps; } if (!_bRefreshing) { WriteAggregatedConditionsToProperty(tEventHost, TheCommonUtils.CDate(notification.Message.PublishTime)); } } } // Legacy format: do we still need to support this? Existing event support was not really usable... //foreach (var eventField in eventData) //{ // string propertyName; // if (tEventHost is TheOPCUATagThing) // TODO Create a TheOPCUAEventThing // { // // If this is a dedicated event thing, use the original value name // // TODO Is this really what we want to do or do we also want to use the full browsepath for dedicated event things? // throw new NotImplementedException("Should never get here"); // //propertyName = field.BrowsePath[0].Name; // } // else // { // // This is an external, multi-event thing: use the browsepath to avoid collisions with properties from multiple events // propertyName = DisplayName + "." + eventField.Key; // } // SetPropertyFromVariant(tEventHost, propertyName, eventField.Value, sourceTime); //} } } catch (Exception ex) { TheBaseAssets.MySYSLOG.WriteToLog(78102, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyOPCServer.GetBaseThing().EngineName, $"Internal error processing event notification", eMsgLevel.l1_Error, $"{DisplayName} {GetNodeIdForLogs()} {EventInfo.AggregateRetainedConditions}: {ex.ToString()}")); } }
void sinkTriggerTimeout(object pTime) { if (!TheBaseAssets.MasterSwitch) { mTimer?.Dispose(); mTimer = null; return; } if (IsDisabled) { if (MyBaseThing.StatusLevel != 0) { MyBaseThing.StatusLevel = 0; MyBaseThing.LastMessage = "Countdown disabled"; } return; } else if (MyBaseThing.StatusLevel == 0) { MyBaseThing.StatusLevel = 1; MyBaseThing.LastMessage = "Countdown enabled"; } if (TheCommonUtils.cdeIsLocked(TriggerLock)) { return; } lock (TriggerLock) { int tTIme = (TheCommonUtils.CInt(MyBaseThing.Value) - 1); if (tTIme >= 0) { MyBaseThing.Value = tTIme.ToString(); if (TheCommonUtils.CBool(TheBaseAssets.MySettings.GetSetting("VThing-SimTest")) == true && MyBaseThing.ID == "TESTSIM") { var response = new CDMyMeshManager.Contracts.MsgReportTestStatus { NodeId = TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID, PercentCompleted = 100 - tTIme, SuccessRate = 100 - tTIme, Status = CDMyMeshManager.Contracts.eTestStatus.Running, TestRunId = TheCommonUtils.CGuid(TheBaseAssets.MySettings.GetSetting("TestRunID")), Timestamp = DateTimeOffset.Now, ResultDetails = new Dictionary <string, object> { { "SomeKPI", 123 }, }, }.Publish(); } } if (tTIme <= 0 && mTimer != null) { mTimer.Dispose(); mTimer = null; IsActive = false; MyBaseThing.StatusLevel = 0; if (TheCommonUtils.CBool(TheBaseAssets.MySettings.GetSetting("VThing-SimTest")) == true && MyBaseThing.ID == "TESTSIM") { TheCommonUtils.TaskDelayOneEye(2000, 100).ContinueWith(t => { var response = new CDMyMeshManager.Contracts.MsgReportTestStatus { NodeId = TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID, PercentCompleted = 100, SuccessRate = 100, Status = CDMyMeshManager.Contracts.eTestStatus.Success, TestRunId = TheCommonUtils.CGuid(TheBaseAssets.MySettings.GetSetting("TestRunID")), Timestamp = DateTimeOffset.Now, ResultDetails = new Dictionary <string, object> { { "SomeKPI", 123 }, }, }.Publish(); }); } if (Restart) { sinkTriggered(this.GetProperty(nameof(StartValue), false)); } else { CountBar?.SetUXProperty(Guid.Empty, string.Format("MaxValue=100")); } } } }
void sinkDisableChanged(cdeP p) { TheBaseAssets.MyServiceHostInfo.DisableConsole = TheCommonUtils.CBool(p); }
public override bool DoCreateUX() { var tFlds = TheNMIEngine.AddStandardForm(MyBaseThing, "FACEPLATE", 18, null, null, 0, "...Virtual State Sensors"); SummaryForm = (tFlds["DashIcon"] as TheDashPanelInfo); MyStatusForm = tFlds["Form"] as TheFormInfo; MyStatusForm.ModelID = "VStateSensorForm"; TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.TileButton, 1112, 2, 0, "Details...", null, new nmiCtrlTileButton { OnClick = $"TTS:%RealSensorThing%", RenderTarget = "VSDETBUT%cdeMID%", NoTE = true, Background = "transparent", TileWidth = 3, TileHeight = 1, TileFactorY = 2, ClassName = "cdeEmptyButtoninner" }); var ts = TheNMIEngine.AddStatusBlock(MyBaseThing, MyStatusForm, 100); ts["Group"].SetParent(1); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.CollapsibleGroup, 200, 2, 0xc0, "V-Sensor Settings...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup() { DoClose = true, MaxTileWidth = 6, IsSmall = true, ParentFld = 1 })); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.ComboBox, 210, 2, 0xc0, "Sensor Type", "StateSensorType", new nmiCtrlComboBox { ParentFld = 200, FldWidth = 4, TileWidth = 6, Options = "analog;binary;state" }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.CollapsibleGroup, 220, 2, 0xc0, "Settings (Analog Sensor Only)...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup() { DoClose = true, MaxTileWidth = 6, ParentFld = 1, IsSmall = true })); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.SingleEnded, 225, 2, 0xc0, "Sensor Units", "StateSensorUnit", new nmiCtrlSingleEnded { ParentFld = 220, TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.SingleEnded, 221, 2, 0x0, "Sensor Value Name", "StateSensorValueName", new nmiCtrlSingleEnded { ParentFld = 220, TileWidth = 6 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.Number, 228, 2, 0xc0, "Average Value", "StateSensorAverage", new nmiCtrlNumber { ParentFld = 220, TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.Number, 230, 2, 0xc0, "Min Value", "StateSensorMinValue", new nmiCtrlNumber { ParentFld = 220, TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.Number, 240, 2, 0xc0, "Max Value", "StateSensorMaxValue", new nmiCtrlNumber { ParentFld = 220, TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.Number, 245, 2, 0xc0, "Value Divider", "StateSensorScaleFactor", new nmiCtrlNumber { TileWidth = 3, ParentFld = 220 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.Number, 246, 2, 0xc0, "Digits", "StateSensorDigits", new nmiCtrlNumber { MinValue = 0, TileWidth = 3, ParentFld = 220 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.SingleCheck, 247, 2, 0xc0, "Force Absolute", "StateSensorIsAbs", new nmiCtrlSingleCheck { TileWidth = 3, ParentFld = 220 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.ThingPicker, 212, 2, 0xc0, "Thing Picker", "RealSensorThing", new nmiCtrlThingPicker() { ParentFld = 200, IncludeEngines = true, IncludeRemotes = true }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.PropertyPicker, 213, 2, 0xc0, "Property Picker", "RealSensorProperty", new nmiCtrlPropertyPicker() { ParentFld = 200, ThingFld = 212 }); GetProperty("RealSensorProperty", true).RegisterEvent(eThingEvents.PropertyChanged, (p) => { EngageMapper(); }); var tEngage = TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.TileButton, 214, 2, 0xC0, "Restart Sensor", null, new nmiCtrlNumber { ParentFld = 200, TileWidth = 6, NoTE = true }); tEngage.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "reset", (sender, para) => { EngageMapper(); }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.CollapsibleGroup, 249, 2, 0xc0, "Advanced Settings...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup() { DoClose = true, MaxTileWidth = 6, ParentFld = 200, IsSmall = true })); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.SingleCheck, 250, 2, 0xC0, "Replicate", "IsGlobal", new nmiCtrlNumber { ParentFld = 249, TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.Number, 255, 2, 0xC0, "NMI Interval", "Interval", new nmiCtrlNumber { ParentFld = 249, TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.CollapsibleGroup, 260, 2, 0xc0, "Pre-Processing...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup() { DoClose = true, MaxTileWidth = 6, ParentFld = 220, IsSmall = true })); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.ComboBox, 261, 2, 0xC0, "Pre-Processing", "PrePro", new nmiCtrlComboBox { Options = "Raw Value:0;Min Value:1;Max Value:2;Average:3", ParentFld = 260, TileWidth = 6, DefaultValue = "0" }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.Number, 265, 2, 0xC0, "PrePro Window", "PreProTime", new nmiCtrlNumber { ParentFld = 260, TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.SingleEnded, 216, 2, 0x0, "Match Pattern", nameof(ValueMatchPattern), new nmiCtrlSingleEnded { ParentFld = 200, TileWidth = 6 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.SingleEnded, 217, 2, 0x0, "Filter Pattern", nameof(ValueFilterPattern), new nmiCtrlSingleEnded { ParentFld = 200, TileWidth = 6 }); if (TheCommonUtils.CBool(TheBaseAssets.MySettings.GetSetting("RedPill"))) { var t = TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.TileButton, 266, 2, 0xC0, "Test", null, new nmiCtrlTileButton { NoTE = true, Background = "transparent", TileWidth = 3, TileHeight = 1 }); t.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "hakko", (sender, para) => { cdeP tRW = GetProperty("RawValue", true); cdeP.SetSafePropertyNumber(tRW, "StateSensorMinValue", TheCommonUtils.GetRandomUInt(0, 100)); TheThing.SetSafePropertyNumber(MyBaseThing, "[RawValue].[StateSensorAverage]", TheCommonUtils.GetRandomUInt(0, 100)); }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.Number, 267, 2, 0xc0, "Average Value", "[RawValue].[StateSensorAverage]", new nmiCtrlNumber { TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.Number, 268, 2, 0xc0, "Min Value", "[RawValue].[StateSensorMinValue]", new nmiCtrlNumber { TileWidth = 3 }); } return(true); }
// 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; } }
private void SinkUpdateStorage(TheFieldInfo arg1, cdeP arg2) { TheBaseAssets.MySettings.SetSetting("UseStorageForThingRegistry", TheCommonUtils.CBool(arg2.Value).ToString()); }