public void DeclareSecurePropertyTest() { var testPW = "testpassword123YYY###$$$"; var testThing = new TheThing(); TheThing.SetSafePropertyString(testThing, "Password", testPW); var testPWReadNotEncrypted = TheThing.GetSafePropertyString(testThing, "Password"); Assert.AreSame(testPW, testPWReadNotEncrypted, "Failed to read ununecrypted property"); testThing.DeclareSecureProperty("Password", ePropertyTypes.TString); var testPWReadNotEncryptedObject = testThing.GetProperty("Password").Value; Assert.IsTrue(testPWReadNotEncryptedObject is string, $"Encrypted password is not of type string. Type: {testPWReadNotEncryptedObject.GetType()}"); var testPWReadObjectString = testPWReadNotEncryptedObject as string; Assert.AreNotSame(testPW, testPWReadObjectString, "Password not encrypted after transition from unsecure to secure property"); Assert.IsTrue((testPWReadNotEncryptedObject as string).StartsWith("&^CDESP1^&:"), "Encrypted string does not have expected encryption prefix"); var testPWReadDecryptedString = TheThing.GetSafePropertyString(testThing, "Password"); Assert.AreEqual(testPW, testPWReadDecryptedString, "Password not preserved after transition from unsecure to secure property"); }
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(); } }
public override bool Init() { if (!mIsInitStarted) { mIsInitStarted = true; MyBaseEngine.RegisterEvent(eEngineEvents.ShutdownEvent, OnShutdown); TheThing.SetSafePropertyBool(MyBaseThing, "IsConnected", false); IBaseEngine tBase = TheThingRegistry.GetBaseEngine(TheThing.GetSafePropertyString(MyBaseThing, "ISOLaterName"), true); if (tBase != null) { MyIsolator = tBase.GetISOLater() as Process; if (MyIsolator == null) { MyBaseThing.LastMessage = "Engine not isolated"; MyBaseThing.StatusLevel = 3; mIsInitCompleted = true; return(true); } MyBaseThing.LastMessage = "KPIs monitor ready"; MyBaseThing.StatusLevel = 1; if (TheThing.GetSafePropertyBool(MyBaseThing, "AutoConnect")) { Connect(); } } else { MyBaseThing.LastMessage = "Base Engine cloud not be located"; MyBaseThing.StatusLevel = 3; } mIsInitCompleted = true; } return(true); }
public void AddSpeedGauge(TheFormInfo tMyForm, int pFldNumber = 25000, int pParentFld = TheDefaultSensor.SensorGaugeGroup, bool IsHighGood = false) { string Plotband = ""; if (IsHighGood) { Plotband = $"PlotBand=[{{ \"from\": {TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorMinValue")}, \"to\": {TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorAverage")}, \"color\": \"#FF000088\" }}, {{ \"from\": {TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorAverage")}, \"to\": {TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorMaxValue")}, \"color\": \"#00FF0044\" }}]"; } else { Plotband = $"PlotBand=[{{ \"from\": {TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorMinValue")}, \"to\": {TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorAverage")}, \"color\": \"#00FF0088\" }}, {{ \"from\": {TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorAverage")}, \"to\": {TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorMaxValue")}, \"color\": \"#FF000044\" }}]"; } GaugeFld = TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.UserControl, pFldNumber, 0, 0, null, "QValue", new ThePropertyBag() { "ControlType=Speed Gauge", "NoTE=true", $"ParentFld={pParentFld}", "TileWidth=6", "TileHeight=3", $"MinValue={TheThing.GetSafePropertyNumber(MyBaseThing,"StateSensorMinValue")}", $"MaxValue={TheThing.GetSafePropertyNumber(MyBaseThing,"StateSensorMaxValue")}", $"SubTitle={TheThing.GetSafePropertyString(MyBaseThing, "StateSensorUnit")}", Plotband, $"SetSeries={{ \"name\": \"{TheThing.GetSafePropertyString(MyBaseThing, "StateSensorValueName")}\",\"data\": [{TheThing.GetSafePropertyNumber(MyBaseThing,"QValue")}],\"tooltip\": {{ \"valueSuffix\": \" {TheThing.GetSafePropertyString(MyBaseThing, "StateSensorUnit")}\"}}}}", $"Value={MyBaseThing.Value}" }); }
public override void DoInit() { base.DoInit(); IsActive = false; if (!string.IsNullOrEmpty(TheThing.GetSafePropertyString(MyBaseThing, "RealSensorThing")) && !string.IsNullOrEmpty(TheThing.GetSafePropertyString(MyBaseThing, "RealSensorProperty"))) { EngageMapper(); } }
/// <summary> /// If this is a service the SimplexProc event will be called when the C-DEngine receives a new event sent by a subscriber to this service /// </summary> /// <param name="pMsg">The Message to be Processed</param> private void ProcessServiceMessage(TheProcessMessage pMsg) { string[] cmd = pMsg.Message.TXT.Split(':'); switch (cmd[0]) //string 2 cases { case "WEBRELAY_RESPONSE": TheRequestData tState = TheCommonUtils.DeserializeJSONStringToObject <TheRequestData>(pMsg.Message.PLS); if (pMsg.Message.PLB != null && pMsg.Message.PLB.Length > 0) { tState.ResponseBuffer = pMsg.Message.PLB; } tState.RequestUri = new Uri(tState.RequestUriString); //tState.SessionState = new TheSessionState() { SScopeID = pMsg.SID }; sinkResults(tState); break; case "WEBRELAY_REQUEST": TheRequestData tData = TheCommonUtils.DeserializeJSONStringToObject <TheRequestData>(pMsg.Message.PLS); if (tData != null) { tData.RequestUri = new Uri(tData.RequestUriString); //tData.SessionState = new TheSessionState() { SScopeID = pMsg.SID }; if (pMsg.Message.PLB != null && pMsg.Message.PLB.Length > 0) { tData.PostData = pMsg.Message.PLB; } tData.CookieObject = pMsg.Message; ReadHttpPage(tData, tData.SessionState.ARApp, null, sinkProcessResponse); //InterceptHttpRequest(tData,tData.SessionState.ARApp); } break; case "WEBRELAY_REQUESTWRA": TSM tTSM = new TSM(); List <TheThing> webApps = TheThingRegistry.GetThingsOfEngine(MyBaseEngine.GetEngineName()); foreach (TheThing tApp in webApps) { if (tApp.Address.Equals(pMsg.Message.PLS)) { tTSM.PLS = $"/CDEWRA{tApp.cdeMID}" + TheThing.GetSafePropertyString(tApp, "HomePage"); break; } } if (!string.IsNullOrEmpty(tTSM.PLS)) { string[] org = pMsg.Message.ORG.Split(':'); TheThing senderThing = TheThingRegistry.GetThingByMID(TheCommonUtils.CGuid(org[1]), true); IBaseEngine senderEngine = TheThingRegistry.GetBaseEngine(senderThing, true); tTSM.ENG = senderEngine.GetEngineName(); tTSM.TXT = "RESPONSEWRA"; TheCommCore.PublishToOriginator(pMsg.Message, tTSM, true); } break; } }
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); }
public override void DoInit() { base.RegisterEvent("HistorianReady", sinkHistReady2); TheThing.SetSafePropertyString(MyBaseThing, "ReportCategory", "..Virtual Sensor"); base.DoInit(); MyBaseThing.LastMessage = "Sensor ready"; if (!string.IsNullOrEmpty(TheThing.GetSafePropertyString(MyBaseThing, "RealSensorThing")) && !string.IsNullOrEmpty(TheThing.GetSafePropertyString(MyBaseThing, "RealSensorProperty"))) { EngageMapper(); } }
void sinkUpdateUX2(cdeP prop) { string Plotband; if (TheThing.GetSafePropertyBool(MyBaseThing, "IsLowAlarm")) { Plotband = $"SubTitle={TheThing.GetSafePropertyString(MyBaseThing, "StateSensorUnit")}:;:PlotBand=[{{ \"from\": {TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorMinValue")}, \"to\": {TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorAverage")}, \"color\": \"#FF000088\" }}, {{ \"from\": {TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorAverage")}, \"to\": {TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorMaxValue")}, \"color\": \"#00FF0044\" }}]"; } else { Plotband = $"SubTitle={TheThing.GetSafePropertyString(MyBaseThing, "StateSensorUnit")}:;:PlotBand=[{{ \"from\": {TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorMinValue")}, \"to\": {TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorAverage")}, \"color\": \"#00FF0088\" }}, {{ \"from\": {TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorAverage")}, \"to\": {TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorMaxValue")}, \"color\": \"#FF000044\" }}]"; } GaugeFld?.SetUXProperty(Guid.Empty, Plotband); }
private void RemoveTrigger(TheRule tRule, bool DoForce) { if (TheCDEngines.MyThingEngine == null || !TheBaseAssets.MasterSwitch) { return; } if (tRule.IsRuleActive || DoForce) { if (TheThingRegistry.HasThingsWithFunc(MyBaseEngine.GetEngineName(), s => s.cdeMID != tRule.GetBaseThing().cdeMID&& TheThing.GetSafePropertyString(s, "TriggerObject") == tRule.TriggerObject && TheThing.GetSafePropertyBool(s, "IsRuleActive"))) { return; } switch (tRule.TriggerObjectType) { default: TheThing tTriggerThing = TheThingRegistry.GetThingByMID("*", TheCommonUtils.CGuid(tRule.TriggerObject)); if (tTriggerThing != null) { cdeP tProp = tTriggerThing.GetProperty(tRule.TriggerProperty); if (tProp != null) { tProp.UnregisterEvent(eThingEvents.PropertyChanged, sinkRuleAction); } } break; case "CDE_ENGINE": TheThing tBase = TheThingRegistry.GetBaseEngineAsThing(tRule.TriggerObject); if (tBase != null) { tBase.UnregisterEvent(eEngineEvents.IncomingMessage, sinkRuleIncoming); } break; case "CDE_EVENTFIRED": TheThing tBaseE = TheThingRegistry.GetThingByID("*", tRule.TriggerObject); if (tBaseE != null) { tBaseE.UnregisterEvent(tRule.TriggerProperty, sinkRuleThingEvent); } break; } tRule.IsRuleActive = false; tRule.IsRuleRunning = false; tRule.IsRuleWaiting = true; } }
void sinkFileReceived(ICDEThing pThing, object pFileName) { TheProcessMessage pMsg = pFileName as TheProcessMessage; if (pMsg?.Message == null) { return; } var tIm = TheThing.GetSafePropertyString(MyBaseThing, "CurrentImage"); if (!string.IsNullOrEmpty(tIm) && tIm != pMsg.Message.TXT) { File.Delete(TheCommonUtils.cdeFixupFileName(tIm)); } TheThing.SetSafePropertyString(MyBaseThing, "CurrentImage", pMsg.Message.TXT); TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", string.Format("Update to Image-File ({0}) received!", pMsg.Message.TXT))); }
void sinkUpdateUX(cdeP prop) { if (prop.Name == "StateSensorValueName") { ValueField?.SetUXProperty(Guid.Empty, $"Title={TheThing.GetSafePropertyString(MyBaseThing, "StateSensorValueName")}"); } if (prop.Name == "StateSensorMaxValue" || prop.Name == "StateSensorMinValue" || prop.Name == "StateSensorSteps") { LiveChartFld?.SetUXProperty(Guid.Empty, $"MaxValue={TheThing.GetSafePropertyString(MyBaseThing, "StateSensorMaxValue")}:;:MinValue={TheThing.GetSafePropertyString(MyBaseThing, "StateSensorMinValue")}"); GaugeFld?.SetUXProperty(Guid.Empty, $"MaxValue={TheThing.GetSafePropertyString(MyBaseThing, "StateSensorMaxValue")}:;:MinValue={TheThing.GetSafePropertyString(MyBaseThing, "StateSensorMinValue")}"); if (mBucket != null) { mBucket = new TheBucketChart <T>((int)TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorMinValue"), (int)TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorMaxValue"), (int)TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorSteps"), true); BucketChartFld?.SetUXProperty(Guid.Empty, $"XAxis={{ \"categories\": {mBucket.GetBuckets()} }}"); TheThing.SetSafePropertyString(MyBaseThing, "BucketChart", mBucket.GetBucketArray()); } } }
void sinkThingWasRegistered(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 = new TheRule(pThing, this) { Parent = MyBaseThing.ID }; tRule.RegisterEvent(eEngineEvents.ThingUpdated, sinkUpdated); RegisterRule(tRule); ActivateRules(); } }
public bool Init() { if (mIsInitCalled) { return(false); } mIsInitCalled = true; MyBaseThing.RegisterEvent(eEngineEvents.IncomingMessage, HandleMessage); if (TheThing.GetSafePropertyString(MyBaseThing, "VisitorCount") == "") { VisitorCount = 0; } MyNodePrintsName = $"NodePrints{TheThing.GetSafeThingGuid(MyBaseThing, "NodePrints")}"; TheBaseEngine.WaitForStorageReadiness(OnStorageReady, true); MyBaseThing.SetPublishThrottle(15000); TheCommCore.RegisterRelayEvents(null, null, sinkNewConnection); if (MyVisitorLog == null) { MyVisitorLog = new TheVisitorLog(MyBaseThing); } TheQueuedSenderRegistry.RegisterHealthTimer(GetSystemInfo); TheCDEngines.MyNMIService.RegisterEvent("NMI_MY_LOCATION", (sender2, para) => { var t = para as TheNMILocationInfo; if (t != null) { var NewEntry = new TheVisitorLogData { cdeN = t.cdeN, latitude = t.Latitude, longitude = t.Longitude, ip = t.ClientInfo?.UserID.ToString(), LastVisit = DateTimeOffset.Now, Description = t.ClientInfo != null && t.ClientInfo.UserID != Guid.Empty ? TheUserManager.GetUserFullName(t.ClientInfo.UserID) : "Unknown user" }; MyVisitorLog.LogVisitor(NewEntry); myGoogleMap?.SetUXProperty(Guid.Empty, $"AddMarker={TheCommonUtils.SerializeObjectToJSONString(NewEntry)}"); } }); TheCommCore.MyHttpService.RegisterHttpInterceptorB4("/cdemeshinfo.aspx", sinkRequestMeshInfo); MyBaseEngine.ProcessInitialized(); MyBaseEngine.SetEngineReadiness(true, null); MyBaseEngine.SetStatusLevel(1); mIsInitialized = true; return(true); }
public static bool CopyStateSensorInfo(TheThing pBaseThing) { if (pBaseThing == null) { return(false); } var t = TheThingRegistry.GetThingByMID("*", TheThing.GetSafePropertyGuid(pBaseThing, "RealSensorThing")); if (t != null && TheThing.GetSafePropertyBool(t, "IsStateSensor")) { if (string.IsNullOrEmpty(TheThing.GetSafePropertyString(pBaseThing, "StateSensorType"))) { TheThing.SetSafePropertyString(pBaseThing, "StateSensorType", TheThing.GetSafePropertyString(t, "StateSensorType")); } if (string.IsNullOrEmpty(TheThing.GetSafePropertyString(pBaseThing, "StateSensorUnit"))) { TheThing.SetSafePropertyString(pBaseThing, "StateSensorUnit", TheThing.GetSafePropertyString(t, "StateSensorUnit")); } if (string.IsNullOrEmpty(TheThing.GetSafePropertyString(pBaseThing, "StateSensorValueName"))) { TheThing.SetSafePropertyString(pBaseThing, "StateSensorValueName", TheThing.GetSafePropertyString(t, "StateSensorValueName")); } if (pBaseThing.GetProperty("StateSensorAverage") == null) { TheThing.SetSafePropertyNumber(pBaseThing, "StateSensorAverage", TheThing.GetSafePropertyNumber(t, "StateSensorAverage")); } if (pBaseThing.GetProperty("StateSensorMinValue") == null) { TheThing.SetSafePropertyNumber(pBaseThing, "StateSensorMinValue", TheThing.GetSafePropertyNumber(t, "StateSensorMinValue")); } if (pBaseThing.GetProperty("StateSensorMaxValue") == null) { TheThing.SetSafePropertyNumber(pBaseThing, "StateSensorMaxValue", TheThing.GetSafePropertyNumber(t, "StateSensorMaxValue")); } if (string.IsNullOrEmpty(TheThing.GetSafePropertyString(pBaseThing, "StateSensorIcon"))) { TheThing.SetSafePropertyString(pBaseThing, "StateSensorIcon", TheThing.GetSafePropertyString(t, "StateSensorIcon")); } return(true); } return(false); }
public override void Connect(TheProcessMessage pMsg) { if (IsConnected) { return; } IsConnected = true; MyBaseThing.StatusLevel = 1; MyBaseThing.LastMessage = $"Connected to Logger at {DateTimeOffset.Now}"; mLogFilePath = Address; mMaxLogFileSize = (int)TheThing.GetSafePropertyNumber(MyBaseThing, "MaxLogFileSize"); mWriteToConsole = TheThing.GetSafePropertyBool(MyBaseThing, "WriteToConsole"); MyCurLog = TheThing.GetSafePropertyString(MyBaseThing, "LogFilePath"); mLogFileDate = TheThing.GetSafePropertyDate(MyBaseThing, "LogFileDate"); if (string.IsNullOrEmpty(MyCurLog) || (mLogFileDate != DateTimeOffset.MinValue && mLogFileDate.Day != DateTimeOffset.Now.Day)) { LogFilePath = MyCurLog = TheCommonUtils.cdeFixupFileName(mLogFilePath + string.Format("\\LOG_{0:yyyMMdd_HHmmss}.txt", DateTime.Now)); LogFileDate = mLogFileDate = DateTimeOffset.Now; } TheCommonUtils.CreateDirectories(MyCurLog); TheCDEngines.MyContentEngine.RegisterEvent(eEngineEvents.NewEventLogEntry, sinkNewEvent); #if !CDE_NET4 && !CDE_NET35 if (TheBaseAssets.MyCmdArgs?.ContainsKey("CreateEventLog") != true) { // CODE REVIEW: What is the purpose of this export? var pipelineConfig = MyBaseThing.GetThingPipelineConfigurationAsync(false).Result; if (pipelineConfig != null) { var tWrite = TheCommonUtils.SerializeObjectToJSONString(pipelineConfig); TheCommonUtils.CreateDirectories(TheCommonUtils.cdeFixupFileName($"\\ConfigTemplates\\{MyBaseThing.FriendlyName}.cdeConfig")); using (System.IO.StreamWriter fs = new System.IO.StreamWriter(TheCommonUtils.cdeFixupFileName($"\\ConfigTemplates\\{MyBaseThing.FriendlyName}.cdeConfig"), false)) { fs.Write(tWrite); } } } #endif }
private void WriteAggregatedConditionsToProperty(ICDEThing tEventHost, DateTimeOffset time) { var currentConditionsAsJson = TheCommonUtils.SerializeObjectToJSONString(_currentConditionsByConditionId.Values.OrderByDescending(evnt => { if (evnt.TryGetValue("Time", out var evntTime)) { return(evntTime); } return(null); }).ToList()); if (TheThing.GetSafePropertyString(tEventHost.GetBaseThing(), DisplayName) != currentConditionsAsJson) { TheBaseAssets.MySYSLOG.WriteToLog(78102, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(MyOPCServer.GetBaseThing().EngineName, $"Updated current events {_currentConditionsByConditionId.Count} - {currentConditionsAsJson}", eMsgLevel.l6_Debug, $"{DisplayName} {GetNodeIdForLogs()} {EventInfo.AggregateRetainedConditions}")); // Using publish time because the event timestamps could be way in the past (i.e. when a recent event just was removed) tEventHost.GetBaseThing().SetProperty(DisplayName, currentConditionsAsJson, time); } else { TheBaseAssets.MySYSLOG.WriteToLog(78102, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(MyOPCServer.GetBaseThing().EngineName, $"No change to current events {_currentConditionsByConditionId.Count} - {currentConditionsAsJson}", eMsgLevel.l6_Debug, $"{DisplayName} {GetNodeIdForLogs()} {EventInfo.AggregateRetainedConditions}")); } }
protected override void SensorCyclicCalc(long timer) { base.SensorCyclicCalc(timer); if ((timer % PingFreq) != 0) { return; } if (IsInCyclic) { return; } IsInCyclic = true; PingFreq = (int)TheThing.GetSafePropertyNumber(MyBaseEngine.GetBaseThing(), "CalcAggregation"); if (PingFreq == 0) { PingFreq = 30; } var tVals = MyHistorian?.GetValues(); //TODO: This returns null if the SensorHistorian is in the SQL Server. We need to think about what we do here! if (tVals?.Any() == true) { string tValues = TheThing.GetSafePropertyString(MyBaseThing, "HistoryFields"); if (tValues.Contains("QValue_Ave")) { TheThing.SetSafePropertyNumber(MyBaseThing, "QValue_Ave", tVals.Average(w => w.PB.ContainsKey("QValue") ? TheCommonUtils.CDbl(w.PB["QValue"]) : 0)); } if (tValues.Contains("QValue_Min")) { TheThing.SetSafePropertyNumber(MyBaseThing, "QValue_Min", tVals.Min(w => w.PB.ContainsKey("QValue") ? TheCommonUtils.CDbl(w.PB["QValue"]) : 0)); } if (tValues.Contains("QValue_Max")) { TheThing.SetSafePropertyNumber(MyBaseThing, "QValue_Max", tVals.Max(w => w.PB.ContainsKey("QValue") ? TheCommonUtils.CDbl(w.PB["QValue"]) : 0)); } } IsInCyclic = false; }
string[] GetLabelValues(TheThing tThing, string[] labelNames) { var labelValues = new string[labelNames.Length]; int i = 0; foreach (var labelName in labelNames) { if (labelName == "cdeN" || labelName == "NodeId") { labelValues[i] = GetValidLabelValue(tThing.cdeN.ToString()); } else if (labelName == "cdeMID") { labelValues[i] = GetValidLabelValue(tThing.cdeMID.ToString()); } else { labelValues[i] = GetValidLabelValue(TheThing.GetSafePropertyString(tThing, labelName)); } i++; } return(labelValues); }
void sinkRuleIncoming(ICDEThing sender, object pIncoming) { TheProcessMessage pMsg = pIncoming as TheProcessMessage; if (pMsg == null || pMsg.Message == null) { return; } //System.Diagnostics.Debug.WriteLine(string.Format("{0} {1} {2}", pMsg.Message.ENG, pMsg.Message.TXT, pMsg.Message.PLS)); List <TheThing> tList = TheThingRegistry.GetThingsByFunc("*", s => TheThing.GetSafePropertyString(s, "TriggerObject") == pMsg.Message.ENG); if (tList != null) { foreach (TheThing tThing in tList) { TheRule tRule = tThing.GetObject() as TheRule; if (tRule == null || !tRule.IsRuleActive) { continue; } if (tRule.TriggerStartTime > DateTimeOffset.Now) { continue; } if (tRule.TriggerEndTime < DateTimeOffset.Now) { RemoveTrigger(tRule, false); continue; } if (pMsg.Message.TXT.StartsWith(tRule.TriggerProperty)) { tRule.RuleTrigger(pMsg.Message.PLS); } } } }
private void EngageMapper() { TheThingRegistry.UnmapPropertyMapper(mRealThingGuid); mRealThingGuid = TheThingRegistry.PropertyMapper(TheThing.GetSafePropertyGuid(MyBaseThing, "RealSensorThing"), TheThing.GetSafePropertyString(MyBaseThing, "RealSensorProperty"), MyBaseThing.cdeMID, "RawValue", false); if (mRealThingGuid == Guid.Empty) { MyBaseThing.StatusLevel = 0; MyBaseThing.LastMessage = "Mapper not active"; IsActive = false; } else { MyBaseThing.LastMessage = "Mapper engaged"; MyBaseThing.StatusLevel = 1; TheDefaultSensor.CopyStateSensorInfo(MyBaseThing); SummaryForm?.SetUXProperty(Guid.Empty, string.Format("Background={0}", TheNMIEngine.GetStatusColor(MyBaseThing.StatusLevel))); IsActive = true; } }
void sinkPrePro(cdeP pProp) { if (TheThing.GetSafePropertyString(MyBaseThing, "StateSensorType") != "analog") { SetProperty("Value", pProp.Value); return; } int prepro = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(MyBaseThing, "PrePro")); int preprotime = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(MyBaseThing, "PreProTime")); double valScale = TheCommonUtils.CDbl(TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorScaleFactor")); var pPropString = TheCommonUtils.CStr(pProp); if (!string.IsNullOrEmpty(ValueFilterPattern)) { try { if (ValueFilterPattern != filterPattern || filterRegex == null) { #if !CDE_NET4 filterRegex = new Regex(ValueFilterPattern, RegexOptions.Compiled | RegexOptions.CultureInvariant, new TimeSpan(0, 0, 5)); #else filterRegex = new Regex(ValueFilterPattern, RegexOptions.Compiled | RegexOptions.CultureInvariant); #endif filterPattern = ValueFilterPattern; } pPropString = filterRegex.Match(pPropString).Value; } catch (Exception e) { LastMessage = $"Error applying filter pattern: {e.Message}"; return; // CODE REVIEW: Or ist it better to treat this as 0, so other time processing doesn not get confused? } } double pValue; if (!string.IsNullOrEmpty(ValueMatchPattern)) { try { if (ValueMatchPattern != matchPattern || matchRegex == null) { #if !CDE_NET4 matchRegex = new Regex(ValueMatchPattern, RegexOptions.Compiled | RegexOptions.CultureInvariant, new TimeSpan(0, 0, 5)); #else matchRegex = new Regex(ValueMatchPattern, RegexOptions.Compiled | RegexOptions.CultureInvariant); #endif matchPattern = ValueMatchPattern; } if (matchRegex.IsMatch(pProp.ToString())) { pValue = 1; } else { pValue = 0; } } catch (Exception e) { LastMessage = $"Error applying match pattern: {e.Message}"; return; // CODE REVIEW: Or ist it better to treat this as 0, so other time processing doesn not get confused? } } else { pValue = TheCommonUtils.CDbl(pPropString); } if (valScale != 0) { pValue /= valScale; } if (pValue < 0 && TheThing.GetSafePropertyBool(MyBaseThing, "StateSensorIsAbs")) { pValue = Math.Abs(pValue); } if (preprotime > 0 && prepro > 0) { if (pValue < min) { min = pValue; } if (pValue > max) { max = pValue; } ave += pValue; aveCnt++; if (DateTimeOffset.Now.Subtract(lastWrite).TotalSeconds < preprotime) { return; } lastWrite = DateTimeOffset.Now; switch (prepro) { case 1: if (min == double.MaxValue) { return; } pValue = min; min = double.MaxValue; break; case 2: if (max == double.MinValue) { return; } pValue = max; min = double.MinValue; break; case 3: if (aveCnt == 0) { return; } pValue = ave / aveCnt; ave = 0; aveCnt = 0; break; } } if (GetProperty("StateSensorDigits", false) != null) { int tDigits = (int)TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorDigits"); SetProperty("Value", decimal.Round((decimal)pValue, tDigits, MidpointRounding.AwayFromZero)); } else { SetProperty("Value", pValue); } }
internal static TheScreenInfo GenerateLiveScreen(Guid pScreenId, TheClientInfo tClientInfo) // Guid pUserGuid, int lcid, int pFlag) { if (TheCDEngines.MyNMIService == null) { return(null); } TheScreenInfo tInfo = new TheScreenInfo { cdeMID = pScreenId, MyDashboard = null, MyStorageInfo = new List <TheFormInfo>(), MyStorageMeta = new cdeConcurrentDictionary <string, TheFormInfo>(), MyStorageMirror = new List <object>(), MyDashPanels = new List <TheDashPanelInfo>() }; TheThing tLiveForm = TheThingRegistry.GetThingByMID("*", pScreenId); if (tLiveForm == null || !TheUserManager.HasUserAccess(tClientInfo.UserID, tLiveForm.cdeA)) { return(null); //V3.1: BUG 126 - could lead to racing condition. TODO: Revisit later //TheFormInfo tI = new TheFormInfo(tLiveForm) { FormTitle = (tLiveForm == null ? "Form not Found!" : "Access Denied!") }; //tI.TargetElement = pScreenId.ToString(); //tI.AssociatedClassName = pScreenId.ToString(); //tInfo.MyStorageInfo.Add(tI); //tI.FormFields = new List<TheFieldInfo>(); //TheFieldInfo tFldInfo = new TheFieldInfo(null, null, 10, 0, 0); //tFldInfo.Type = eFieldType.SmartLabel; //tFldInfo.Header = (tLiveForm == null ? "This Form was defined but has not Meta-Data associated with it." : "You do not have the required access permissions!"); //tI.FormFields.Add(tFldInfo); //return tInfo; } string tFormName = TheThing.GetSafePropertyString(tLiveForm, "FriendlyName"); List <TheThing> tFields = TheThingRegistry.GetThingsByFunc("*", s => s.cdeO == TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID && TheThing.GetSafePropertyString(s, "FormName") == tFormName && TheThing.GetSafePropertyBool(s, "IsLiveTag") && (s.UID == Guid.Empty || s.UID == tClientInfo.UserID)); if (tFields != null && tFields.Any()) { string tFormTitle = TheThing.GetSafePropertyString(tLiveForm, "FormTitle"); if (string.IsNullOrEmpty(tFormTitle)) { tFormTitle = tFormName; } TheFormInfo tI = new TheFormInfo(tLiveForm) { FormTitle = tFormTitle, TargetElement = pScreenId.ToString(), DefaultView = eDefaultView.Form, TileWidth = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(tLiveForm, "TileWidth")), TileHeight = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(tLiveForm, "TileHeight")), IsUsingAbsolute = TheThing.GetSafePropertyBool(tLiveForm, "IsAbsolute"), AssociatedClassName = pScreenId.ToString() }; tInfo.MyStorageInfo.Add(tI); tI.FormFields = new List <TheFieldInfo>(); int fldNo = 10; foreach (TheThing tTh in tFields) { int tfldNo = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(tTh, "FldOrder")); if (tfldNo == 0) { tfldNo = fldNo; } int tFlags = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(tTh, "Flags")); cdeP ValProp = tTh.GetProperty("Value"); bool IsNewFld = true; TheFieldInfo tFldInfo = TheNMIEngine.GetFieldById(TheThing.GetSafePropertyGuid(tTh, "FldID")); if (tFldInfo == null) { tFldInfo = new TheFieldInfo(tTh, "Value", tfldNo, tFlags & 0xFFBF, tTh.GetBaseThing().cdeA); } else { tFldInfo.FldOrder = tfldNo; tFldInfo.Flags = tFlags; IsNewFld = false; } if (tFldInfo.PropertyBag == null) { tFldInfo.PropertyBag = new ThePropertyBag(); } ThePropertyBag.PropBagUpdateValue(tFldInfo.PropertyBag, "IsOnTheFly", "=", "True"); ThePropertyBag.PropBagUpdateValue(tFldInfo.PropertyBag, "UXID", "=", $"{tTh.cdeMID}"); tFldInfo.Header = tTh.FriendlyName; RegisterNMISubscription(tClientInfo, "Value", tFldInfo); string tControlType = TheThing.GetSafePropertyString(tTh, "ControlType"); if (TheCommonUtils.CInt(tControlType) == 0 && !TheCommonUtils.IsNullOrWhiteSpace(tControlType)) { tFldInfo.Type = eFieldType.UserControl; RegisterFieldEvents(tTh, ValProp, IsNewFld, tFldInfo, tControlType); } else { tFldInfo.Type = (eFieldType)TheCommonUtils.CInt(tControlType); } tFldInfo.DefaultValue = ValProp?.ToString(); tFldInfo.TileWidth = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(tTh, "TileWidth")); tFldInfo.TileHeight = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(tTh, "TileHeight")); foreach (cdeP prop in tTh.GetNMIProperties()) { ThePropertyBag.PropBagUpdateValue(tFldInfo.PropertyBag, prop.Name, "=", prop.ToString()); } if (tFldInfo.Type == eFieldType.TileButton) { tTh.DeclareNMIProperty("IsDown", ePropertyTypes.TBoolean); ThePropertyBag.PropBagUpdateValue(tFldInfo.PropertyBag, "EnableTap", "=", "True"); tFldInfo.RegisterUXEvent(tTh, eUXEvents.OnPropertyChanged, "IsDown", (pThing, pObj) => { if (!(pObj is TheProcessMessage pMsg) || pMsg.Message == null) { return; } TheThing.SetSafePropertyBool(pThing, "IsDown", TheCommonUtils.CBool(pMsg.Message.PLS)); });
public virtual void DoCreateUX(TheFormInfo tMyForm, ThePropertyBag pChartControlBag = null) { var tQVN = TheThing.GetSafePropertyString(MyBaseThing, "StateSensorValueName"); //var tQV = TheThing.GetSafePropertyString(MyBaseThing, "StateSensorValue"); var tQU = TheThing.GetSafePropertyString(MyBaseThing, "StateSensorUnit"); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.TileGroup, 12460, 0, 0, null, null, new nmiCtrlTileGroup { ParentFld = 12011, TileWidth = 6, TileHeight = 3 }); ValueField = TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SmartLabel, 12461, 0, 0, $"{tQVN}", "QValue", new nmiCtrlSmartLabel { ParentFld = 12460, TileWidth = 6, TileFactorY = 2, TileHeight = 3, FontSize = 96 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SmartLabel, 12462, 0, 0, $"{tQU}", "StateSensorUnit", new nmiCtrlSmartLabel { ParentFld = 12460, NoTE = true, TileWidth = 6, TileFactorY = 2, TileHeight = 1, FontSize = 18, HorizontalAlignment = "right", VerticalAlignment = "top" }); var tG = TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.TileGroup, 12000, 0, 0, null, null, new nmiCtrlTileGroup() { TileWidth = 18 }); tG.AddOrUpdatePlatformBag(eWebPlatform.Mobile, new nmiPlatBag { MaxTileWidth = 6 }); tG.AddOrUpdatePlatformBag(eWebPlatform.HoloLens, new nmiPlatBag { MaxTileWidth = 12 }); tG.AddOrUpdatePlatformBag(eWebPlatform.TeslaXS, new nmiPlatBag { MaxTileWidth = 12 }); string pSensorPicSource = TheThing.GetSafePropertyString(MyBaseThing, "StateSensorLogo"); if (string.IsNullOrEmpty(pSensorPicSource)) { pSensorPicSource = "SENSORS/Images/SensorLogo_156x78.png"; } TheSensorNMI.CreatePerformanceHeader(MyBaseThing, tMyForm, 12010, 12000, pSensorPicSource); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.CollapsibleGroup, 12030, 2, 0, $"Live Chart", null, new nmiCtrlCollapsibleGroup() { ParentFld = 12000, TileWidth = 6, NoTE = true, Background = "transparent", Foreground = "black", FontSize = 10, IsSmall = true, HorizontalAlignment = "left" }); //LabelClassName = "cdeTileGroupHeaderSmall SensorGroupLabel", LabelForeground = "white", LiveChartFld = TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.UserControl, 12031, 2, 0, $"{tQVN} Chart", "QValue", new ThePropertyBag() { "ControlType=Live Chart", "ParentFld=12030", "NoTE=true", $"Title={tQVN}", "SeriesNames=[{ \"name\":\"Current Temp\", \"lineColor\":\"rgba(0,255,0,0.39)\"}, { \"name\":\"Max Temp\", \"lineColor\":\"rgba(0,0,255,0.64)\"}]", "TileWidth=6", "TileHeight=4", "Speed=500", $"MaxValue={TheThing.GetSafePropertyNumber(MyBaseThing, "StateSensorMaxValue")}", "Delay=0", "Background=rgba(0,0,0,0.01)" }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.CollapsibleGroup, 12040, 2, 0, "Distribution Curve", null, new nmiCtrlCollapsibleGroup() { ParentFld = 12000, TileWidth = 6, NoTE = true, Background = "transparent", Foreground = "black", FontSize = 10, IsSmall = true, HorizontalAlignment = "left" }); //LabelClassName = "cdeTileGroupHeaderSmall SensorGroupLabel", LabelForeground = "white", BucketChartFld = TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.UserControl, 12041, 0, 0, $"{tQVN} Chart", "BucketChart", new ThePropertyBag() { "NoTE=true", "ParentFld=12040", $"SubTitle={tQVN}", $"SetSeries={{\"name\": \"{tQVN}\"}}", "TileWidth=6", "TileHeight=4", "ControlType=Stack Chart", $"XAxis={{ \"categories\": {mBucket?.GetBuckets()} }}", $"iValue={mBucket?.GetBucketArray()}" }); TheSensorNMI.CreateDeviceDetails(MyBaseThing, tMyForm, 12060, 12000, null); // new List<string> { $"{tQVN},{tQV}" }); if (pChartControlBag == null) { pChartControlBag = new ThePropertyBag { "DoClose=true" } } ; else { ThePropertyBag.PropBagUpdateValue(pChartControlBag, "DoClose", "=", "true"); } var tt = MyHistorian?.CreateHistoryTrendUX(tMyForm, 12300, 12000, $"{tQVN} Trend", $"{tQVN} Trend", TheThing.GetSafePropertyString(MyBaseThing, "HistoryFields"), false, false, pChartControlBag); }
public virtual bool DoCreateUX() { MyEditorForm = new TheFormInfo(MyBaseThing) { DefaultView = eDefaultView.Form, PropertyBag = new ThePropertyBag { "MaxTileWidth=6", "HideCaption=true", "AllowDrag=true" } }; MyEditorForm.ModelID = "NMIEditor"; TheDashboardInfo tDash = TheNMIEngine.GetDashboardById(TheNMIHtml5RT.eNMIDashboard); MyEditorDashIcon = TheNMIEngine.AddFormToThingUX(tDash, MyBaseThing, MyEditorForm, "CMyForm", "NMI Control Editor", 1, 0x89, 0x80, "NMI", null, new ThePropertyBag() { "RenderTarget=cdeInSideBarRight", "NeverHide=true" }); //"mAllowDrag=true", "nVisibility=false", MySampleControl = TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.SingleEnded, 3, 2, MyBaseThing.cdeA, "CurrentValue", "Value", null); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.TileGroup, 9, 0, 0, null, null, new nmiCtrlTileGroup { TileWidth = 7, TileHeight = 1, TileFactorY = 2 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.TileButton, 10, 2, 0, "Basic", null, new nmiCtrlTileButton { ParentFld = 9, OnClick = "GRP:NMIP:Basic", TileWidth = 1, TileHeight = 1, TileFactorY = 2, NoTE = true, ClassName = "cdeTransitButton" }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.TileButton, 20, 2, 0, "Screen", null, new nmiCtrlTileButton { ParentFld = 9, OnClick = "GRP:NMIP:Screen", TileWidth = 1, TileHeight = 1, TileFactorY = 2, NoTE = true, ClassName = "cdeTransitButton" }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.TileButton, 30, 2, 0, "All", null, new nmiCtrlTileButton { ParentFld = 9, OnClick = "GRP:NMIP:All", TileWidth = 1, TileHeight = 1, TileFactorY = 2, NoTE = true, ClassName = "cdeTransitButton" }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.TileButton, 40, 2, 0, "Source", null, new nmiCtrlTileButton { ParentFld = 9, OnClick = "GRP:NMIP:Source", TileWidth = 1, TileHeight = 1, TileFactorY = 2, NoTE = true, ClassName = "cdeTransitButton" }); //TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.TileButton, 50, 2, 0, "Compounds", null, new nmiCtrlTileButton { OnClick = "GRP:Cate:5", TileWidth = 2, TileHeight = 1, TileFactorY = 2, NoTE = true, ClassName = "cdeTransitButton" }); //TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.TileButton, 60, 2, 0, "Gauges", null, new nmiCtrlTileButton { OnClick = "GRP:Cate:6", TileWidth = 2, TileHeight = 1, TileFactorY = 2, NoTE = true, ClassName = "cdeTransitButton" }); TheFieldInfo mSendbutton = TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.TileButton, 70, 2, 0x80, "Reload", false, "", null, new nmiCtrlTileButton() { ParentFld = 9, TileWidth = 2, NoTE = true, TileFactorY = 2, ClassName = "cdeGoodActionButton" }); mSendbutton.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "", (pThing, pPara) => { TheProcessMessage pMsg = pPara as TheProcessMessage; if (pMsg?.Message == null) { return; } UpdateUx(pThing.GetBaseThing()); MyEditorForm.Reload(pMsg, tDash.cdeMID, true); }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.TileGroup, 1000, 2, 0x80, null, null, new nmiCtrlTileGroup() { Group = "NMIP:Basic" }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.ComboBox, 1010, 2, 0x80, "Control Type", "ControlType", new ThePropertyBag() { "Options=%RegisteredControlTypes%", "ParentFld=1000" }); GetProperty("ControlType", true).RegisterEvent(eThingEvents.PropertyChanged, (p) => { UpdateUx(MyBaseThing); }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.Number, 1020, 2, 0, "Tile Width", "TileWidth", new nmiCtrlNumber() { ParentFld = 1000, TileHeight = 1, TileFactorY = 1, DefaultValue = "6", TileWidth = 3 }); GetProperty("TileWidth", true).RegisterEvent(eThingEvents.PropertyChanged, (p) => { MySampleControl.SetUXProperty(Guid.Empty, "TileWidth= " + p.ToString()); }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.Number, 1030, 2, 0, "Tile Height", "TileHeight", new nmiCtrlNumber() { ParentFld = 1000, TileHeight = 1, TileFactorY = 1, DefaultValue = "1", TileWidth = 3 }); GetProperty("TileHeight", true).RegisterEvent(eThingEvents.PropertyChanged, (p) => { MySampleControl.SetUXProperty(Guid.Empty, "TileHeight= " + p.ToString()); }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.ComboBox, 1040, 2, 0, "Horizontal Alignment", "HorizontalAlignment", new nmiCtrlComboBox() { ParentFld = 1000, Options = ";left;center;right" }); GetProperty("HorizontalAlignment", true).RegisterEvent(eThingEvents.PropertyChanged, (p) => { MySampleControl.SetUXProperty(Guid.Empty, "HorizontalAlignment= " + p.ToString()); }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.ComboBox, 1050, 2, 0, "Class Name", "ClassName", new nmiCtrlComboBox() { ParentFld = 1000, Options = ";BlueWhite;GreenYellow;RedWhite" }); GetProperty("ClassName", true).RegisterEvent(eThingEvents.PropertyChanged, (p) => { MySampleControl.SetUXProperty(Guid.Empty, "ClassName= " + p.ToString()); }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.SingleEnded, 1060, 2, 0, "HelpText", "HelpText", new nmiCtrlSingleEnded() { ParentFld = 1000 }); GetProperty("HelpText", true).RegisterEvent(eThingEvents.PropertyChanged, (p) => { MySampleControl.SetUXProperty(Guid.Empty, "HelpText= " + p.ToString()); }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.ComboBox, 1070, 2, 0, "Opacity", "Opacity", new nmiCtrlComboBox() { ParentFld = 1000, Options = ";0.1;0.3;0.5;0.7;0.9;1.0" }); GetProperty("Opacity", true).RegisterEvent(eThingEvents.PropertyChanged, (p) => { MySampleControl.SetUXProperty(Guid.Empty, "Opacity= " + p.ToString()); }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.SingleCheck, 1080, 2, 0, "No TE", "NoTE", new nmiCtrlSingleCheck() { ParentFld = 1000 }); GetProperty("NoTE", true).RegisterEvent(eThingEvents.PropertyChanged, (p) => { MySampleControl.SetUXProperty(Guid.Empty, "NoTE= " + p.ToString()); }); //Screen Properties TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.TileGroup, 3000, 2, 0x80, null, null, new nmiCtrlTileGroup() { Group = "NMIP:Screen", Visibility = false }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.ComboOption, 3010, 2, 0x80, "NMI Screen", "FormName", new ThePropertyBag() { "Options=%GetLiveScreens%", "TileWidth=6", "TileHeight=1", "ParentFld=3000" }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.CheckField, 3020, 2, 0x80, "Flags", "Flags", new ThePropertyBag() { "Bits=6", "TileHeight=6", "TileFactorY=2", "ImageList=<span class='fa-stack'><i class='fa fa-stack-1x'></i><i class='fa fa-stack-2x'> </i></span>," + "<span class='fa-stack'><i class='fa fa-stack-1x'></i><i class='fa fa-stack-2x'> </i></span>," + "<span class='fa-stack'><i class='fa fa-stack-1x'></i><i class='fa fa-stack-2x text-danger' style='opacity:0.5'></i></span>," + "<span class='fa-stack'><i class='fa fa-stack-1x'></i><i class='fa fa-stack-2x text-danger' style='opacity:0.5'></i></span>," + "<span class='fa-stack'><i class='fa fa-stack-1x'></i><i class='fa fa-stack-2x text-danger' style='opacity:0.5'></i></span>," + "<span class='fa-stack'><i class='fa fa-stack-1x'></i><i class='fa fa-stack-2x text-danger' style='opacity:0.5'></i></span>", "ParentFld=3000" }).FldWidth = 1; //ALL Properties TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.TileGroup, 2000, 2, 0x80, null, null, new nmiCtrlTileGroup() { TileWidth = 6, Group = "NMIP:All", Visibility = false }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.Table, 2010, 0xA2, 0x80, "All Properties", "mypropertybag;1", new ThePropertyBag() { "NoTE=true", "TileHeight=4", "TileLeft=9", "TileTop=3", "TileWidth=6", "FldWidth=6", "ParentFld=2000" }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.SingleEnded, 2020, 0x0A, 0, "New Property Name", "ScratchName", new nmiCtrlSingleEnded() { ParentFld = 2000 }); TheFieldInfo tBut = TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.TileButton, 2040, 0x0A, 0, "Add Property", false, null, null, new nmiCtrlTileButton() { ParentFld = 2000, NoTE = true, ClassName = "cdeGoodActionButton" }); tBut.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "AddProp", (pThing, pObj) => { TheProcessMessage pMsg = pObj as TheProcessMessage; if (pMsg?.Message == null) { return; } string[] parts = pMsg.Message.PLS.Split(':'); TheThing tOrg = pThing.GetBaseThing(); // TheThingRegistry.GetThingByMID(MyBaseEngine.GetEngineName(), TheCommonUtils.CGuid(parts[2])); //if (tOrg == null) return; string tNewPropName = TheThing.GetSafePropertyString(tOrg, "ScratchName"); if (string.IsNullOrEmpty(tNewPropName)) { TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", "Please specify a new property name")); } else { if (tOrg.GetProperty(tNewPropName) != null) { TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", "Property already exists")); } else { tOrg.DeclareNMIProperty(tNewPropName, ePropertyTypes.TString); TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", "Property Added")); MyEditorForm.Reload(pMsg, false); } tOrg.SetProperty("ScratchName", ""); } }); //THING Connector TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.TileGroup, 5000, 2, 0x80, null, null, new nmiCtrlTileGroup() { TileWidth = 6, Group = "NMIP:Source", Visibility = false }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.ThingPicker, 5010, 2, 0x80, "Source Thing", "Address", new nmiCtrlThingPicker() { ParentFld = 5000, IncludeEngines = true }); TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.PropertyPicker, 5020, 2, 0x80, "Source Property", "SourceProp", new nmiCtrlPropertyPicker() { ParentFld = 5000, ThingFld = 5010 }); TheFieldInfo mSendbutton2 = TheNMIEngine.AddSmartControl(MyBaseThing, MyEditorForm, eFieldType.TileButton, 5050, 2, 0x80, "Engage", false, "", null, new nmiCtrlTileButton() { NoTE = true, TileWidth = 6, ClassName = "cdeGoodActionButton", ParentFld = 5000 }); mSendbutton2.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "", (pThing, pPara) => { TheProcessMessage pMsg = pPara as TheProcessMessage; if (pMsg?.Message == null) { return; } UpdateUx(pThing.GetBaseThing()); }); UpdateUx(MyBaseThing); return(true); }
private void UpdateUx(TheThing pThing) { ThePropertyBag.MergeUXBagFromProperties(MySampleControl?.PropertyBag, pThing); SetCtrlType(); TheThingRegistry.UnmapPropertyMapper(MapperGuid); if (!string.IsNullOrEmpty(pThing.Address)) { MapperGuid = TheThingRegistry.PropertyMapper(TheCommonUtils.CGuid(pThing.Address), TheThing.GetSafePropertyString(pThing, "SourceProp"), pThing.cdeMID, "Value", true); if (MapperGuid != Guid.Empty) { pThing.StatusLevel = 1; pThing.LastMessage = "Mapper engaged"; } else { pThing.StatusLevel = 2; pThing.LastMessage = "Mapper failed to engaged"; } } else { pThing.StatusLevel = 0; pThing.LastMessage = "Mapper not engaged"; } }
void sinkRegisterIsos() { var tEngs = TheThingRegistry.GetBaseEnginesAsThing(false, true); foreach (var t in tEngs) { if (TheThing.GetSafePropertyBool(t, "IsIsolated")) { IBaseEngine tBase = TheThingRegistry.GetBaseEngine(t, true); if (tBase != null && tBase.GetISOLater() != null) { TheThing tT = TheThingRegistry.GetThingByFunc(MyBaseEngine.GetEngineName(), s => s.DeviceType == TheISOlaterKPIs.eDeviceType && TheThing.GetSafePropertyString(s, "ISOLaterName") == t.EngineName); var tKPI = new TheISOlaterKPIs(tT, this, t.EngineName); TheThingRegistry.RegisterThing(tKPI); } } } List <TheThing> tDevList = TheThingRegistry.GetThingsByProperty(MyBaseEngine.GetEngineName(), Guid.Empty, "DeviceType", TheKPIReport.eDeviceType); if (tDevList.Count > 0) { foreach (TheThing tDev in tDevList) { if (tDev.GetObject() == null) { TheKPIReport cs = new TheKPIReport(tDev, this); TheThingRegistry.RegisterThing(cs); } } } }
private void UpdateUx() { ThePropertyBag.MergeUXBagFromProperties(CountBar?.PropertyBag, MyBaseThing); SetCtrlType(); if (TimestampField != null) { TimestampField?.SetUXProperty(Guid.Empty, $"Visibility={ShowTimestamp}"); ChangeTimestampField?.SetUXProperty(Guid.Empty, $"Visibility={ShowChangeTimestamp}"); } TheThingRegistry.UnmapPropertyMapper(MapperGuid); if (!string.IsNullOrEmpty(MyBaseThing.Address)) { MapperGuid = TheThingRegistry.PropertyMapper(TheCommonUtils.CGuid(MyBaseThing.Address), TheThing.GetSafePropertyString(MyBaseThing, "SourceProp"), MyBaseThing.cdeMID, "Value", true); if (MapperGuid != Guid.Empty) { MyBaseThing.StatusLevel = 1; MyBaseThing.LastMessage = "Mapper engaged"; } else { MyBaseThing.StatusLevel = 2; MyBaseThing.LastMessage = "Mapper failed to engaged"; } } else { MyBaseThing.StatusLevel = 0; MyBaseThing.LastMessage = "Mapper not engaged"; } }
public override bool DoCreateUX() { MyBaseThing.RegisterProperty("ClickState"); var tFlds = TheNMIEngine.AddStandardForm(MyBaseThing, null, 24, null, "Value"); MyStatusForm = tFlds["Form"] as TheFormInfo; //MyStatusForm.PropertyBag = new ThePropertyBag { "TileWidth=6" }; MyStatusForm.RegisterEvent2(eUXEvents.OnShow, (pmse, sen) => { UpdateUx(); }); SummaryForm = tFlds["DashIcon"] as TheDashPanelInfo; SummaryForm.PropertyBag = new nmiDashboardTile() { Format = $"{MyBaseThing.FriendlyName}<br>{{0}}", Caption = MyBaseThing.FriendlyName }; CountBar = TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.SingleEnded, 5, 2, MyBaseThing.cdeA, "CurrentValue", "Value", null); ChangeTimestampField = TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.DateTime, 6, 0, MyBaseThing.cdeA, "Last Change", nameof(ValueChangeTimestamp), new nmiCtrlDateTime { ParentFld = 1, Visibility = ShowChangeTimestamp }); TimestampField = TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.DateTime, 7, 0, MyBaseThing.cdeA, "Timestamp", nameof(ValueTimestamp), new nmiCtrlDateTime { ParentFld = 1, Visibility = ShowChangeTimestamp }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.CollapsibleGroup, 800, 2, 0x80, "Configuration...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup() { ParentFld = 1, DoClose = true, IsSmall = true })); var ts = TheNMIEngine.AddStatusBlock(MyBaseThing, MyStatusForm, 810); ts["Group"].SetParent(800); ts["Group"].PropertyBag = new nmiCtrlCollapsibleGroup { DoClose = true }; TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.CollapsibleGroup, 1000, 2, 0x80, "NMI Settings...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup() { ParentFld = 800, DoClose = true, IsSmall = true, TileWidth = 6 })); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.CollapsibleGroup, 3000, 2, 0x80, "Advanced NMI Settings...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup() { ParentFld = 1000, DoClose = true, IsSmall = true, TileWidth = 6 })); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.ComboOption, 3010, 2, 0x80, "NMI Screen", "FormName", new ThePropertyBag() { "Options=%GetLiveScreens%", "TileWidth=6", "TileHeight=1", "ParentFld=3000" }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.CheckField, 3020, 2, 0x80, "Flags", "Flags", new ThePropertyBag() { "Bits=6", "TileHeight=6", "TileFactorY=2", "ImageList=<span class='fa-stack'><i class='fa fa-stack-1x'></i><i class='fa fa-stack-2x'> </i></span>," + "<span class='fa-stack'><i class='fa fa-stack-1x'></i><i class='fa fa-stack-2x'> </i></span>," + "<span class='fa-stack'><i class='fa fa-stack-1x'></i><i class='fa fa-stack-2x text-danger' style='opacity:0.5'></i></span>," + "<span class='fa-stack'><i class='fa fa-stack-1x'></i><i class='fa fa-stack-2x text-danger' style='opacity:0.5'></i></span>," + "<span class='fa-stack'><i class='fa fa-stack-1x'></i><i class='fa fa-stack-2x text-danger' style='opacity:0.5'></i></span>," + "<span class='fa-stack'><i class='fa fa-stack-1x'></i><i class='fa fa-stack-2x text-danger' style='opacity:0.5'></i></span>", "ParentFld=3000" }).FldWidth = 1; TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.ComboBox, 1500, 2, 0x80, "Control Type", "ControlType", new ThePropertyBag() { "Options=%RegisteredControlTypes%", "ParentFld=1000" }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.CollapsibleGroup, 2000, 2, 0x80, "All Properties...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup() { NoTE = true, ParentFld = 1000, DoClose = true, IsSmall = true, TileWidth = 6 })); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.Table, 2010, 0xA2, 0x80, "All Properties", "mypropertybag;1", new ThePropertyBag() { "NoTE=true", "TileHeight=4", "TileLeft=9", "TileTop=3", "TileWidth=6", "FldWidth=6", "ParentFld=2000" }); TheNMIEngine.AddFields(MyStatusForm, new List <TheFieldInfo> { { new TheFieldInfo() { FldOrder = 2020, DataItem = "MyPropertyBag.ScratchName.Value", Flags = 0x0A, Type = eFieldType.SingleEnded, Header = "New Property Name", TileWidth = 6, TileHeight = 1, PropertyBag = new ThePropertyBag() { "ParentFld=2000" } } }, }); TheFieldInfo tBut = TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.TileButton, 2040, 0x0A, 0, "Add Property", false, null, null, new nmiCtrlTileButton() { ParentFld = 2000, NoTE = true, ClassName = "cdeGoodActionButton" }); tBut.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "AddProp", (pThing, pObj) => { TheProcessMessage pMsg = pObj as TheProcessMessage; if (pMsg?.Message == null) { return; } string[] parts = pMsg.Message.PLS.Split(':'); TheThing tOrg = TheThingRegistry.GetThingByMID(MyBaseEngine.GetEngineName(), TheCommonUtils.CGuid(parts[2])); if (tOrg == null) { return; } string tNewPropName = TheThing.GetSafePropertyString(tOrg, "ScratchName"); if (string.IsNullOrEmpty(tNewPropName)) { TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", "Please specify a new property name")); } else { if (tOrg.GetProperty(tNewPropName) != null) { TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", "Property already exists")); tOrg.SetProperty("ScratchName", ""); } else { tOrg.DeclareNMIProperty(tNewPropName, ePropertyTypes.TString); TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", "Property Added")); tOrg.SetProperty("ScratchName", ""); MyStatusForm.Reload(pMsg, false); } } }); TheFieldInfo mSendbutton = TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.TileButton, 1550, 2, 0x80, "Reload", false, "", null, new nmiCtrlTileButton() { TileWidth = 6, NoTE = true, ClassName = "cdeGoodActionButton", ParentFld = 1000 }); mSendbutton.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "", (pThing, pPara) => { TheProcessMessage pMsg = pPara as TheProcessMessage; if (pMsg?.Message == null) { return; } UpdateUx(); MyStatusForm.Reload(pMsg, true); //TheNMIEngine.GetEngineDashBoardByThing(MyBaseEngine.GetBaseThing()).Reload(pMsg, true); }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.CollapsibleGroup, 5000, 2, 0x80, "Source...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup() { DoClose = true, IsSmall = true, ParentFld = 800, TileWidth = 6 })); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.ThingPicker, 5010, 2, 0x80, "Source Thing", "Address", new nmiCtrlThingPicker() { ParentFld = 5000, IncludeEngines = true, IncludeRemotes = true }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.PropertyPicker, 5020, 2, 0x80, "Source Property", "SourceProp", new nmiCtrlPropertyPicker() { ParentFld = 5000, ThingFld = 5010 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.SingleCheck, 5030, 2, 0x80, "Show Timestamp", nameof(ShowTimestamp), new nmiCtrlSingleCheck { ParentFld = 5000, TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.SingleCheck, 5040, 2, 0x80, "Show Change Time", nameof(ShowChangeTimestamp), new nmiCtrlSingleCheck { ParentFld = 5000, TileWidth = 3 }); TheFieldInfo mSendbutton2 = TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.TileButton, 5050, 2, 0x80, "Engage", false, "", null, new nmiCtrlTileButton() { NoTE = true, TileWidth = 6, ClassName = "cdeGoodActionButton", ParentFld = 5000 }); mSendbutton2.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "", (pThing, pPara) => { TheProcessMessage pMsg = pPara as TheProcessMessage; if (pMsg?.Message == null) { return; } UpdateUx(); }); UpdateUx(); return(true); }
public override bool CreateUX() { if (!mIsInitialized) { IsUXReady = true; TheBaseAssets.MySYSLOG.WriteToLog(500, new TSM(MyBaseThing.EngineName, $"Create UX delays because Init not called for Sensor {MyBaseThing.FriendlyName}", eMsgLevel.l1_Error)); return(false); } if (!mIsUXInitCalled) { mIsUXInitCalled = true; var pReportName = TheThing.GetSafePropertyString(MyBaseThing, "ReportName"); if (string.IsNullOrEmpty(pReportName)) { pReportName = "Sensor Report"; } var pReportFace = TheThing.GetSafePropertyString(MyBaseThing, "ReportFace"); if (string.IsNullOrEmpty(pReportFace)) { pReportFace = "/pages/ThingFace.html"; } var pReportCate = TheThing.GetSafePropertyString(MyBaseThing, "ReportCategory"); TheFormInfo tMyForm = TheSensorNMI.CreateSensorForm(MyBaseThing, pReportFace, pReportName, pReportCate); tMyForm.ModelID = "DefaultSensorTemplateForm"; //tMyForm.RegisterEvent(eUXEvents.OnShow, (sender, para) => //{ // var pMsg = para as TheProcessMessage; // if (pMsg?.Message == null) return; // ValueField?.SetUXProperty(pMsg.Message.GetOriginator(), $"Title={TheThing.GetSafePropertyString(MyBaseThing, "StateSensorValueName")}"); //}); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.CollapsibleGroup, 210, 6, 0, "Sensor Info...", null, new nmiCtrlCollapsibleGroup { IsSmall = true, DoClose = true, ParentFld = 1 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleEnded, 230, 2, 0, "Vendor name", "VendorName", new nmiCtrlTextArea { ParentFld = 210 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, 240, 2, 0, "Vendor ID", "VendorID", new nmiCtrlNumber { ParentFld = 210 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleEnded, 241, 2, 0, "Vendor Text", "VendorText", new nmiCtrlTextArea { ParentFld = 210 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleEnded, 245, 2, 0, "Product Name", "ProductName", new nmiCtrlTextArea { ParentFld = 210 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleEnded, 250, 2, 0, "Product ID", "ProductID", new nmiCtrlTextArea { ParentFld = 210 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.TextArea, 255, 2, 0, "Product Text", "ProductText", new nmiCtrlTextArea { ParentFld = 210 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleEnded, 260, 2, 0, "Serial number", "SerialNumber", new nmiCtrlTextArea { ParentFld = 210 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleEnded, 261, 2, 0, "Sensor Units", "StateSensorUnit", new nmiCtrlNumber { TileWidth = 6, TileHeight = 1, ParentFld = 210 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleEnded, 262, 2, 0, "Sensor Value Name", "StateSensorValueName", new nmiCtrlNumber { TileWidth = 6, TileHeight = 1, ParentFld = 210 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.CollapsibleGroup, 400, 6, 0, "Sensor Settings...", null, new nmiCtrlCollapsibleGroup { ParentFld = 210, IsSmall = true, DoClose = true }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.TileGroup, 401, 6, 0, null, null, new nmiCtrlTileGroup { ParentFld = 400, TileWidth = 6, TileHeight = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 402, 2, 0, "Publish Sensor Value", "PublishValue", new nmiCtrlSingleCheck { ParentFld = 401, TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, 403, 2, 0, "Publish Every (sec)", "PublishEvery", new nmiCtrlNumber { TileWidth = 3, TileHeight = 1, MinValue = 0, ParentFld = 401 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.ComboBox, 404, 2, 0, "Sensor Category", "SensorCategory", new nmiCtrlComboBox { Options = ";Energy-Sensor;Energy-Power;Energy-Current;Energy-Voltage;Temperature;Humidity", ParentFld = 401, TileWidth = 6 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.ComboBox, 405, 2, 0, "Target Chart", "TargetChart", new nmiCtrlComboBox { ParentFld = 401, TileWidth = 6, Options = "none;Sensor Chart" }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.TileGroup, 410, 6, 0, null, null, new nmiCtrlTileGroup { ParentFld = 400, TileWidth = 6, TileHeight = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, 411, 2, 0, "Min Value", "StateSensorMinValue", new nmiCtrlNumber { TileWidth = 3, TileHeight = 1, MinValue = int.MinValue, ParentFld = 410 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, 412, 2, 0, "Max Value", "StateSensorMaxValue", new nmiCtrlNumber { TileWidth = 3, TileHeight = 1, ParentFld = 410, MinValue = int.MinValue }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, 414, 2, 0, "Threshold", "StateSensorAverage", new nmiCtrlNumber { TileWidth = 3, TileHeight = 1, ParentFld = 410, MinValue = int.MinValue }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 415, 2, 0, "Alarm is Low", "IsLowAlarm", new nmiCtrlSingleCheck { ParentFld = 410, TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, 416, 2, 0, "Digits", "Digits", new nmiCtrlNumber { DefaultValue = "0", TileWidth = 3, TileHeight = 1, ParentFld = 410 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, 417, 2, 0, "Scale Factor", "ValScaleFactor", new nmiCtrlNumber { DefaultValue = "0", TileWidth = 3, TileHeight = 1, ParentFld = 410 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.TileGroup, 420, 6, 0, null, null, new nmiCtrlTileGroup { ParentFld = 400, TileWidth = 4, TileHeight = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, 426, 2, 0, "Bucket Steps", "StateSensorSteps", new nmiCtrlNumber { TileWidth = 3, TileHeight = 1, ParentFld = 420 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, 427, 2, 0, "Update Throttle (ms)", "UpdateThrottle", new nmiCtrlNumber { TileWidth = 3, TileHeight = 1, ParentFld = 420 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, 428, 2, 0, "Time Until Absent (sec)", "TimeToAbsent", new nmiCtrlNumber { TileWidth = 3, TileHeight = 1, ParentFld = 420 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.CollapsibleGroup, 430, 6, 0, "Advanced Settings...", null, new nmiCtrlCollapsibleGroup { ParentFld = 400, IsSmall = true, DoClose = true }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 431, 2, 0, "Disable Sensor", nameof(IsDisabled), new nmiCtrlSingleCheck { ParentFld = 430, TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleCheck, 432, 2, 0xC0, "Replicate", "IsGlobal", new nmiCtrlNumber { ParentFld = 430, TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, 433, 2, 0, "Calc Aggregation (sec)", "CalcAggregation", new nmiCtrlNumber { TileWidth = 6, TileHeight = 1, LabelFontSize = 16, ParentFld = 430, DefaultValue = "30" }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, 434, 2, 0, "Bucket Calculation Interval (ms)", "BucketCalcInterval", new nmiCtrlNumber { TileWidth = 6, TileHeight = 1, LabelFontSize = 16, ParentFld = 430, DefaultValue = "3000" }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, 435, 2, 0, "History Retain (days)", "HistoryRetain", new nmiCtrlNumber { TileWidth = 6, TileHeight = 1, LabelFontSize = 16, ParentFld = 430, DefaultValue = "7" }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.Number, 436, 2, 0, "History Sample Period (sec)", "HistorySamplePeriod", new nmiCtrlNumber { TileWidth = 6, TileHeight = 1, LabelFontSize = 16, ParentFld = 430, DefaultValue = "1" }); TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.SingleEnded, 437, 2, 0, "History Fields", "HistoryFields", new nmiCtrlNumber { TileWidth = 6, TileHeight = 1, ParentFld = 430, DefaultValue = "QValue;QValue_Ave;QValue_Min;QValue_Max" }); DoCreateUX(tMyForm); SensorForm = tMyForm; mIsUXInitialized = true; } return(true); }