private static void SendGlobalThings(Guid targetNodeId) { // Do not send more often than every 60 seconds if (lastGlobalThingSendPerNode.TryGetValue(targetNodeId, out thingSendStatus timeAndPending)) { if (DateTimeOffset.Now.Subtract(timeAndPending.lastSend).TotalSeconds < 59) // && !timeAndPending.Pending) { return; } } var globalThings = TheThingRegistry.GetThingsByFunc("*", (t) => TheThing.GetSafePropertyBool(t, "IsRegisteredGlobally") && t.IsOnLocalNode()); if (globalThings != null) { TSM tTSM = new TSM(eEngineName.ContentService, "CDE_SYNC_THINGS", TheCommonUtils.SerializeObjectToJSONString(globalThings)); tTSM.SetToServiceOnly(true); if (targetNodeId == Guid.Empty) { TheCommCore.PublishCentral(tTSM); } else { TheCommCore.PublishToNode(targetNodeId, tTSM); } lastGlobalThingSendPerNode[targetNodeId] = new thingSendStatus { lastSend = DateTimeOffset.Now, Pending = false }; } }
void sinkRuleAction(cdeP pProp) { //List<TheRule> tList = MyRulesStore.MyMirrorCache.GetEntriesByFunc(s => TheCommonUtils.CGuid(s.TriggerObject) != Guid.Empty && TheCommonUtils.CGuid(s.TriggerObject) == TheCommonUtils.CGuid(pEvent.TXT)); List <TheThing> tList = TheThingRegistry.GetThingsByFunc("*", s => pProp.cdeO != Guid.Empty && TheCommonUtils.CGuid(TheThing.GetSafePropertyString(s, "TriggerObject")) == pProp.cdeO); 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, true); continue; } if (string.IsNullOrEmpty(pProp.Name) || string.IsNullOrEmpty(pProp.ToString())) { continue; } if (!pProp.Name.Equals(tRule.TriggerProperty)) { continue; } tRule.RuleTrigger(pProp.ToString()); TheThing.SetSafePropertyDate(tRule.GetBaseThing(), "LastTriggered", DateTimeOffset.Now); } } }
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 GenerateMetrics() { foreach (var senderThing in MySenderThings.TheValues) { if (senderThing.Disable) { continue; } List <TheThing> thingsToSend = null; { var tThing = senderThing.GetThing(); if (tThing == null) { if (!string.IsNullOrEmpty(senderThing.EngineName)) { thingsToSend = TheThingRegistry.GetThingsOfEngine(senderThing.EngineName, true, true); if (!string.IsNullOrEmpty(senderThing.DeviceType)) { thingsToSend.RemoveAll(t => t.DeviceType != senderThing.DeviceType); } } else { if (!string.IsNullOrEmpty(senderThing.DeviceType)) { thingsToSend = TheThingRegistry.GetThingsByFunc("*", t => t.DeviceType.Equals(senderThing.DeviceType, StringComparison.Ordinal), true); } } } else { thingsToSend = new List <TheThing> { tThing }; } } if (thingsToSend == null || thingsToSend.Count == 0) { continue; } //if (string.IsNullOrEmpty(senderThing.PropertiesIncluded)) senderThing.PropertiesIncluded = "Value"; //Make sure we have at least one included var propsIncludedConf = string.IsNullOrEmpty(senderThing.PropertiesIncluded) ? null : TheCommonUtils.cdeSplit(senderThing.PropertiesIncluded, ',', false, false); var propsExcluded = string.IsNullOrEmpty(senderThing.PropertiesExcluded) ? null : TheCommonUtils.cdeSplit(senderThing.PropertiesExcluded, ',', false, false); var propsIncludedSplit = propsIncludedConf?.Select(p => TheCommonUtils.cdeSplit(p, ';', false, false)); var propsIncluded = propsIncludedSplit?.Select(p => p[0]); foreach (var tThing in thingsToSend) { // Capture the metrics as specified in the sender thing var tMetricThing = nsCDEngine.ViewModels.TheThingStore.CloneFromTheThing(tThing, false, true, true, propsIncluded, propsExcluded); // Unpack any JSON objects (i.e. DeviceGateLogMesh) into separate properties foreach (var tMetric in tMetricThing.PB.ToList()) { if (tMetric.Value?.ToString().Contains("{") == true) { var metricValue = tMetric.Value.ToString().Trim(); if (metricValue.StartsWith("{") && metricValue.EndsWith("}")) { try { var jsonBag = TheCommonUtils.DeserializeJSONStringToObject <Dictionary <string, object> >(metricValue); if (jsonBag?.Count > 0) { if (jsonBag.TryGetValue("PLO", out var payload)) { // Unpack the PLO in case the payload is a KPI TSM try { var payloadBag = TheCommonUtils.DeserializeJSONStringToObject <Dictionary <string, object> >(payload.ToString()); if (payloadBag != null && payloadBag.Count > 0) { jsonBag = payloadBag as Dictionary <string, object>; } } catch { } } foreach (var prop in jsonBag) { var metricPrefix = $"[{tMetric.Key.Trim(new char[] { '[', ']' })}]"; var metricName = $"{metricPrefix}.[{prop.Key}]"; if (propsIncluded?.Contains(metricName) == true || propsIncluded?.Contains($"{metricPrefix}.*") == true) { tMetricThing.PB[metricName] = prop.Value; } } if (tMetricThing.PB.ContainsKey(tMetric.Key)) { tMetricThing.PB.Remove(tMetric.Key); } } } catch { } } } } foreach (var tMetric in tMetricThing.PB) { string metricName = ""; try { var propertyName = tMetric.Key; var metricInfo = propsIncludedSplit.FirstOrDefault(ps => ps[0] == propertyName); if (metricInfo != null && metricInfo.Length > 1) { metricName = metricInfo[1]; } else { metricName = GetValidLabelName(tMetric.Key); } var valueToReport = GetMetricValue(tMetric.Value); if (senderThing.ChangeNaNToNull && valueToReport == 0) //CM: closest reuse of disable sending of null/0 { continue; } var labels = GetMetricLabels(senderThing, propertyName, metricName); switch (senderThing.TargetType?.ToLowerInvariant()) { case "counter": { var counter = myCountersByMetricName.GetOrAdd(metricName, (s) => { Prometheus.Counter cs; try { cs = Metrics.CreateCounter(s, "", labels); return(cs); } catch (Exception e) { TheBaseAssets.MySYSLOG.WriteToLog(95307, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(strPrometheusExporter, $"Error creating metric {s} in server: {this.MyBaseThing?.Address}", eMsgLevel.l1_Error, e.ToString())); } return(null); }); if (counter != null) { if (counter.LabelNames.Length > 0) { var labelValues = GetLabelValues(tThing, counter.LabelNames); var labelCounter = counter.Labels(labelValues); var valueInc = valueToReport - labelCounter.Value; if (valueInc > 0) { labelCounter.Inc(valueInc); } else if (valueInc < 0) { TheBaseAssets.MySYSLOG.WriteToLog(95307, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(strPrometheusExporter, $"Error reporting metric {metricName} in '{this.MyBaseThing?.Address} {this.MyBaseThing}'. Counter value {valueToReport} smaller than reported {labelCounter.Value}", eMsgLevel.l1_Error)); } } else { counter.Inc(valueToReport - counter.Value); } } } break; case null: case "": case "gauge": { var gauge = myGaugesByMetricName.GetOrAdd(metricName, (s) => Metrics.CreateGauge(s, "", labels)); if (gauge != null) { if (gauge.LabelNames.Length > 0) { var labelValues = GetLabelValues(tThing, gauge.LabelNames); gauge.Labels(labelValues).Set(valueToReport); } else { gauge.Set(valueToReport); } } } break; case "histogram": { var histogram = myHistogramsByMetricName.GetOrAdd(metricName, (s) => Metrics.CreateHistogram(s, "", GetHistogramBuckets(senderThing, propertyName, metricName, labels))); if (histogram != null) { if (histogram.LabelNames.Length > 0) { var labelValues = GetLabelValues(tThing, histogram.LabelNames); histogram.Labels(labelValues).Observe(valueToReport); } else { histogram.Observe(valueToReport); } } } break; case "summary": { var summary = mySummariesByMetricName.GetOrAdd(metricName, (s) => Metrics.CreateSummary(s, "", labels)); if (summary != null) { if (summary.LabelNames.Length > 0) { var labelValues = GetLabelValues(tThing, summary.LabelNames); summary.Labels(labelValues).Observe(valueToReport); } else { summary.Observe(valueToReport); } } } break; default: TheBaseAssets.MySYSLOG.WriteToLog(95307, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(strPrometheusExporter, $"Unexpected metric type in server: {this.MyBaseThing?.Address}", eMsgLevel.l1_Error, senderThing.TargetType)); break; } } catch (Exception e) { TheBaseAssets.MySYSLOG.WriteToLog(95307, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(strPrometheusExporter, $"Error reporting metric {metricName} in server: {this.MyBaseThing?.Address}", eMsgLevel.l1_Error, e.ToString())); } } } } }
internal static TheScreenInfo GenerateLiveScreen(Guid pScreenId, TheClientInfo tClientInfo) // Guid pUserGuid, int lcid, int pFlag) { if (TheCDEngines.MyNMIService == null) { return(null); } TheScreenInfo tInfo = new TheScreenInfo { cdeMID = pScreenId, MyDashboard = null, MyStorageInfo = new List <TheFormInfo>(), MyStorageMeta = new cdeConcurrentDictionary <string, TheFormInfo>(), MyStorageMirror = new List <object>(), MyDashPanels = new List <TheDashPanelInfo>() }; TheThing tLiveForm = TheThingRegistry.GetThingByMID("*", pScreenId); if (tLiveForm == null || !TheUserManager.HasUserAccess(tClientInfo.UserID, tLiveForm.cdeA)) { return(null); //V3.1: BUG 126 - could lead to racing condition. TODO: Revisit later //TheFormInfo tI = new TheFormInfo(tLiveForm) { FormTitle = (tLiveForm == null ? "Form not Found!" : "Access Denied!") }; //tI.TargetElement = pScreenId.ToString(); //tI.AssociatedClassName = pScreenId.ToString(); //tInfo.MyStorageInfo.Add(tI); //tI.FormFields = new List<TheFieldInfo>(); //TheFieldInfo tFldInfo = new TheFieldInfo(null, null, 10, 0, 0); //tFldInfo.Type = eFieldType.SmartLabel; //tFldInfo.Header = (tLiveForm == null ? "This Form was defined but has not Meta-Data associated with it." : "You do not have the required access permissions!"); //tI.FormFields.Add(tFldInfo); //return tInfo; } string tFormName = TheThing.GetSafePropertyString(tLiveForm, "FriendlyName"); List <TheThing> tFields = TheThingRegistry.GetThingsByFunc("*", s => s.cdeO == TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID && TheThing.GetSafePropertyString(s, "FormName") == tFormName && TheThing.GetSafePropertyBool(s, "IsLiveTag") && (s.UID == Guid.Empty || s.UID == tClientInfo.UserID)); if (tFields != null && tFields.Any()) { string tFormTitle = TheThing.GetSafePropertyString(tLiveForm, "FormTitle"); if (string.IsNullOrEmpty(tFormTitle)) { tFormTitle = tFormName; } TheFormInfo tI = new TheFormInfo(tLiveForm) { FormTitle = tFormTitle, TargetElement = pScreenId.ToString(), DefaultView = eDefaultView.Form, TileWidth = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(tLiveForm, "TileWidth")), TileHeight = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(tLiveForm, "TileHeight")), IsUsingAbsolute = TheThing.GetSafePropertyBool(tLiveForm, "IsAbsolute"), AssociatedClassName = pScreenId.ToString() }; tInfo.MyStorageInfo.Add(tI); tI.FormFields = new List <TheFieldInfo>(); int fldNo = 10; foreach (TheThing tTh in tFields) { int tfldNo = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(tTh, "FldOrder")); if (tfldNo == 0) { tfldNo = fldNo; } int tFlags = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(tTh, "Flags")); cdeP ValProp = tTh.GetProperty("Value"); bool IsNewFld = true; TheFieldInfo tFldInfo = TheNMIEngine.GetFieldById(TheThing.GetSafePropertyGuid(tTh, "FldID")); if (tFldInfo == null) { tFldInfo = new TheFieldInfo(tTh, "Value", tfldNo, tFlags & 0xFFBF, tTh.GetBaseThing().cdeA); } else { tFldInfo.FldOrder = tfldNo; tFldInfo.Flags = tFlags; IsNewFld = false; } if (tFldInfo.PropertyBag == null) { tFldInfo.PropertyBag = new ThePropertyBag(); } ThePropertyBag.PropBagUpdateValue(tFldInfo.PropertyBag, "IsOnTheFly", "=", "True"); ThePropertyBag.PropBagUpdateValue(tFldInfo.PropertyBag, "UXID", "=", $"{tTh.cdeMID}"); tFldInfo.Header = tTh.FriendlyName; RegisterNMISubscription(tClientInfo, "Value", tFldInfo); string tControlType = TheThing.GetSafePropertyString(tTh, "ControlType"); if (TheCommonUtils.CInt(tControlType) == 0 && !TheCommonUtils.IsNullOrWhiteSpace(tControlType)) { tFldInfo.Type = eFieldType.UserControl; RegisterFieldEvents(tTh, ValProp, IsNewFld, tFldInfo, tControlType); } else { tFldInfo.Type = (eFieldType)TheCommonUtils.CInt(tControlType); } tFldInfo.DefaultValue = ValProp?.ToString(); tFldInfo.TileWidth = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(tTh, "TileWidth")); tFldInfo.TileHeight = TheCommonUtils.CInt(TheThing.GetSafePropertyNumber(tTh, "TileHeight")); foreach (cdeP prop in tTh.GetNMIProperties()) { ThePropertyBag.PropBagUpdateValue(tFldInfo.PropertyBag, prop.Name, "=", prop.ToString()); } if (tFldInfo.Type == eFieldType.TileButton) { tTh.DeclareNMIProperty("IsDown", ePropertyTypes.TBoolean); ThePropertyBag.PropBagUpdateValue(tFldInfo.PropertyBag, "EnableTap", "=", "True"); tFldInfo.RegisterUXEvent(tTh, eUXEvents.OnPropertyChanged, "IsDown", (pThing, pObj) => { if (!(pObj is TheProcessMessage pMsg) || pMsg.Message == null) { return; } TheThing.SetSafePropertyBool(pThing, "IsDown", TheCommonUtils.CBool(pMsg.Message.PLS)); });
public bool ActivateRules() { if (TheCDEngines.MyThingEngine == null || TheBaseAssets.MyServiceHostInfo.IsCloudService || TheCommonUtils.cdeIsLocked(LockRules) || !mIsInitialized) { return(false); } lock (LockRules) { if (mIsInitialized) { InitRules(); } //List<TheRule> tList = MyRulesStore.MyMirrorCache.GetEntriesByFunc(s => s.IsRuleActive && !s.IsRuleRunning && s.IsRuleWaiting); List <TheThing> tList = TheThingRegistry.GetThingsByFunc("*", s => TheThing.GetSafePropertyString(s, "Parent").Equals(MyBaseThing.ID) && //TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID) && TheThing.GetSafePropertyBool(s, "IsRuleActive") && !TheThing.GetSafePropertyBool(s, "IsRuleRunning") && TheThing.GetSafePropertyBool(s, "IsRuleWaiting")); if (tList != null && tList.Count > 0) { foreach (TheThing tThing in tList) { TheRule tRule = tThing.GetObject() as TheRule; if (tRule == null) { continue; } if (string.IsNullOrEmpty(tRule.TriggerProperty)) { tRule.IsIllegal = true; tRule.IsRuleWaiting = false; continue; } if (tRule.TriggerStartTime > DateTimeOffset.Now) { continue; } if (tRule.TriggerEndTime < DateTimeOffset.Now) { RemoveTrigger(tRule, false); continue; } switch (tRule.TriggerObjectType) { case "CDE_ENGINE": TheThing tBase = TheThingRegistry.GetBaseEngineAsThing(tRule.TriggerObject); if (tBase != null) { tBase.RegisterEvent(eEngineEvents.IncomingMessage, sinkRuleIncoming); tRule.IsRuleWaiting = false; tRule.IsRuleRunning = true; tRule.IsTriggerObjectAlive = true; TheSystemMessageLog.WriteLog(4445, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(eKnownDeviceTypes.TheThingRule, $"Rule {tRule.FriendlyName} started with TriggerType: {tRule.TriggerObjectType}"), false); } break; case "CDE_EVENTFIRED": TheThing tBaseE = TheThingRegistry.GetBaseEngineAsThing(tRule.TriggerObject); if (tBaseE != null) { tBaseE.RegisterEvent(tRule.TriggerProperty, sinkRuleThingEvent); tRule.IsRuleWaiting = false; tRule.IsRuleRunning = true; tRule.IsTriggerObjectAlive = true; TheSystemMessageLog.WriteLog(4445, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(eKnownDeviceTypes.TheThingRule, $"Rule {tRule.FriendlyName} started with TriggerType: {tRule.TriggerObjectType}"), false); } break; default: TheThing tTriggerThing = TheThingRegistry.GetThingByMID("*", TheCommonUtils.CGuid(tRule.TriggerObject)); if (tTriggerThing != null) { //if (tTriggerThing.GetObject() == null) continue; //TODO: Verify if this can stay removed //if (tTriggerThing.GetProperty("FriendlyName").Value.ToString().Contains("Motion")) continue; cdeP tProp = tTriggerThing.GetProperty(tRule.TriggerProperty, true); if (tProp != null) { tProp.UnregisterEvent(eThingEvents.PropertyChanged, sinkRuleAction); tProp.RegisterEvent(eThingEvents.PropertyChanged, sinkRuleAction); } tRule.IsRuleWaiting = false; tRule.IsRuleRunning = true; tRule.IsTriggerObjectAlive = true; tRule.RuleTrigger(tProp.ToString(), true); TheSystemMessageLog.WriteLog(4445, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(eKnownDeviceTypes.TheThingRule, $"Rule {tRule.FriendlyName} started with TriggerType: {tRule.TriggerObjectType}"), false); } break; } } } } return(true); }
public override void HandleMessage(ICDEThing sender, object pIncoming) { TheProcessMessage pMsg = pIncoming as TheProcessMessage; if (pMsg == null || pMsg.Message == null) { return; } string[] tCmd = pMsg.Message.TXT.Split(':'); switch (tCmd[0]) //string 2 cases { case "CDE_INITIALIZED": MyBaseEngine.SetInitialized(pMsg.Message); break; case "CDE_INITIALIZE": if (!MyBaseEngine.GetEngineState().IsEngineReady) { MyBaseEngine.SetInitialized(pMsg.Message); } MyBaseEngine.ReplyInitialized(pMsg.Message); break; case "CDE_REGISTERRULE": TheRule tRule = TheCommonUtils.DeserializeJSONStringToObject <TheRule>(pMsg.Message.PLS); if (tRule != null) { RegisterRule(tRule); } break; case "CLAIM_RULES": List <TheThing> tList = TheThingRegistry.GetThingsByFunc(eEngineName.ThingService, s => TheThing.GetSafePropertyString(s, "DeviceType").Equals(eKnownDeviceTypes.TheThingRule)); if (tList != null && tList.Count > 0) { foreach (TheThing tThing in tList) { tThing.Parent = MyBaseThing.ID; tThing.EngineName = MyBaseEngine.GetEngineName(); } } ActivateRules(); MyDash.Reload(null, false); TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", $"{tList.Count} New Rules claimed")); break; case "REFRESH_DASH": ActivateRules(); MyDash.Reload(null, false); break; case "FIRE_RULE": var t = TheThingRegistry.GetThingByMID(MyBaseEngine.GetEngineName(), TheCommonUtils.CGuid(pMsg?.Message?.PLS)); if (t != null) { TheRule tR = t.GetObject() as TheRule; if (tR != null) { tR.RuleTrigger(tR.TriggerOldValue, true); } } break; } }
private IEnumerable <TheThing> GetMatchingThings(Subscription subscription) { var things = new List <TheThing>(); if (_thingReference.ThingMID.HasValue && _thingReference.ThingMID != Guid.Empty) { var thing = TheThingRegistry.GetThingByMID(_thingReference.ThingMID.Value, true); if (thing != null) { things.Add(thing); } return(things); } IBaseEngine baseEngine = null; List <TheThing> matchingThings = null; if (!string.IsNullOrEmpty(_thingReference.EngineName)) { baseEngine = TheThingRegistry.GetBaseEngine(_thingReference.EngineName); if (baseEngine == null) { TheCDEngines.RegisterNewMiniRelay(_thingReference.EngineName); baseEngine = TheThingRegistry.GetBaseEngine(_thingReference.EngineName); } if (baseEngine != null) { subscription?.AddSubscription(baseEngine, this); matchingThings = TheThingRegistry.GetThingsOfEngine(_thingReference.EngineName, true, true); } } else { object deviceTypeObj = null; if (_thingReference.PropertiesToMatch?.TryGetValue("DeviceType", out deviceTypeObj) == true) { var deviceType = TheCommonUtils.CStr(deviceTypeObj); if (!string.IsNullOrEmpty(deviceType)) { matchingThings = TheThingRegistry.GetThingsByFunc("*", t => t.DeviceType.Equals(deviceType, StringComparison.Ordinal), true); } } } if (matchingThings != null) { foreach (var thing in matchingThings) { if (Matches(thing)) { if (baseEngine == null) { subscription?.AddSubscription(thing.GetBaseEngine(), this); } things.Add(thing); } } } return(things); }