void SendRuleTSM(bool serviceOnly) { string engine = TheCommonUtils.CStr(GetProperty("TSMEngine", false)); string text = TheCommonUtils.CStr(GetProperty("TSMText", false)); string payload = TheCommonUtils.CStr(GetProperty("TSMPayload", false)); //payload = payload.Replace("%DTO%", TheCommonUtils.CStr(DateTimeOffset.Now)); //text = text.Replace("%DTO%", TheCommonUtils.CStr(DateTimeOffset.Now)); ICDEThing triggerThing = TheThingRegistry.GetThingByMID("*", TheCommonUtils.CGuid(TriggerObject)) as ICDEThing; string escPayload = TheCommonUtils.GenerateFinalStr(payload, triggerThing); escPayload = TheCommonUtils.GenerateFinalStr(escPayload, MyBaseThing); string escText = TheCommonUtils.GenerateFinalStr(text, triggerThing); escText = TheCommonUtils.GenerateFinalStr(escText, MyBaseThing); if (!string.IsNullOrEmpty(engine) && !string.IsNullOrEmpty(text)) { TSM customTSM = new TSM(engine, escText, escPayload); if (serviceOnly) { customTSM.SetToServiceOnly(true); } TheCommCore.PublishCentral(customTSM, true); } if (IsRuleLogged) { LogEvent(escPayload); } if (TheThing.GetSafePropertyBool(MyBaseThing, "IsEVTLogged")) { TheLoggerFactory.LogEvent(eLoggerCategory.RuleEvent, TheCommonUtils.GenerateFinalStr(MyBaseThing.FriendlyName, MyBaseThing), eMsgLevel.l4_Message, TheBaseAssets.MyServiceHostInfo.GetPrimaryStationURL(false), escText, escPayload); } }
internal MsgOPCUAReadTagsResponse MsgReadOpcTagTest(List <string> tags, List <object> expectedResultValues = null) { var response = myOPCClient.ReadTagsAsync(tags, new TimeSpan(0, 1, 0)).Result; Assert.IsNotNull(response); Assert.IsTrue(String.IsNullOrEmpty(response.Error), $"Error from Read Tags async: {response.Error}"); Assert.IsNotNull(response.Results); Assert.IsTrue(response.Results.Count == tags.Count, $"Unexpected result count from Read OPC Tag message: {response.Results.Count}. Expected less than {tags.Count}"); Assert.IsTrue(String.IsNullOrEmpty(response.Error), $"Error sending Read OPC Tag message: {response.Error}"); if (expectedResultValues != null) { Assert.IsTrue(response.Results.Count == expectedResultValues.Count, $"Test error? expected result count does not match result from Read OPC Tag message: {response.Results.Count}. Expected {expectedResultValues.Count}"); } int resultIndex = 0; foreach (var result in response.Results) { Assert.IsTrue(String.IsNullOrEmpty(result.Error), $"Result for node {tags[resultIndex]} returned error {result.Error}"); if (expectedResultValues != null) { var expectedResult = expectedResultValues[resultIndex]; Assert.IsTrue(TheCommonUtils.CStr(expectedResult) == TheCommonUtils.CStr(result.TagValue), $"Result for node {tags[resultIndex]} was {result.TagValue}. Expected: {expectedResult}"); } else { Assert.IsNotNull(result.TagValue); } resultIndex++; } return(response); }
string PropertyOPCToString(ePropertyTypes propcdeT, object prop) { if (propcdeT == ePropertyTypes.TBinary) { if (prop == null) { return("(null)"); } StringBuilder buffer = new StringBuilder(); byte[] bytes = (byte[])prop; for (int ii = 0; ii < bytes.Length; ii++) { buffer.AppendFormat(null, "{0:X2}", bytes[ii]); } return(buffer.ToString()); } else { if (prop == null) { return(null); } } return(TheCommonUtils.CStr(prop)); }
public override bool Init() { if (mIsInitCalled) { return(false); } mIsInitCalled = true; ReqBuffer = new TheMirrorCache <TheRequestData>(0); string t = TheCommonUtils.CStr(TheBaseAssets.MySettings.GetSetting("WRA_RequestTimeout")); if (!string.IsNullOrEmpty(t)) { RequestTimeout = TheCommonUtils.CInt(t); } if (RequestTimeout < 15) { RequestTimeout = 15; } InitServices(); TheCommCore.MyHttpService.RegisterHttpInterceptorB4("/", InterceptHttpRequest); TheScopeManager.RegisterScopeChanged(sinkScopeIDUpdate); MyBaseThing.RegisterEvent(eEngineEvents.IncomingMessage, HandleMessage); mIsInitialized = true; MyBaseEngine.ProcessInitialized(); return(true); }
public void CStrDateTimeOffsetTest() { var date = new DateTimeOffset(2017, 12, 21, 11, 12, 13, 456, new TimeSpan(1, 0, 0)); var dateString = TheCommonUtils.CStr(date); var expectedString = "2017-12-21T11:12:13.4560000+01:00"; Assert.AreEqual(expectedString, dateString); }
public bool Equals(OpcClientDataLogEntry x, OpcClientDataLogEntry y) { if ( x.TagId == y.TagId && (x.Source == y.Source // || (Math.Abs((x.Source - y.Source).Ticks) <= _toleranceInTicks) )) { var xValue = TheCommonUtils.CStr(x.value); var yValue = TheCommonUtils.CStr(y.value); if (xValue == yValue) { return(true); } if (yValue.Contains("http://opcfoundation.org/UA/2008/02/Types.xsd") || xValue.Contains("http://opcfoundation.org/UA/2008/02/Types.xsd")) { return(true); } if ((string.IsNullOrEmpty(xValue) && yValue.StartsWith("[")) || (string.IsNullOrEmpty(yValue) && xValue.StartsWith("["))) { return(true); } if ((xValue == "(null)" && string.IsNullOrEmpty(yValue)) || (yValue == "(null)" && string.IsNullOrEmpty(xValue))) { return(true); } } if (x.TagId == $"[{y.TagId}].[statusCode]" && x.Source == y.Source) { if (TheCommonUtils.CStr(x.value) == TheCommonUtils.CStr(y.Status)) { return(true); } } if (y.TagId == $"[{x.TagId}].[statusCode]" && x.Source == y.Source) { if (TheCommonUtils.CStr(y.value) == TheCommonUtils.CStr(x.Status)) { return(true); } } if (x.TagId == $"[{y.TagId}].[sequenceNumber]" && x.Source == y.Source) { if (y.SequenceNumber == null || (TheCommonUtils.CStr(x.value) == TheCommonUtils.CStr(y.SequenceNumber.Value))) { return(true); } } if (y.TagId == $"[{x.TagId}].[sequenceNumber]" && x.Source == y.Source) { if (x.SequenceNumber == null || (TheCommonUtils.CStr(y.value) == TheCommonUtils.CStr(x.SequenceNumber.Value))) { return(true); } } return(false); }
private void ShowKPI(int pFldOrder, string pLabel, string pUpdName, int MaxVal = 100, int AveVal = 50, string pUnits = "bytes") { TheNMIEngine.AddSmartControl(MyBaseThing, mMyForm, eFieldType.TileGroup, pFldOrder, 0, 0, null, null, new nmiCtrlTileGroup { ParentFld = 300, TileWidth = 6 }); TheNMIEngine.AddSmartControl(MyBaseThing, mMyForm, eFieldType.SmartLabel, pFldOrder + 1, 0, 0, null, null, new nmiCtrlSmartLabel { ParentFld = pFldOrder, Text = pLabel, NoTE = true, TileFactorY = 2, TileHeight = 1, TileWidth = 5, ClassName = "cdeTileGroupHeaderSmall" }); var tBut = TheNMIEngine.AddSmartControl(MyBaseThing, mMyForm, eFieldType.TileButton, pFldOrder + 2, 2, 0, "V-Tise", null, new nmiCtrlTileButton { ParentFld = pFldOrder, NoTE = true, TileFactorY = 2, TileHeight = 1, TileWidth = 1, ClassName = "cdeGlassButton" }); tBut.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, $"But{pUpdName}", (sender, para) => { TheThing tT = TheThingRegistry.GetThingByID(MyBaseEngine.GetEngineName(), $"ISO{MyBaseThing.cdeMID}:{pUpdName}"); if (tT == null) { TheKPIReport tRep = new TheKPIReport(null, MyPlugin); TheThing.SetSafePropertyGuid(tRep, "RealSensorThing", MyBaseThing.cdeMID); tRep.GetBaseThing().ID = $"ISO{MyBaseThing.cdeMID}:{pUpdName}"; MyBaseThing.GetProperty(pUpdName, true); TheThing.SetSafePropertyString(tRep, "RealSensorProperty", pUpdName); TheThing.SetSafePropertyNumber(tRep, "StateSensorMaxValue", MaxVal); TheThing.SetSafePropertyNumber(tRep, "StateSensorAverage", AveVal); TheThing.SetSafePropertyNumber(tRep, "StateSensorSteps", MaxVal / 15); TheThing.SetSafePropertyString(tRep, "StateSensorValueName", pLabel); TheThing.SetSafePropertyString(tRep, "StateSensorUnit", pUnits); TheThing.SetSafePropertyString(tRep, "FriendlyName", MyBaseThing.FriendlyName); TheThing.SetSafePropertyString(tRep, "ReportName", $"ISO-KPI: {MyBaseThing.FriendlyName} - {pLabel}"); TheThing.SetSafePropertyString(tRep, "ReportCategory", "ISO KPI Reports"); ThePluginInfo tI = MyPlugin.GetBaseEngine().GetPluginInfo(); if (tI != null) { TheThing.SetSafePropertyString(tRep, "SerialNumber", TheCommonUtils.CStr(tI.CurrentVersion)); TheThing.SetSafePropertyString(tRep, "VendorName", TheCommonUtils.CStr(tI.Developer)); TheThing.SetSafePropertyString(tRep, "ProductName", TheCommonUtils.CStr(tI.ServiceDescription)); TheThing.SetSafePropertyString(tRep, "ProductText", TheCommonUtils.CStr(tI.LongDescription)); TheThing.SetSafePropertyString(tRep, "VendorText", TheCommonUtils.CStr(tI.DeveloperUrl)); TheThing.SetSafePropertyString(tRep, "ProductID", TheCommonUtils.CStr(tI.cdeMID)); } TheThingRegistry.RegisterThing(tRep); MyBaseEngine.ProcessMessage(new TheProcessMessage(new TSM(MyBaseEngine.GetEngineName(), "REFRESH_DASH"))); } else { TheCommCore.PublishToOriginator((para as TheProcessMessage).Message, new TSM(eEngineName.NMIService, "NMI_TTS", tT.cdeMID.ToString())); } }); TheNMIEngine.AddSmartControl(MyBaseThing, mMyForm, eFieldType.SmartLabel, pFldOrder + 3, 0, 0, null, pUpdName, new nmiCtrlSingleEnded { ParentFld = pFldOrder, TileWidth = 2 }); TheNMIEngine.AddSmartControl(MyBaseThing, mMyForm, eFieldType.BarChart, pFldOrder + 4, 0, 0, null, pUpdName, new nmiCtrlBarChart() { ParentFld = pFldOrder, MaxValue = MaxVal, TileWidth = 4, NoTE = true, Foreground = "blue" }); }
static string CDictToString(Dictionary <string, object> dict) { if (dict == null) { return(null); } var dictString = dict.Aggregate("", (s, kv) => $"{s},{kv.Key}={TheCommonUtils.CStr(kv.Value)}"); if (dictString.Length > 0) { dictString = dictString.Substring(1); } return(dictString); }
public static bool StartTheSite(TheBaseApplication pApplication, HttpContext pContext) { if (TheCommonUtils.cdeIsLocked(lockStart)) { return(false); } lock (lockStart) { if (!WasHereBefore && !TheBaseAssets.MasterSwitch) { WasHereBefore = true; } else { return(false); } } Dictionary <string, string> ArgList = new Dictionary <string, string>(); MySite = TheCommonUtils.CStr(System.Configuration.ConfigurationManager.AppSettings["MyStationURL"]); //MSU-OK if (string.IsNullOrEmpty(MySite) && pContext != null) { MySite = pContext.Request.Url.Scheme + "://" + pContext.Request.Url.Host; //.Authority; if (pContext.Request.Url.Port > 0 && pContext.Request.Url.Port != TheBaseAssets.MyServiceHostInfo.MyStationPort) { TheBaseAssets.MyServiceHostInfo.MyStationPort = (ushort)pContext.Request.Url.Port; if ((pContext.Request.Url.Scheme.Equals("https") && pContext.Request.Url.Port != 443) || (pContext.Request.Url.Scheme.Equals("http") && pContext.Request.Url.Port != 80)) { MySite += ":" + pContext.Request.Url.Port; } } } ArgList["MyStationURL"] = MySite; if (!pApplication.StartBaseApplication(null, ArgList)) { return(false); } if (!TheBaseAssets.MyActivationManager.CheckLicense(new Guid("{5737240C-AA66-417C-9B66-3919E18F9F4A}"), "", null, 1)) { ExpiredText = "...Cloud has Expired - contact C-Labs for updated version"; return(false); } return(true); }
private TheThing CreateThingForTest(TheEngineDeviceTypeInfo deviceType, out TestInfo testInfo) { if (!configs.TryGetValue($"{deviceType.EngineName}/{deviceType.DeviceType}", out testInfo)) { WriteLine($"{deviceType}: No config found. Using default."); // No test config found: just create the instance without any configuration testInfo = new TestInfo { MinimumBrowseTags = 0, MaximumBrowseTags = 100, Config = new TheThing.TheThingConfiguration { ThingIdentity = new TheThingIdentity { EngineName = deviceType.EngineName, DeviceType = deviceType.DeviceType, }, ConfigurationValues = new List <TheThing.TheConfigurationProperty> { } } }; } var config = testInfo.Config; if (string.IsNullOrEmpty(config.ThingIdentity?.EngineName)) { config.ThingIdentity = new TheThingIdentity { EngineName = deviceType.EngineName, DeviceType = deviceType.DeviceType, }; var addressValue = config.ConfigurationValues.FirstOrDefault(c => c.Name == "Address"); if (addressValue != null) { config.ThingIdentity.ID = TheCommonUtils.CStr(addressValue); } } var owner = TheThingRegistry.GetBaseEngineAsThing(eEngineName.ContentService); var testThing = TheThing.CreateThingFromConfigurationAsync(owner, config).Result; Assert.IsNotNull(testThing, $"Error creating thing for {config.ThingIdentity.EngineName} / {config.ThingIdentity.DeviceType}"); return(testThing); }
string SerializeJSonArray(TheThingStore thingEvent, IEnumerable<Measurement> measurements) { if (!(measurements is List<Measurement>)) { measurements = new List<Measurement>(measurements); } var payload = new MeasurementPayload(); object deviceId; if (thingEvent.PB.TryGetValue("deviceID", out deviceId)) { payload.device.deviceID = TheCommonUtils.CStr(deviceId); } else { payload.device.deviceID = TheCommonUtils.cdeGuidToString(thingEvent.cdeMID); } payload.measurements.AddRange(measurements); string eventPayloadJson = TheCommonUtils.SerializeObjectToJSONString(payload); //eventPayloadJson = eventPayloadJson.Replace("\"contentspec\"", "\"content-spec\""); // Hack to avoid newtonsoft dependency for now: attribute ignored by cdeEngine internal serializer return eventPayloadJson; }
public static VerifierStats CompareDataLogs <T>(string opcClientDataPath, string meshDataPath, string outputPath, Func <List <MeshSenderDataLogEntry <T> >, TimeSpan, List <OpcClientDataLogEntry> > converter, TimeSpan timeZoneOffset, int toleranceInTicks = 0, Action <List <OpcClientDataLogEntry>, List <OpcClientDataLogEntry> > sanitizeDataCallback = null) { var stats = new VerifierStats(); var opcTags = DataLogParser.ReadOpcClientDataLog(opcClientDataPath); var opc35Running = opcTags.Where(t => t.TagId == "35.Running").ToList(); var opc35RunningOutOfSequence = new List <OpcClientDataLogEntry>(); int lastAdded = -1; for (int i = 1; i < opc35Running.Count; i++) { if (TheCommonUtils.CStr(opc35Running[i].value) == TheCommonUtils.CStr(opc35Running[i - 1].value)) { if (lastAdded != i - 1) { opc35RunningOutOfSequence.Add(opc35Running[i - 1]); } opc35RunningOutOfSequence.Add(opc35Running[i]); lastAdded = i; } } stats.opc35RunningOutOfSequence = opc35RunningOutOfSequence.Count; var meshEntries = DataLogParser.ReadJsonOPCDataLog <T>(meshDataPath); var meshTags = converter(meshEntries, timeZoneOffset); //var meshTags = DataLogParser.ConvertMeshSenderDataToOpcTags(meshEntries, timeZoneOffset).Where(mTag => mTag.TagId != "DeviceGateLog").ToList(); sanitizeDataCallback?.Invoke(opcTags, meshTags); string filePrefix = outputPath != null?Path.Combine(outputPath, DateTime.Now.ToString("yyyyMMdd_hhmmss")) : null; stats.outputPathPrefix = filePrefix; //File.WriteAllText($"{filePrefix}allmesh", TheCommonUtils.SerializeObjectToJSONString(meshTags.OrderBy(e => e.Source.ToString("yyyyMMddhhmmss")+"/"+e.TagId), true)); //File.WriteAllText($"{filePrefix}allopc", TheCommonUtils.SerializeObjectToJSONString(opcTags.OrderBy(e => e.Source.ToString("yyyyMMddhhmmss") + "/" + e.TagId), true)); if (filePrefix != null) { File.WriteAllText($"{filePrefix}opc35runningoutofsequence.log", TheCommonUtils.SerializeObjectToJSONString(opc35RunningOutOfSequence.OrderBy(e => e.Source.ToString("yyyyMMddhhmmss") + "/" + e.TagId)).Replace("},{", "},\r\n{")); } var uniqueOPCTags = opcTags.Distinct(new CompareOpcTagsP08()).ToList(); stats.duplicateOPCTagCount = opcTags.Count - uniqueOPCTags.Count; var duplicateOPCTags = opcTags.Except(uniqueOPCTags).ToList(); // uses object identity comparison if (filePrefix != null) { File.WriteAllText($"{filePrefix}opcduplicate.log", TheCommonUtils.SerializeObjectToJSONString(duplicateOPCTags.OrderBy(e => e.Source.ToString("yyyyMMddhhmmss") + "/" + e.TagId)).Replace("},{", "},\r\n{")); } var uniqueMeshTags = meshTags.Distinct(new CompareOpcTagsP08()).ToList(); //File.WriteAllText($"{filePrefix}uniquemesh", TheCommonUtils.SerializeObjectToJSONString(uniqueMeshTags.OrderBy(e => e.Source.ToString("yyyyMMddhhmmss") + "/" + e.TagId), true)); stats.duplicateMeshTagCount = meshTags.Count - uniqueMeshTags.Count; var duplicateMeshTags = meshTags.Except(uniqueMeshTags).ToList(); // uses object identity comparison if (filePrefix != null) { File.WriteAllText($"{filePrefix}meshduplicate.log", TheCommonUtils.SerializeObjectToJSONString(duplicateMeshTags.OrderBy(e => e.Source.ToString("yyyyMMddhhmmss") + "/" + e.TagId)).Replace("},{", "},\r\n{")); } var comparer = new CompareOpcTagsP08(toleranceInTicks); var missingOpcTags = opcTags.Where(oTag => !uniqueMeshTags.Contains(oTag, comparer)).ToList(); if (filePrefix != null) { File.WriteAllText($"{filePrefix}missingopc.log", TheCommonUtils.SerializeObjectToJSONString(missingOpcTags.OrderBy(e => e.Source.ToString("yyyyMMddhhmmss") + "/" + e.TagId)).Replace("},{", "},\r\n{")); } var opcTagsClone = opcTags.ToList(); var extraMeshTags = meshTags.Where(mTag => { return(!opcTags.Contains(mTag, comparer)); // possible optimization: remove tags that have already been found, but have to consider entries that apply multiple times (for props-of-props like [tag].[statusCode]) //var oTag = opcTags.FirstOrDefault(t => comparer.Equals(t, mTag)); //if (oTag != null) //{ // //opcTagsClone.Remove(oTag); //} //return oTag == null; }).ToList(); if (filePrefix != null) { File.WriteAllText($"{filePrefix}extramesh.log", TheCommonUtils.SerializeObjectToJSONString(extraMeshTags.OrderBy(e => e.Source.ToString("yyyyMMddhhmmss") + "/" + e.TagId)).Replace("},{", "},\r\n{")); } stats.missingOpcTags = missingOpcTags.Count; stats.extraMeshTags = extraMeshTags.Count; return(stats); }
internal void SetVer(TheRequestData pRequestData, bool tSessionReset, bool UpdateLog, Guid WPID) { TheSessionState pSession = pRequestData?.SessionState; if (pSession == null || pSession.HasExpired) { return; } try { if (tSessionReset) { lock (pSession.MySessionLock) { //pSession.CMember = sstrLocalMachine; pSession.MembUID = ""; pSession.MembPWD = ""; pSession.MembFullName = ""; pSession.Status = "N"; pSession.CID = Guid.Empty; pSession.Debug = 0; pSession.MembLevel = 0; pSession.PUIDHigh = 0; pSession.PUIDLow = 0; //<Fix>3.5.202,CM,5/20/2004,Vertical Application must be reset as well</Fix> pSession.CustomDataLng = 0; pSession.LCID = 0; WriteSession(pSession); } //TheSystemMessageLog.ToCo(string.Format("SESS: Reset Session {0}", pRequestData.SessionState)); } else { if (UpdateLog) { pSession.LastAccess = DateTimeOffset.Now; pSession.cdeCTIM = DateTimeOffset.Now; if (TheCommonUtils.cdeIsLocked(pSession.MySessionLock)) // Is writing already...dont do it again { return; } lock (pSession.MySessionLock) //CODE-REVIEW: Is this really necessarry? { pSession.CurrentWPID = WPID; pSession.Status = "A"; if (pRequestData.ServerTags != null) { pSession.InitReferer = pRequestData.ServerTags.cdeSafeGetValue("HTTP_REFERER"); } if (string.IsNullOrEmpty(pSession.InitReferer) && pRequestData.Header != null) { pSession.InitReferer = pRequestData.Header.cdeSafeGetValue("REFERER"); } if (string.IsNullOrEmpty(pSession.InitReferer) && !string.IsNullOrEmpty(pSession.CurrentURL)) { pSession.InitReferer = pSession.CurrentURL; } string gstrCurURL = pRequestData.RequestUri.LocalPath + "/" + pRequestData.RequestUri.Query; pSession.CurrentURL = gstrCurURL; if (string.IsNullOrEmpty(pSession.InitReferer)) { try { //CM:4.105 No idea why this exists - must be legacy code //if (pSession.StateCookies == null) pSession.StateCookies = new cdeConcurrentDictionary<string, string>(); //string tref = TheCommonUtils.cdeEncrypt(TheCommonUtils.CStr(gstrCurURL), TheBaseAssets.MySecrets.GetAI()); //3.083: Must use AI //pSession.StateCookies.TryAdd(MySite.cdeMID.ToString() + "CDEREF", TheCommonUtils.cdeEscapeString(tref)); pSession.InitReferer = TheCommonUtils.CStr(gstrCurURL); } catch { //ignored } } WriteSession(pSession); // TheSystemMessageLog.ToCo(string.Format("SESS: Updating Session {0}", pRequestData.SessionState)); } } } } catch (Exception e) { TheBaseAssets.MySYSLOG.WriteToLog(1235, new TSM("SSM", "<HR>SetVer: Exception occurred:", e.ToString())); } }
internal bool GetSessionState(Guid pSessionID, TheRequestData pRequestData, bool NoCreate) { if (pRequestData == null) { return(false); } bool IsNewState = false; try { //lock (MySessionStates.MyRecordsLock) //CODE-REVIEW: Why? Validate get session back and has its own log. If Session is null, we can create a { //TheSystemMessageLog.ToCo("SESS: Validating"); if (Guid.Empty != pSessionID) { pRequestData.SessionState = ValidateSEID(pSessionID); //Measure Frequency } if (pRequestData.SessionState == null) { pRequestData.SessionState = GetSessionIDByDeviceID(pRequestData.DeviceID); if (pRequestData.SessionState == null && NoCreate == false) { TheBaseAssets.MySYSLOG.WriteToLog(1234, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("SSM", $"SESS: Creating new Session for {pRequestData.cdeRealPage}")); pRequestData.SessionState = CreateSession(pRequestData, pSessionID); //if (pSessionID != Guid.Empty) pRequestData.SessionState.cdeMID = pSessionID; //Moved to CreateSession to prevent double sessions in StorageMirror if (pRequestData.SessionState.StateCookies == null) { pRequestData.SessionState.StateCookies = new cdeConcurrentDictionary <string, string>(); } if (pRequestData.SessionState.StateCookies.ContainsKey(MySite.cdeMID.ToString() + "CDESEID")) { pRequestData.SessionState.StateCookies[MySite.cdeMID.ToString() + "CDESEID"] = TheCommonUtils.cdeEscapeString(TheCommonUtils.cdeEncrypt(TheCommonUtils.CStr(pRequestData.SessionState.cdeMID), TheBaseAssets.MySecrets.GetAI())); //3.083: Must use SecureID } else { pRequestData.SessionState.StateCookies.TryAdd(MySite.cdeMID.ToString() + "CDESEID", TheCommonUtils.cdeEscapeString(TheCommonUtils.cdeEncrypt(TheCommonUtils.CStr(pRequestData.SessionState.cdeMID), TheBaseAssets.MySecrets.GetAI()))); //3.083: Must use SecureID } WriteSession(pRequestData.SessionState); IsNewState = true; //TheSystemMessageLog.ToCo(string.Format("SESS: Creating Done. New CNT:{0} ID:{1}", MySessionStates.Count, pRequestData.SessionState.cdeMID)); } } //if (!IsNewState) // TheSystemMessageLog.ToCo(string.Format("SESS: Found {0}", pRequestData.SessionState)); } } catch (Exception e) { TheBaseAssets.MySYSLOG.WriteToLog(1233, new TSM("SSM", "<HR>GetSessionState: Exception occured:", e.ToString())); } return(IsNewState); }
private static async Task GetThingPipelineConfigurationRecursiveAsync(TheThing tThing, bool bGeneralize, List <TheThingConfiguration> pipelineConfig, List <TheThing> thingsVisited) { if (tThing == null || thingsVisited.Contains(tThing)) { return; } thingsVisited.Add(tThing); var thingConfig = await tThing.GetThingConfigurationAsync(bGeneralize, true); if (thingConfig == null) { return; } if (thingConfig.ConfigurationValues != null) { var thingReferencesFromProperties = thingConfig.ConfigurationValues.Where(cv => cv.IsThingReference == true); foreach (var thingReferenceProps in thingReferencesFromProperties) { // This is sub optimal: inside GetThingConfiguratioAsync we already have the thing. Export is not perf sensitive so doing it this way instead of restructuring the code var tReferencedThing = TheThingRegistry.GetThingByMID(TheCommonUtils.CGuid(thingReferenceProps.Value), true); if (tReferencedThing == null) { try { var tThingReference = TheCommonUtils.DeserializeJSONStringToObject <TheThingReference>(TheCommonUtils.CStr(thingReferenceProps.Value)); tReferencedThing = tThingReference?.GetMatchingThing(); } catch { } } if (tReferencedThing != null) { await GetThingPipelineConfigurationRecursiveAsync(tReferencedThing, bGeneralize, pipelineConfig, thingsVisited); } } } if (thingConfig.SensorSubscriptions != null) { var sensorTargetThings = thingConfig.SensorSubscriptions.SelectMany(sub => sub.TargetThing.GetMatchingThings()).Distinct(); // Find any things into which this provider is sending sensor data foreach (var sensorTargetThing in sensorTargetThings) { if (sensorTargetThing != null) { await GetThingPipelineConfigurationRecursiveAsync(sensorTargetThing, bGeneralize, pipelineConfig, thingsVisited); } } } if (thingConfig.ThingSubscriptions != null) { // Find any things that this consumer gets data from var consumedThings = thingConfig.ThingSubscriptions.SelectMany(sub => sub.ThingReference.GetMatchingThings()).Distinct().ToList(); foreach (var consumedThing in consumedThings) { if (consumedThing != null) { await GetThingPipelineConfigurationRecursiveAsync(consumedThing, bGeneralize, pipelineConfig, thingsVisited); } } } if (thingConfig.ThingReferences != null) { // Find any things that this thing declares to have a reference to var referencedThings = thingConfig.ThingReferences.SelectMany(thingRef => thingRef.GetMatchingThings()).Distinct().ToList(); foreach (var referencedThing in referencedThings) { if (referencedThing != null) { await GetThingPipelineConfigurationRecursiveAsync(referencedThing, bGeneralize, pipelineConfig, thingsVisited); } } } // Add this thing after any things it depends on (and that it needs to be created before it gets created) pipelineConfig.Add(thingConfig); // Subsequent things depend on this thing // Find things that consumer data from this thing // First find any history consumers (more efficient) var historyConsumers = tThing.Historian?.GetConsumerRegistrations(); if (historyConsumers != null) { foreach (var historyConsumer in historyConsumers) { if (historyConsumer.OwnerThing != null) { await GetThingPipelineConfigurationRecursiveAsync(historyConsumer.OwnerThing, bGeneralize, pipelineConfig, thingsVisited); } } } // Enumerate all consumers and find the ones that subscribe to this thing foreach (var consumerThing in TheThingRegistry.GetBaseEnginesByCap(eThingCaps.SensorConsumer).SelectMany(eng => TheThingRegistry.GetThingsOfEngine(eng.GetEngineName(), eThingCaps.SensorConsumer).Where(thing => !thingsVisited.Contains(thing)))) { var thingSubscriptionResponse = await consumerThing.GetThingSubscriptionsAsync(new MsgGetThingSubscriptions { Generalize = bGeneralize }); if (thingSubscriptionResponse != null && string.IsNullOrEmpty(thingSubscriptionResponse.Error)) { foreach (var thingConsumed in thingSubscriptionResponse.ThingSubscriptions.SelectMany(sub => sub.ThingReference.GetMatchingThings()).Where(thingConsumed => thingConsumed == tThing)) { await GetThingPipelineConfigurationRecursiveAsync(consumerThing, bGeneralize, pipelineConfig, thingsVisited); } } else { // TODO should we fail the export? Log it? Report the error(s) to the caller? } } // Find any provider things that provide data into a sensor property in this thing var sensorProperties = tThing.GetSensorPropertyMetaData(); if (sensorProperties?.Any() == true) { var providerThings = sensorProperties.Select(sensorProp => sensorProp.ProviderInfo.Provider).Distinct().ToList(); foreach (var providerThing in providerThings) { if (providerThing != null && !thingsVisited.Contains(providerThing)) { await GetThingPipelineConfigurationRecursiveAsync(providerThing, bGeneralize, pipelineConfig, thingsVisited); } } } }
/// <summary> /// Creates a ThePipelineConfiguration that only contains the configuration values needed to specialize a pipeline instance. This is typically used an answer file that instantiates a thing pipeline. /// </summary> /// <param name="pipelineConfig">The pipeline configuration to be used as the basis for the answer configuration.</param> /// <param name="bRemoveDefaultedValuesFromPipelineConfig">If true, any configuration values in the pipelineConfig that match the declared default value are removed from both the pipelineConfig (input) and the answer config (return value).</param> /// <returns>The pipeline answer configuration that only contains specialization values.</returns> public static ThePipelineConfiguration GeneratePipelineAnswerConfiguration(ThePipelineConfiguration pipelineConfig, bool bRemoveDefaultedValuesFromPipelineConfig) { var pipelineAnswerConfig = new ThePipelineConfiguration(); pipelineAnswerConfig.ThingConfigurations = new List <TheThingConfiguration>(); foreach (var thingConfig in pipelineConfig.ThingConfigurations) { var thingAnswerConfig = new TheThingConfiguration { ThingSpecializationParameters = thingConfig.ThingSpecializationParameters, }; thingConfig.ThingSpecializationParameters = new Dictionary <string, object>(); if (bRemoveDefaultedValuesFromPipelineConfig) { foreach (var config in thingConfig.ConfigurationValues.ToList()) { if ((config.Value == null && config.DefaultValue == null) || (config.Value != null && TheCommonUtils.CStr(config.Value) == TheCommonUtils.CStr(config.DefaultValue))) { thingConfig.ConfigurationValues.Remove(config); } else { } if (thingAnswerConfig.ThingSpecializationParameters.TryGetValue(config.Name, out var value)) { if ((config.Value == null && value == null) || (config.Value != null && TheCommonUtils.CStr(config.Value) == TheCommonUtils.CStr(value))) { thingAnswerConfig.ThingSpecializationParameters.Remove(config.Name); } } } } pipelineAnswerConfig.ThingConfigurations.Add(thingAnswerConfig); } return(pipelineAnswerConfig); }
private void GetISMHealthData() { if (TheCommonUtils.cdeIsLocked(GetHealthLock) || !AreCounterInit) { return; } lock (GetHealthLock) { MyHealthData.StationWatts = LastStationWatts; MyHealthData.QSenders = TheCDEKPIs.QSenders; MyHealthData.QSReceivedTSM = TheCDEKPIs.QSReceivedTSM; MyHealthData.QSSendErrors = TheCDEKPIs.QSSendErrors; MyHealthData.QSInserted = TheCDEKPIs.QSInserted; MyHealthData.QSQueued = TheCDEKPIs.QSQueued; MyHealthData.QSRejected = TheCDEKPIs.QSRejected; MyHealthData.QSSent = TheCDEKPIs.QSSent; MyHealthData.QKBSent = Math.Floor(TheCDEKPIs.QKBSent > 0 ? TheCDEKPIs.QKBSent / 1024 : 0); MyHealthData.QKBReceived = Math.Floor(TheCDEKPIs.QKBReceived > 0 ? TheCDEKPIs.QKBReceived / 1024 : 0); MyHealthData.QSLocalProcessed = TheCDEKPIs.QSLocalProcessed; MyHealthData.CCTSMsRelayed = TheCDEKPIs.CCTSMsRelayed; MyHealthData.CCTSMsReceived = TheCDEKPIs.CCTSMsReceived; MyHealthData.CCTSMsEvaluated = TheCDEKPIs.CCTSMsEvaluated; MyHealthData.EventTimeouts = TheCDEKPIs.EventTimeouts; MyHealthData.TotalEventTimeouts = TheCDEKPIs.TotalEventTimeouts; MyHealthData.KPI1 = TheCDEKPIs.KPI1; MyHealthData.KPI2 = TheCDEKPIs.KPI2; MyHealthData.KPI3 = TheCDEKPIs.KPI3; MyHealthData.KPI4 = TheCDEKPIs.KPI4; MyHealthData.KPI5 = TheCDEKPIs.KPI5; MyHealthData.KPI6 = TheCDEKPIs.KPI6; MyHealthData.KPI7 = TheCDEKPIs.KPI7; MyHealthData.KPI8 = TheCDEKPIs.KPI8; MyHealthData.KPI9 = TheCDEKPIs.KPI9; MyHealthData.KPI10 = TheCDEKPIs.KPI10; MyHealthData.HTCallbacks = TheCDEKPIs.HTCallbacks; TheCDEKPIs.Reset(); MyHealthData.HostAddress = System.Environment.MachineName; MyHealthData.FriendlyName = TheBaseAssets.MyServiceHostInfo.GetPrimaryStationURL(false); MyHealthData.HostVersion = TheBaseAssets.MyServiceHostInfo.Version; MyHealthData.LastUpdate = DateTimeOffset.Now; DiskInfo di = GetDiskInfo(); MyHealthData.DiskSpaceFree = di.TotalFreeSpace; if (di.TotalSize > 0 && di.TotalFreeSpace <= di.TotalSize) { MyHealthData.DiskSpaceUsage = ((di.TotalSize - di.TotalFreeSpace) / di.TotalSize) * 100; } else { MyHealthData.DiskSpaceUsage = 0; } try { if (wmiObjectWin32 != null) { var tRed = wmiObjectWin32.Get().Cast <ManagementObject>(); var memoryValues = tRed.Select(mo => new { FreePhysicalMemory = TheCommonUtils.CDbl(mo["FreePhysicalMemory"].ToString()), TotalVisibleMemorySize = TheCommonUtils.CDbl(mo["TotalVisibleMemorySize"].ToString()) }).FirstOrDefault(); if (memoryValues != null) { MyHealthData.RAMAvailable = memoryValues.FreePhysicalMemory; //var percent = ((memoryValues.TotalVisibleMemorySize - memoryValues.FreePhysicalMemory) / memoryValues.TotalVisibleMemorySize) * 100; } } } catch (Exception e) { TheBaseAssets.MySYSLOG.WriteToLog(8007, new TSM("jcHealth", "wmiObject-Warning (Not Supported on XP)", eMsgLevel.l2_Warning, e.ToString())); } try { MeasureProcessCPU(); MyHealthData.cdeLoad = cpuUsageSinceLastMeasure; // Can also use cpuUsageSinceStart, depending on purpose of metric } catch (Exception e) { TheBaseAssets.MySYSLOG.WriteToLog(8007, new TSM("jcHealth", "Could not get CPU usage for process", eMsgLevel.l2_Warning, e.ToString())); } try { if (MyCPULoadCounter != null) { MyHealthData.CPULoad = TheCommonUtils.CDbl(MyCPULoadCounter.NextValue()).cdeTruncate(2); } } catch (Exception e) { TheBaseAssets.MySYSLOG.WriteToLog(8007, new TSM("jcHealth", "PerfCounter-Warning (Not Supported on XP)", eMsgLevel.l2_Warning, e.ToString())); MyCPULoadCounter = new PerformanceCounter { CategoryName = "Processor Information", CounterName = "% Processor Time", InstanceName = "_Total" }; } try { //if (MyHealthData != null && MyCDELoadCounter != null) // MyHealthData.cdeLoad = MyCDELoadCounter.NextValue().cdeTruncate(2); } catch (Exception e) { TheBaseAssets.MySYSLOG.WriteToLog(8007, new TSM("jcHealth", "PerfCounter-Warning (Not Supported on XP)", eMsgLevel.l2_Warning, e.ToString())); MyCDELoadCounter = new PerformanceCounter { CategoryName = "Process", CounterName = "% Processor Time", InstanceName = Process.GetCurrentProcess().ProcessName }; } if (UseNicState) { UpdateNetworkInterface(); } else { if (MyCounter?.Count > 0) { foreach (var t in MyCounter) { try { MyHealthData.SetProperty(t.PropertyName, t.PerfCounter.NextValue()); } catch (Exception) { TheBaseAssets.MySYSLOG.WriteToLog(8007, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("jcHealth", $"PerfCounter: {t.PropertyName} could not be read", eMsgLevel.l2_Warning)); } } } } try { MyHealthData.cdeCTIM = DateTimeOffset.Now; MyHealthData.LastUpdate = DateTimeOffset.Now; using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("select CreationDate from Win32_Process where Name='System'")) { foreach (ManagementObject share in searcher.Get()) { foreach (PropertyData pData in share.Properties) { if (pData.Name.Equals("CreationDate")) { DateTime dc = ManagementDateTimeConverter.ToDateTime(TheCommonUtils.CStr(pData.Value)); //dc = dc.AddTicks(-TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).Ticks).ToLocalTime(); TimeSpan ts = DateTime.Now.Subtract(dc); MyHealthData.PCUptime = ts.TotalMinutes; } } } } /// cde Process Specific Information int nProcessID = Process.GetCurrentProcess().Id; using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("select CreationDate,WorkingSetSize,HandleCount,ThreadCount from Win32_Process where ProcessID='" + nProcessID + "'")) { foreach (ManagementObject share in searcher.Get()) { foreach (PropertyData PC in share.Properties) { string objName = PC.Name; string objValue = ""; if (PC.Value != null && PC.Value.ToString() != "") { switch (PC.Value.GetType().ToString()) { case "System.String[]": string[] str = (string[])PC.Value; foreach (string st in str) { objValue += st + " "; } break; case "System.UInt16[]": ushort[] shortData = (ushort[])PC.Value; foreach (ushort st in shortData) { objValue += st.ToString() + " "; } break; default: objValue = PC.Value.ToString(); break; } } switch (objName) { case "CreationDate": DateTime dc = ManagementDateTimeConverter.ToDateTime(PC.Value.ToString()); //dc=dc.AddTicks(-TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).Ticks).ToLocalTime(); TimeSpan ts = DateTime.Now.Subtract(dc); MyHealthData.cdeUptime = ts.TotalMinutes; break; case "WorkingSetSize": MyHealthData.cdeWorkingSetSize = TheCommonUtils.CLng(objValue) / 1024; break; case "HandleCount": MyHealthData.cdeHandles = TheCommonUtils.CInt(objValue); break; case "ThreadCount": MyHealthData.cdeThreadCount = TheCommonUtils.CInt(objValue); break; } } break; } } //if (!WasRunBefore) UpdateDiagInfo(MyHealthData); } catch (Exception e) { TheBaseAssets.MySYSLOG.WriteToLog(8008, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("jcHealth", "Ring0-Warning", eMsgLevel.l2_Warning, e.ToString())); } } }
private async Task RunScriptAsync(TheScript script, TheThing variables, int stepNumber = 1, bool replay = false) { TheThing variablesSnapshot; try { for (; stepNumber <= script.Steps.Length; stepNumber++) { //Clone thing before step occurs variablesSnapshot = new TheThing(); variables.CloneThingAndPropertyMetaData(variablesSnapshot, true); var step = script.Steps[stepNumber - 1]; var existingSnapshot = MyScriptTableStorage.MyMirrorCache.GetEntryByFunc(snapshot => snapshot.ScriptName == script.Name && snapshot.ScriptStep == stepNumber); if (existingSnapshot?.Disabled == true) { TheBaseAssets.MySYSLOG.WriteToLog(175002, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseThing.EngineName, "Finished script step: skipped step because it was disabled", eMsgLevel.l3_ImportantMessage, TheCommonUtils.SerializeObjectToJSONString(new Dictionary <String, object> { { "Script", script.Name }, { "Step", stepNumber }, { "Message", step.Message.MessageName }, { "Target", step.Message.Target }, }))); UpdateStorageList(script.Name, "Disabled", stepNumber, script, variablesSnapshot, replay); continue; } if (step.Condition != null) { var condition = TheCommonUtils.GenerateFinalStr(step.Condition, variables); if ( (condition == "" || condition.ToLowerInvariant() == "false" || condition.Trim() == "0") || (condition.StartsWith("!") && condition.Length >= 1 && (condition.Substring(1).ToLowerInvariant() == "true") || condition.Substring(1).Trim() == "1")) { TheBaseAssets.MySYSLOG.WriteToLog(175002, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseThing.EngineName, "Finished script step: skipped step due to condition not met", eMsgLevel.l3_ImportantMessage, TheCommonUtils.SerializeObjectToJSONString(new Dictionary <String, object> { { "Script", script.Name }, { "Step", stepNumber }, { "Message", step.Message.MessageName }, { "Target", step.Message.Target }, { "Condition", step.Condition }, { "ConditionEvaluated", condition }, }))); UpdateStorageList(script.Name, "Condition Not Met", stepNumber, script, variablesSnapshot, replay); continue; } } var messageType = TheCommonUtils.GenerateFinalStr(step.Message.MessageName, variables); var txtPayload = TheCommonUtils.GenerateFinalStr(step.Message.Parameters?.ToString(), variables); { var txtPayload2 = txtPayload?.Replace("\"\\\"", ""); var txtPayload3 = txtPayload2?.Replace("\\\"\"", ""); txtPayload = txtPayload3; } // TODO Need a simpler and more flexible way to specify thing address in the script JSON var target = step.Message.Target; if (target == null) { if (txtPayload.Contains("EngineName")) { var payloadDict = TheCommonUtils.DeserializeJSONStringToObject <Dictionary <string, object> >(txtPayload); object engineNameInferred = null; if (payloadDict?.TryGetValue("EngineName", out engineNameInferred) == true && !string.IsNullOrEmpty(engineNameInferred?.ToString())) { target = new TheMessageAddress { EngineName = engineNameInferred.ToString() }; } } } if (target.EngineName.StartsWith("%") || target.EngineName.StartsWith("{")) { target.EngineName = TheCommonUtils.GenerateFinalStr(target.EngineName, variables); // TODO Clean this up: support a serialized TheMessageAddress in the engine name, so that an output variable can be fed into a method invocation try { var newTarget = TheCommonUtils.DeserializeJSONStringToObject <TheMessageAddress>(target.EngineName); if (newTarget != null) { target = newTarget; } } catch { // parsing error: ignore, will result in other errors downstream } } await TheThingRegistry.WaitForInitializeAsync(target); bool bDoRetry; int remainingRetryCount = step.RetryCount ?? 0; do { existingSnapshot = MyScriptTableStorage.MyMirrorCache.GetEntryByFunc(snapshot => snapshot.ScriptName == script.Name && snapshot.ScriptStep == stepNumber); if (existingSnapshot?.Disabled == true) { TheBaseAssets.MySYSLOG.WriteToLog(175002, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseThing.EngineName, "Finished script step: skipped step because it was disabled", eMsgLevel.l3_ImportantMessage, TheCommonUtils.SerializeObjectToJSONString(new Dictionary <String, object> { { "Script", script.Name }, { "Step", stepNumber }, { "Message", step.Message.MessageName }, { "Target", step.Message.Target }, }))); UpdateStorageList(script.Name, "Disabled", stepNumber, script, variablesSnapshot, replay); break; } bDoRetry = false; var response = await TheCommRequestResponse.PublishRequestAsync(MyBaseThing, target, messageType, new TimeSpan(0, 0, 0, 0, step.Message.timeout), null, txtPayload, null); if (!string.IsNullOrEmpty(response?.PLS)) { var outputs = TheCommonUtils.DeserializeJSONStringToObject <Dictionary <string, object> >(response.PLS); if (outputs != null) { if (step.Message.outputs != null) { foreach (var output in step.Message.outputs) { if (output.Key == "*") { variables.SetProperty(output.Value, response.PLS); } else if (outputs.TryGetValue(output.Key, out var outputValue)) { variables.SetProperty(output.Value, outputValue); if (output.Value.Contains("Error") && !string.IsNullOrEmpty(TheCommonUtils.CStr(outputValue))) { TheBaseAssets.MySYSLOG.WriteToLog(175004, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseThing.EngineName, "Error in script step: output reported error", eMsgLevel.l1_Error, TheCommonUtils.SerializeObjectToJSONString(new Dictionary <String, object> { { "Script", script.Name }, { "Step", stepNumber }, { "Message", messageType }, { "Target", target }, { "PLS", txtPayload }, { "Response", response }, { "ResponsePLS", response?.PLS }, }))); UpdateStorageList(script.Name, $"Error {outputValue} in output", stepNumber, script, variablesSnapshot, replay); if (remainingRetryCount < 0 || remainingRetryCount > 0) { remainingRetryCount--; bDoRetry = true; } string retriesRemaining = bDoRetry ? (remainingRetryCount >= 0 ? $"{remainingRetryCount + 1}" : "infinite") : "none"; MyBaseThing.SetStatus(3, $"Error in script '{script?.Name}', step {stepNumber}: output '{output.Value}' reported error {outputValue}. Retries remaining: {retriesRemaining}"); } } else { // TODO provide access to sub-elements in the JSON //var outputParts = output.Key.Split('/'); //dynamic currentNode = outputs; //foreach (var outputPart in outputParts) //{ // if (currentNode.TryGetValue(outputPart, out var nextNode)) // { // currentNode = nextNode; // } //} } } } TheBaseAssets.MySYSLOG.WriteToLog(175003, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseThing.EngineName, "Finished script step", eMsgLevel.l3_ImportantMessage, TheCommonUtils.SerializeObjectToJSONString(new Dictionary <String, object> { { "Script", script.Name }, { "Step", stepNumber }, { "Message", messageType }, { "Target", target }, { "PLS", txtPayload }, { "ResponsePLS", response.PLS }, }))); UpdateStorageList(script.Name, "Finished", stepNumber, script, variablesSnapshot, replay); } else { TheBaseAssets.MySYSLOG.WriteToLog(175004, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseThing.EngineName, "Error in script step: no outputs found in response", eMsgLevel.l1_Error, TheCommonUtils.SerializeObjectToJSONString(new Dictionary <String, object> { { "Script", script.Name }, { "Step", stepNumber }, { "Message", messageType }, { "Target", target }, { "PLS", txtPayload }, { "Response", response }, { "ResponsePLS", response?.PLS }, }))); UpdateStorageList(script.Name, "Error: No Output", stepNumber, script, variablesSnapshot, replay); if (step.DontRetryOnEmptyResponse != true && (remainingRetryCount < 0 || remainingRetryCount > 0)) { remainingRetryCount--; bDoRetry = true; } string retriesRemaining = bDoRetry ? (remainingRetryCount >= 0 ? $"{remainingRetryCount + 1}" : "infinite") : "none"; MyBaseThing.SetStatus(3, $"Error in script '{script?.Name}', step {stepNumber}: no outputs found in response. Retries remaining: {retriesRemaining}"); } } else { TheBaseAssets.MySYSLOG.WriteToLog(175005, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseThing.EngineName, "Error Script step: timeout", eMsgLevel.l1_Error, TheCommonUtils.SerializeObjectToJSONString(new Dictionary <String, object> { { "Script", script.Name }, { "Step", stepNumber }, { "Message", messageType }, { "Target", target }, { "PLS", txtPayload }, { "Response", response }, }))); UpdateStorageList(script.Name, "Error: Timeout", stepNumber, script, variablesSnapshot, replay); //Retries infinitely unless count is specified if (remainingRetryCount < 0 || remainingRetryCount > 0) { remainingRetryCount--; bDoRetry = true; } string retriesRemaining = bDoRetry ? (remainingRetryCount >= 0 ? $"{remainingRetryCount + 1}" : "infinite") : "none"; MyBaseThing.SetStatus(3, $"Error in script '{script?.Name}', step {stepNumber}: timeout. Retries remaining: {retriesRemaining}"); } if (bDoRetry) { await TheCommonUtils.TaskDelayOneEye(30000, 100).ConfigureAwait(false); } } while (bDoRetry && TheBaseAssets.MasterSwitch); } } catch (Exception e) { TheBaseAssets.MySYSLOG.WriteToLog(175006, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseThing.EngineName, "Error in script step", eMsgLevel.l1_Error, TheCommonUtils.SerializeObjectToJSONString(new Dictionary <String, object> { { "Script", script.Name }, { "Exception", e.Message }, }))); MyBaseThing.SetStatus(3, $"Error in script '{script?.Name}': {e.Message}"); //Save variables instead of snapshot in case of error UpdateStorageList(script.Name, $"Error: {e.Message}", stepNumber, script, variables, replay); } }
/// <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, }); } }
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); }
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); } }
bool Matches(TheThing thingToMatch) { if (_thingReference.PropertiesToMatch == null) { return(true); } foreach (var propToMatch in _thingReference.PropertiesToMatch) { if (!Regex.IsMatch(TheThing.GetSafePropertyString(thingToMatch, propToMatch.Key), TheCommonUtils.CStr(propToMatch.Value))) { return(false); } } return(true); }