/// <summary> /// Finds a free socket port in the given range on a given IP Address /// </summary> /// <param name="LowRange">Low boundary of the area to scan</param> /// <param name="UpperRange">Upper boundary of the area to scan</param> /// <param name="OnThisIP">IP Address to scan on</param> /// <returns></returns> public static uint GetFreePort(uint LowRange, uint UpperRange, IPAddress OnThisIP) { uint num; Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); while (true) { num = TheCommonUtils.GetRandomUInt(LowRange, UpperRange); IPEndPoint localEP = new IPEndPoint(OnThisIP, (int)num); try { socket.Bind(localEP); } catch (Exception exception) { TheBaseAssets.MySYSLOG.WriteToLog(146, new TSM("UPnP", "GetFreePort Error", eMsgLevel.l1_Error, exception.ToString())); } break; } socket.Close(); return(num); }
public void GetRandomUIntTest(int factor) { Thread.Sleep(100); var valueDistribution = new Dictionary <int, int>(); int count = 300000 * factor; for (int i = 0; i < count; i++) { uint result; result = TheCommonUtils.GetRandomUInt(1, 1000); Assert.IsTrue(result >= 1 && result < 1000); if (result != 1) { } int iResult = (int)result; if (valueDistribution.ContainsKey(iResult)) { valueDistribution[iResult] = valueDistribution[iResult] + 1; } else { valueDistribution.Add(iResult, 1); } } int acceptableCount = (int)((count / 1000) * 0.70); for (int i = 1; i < 1000; i++) { int valueCount = 0; valueDistribution.TryGetValue(i, out valueCount); if (valueCount < acceptableCount) { count++; } Assert.IsFalse(valueCount < acceptableCount, $"Count for {i} not acceptable: {valueCount} should be {acceptableCount}"); } }
public override bool DoCreateUX() { var tFlds = TheNMIEngine.AddStandardForm(MyBaseThing, "FACEPLATE", 18, null, null, 0, "...Virtual State Sensors"); SummaryForm = (tFlds["DashIcon"] as TheDashPanelInfo); MyStatusForm = tFlds["Form"] as TheFormInfo; MyStatusForm.ModelID = "VStateSensorForm"; TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.TileButton, 1112, 2, 0, "Details...", null, new nmiCtrlTileButton { OnClick = $"TTS:%RealSensorThing%", RenderTarget = "VSDETBUT%cdeMID%", NoTE = true, Background = "transparent", TileWidth = 3, TileHeight = 1, TileFactorY = 2, ClassName = "cdeEmptyButtoninner" }); var ts = TheNMIEngine.AddStatusBlock(MyBaseThing, MyStatusForm, 100); ts["Group"].SetParent(1); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.CollapsibleGroup, 200, 2, 0xc0, "V-Sensor Settings...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup() { DoClose = true, MaxTileWidth = 6, IsSmall = true, ParentFld = 1 })); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.ComboBox, 210, 2, 0xc0, "Sensor Type", "StateSensorType", new nmiCtrlComboBox { ParentFld = 200, FldWidth = 4, TileWidth = 6, Options = "analog;binary;state" }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.CollapsibleGroup, 220, 2, 0xc0, "Settings (Analog Sensor Only)...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup() { DoClose = true, MaxTileWidth = 6, ParentFld = 1, IsSmall = true })); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.SingleEnded, 225, 2, 0xc0, "Sensor Units", "StateSensorUnit", new nmiCtrlSingleEnded { ParentFld = 220, TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.SingleEnded, 221, 2, 0x0, "Sensor Value Name", "StateSensorValueName", new nmiCtrlSingleEnded { ParentFld = 220, TileWidth = 6 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.Number, 228, 2, 0xc0, "Average Value", "StateSensorAverage", new nmiCtrlNumber { ParentFld = 220, TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.Number, 230, 2, 0xc0, "Min Value", "StateSensorMinValue", new nmiCtrlNumber { ParentFld = 220, TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.Number, 240, 2, 0xc0, "Max Value", "StateSensorMaxValue", new nmiCtrlNumber { ParentFld = 220, TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.Number, 245, 2, 0xc0, "Value Divider", "StateSensorScaleFactor", new nmiCtrlNumber { TileWidth = 3, ParentFld = 220 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.Number, 246, 2, 0xc0, "Digits", "StateSensorDigits", new nmiCtrlNumber { MinValue = 0, TileWidth = 3, ParentFld = 220 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.SingleCheck, 247, 2, 0xc0, "Force Absolute", "StateSensorIsAbs", new nmiCtrlSingleCheck { TileWidth = 3, ParentFld = 220 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.ThingPicker, 212, 2, 0xc0, "Thing Picker", "RealSensorThing", new nmiCtrlThingPicker() { ParentFld = 200, IncludeEngines = true, IncludeRemotes = true }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.PropertyPicker, 213, 2, 0xc0, "Property Picker", "RealSensorProperty", new nmiCtrlPropertyPicker() { ParentFld = 200, ThingFld = 212 }); GetProperty("RealSensorProperty", true).RegisterEvent(eThingEvents.PropertyChanged, (p) => { EngageMapper(); }); var tEngage = TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.TileButton, 214, 2, 0xC0, "Restart Sensor", null, new nmiCtrlNumber { ParentFld = 200, TileWidth = 6, NoTE = true }); tEngage.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "reset", (sender, para) => { EngageMapper(); }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.CollapsibleGroup, 249, 2, 0xc0, "Advanced Settings...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup() { DoClose = true, MaxTileWidth = 6, ParentFld = 200, IsSmall = true })); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.SingleCheck, 250, 2, 0xC0, "Replicate", "IsGlobal", new nmiCtrlNumber { ParentFld = 249, TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.Number, 255, 2, 0xC0, "NMI Interval", "Interval", new nmiCtrlNumber { ParentFld = 249, TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.CollapsibleGroup, 260, 2, 0xc0, "Pre-Processing...", null, ThePropertyBag.Create(new nmiCtrlCollapsibleGroup() { DoClose = true, MaxTileWidth = 6, ParentFld = 220, IsSmall = true })); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.ComboBox, 261, 2, 0xC0, "Pre-Processing", "PrePro", new nmiCtrlComboBox { Options = "Raw Value:0;Min Value:1;Max Value:2;Average:3", ParentFld = 260, TileWidth = 6, DefaultValue = "0" }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.Number, 265, 2, 0xC0, "PrePro Window", "PreProTime", new nmiCtrlNumber { ParentFld = 260, TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.SingleEnded, 216, 2, 0x0, "Match Pattern", nameof(ValueMatchPattern), new nmiCtrlSingleEnded { ParentFld = 200, TileWidth = 6 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.SingleEnded, 217, 2, 0x0, "Filter Pattern", nameof(ValueFilterPattern), new nmiCtrlSingleEnded { ParentFld = 200, TileWidth = 6 }); if (TheCommonUtils.CBool(TheBaseAssets.MySettings.GetSetting("RedPill"))) { var t = TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.TileButton, 266, 2, 0xC0, "Test", null, new nmiCtrlTileButton { NoTE = true, Background = "transparent", TileWidth = 3, TileHeight = 1 }); t.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "hakko", (sender, para) => { cdeP tRW = GetProperty("RawValue", true); cdeP.SetSafePropertyNumber(tRW, "StateSensorMinValue", TheCommonUtils.GetRandomUInt(0, 100)); TheThing.SetSafePropertyNumber(MyBaseThing, "[RawValue].[StateSensorAverage]", TheCommonUtils.GetRandomUInt(0, 100)); }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.Number, 267, 2, 0xc0, "Average Value", "[RawValue].[StateSensorAverage]", new nmiCtrlNumber { TileWidth = 3 }); TheNMIEngine.AddSmartControl(MyBaseThing, MyStatusForm, eFieldType.Number, 268, 2, 0xc0, "Min Value", "[RawValue].[StateSensorMinValue]", new nmiCtrlNumber { TileWidth = 3 }); } return(true); }
/// <summary> /// Checks if a node is the current owner for the given source. Waits for a random time, up to 5 seconds, for an owner ship ack from other nodes before doing the actual check. /// </summary> /// <param name="correlationToken"></param> /// <param name="sourceORG"></param> /// <param name="ownerORG"></param> /// <returns></returns> internal async Task <bool?> CheckOwnerAsync(string correlationToken, string sourceORG, string ownerORG) { if (_pendingAcks.TryGetValue(correlationToken, out var taskCS)) { try { await TheCommonUtils.TaskWaitTimeout(taskCS.Task, new TimeSpan(0, 0, 5) + new TimeSpan(0, 0, 0, 0, (int)TheCommonUtils.GetRandomUInt(0, 5000))).ConfigureAwait(false); } catch { } } return(CheckOwner(sourceORG, ownerORG)); }
static public bool CreatePerformanceHeader(TheThing pBaseThing, TheFormInfo pFormInfo, int pFldOrder, int pParent, string pSensorPicSource = "SENSORS/Images/SensorLogo_156x78.png", string pLogo = null) { var tG = TheNMIEngine.AddSmartControl(pBaseThing, pFormInfo, eFieldType.TileGroup, pFldOrder, 0, 0, null, null, new nmiCtrlTileGroup() { ParentFld = pParent, /*MaxTileWidth = 18,*/ Background = "transparent" }); tG.AddOrUpdatePlatformBag(eWebPlatform.Mobile, new nmiPlatBag { MaxTileWidth = 6 }); tG.AddOrUpdatePlatformBag(eWebPlatform.HoloLens, new nmiPlatBag { MaxTileWidth = 12 }); TheNMIEngine.AddSmartControl(pBaseThing, pFormInfo, eFieldType.TileGroup, pFldOrder + 1, 0, 0, null, null, new nmiCtrlTileGroup() { ParentFld = pFldOrder, TileWidth = 6 }); //TheNMIEngine.AddSmartControl(pBaseThing, pFormInfo, eFieldType.StatusLight, pFldOrder + 2, 0, 0, "Current status", "StatusLevel", new TheNMIBaseControl { ParentFld = pFldOrder + 1, TileHeight = 1, TileWidth = 4 }); //TheNMIEngine.AddSmartControl(pBaseThing, pFormInfo, eFieldType.SmartLabel, pFldOrder + 3, 0, 0, null, "LastMessage", new nmiCtrlTextArea() { ParentFld = pFldOrder + 1, TileWidth = 6, TileHeight = 1, Background = "transparent",NoTE=true, FontSize = 20, HorizontalAlignment = "left", VerticalAlignment = "center"/*, Value = pCurrentStatus*/ }); var tMiniStatus = TheNMIEngine.AddSmartControl(pBaseThing, pFormInfo, eFieldType.TileGroup, pFldOrder + 5, 0, 0, null, null, new nmiCtrlTileGroup() { ParentFld = pFldOrder, TileWidth = 6, Background = "transparent" }); if (!string.IsNullOrEmpty(pLogo)) { var tBut2 = TheNMIEngine.AddSmartControl(pBaseThing, pFormInfo, eFieldType.Picture, pFldOrder + 7, 2, 0, null, null, new nmiCtrlPicture() { ParentFld = pFldOrder + 5, TileWidth = 2, TileHeight = 1, NoTE = true, Background = "transparent", Source = pLogo }); tBut2.RegisterUXEvent(pBaseThing, eUXEvents.OnClick, "ImageClick2", (sender, para) => { uint min = TheCommonUtils.CUInt(TheThing.GetSafePropertyNumber(pBaseThing, "StateSensorMinValue")); uint max = TheCommonUtils.CUInt(TheThing.GetSafePropertyNumber(pBaseThing, "StateSensorMaxValue")); TheThing.SetSafePropertyNumber(pBaseThing, "QValue", TheCommonUtils.GetRandomUInt(min, max)); }); } var tFld = TheNMIEngine.AddSmartControl(pBaseThing, pFormInfo, eFieldType.TileGroup, pFldOrder + 8, 0, 0, null, null, new nmiCtrlTileGroup() { ParentFld = pFldOrder, TileWidth = 6, TileHeight = 2, Background = "transparent" }); tFld.AddOrUpdatePlatformBag(eWebPlatform.Any, new nmiPlatBag { Hide = true }); tFld.AddOrUpdatePlatformBag(eWebPlatform.Desktop, new nmiPlatBag { Show = true }); tFld.AddOrUpdatePlatformBag(eWebPlatform.XBox, new nmiPlatBag { Show = true }); TheNMIEngine.AddSmartControl(pBaseThing, pFormInfo, eFieldType.SmartLabel, pFldOrder + 9, 0, 0, null, "FriendlyName", new nmiCtrlSmartLabel() { ParentFld = pFldOrder + 8, NoTE = true, TileWidth = 3, TileHeight = 1, LabelClassName = "cdeSelDevice", FontSize = 20, HorizontalAlignment = "left", VerticalAlignment = "center" /*, Value = pSelectedDeviceName*/ }); if (!string.IsNullOrEmpty(pSensorPicSource)) { var tBut3 = TheNMIEngine.AddSmartControl(pBaseThing, pFormInfo, eFieldType.Picture, pFldOrder + 10, 0, 0, null, null, new nmiCtrlPicture() { NoTE = true, ParentFld = pFldOrder + 8, TileWidth = 3, TileHeight = 1, Source = pSensorPicSource });; tBut3.RegisterUXEvent(pBaseThing, eUXEvents.OnClick, "LogoClick3", (sender, para) => { uint min = TheCommonUtils.CUInt(TheThing.GetSafePropertyNumber(pBaseThing, "StateSensorMinValue")); uint max = TheCommonUtils.CUInt(TheThing.GetSafePropertyNumber(pBaseThing, "StateSensorMaxValue")); TheThing.SetSafePropertyNumber(pBaseThing, "QValue", TheCommonUtils.GetRandomUInt(min, max)); }); } TheNMIEngine.AddSmartControl(pBaseThing, pFormInfo, eFieldType.StatusLight, pFldOrder + 12, 0, 0, null, "StatusLevel", new TheNMIBaseControl { NoTE = true, TileHeight = 1, TileWidth = 1, ParentFld = pFldOrder + 8 }); TheNMIEngine.AddSmartControl(pBaseThing, pFormInfo, eFieldType.TextArea, pFldOrder + 11, 0, 0, null, "LastMessage", new nmiCtrlTextArea { TileHeight = 1, ParentFld = pFldOrder + 8, TileWidth = 5, FontSize = 12, NoTE = true, Foreground = "gray", Background = "Transparent" }); return(true); }
private async Task PlaybackLoop(TheThing tThingOverride, CancellationToken cancelToken, IEnumerable <object> updatesToPlay, TimeSpan startupDelayRange, bool bFromAutoStart) { var lastItemTime = DateTimeOffset.MaxValue; var previousUpdateTime = DateTimeOffset.Now; if (bFromAutoStart && AutoStartDelay > 0 && tThingOverride.FriendlyName != "ignored") // hack to delay only for real things { TheBaseAssets.MySYSLOG.WriteToLog(700, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(MyBaseThing.EngineName, $"Playback loop for {tThingOverride?.FriendlyName} holding for {AutoStartDelay} ms.", eMsgLevel.l6_Debug)); await TheCommonUtils.TaskDelayOneEye(AutoStartDelay, 100); } TheBaseAssets.MySYSLOG.WriteToLog(700, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(MyBaseThing.EngineName, $"Playback loop started for {tThingOverride?.FriendlyName}", eMsgLevel.l6_Debug)); if (startupDelayRange > TimeSpan.Zero) { var startupDelayInMs = (uint)startupDelayRange.TotalMilliseconds; var randomDelay = TheCommonUtils.GetRandomUInt(0, startupDelayInMs); await TheCommonUtils.TaskDelayOneEye((int)randomDelay, 100, cancelToken).ConfigureAwait(false); } var eventconverter = TheEventConverters.GetEventConverter("JSON Things", true) as JSonThingEventConverter; // These get set in the callback from ProcessEventData so we can process them afterwards List <Tuple <TheThing, TheThingStore> > updatesProcessed = new List <Tuple <TheThing, TheThingStore> >(); eventconverter.ApplyUpdateCallback = (thing, update) => { updatesProcessed.Add(Tuple.Create(thing, update)); return(false); }; eventconverter.eventDecoder = (o => o.ToString()); do { foreach (var updateObj in updatesToPlay) { updatesProcessed.Clear(); eventconverter.ProcessEventData(tThingOverride, updateObj, DateTimeOffset.Now); if (IsDisabled) { //How can a cacnel token be set? break; } if (cancelToken.IsCancellationRequested) { break; } foreach (var updateAndThing in updatesProcessed) { TimeSpan timeToWait = TimeSpan.Zero; var tThingProcessed = updateAndThing.Item1; var tThingUpdateProcessed = updateAndThing.Item2; if (PlaybackSpeedFactor > 0) { var now = DateTimeOffset.Now; var timeSinceLastUpdate = now - previousUpdateTime; var timeToNextItem = tThingUpdateProcessed.cdeCTIM - lastItemTime; if (timeToNextItem > TimeSpan.Zero && timeSinceLastUpdate < timeToNextItem) { timeToWait = timeToNextItem - timeSinceLastUpdate; if (timeToWait > TimeSpan.Zero) { if (PlaybackSpeedFactor != 1) { timeToWait = new TimeSpan(0, 0, 0, 0, (int)(timeToWait.TotalMilliseconds / PlaybackSpeedFactor)); } if (MaxItemDelay > 0 && timeToWait.TotalMilliseconds > MaxItemDelay) { timeToWait = new TimeSpan(0, 0, 0, 0, MaxItemDelay); } } else { // falling behind! } } } else if (PlaybackItemDelay > 0) { timeToWait = new TimeSpan(0, 0, 0, 0, PlaybackItemDelay); } if (timeToWait > TimeSpan.Zero) { await TheCommonUtils.TaskDelayOneEye((int)timeToWait.TotalMilliseconds, 100, cancelToken).ConfigureAwait(false); } if (cancelToken.IsCancellationRequested) { break; } lastItemTime = tThingUpdateProcessed.cdeCTIM; { var now = DateTimeOffset.Now; previousUpdateTime = now; var timeToSend = AdjustTimestamps ? now : tThingUpdateProcessed.cdeCTIM; if (tThingOverride != null) { if (tThingUpdateProcessed.PB.ContainsKey("FriendlyName")) { tThingUpdateProcessed.PB["FriendlyName"] = tThingOverride.FriendlyName; } if (tThingUpdateProcessed.PB.ContainsKey("ID")) { tThingUpdateProcessed.PB["ID"] = tThingOverride.FriendlyName; } if (tThingUpdateProcessed.PB.ContainsKey("EngineName")) { tThingUpdateProcessed.PB["EngineName"] = tThingOverride.EngineName; } if (tThingUpdateProcessed.PB.ContainsKey("DeviceType")) { tThingUpdateProcessed.PB["DeviceType"] = tThingOverride.DeviceType; } if (tThingUpdateProcessed.PB.ContainsKey("DeviceType")) { tThingUpdateProcessed.PB["DeviceType"] = tThingOverride.DeviceType; } } tThingProcessed.SetProperties(tThingUpdateProcessed.PB, timeToSend); Interlocked.Add(ref _propertyCounter, tThingUpdateProcessed.PB.Count); _lastSendTime = timeToSend; } } } } while (RestartPlayback && !cancelToken.IsCancellationRequested && !IsDisabled); TheBaseAssets.MySYSLOG.WriteToLog(700, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(MyBaseThing.EngineName, $"Playback loop stopped for {tThingOverride?.FriendlyName}", eMsgLevel.l6_Debug)); }