private async Task RunPlaybackAsync(IEnumerable <cdeP> allProperties, IEnumerable <object> thingUpdates, TimeSpan startupDelayRange, bool bFromAutoStart, double propCountBefore) { for (int j = 1; j <= ReplayCount; j++) { playbackCancel?.Cancel(); playbackCancel = new CancellationTokenSource(); var cancelCombined = CancellationTokenSource.CreateLinkedTokenSource(playbackCancel.Token, TheBaseAssets.MasterSwitchCancelationToken); IsStarted = true; MyBaseThing.StatusLevel = 1; MyBaseThing.LastMessage = $"Playback started: {ItemCount} items. {ParallelPlaybackCount} things."; for (int i = 1; i <= ParallelPlaybackCount; i++) { TheThing tThingOverride = null; if (!string.IsNullOrEmpty(PlaybackEngineName)) { if (TheThingRegistry.GetBaseEngine(PlaybackEngineName) == null) { TheCDEngines.RegisterNewMiniRelay(PlaybackEngineName); } var thingName = $"{MyBaseThing.FriendlyName}{i:D6}"; tThingOverride = TheThingRegistry.GetThingByID(PlaybackEngineName, thingName, true); if (tThingOverride == null) { tThingOverride = new TheThing { FriendlyName = thingName, ID = thingName, EngineName = PlaybackEngineName, DeviceType = PlaybackDeviceType, }; foreach (var prop in allProperties) { tThingOverride.SetProperty(prop.Name, prop.Value, prop.cdeT); } TheThingRegistry.RegisterThing(tThingOverride); } // This only works if the plug-in is actually installed, not with mini relay //var createThingInfo = new TheThingRegistry.MsgCreateThingRequestV1 //{ // EngineName = PlaybackEngineName, // DeviceType = PlaybackDeviceType, // InstanceId = thingName, // FriendlyName = thingName, // CreateIfNotExist = true, // DoNotModifyIfExists = true, // OwnerAddress = MyBaseThing, // Properties = new Dictionary<string, object> { { "ID", thingName } }, //}; //tThingOverride = await TheThingRegistry.CreateOwnedThingAsync(createThingInfo, new TimeSpan(0, 1, 0)); if (tThingOverride == null) { MyBaseThing.LastMessage = "Error creating playback thing"; break; } } var playbackTask = TheCommonUtils.cdeRunTaskChainAsync($"Playback{i}", o => PlaybackLoop(tThingOverride, cancelCombined.Token, thingUpdates, startupDelayRange, bFromAutoStart), true); playbackTasks.Add(playbackTask); } _ = await TheCommonUtils.TaskWhenAll(playbackTasks).ContinueWith(async(t) => { try { PlaybackDuration = sw.Elapsed; sw.Stop(); OnKpiUpdate(null); var propCount = Gen_Stats_PropertyCounter - propCountBefore; var message = $"Playback done. {propCount} props in {PlaybackDuration}. {propCount / PlaybackDuration.TotalSeconds} props/s. {ItemCount * ParallelPlaybackCount / PlaybackDuration.TotalSeconds} items/s."; //MyBaseThing.LastMessage = message; TheBaseAssets.MySYSLOG.WriteToLog(700, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(MyBaseThing.EngineName, message, eMsgLevel.l6_Debug)); await StopPlaybackAsync(message); _ = new CDMyMeshManager.Contracts.MsgReportTestStatus { NodeId = TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID, PercentCompleted = (j * 1.0 / ReplayCount) * 100, SuccessRate = 100, Status = j == ReplayCount ? CDMyMeshManager.Contracts.eTestStatus.Success : CDMyMeshManager.Contracts.eTestStatus.Running, TestRunId = TheCommonUtils.CGuid(TheBaseAssets.MySettings.GetSetting("TestRunID")), Timestamp = DateTimeOffset.Now, ResultDetails = new Dictionary <string, object> { { "Message", message }, { "PropertyCount", propCount }, { "DurationInSeconds", PlaybackDuration.TotalSeconds } }, }.Publish().Result; } catch { } }, TaskContinuationOptions.OnlyOnRanToCompletion); } }
void sinkTriggerTimeout(object pTime) { if (!TheBaseAssets.MasterSwitch) { mTimer?.Dispose(); mTimer = null; return; } if (IsDisabled) { if (MyBaseThing.StatusLevel != 0) { MyBaseThing.StatusLevel = 0; MyBaseThing.LastMessage = "Countdown disabled"; } return; } else if (MyBaseThing.StatusLevel == 0) { MyBaseThing.StatusLevel = 1; MyBaseThing.LastMessage = "Countdown enabled"; } if (TheCommonUtils.cdeIsLocked(TriggerLock)) { return; } lock (TriggerLock) { int tTIme = (TheCommonUtils.CInt(MyBaseThing.Value) - 1); if (tTIme >= 0) { MyBaseThing.Value = tTIme.ToString(); if (TheCommonUtils.CBool(TheBaseAssets.MySettings.GetSetting("VThing-SimTest")) == true && MyBaseThing.ID == "TESTSIM") { var response = new CDMyMeshManager.Contracts.MsgReportTestStatus { NodeId = TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID, PercentCompleted = 100 - tTIme, SuccessRate = 100 - tTIme, Status = CDMyMeshManager.Contracts.eTestStatus.Running, TestRunId = TheCommonUtils.CGuid(TheBaseAssets.MySettings.GetSetting("TestRunID")), Timestamp = DateTimeOffset.Now, ResultDetails = new Dictionary <string, object> { { "SomeKPI", 123 }, }, }.Publish(); } } if (tTIme <= 0 && mTimer != null) { mTimer.Dispose(); mTimer = null; IsActive = false; MyBaseThing.StatusLevel = 0; if (TheCommonUtils.CBool(TheBaseAssets.MySettings.GetSetting("VThing-SimTest")) == true && MyBaseThing.ID == "TESTSIM") { TheCommonUtils.TaskDelayOneEye(2000, 100).ContinueWith(t => { var response = new CDMyMeshManager.Contracts.MsgReportTestStatus { NodeId = TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID, PercentCompleted = 100, SuccessRate = 100, Status = CDMyMeshManager.Contracts.eTestStatus.Success, TestRunId = TheCommonUtils.CGuid(TheBaseAssets.MySettings.GetSetting("TestRunID")), Timestamp = DateTimeOffset.Now, ResultDetails = new Dictionary <string, object> { { "SomeKPI", 123 }, }, }.Publish(); }); } if (Restart) { sinkTriggered(this.GetProperty(nameof(StartValue), false)); } else { CountBar?.SetUXProperty(Guid.Empty, string.Format("MaxValue=100")); } } } }
private async Task StartPlaybackAsync(bool bFromAutoStart) { try { lock (startLock) { if (_isStarting || IsStarted || playbackCancel?.IsCancellationRequested == false || playbackTasks?.Count > 0) { MyBaseThing.LastMessage = "Playback already started"; return; } _isStarting = true; } } catch { } try { if (_kpiTimer == null) { _kpiTimer = new Timer(OnKpiUpdate, null, 0, (int)_kpiInterval.TotalMilliseconds); } else { _kpiTimer.Change(0, (int)_kpiInterval.TotalMilliseconds); } sw = new Stopwatch(); sw.Start(); MyBaseThing.LastMessage = "Loading data..."; var thingUpdates = await LoadThingUpdatesAsync(InputFileName); ItemCount = thingUpdates.Count(); LoadDuration = sw.Elapsed; MyBaseThing.LastMessage = $"Data loaded: {ItemCount} items in {LoadDuration}. Starting playback..."; sw.Restart(); var propCountBefore = Gen_Stats_PropertyCounter; playbackTasks.Clear(); playbackCancel?.Cancel(); playbackCancel = new CancellationTokenSource(); var cancelCombined = CancellationTokenSource.CreateLinkedTokenSource(playbackCancel.Token, TheBaseAssets.MasterSwitchCancelationToken); var startupDelayRange = new TimeSpan(0, 0, 0); var tThingWithAllProperties = new TheThing { FriendlyName = "ignored", ID = "ignored", EngineName = PlaybackEngineName, DeviceType = PlaybackDeviceType, }; _ = new CDMyMeshManager.Contracts.MsgReportTestStatus { NodeId = TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID, PercentCompleted = 0, SuccessRate = 0, Status = CDMyMeshManager.Contracts.eTestStatus.Running, TestRunId = TheCommonUtils.CGuid(TheBaseAssets.MySettings.GetSetting("TestRunID")), Timestamp = DateTimeOffset.Now, ResultDetails = new Dictionary <string, object> { { "Message", "Starting playback " }, }, }.Publish().Result; if (bFromAutoStart && AutoStartDelay > 0) { TheBaseAssets.MySYSLOG.WriteToLog(700, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(MyBaseThing.EngineName, $"Playback gathering all properties from the data file.", eMsgLevel.l6_Debug)); await PlaybackLoop(tThingWithAllProperties, cancelCombined.Token, thingUpdates, startupDelayRange, bFromAutoStart); TheBaseAssets.MySYSLOG.WriteToLog(700, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(MyBaseThing.EngineName, $"Playback gathered all properties from the data file. Found {tThingWithAllProperties.MyPropertyBag.Count} properties.", eMsgLevel.l6_Debug)); } var allProperties = tThingWithAllProperties.GetAllProperties(10).Where(p => p.Name != nameof(TheThing.ID) && p.Name != nameof(TheThing.FriendlyName) && p.Name != nameof(TheThing.EngineName) && p.Name != nameof(TheThing.DeviceType)); _ = new CDMyMeshManager.Contracts.MsgReportTestStatus { NodeId = TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID, PercentCompleted = 0, SuccessRate = 0, Status = CDMyMeshManager.Contracts.eTestStatus.Running, TestRunId = TheCommonUtils.CGuid(TheBaseAssets.MySettings.GetSetting("TestRunID")), Timestamp = DateTimeOffset.Now, ResultDetails = new Dictionary <string, object> { { "Message", "Starting playback loops" }, { "UniquePropertyCount", allProperties.Count() }, { "NumberThings", ParallelPlaybackCount }, }, }.Publish().Result; _ = RunPlaybackAsync(allProperties, thingUpdates, startupDelayRange, bFromAutoStart, propCountBefore); } catch (Exception e) { IsStarted = false; MyBaseThing.StatusLevel = 2; MyBaseThing.LastMessage = $"Error starting playback: {e.Message}"; } finally { lock (startLock) { _isStarting = false; } } }