Files
DP44/Common/DTS.Common.DataModel/StateMachines/OverallArmStatusStateMachine.cs

384 lines
25 KiB
C#
Raw Normal View History

2026-04-17 14:55:32 -04:00
using Stateless;
using Prism.Ioc;
using DTS.Common.Enums.TSRAIRGo;
using DTS.Common.Utilities.Logging;
using System;
using Prism.Events;
namespace DTS.Common.DataModel.StateMachines
{
public class OverallArmStatusStateMachine
{
private readonly IEventAggregator _eventAggregator;
private StateMachine<ArmStateMachineStates.States, Triggers> overallArmStatusStateMachine = null;
private StateMachine<ArmStateMachineStates.States, Triggers>.TriggerWithParameters<ArmStateMachineStates.States> NoDataToDownloadTrigger;
private StateMachine<ArmStateMachineStates.States, Triggers>.TriggerWithParameters<ArmStateMachineStates.States> DataNeverDownloadedTrigger;
private StateMachine<ArmStateMachineStates.States, Triggers>.TriggerWithParameters<ArmStateMachineStates.States> DASNotFoundTrigger;
private StateMachine<ArmStateMachineStates.States, Triggers>.TriggerWithParameters<ArmStateMachineStates.States> FlashClearTrigger;
private StateMachine<ArmStateMachineStates.States, Triggers>.TriggerWithParameters<ArmStateMachineStates.States> WaitingForTriggerTrigger;
private StateMachine<ArmStateMachineStates.States, Triggers>.TriggerWithParameters<ArmStateMachineStates.States> WaitingForScheduleTrigger;
private StateMachine<ArmStateMachineStates.States, Triggers>.TriggerWithParameters<ArmStateMachineStates.States> WaitingForIntervalTrigger;
private StateMachine<ArmStateMachineStates.States, Triggers>.TriggerWithParameters<ArmStateMachineStates.States> RecordingTrigger;
private StateMachine<ArmStateMachineStates.States, Triggers>.TriggerWithParameters<ArmStateMachineStates.States> DoneRecordingTrigger;
private StateMachine<ArmStateMachineStates.States, Triggers>.TriggerWithParameters<ArmStateMachineStates.States> ErrorTrigger;
private StateMachine<ArmStateMachineStates.States, Triggers>.TriggerWithParameters<ArmStateMachineStates.States> CheckingForDataTrigger;
private StateMachine<ArmStateMachineStates.States, Triggers>.TriggerWithParameters<ArmStateMachineStates.States> GettingEventInfoTrigger;
private StateMachine<ArmStateMachineStates.States, Triggers>.TriggerWithParameters<ArmStateMachineStates.States> ReadyForDownloadTrigger;
private StateMachine<ArmStateMachineStates.States, Triggers>.TriggerWithParameters<ArmStateMachineStates.States> DownloadTrigger;
private StateMachine<ArmStateMachineStates.States, Triggers>.TriggerWithParameters<ArmStateMachineStates.States> DownloadCleaningUpTrigger;
private StateMachine<ArmStateMachineStates.States, Triggers>.TriggerWithParameters<ArmStateMachineStates.States> DownloadFinishedTrigger;
private StateMachine<ArmStateMachineStates.States, Triggers>.TriggerWithParameters<ArmStateMachineStates.States> IDLETrigger;
private StateMachine<ArmStateMachineStates.States, Triggers>.TriggerWithParameters<ArmStateMachineStates.States> StreamingTrigger;
private StateMachine<ArmStateMachineStates.States, Triggers>.TriggerWithParameters<ArmStateMachineStates.States> DisarmTrigger;
private StateMachine<ArmStateMachineStates.States, Triggers>.TriggerWithParameters<ArmStateMachineStates.States> RearmingTrigger;
ArmStateMachineStates.States CurrentOverallStatusState = ArmStateMachineStates.States.CheckingForDAS;
/// <summary>
/// Initialize the Event Aggregator and the Overall Arm Status state machine.
/// </summary>
public OverallArmStatusStateMachine()
{
_eventAggregator = ContainerLocator.Container.Resolve<IEventAggregator>();
Initialize();
}
public enum Triggers
{
bFillingBuffer,
CheckingForData,
ConfigurationIsSet,
DASNotFound,
DataNeverDownloaded,
Disarm,
DoneRecording,
Downloading,
DownloadCleaningUp,
DownloadFinished,
Error,
Faulted,
FlashClear,
GettingEventInfo,
IDLE,
IntervalRecording,
NoDataToDownload,
NonIntervalRecording,
PostTestProcessing,
ReadyForDownload,
Rearming,
Recording,
RunButton,
Streaming,
WaitingForTrigger,
WaitingForSchedule,
WaitingForInterval,
a,
c,
d,
e,
h,
n,
rr,
tt,
uu,
yy
}
private void Initialize()
{
overallArmStatusStateMachine = new StateMachine<ArmStateMachineStates.States, Triggers>(ArmStateMachineStates.States.CheckingForDAS);
NoDataToDownloadTrigger = overallArmStatusStateMachine.SetTriggerParameters<ArmStateMachineStates.States>(Triggers.NoDataToDownload);
DataNeverDownloadedTrigger = overallArmStatusStateMachine.SetTriggerParameters<ArmStateMachineStates.States>(Triggers.DataNeverDownloaded);
DASNotFoundTrigger = overallArmStatusStateMachine.SetTriggerParameters<ArmStateMachineStates.States>(Triggers.DASNotFound);
FlashClearTrigger = overallArmStatusStateMachine.SetTriggerParameters<ArmStateMachineStates.States>(Triggers.FlashClear);
RecordingTrigger = overallArmStatusStateMachine.SetTriggerParameters<ArmStateMachineStates.States>(Triggers.Recording);
DoneRecordingTrigger = overallArmStatusStateMachine.SetTriggerParameters<ArmStateMachineStates.States>(Triggers.DoneRecording);
WaitingForTriggerTrigger = overallArmStatusStateMachine.SetTriggerParameters<ArmStateMachineStates.States>(Triggers.WaitingForTrigger);
WaitingForScheduleTrigger = overallArmStatusStateMachine.SetTriggerParameters<ArmStateMachineStates.States>(Triggers.WaitingForSchedule);
WaitingForIntervalTrigger = overallArmStatusStateMachine.SetTriggerParameters<ArmStateMachineStates.States>(Triggers.WaitingForInterval);
CheckingForDataTrigger = overallArmStatusStateMachine.SetTriggerParameters<ArmStateMachineStates.States>(Triggers.CheckingForData);
ErrorTrigger = overallArmStatusStateMachine.SetTriggerParameters<ArmStateMachineStates.States>(Triggers.Error);
GettingEventInfoTrigger = overallArmStatusStateMachine.SetTriggerParameters<ArmStateMachineStates.States>(Triggers.GettingEventInfo);
ReadyForDownloadTrigger = overallArmStatusStateMachine.SetTriggerParameters<ArmStateMachineStates.States>(Triggers.ReadyForDownload);
DownloadTrigger = overallArmStatusStateMachine.SetTriggerParameters<ArmStateMachineStates.States>(Triggers.Downloading);
DownloadCleaningUpTrigger = overallArmStatusStateMachine.SetTriggerParameters<ArmStateMachineStates.States>(Triggers.DownloadCleaningUp);
DownloadFinishedTrigger = overallArmStatusStateMachine.SetTriggerParameters<ArmStateMachineStates.States>(Triggers.DownloadFinished);
IDLETrigger = overallArmStatusStateMachine.SetTriggerParameters<ArmStateMachineStates.States>(Triggers.IDLE);
StreamingTrigger = overallArmStatusStateMachine.SetTriggerParameters<ArmStateMachineStates.States>(Triggers.Streaming);
DisarmTrigger = overallArmStatusStateMachine.SetTriggerParameters<ArmStateMachineStates.States>(Triggers.Disarm);
RearmingTrigger = overallArmStatusStateMachine.SetTriggerParameters<ArmStateMachineStates.States>(Triggers.Rearming);
//--------------------CheckingForDAS--------------------
overallArmStatusStateMachine.Configure(ArmStateMachineStates.States.CheckingForDAS)
.OnEntryFrom(DASNotFoundTrigger, o => SetOverallStatus(o))
.OnEntryFrom(FlashClearTrigger, o => SetOverallStatus(o))
.OnEntryFrom(ReadyForDownloadTrigger, o => SetOverallStatus(o))
.PermitReentry(Triggers.DASNotFound)
.Permit(Triggers.Recording, ArmStateMachineStates.States.Recording)
.Permit(Triggers.ReadyForDownload, ArmStateMachineStates.States.IDLE)
.Permit(Triggers.NoDataToDownload, ArmStateMachineStates.States.IDLE)
.Permit(Triggers.DataNeverDownloaded, ArmStateMachineStates.States.IDLE)
.Permit(Triggers.DoneRecording, ArmStateMachineStates.States.IDLE)
.Permit(Triggers.Streaming, ArmStateMachineStates.States.Streaming)
.Permit(Triggers.FlashClear, ArmStateMachineStates.States.ClearingFlash)
.Permit(Triggers.WaitingForTrigger, ArmStateMachineStates.States.WaitingForTrigger)
.Permit(Triggers.WaitingForSchedule, ArmStateMachineStates.States.WaitingForSchedule)
.Permit(Triggers.WaitingForInterval, ArmStateMachineStates.States.WaitingForInterval);
//--------------------IDLE--------------------------------
overallArmStatusStateMachine.Configure(ArmStateMachineStates.States.IDLE)
.OnEntryFrom(ReadyForDownloadTrigger, o => SetOverallStatus(o))
.OnEntryFrom(NoDataToDownloadTrigger, o => SetOverallStatus(o))
.OnEntryFrom(DataNeverDownloadedTrigger, o => SetOverallStatus(o))
.OnEntryFrom(DoneRecordingTrigger, o => SetOverallStatus(o))
.OnEntryFrom(FlashClearTrigger, o => SetOverallStatus(o))
.OnEntryFrom(WaitingForTriggerTrigger, o => SetOverallStatus(o))
.OnEntryFrom(StreamingTrigger, o => SetOverallStatus(o))
.Permit(Triggers.DASNotFound, ArmStateMachineStates.States.CheckingForDAS)
.Permit(Triggers.FlashClear, ArmStateMachineStates.States.ClearingFlash)
.Permit(Triggers.WaitingForTrigger, ArmStateMachineStates.States.WaitingForTrigger)
.Permit(Triggers.WaitingForSchedule, ArmStateMachineStates.States.WaitingForSchedule)
.Permit(Triggers.WaitingForInterval, ArmStateMachineStates.States.WaitingForInterval)
.PermitReentry(Triggers.ReadyForDownload)
.PermitReentry(Triggers.NoDataToDownload)
.PermitReentry(Triggers.DataNeverDownloaded)
.PermitReentry(Triggers.DoneRecording);
//--------------------Streaming--------------------------
overallArmStatusStateMachine.Configure(ArmStateMachineStates.States.Streaming)
.OnEntryFrom(StreamingTrigger, o => SetOverallStatus(o))
.Permit(Triggers.DASNotFound, ArmStateMachineStates.States.CheckingForDAS)
.Permit(Triggers.DoneRecording, ArmStateMachineStates.States.IDLE)
.Permit(Triggers.NoDataToDownload, ArmStateMachineStates.States.IDLE)
.PermitReentry(Triggers.Streaming);
//--------------------ClearingFlash-----------------------
overallArmStatusStateMachine.Configure(ArmStateMachineStates.States.ClearingFlash)
.OnEntryFrom(FlashClearTrigger, o => SetOverallStatus(o))
.Ignore(Triggers.ReadyForDownload)
.Ignore(Triggers.NoDataToDownload)
.Ignore(Triggers.DataNeverDownloaded)
.Permit(Triggers.WaitingForTrigger, ArmStateMachineStates.States.WaitingForTrigger)
.Permit(Triggers.WaitingForSchedule, ArmStateMachineStates.States.WaitingForSchedule)
.Permit(Triggers.WaitingForInterval, ArmStateMachineStates.States.WaitingForInterval)
.Permit(Triggers.Disarm, ArmStateMachineStates.States.Disarmed)
.Permit(Triggers.Streaming, ArmStateMachineStates.States.Streaming)
.Permit(Triggers.DASNotFound, ArmStateMachineStates.States.CheckingForDAS)
.PermitReentry(Triggers.FlashClear);
//--------------------WaitingForTrigger------------------
overallArmStatusStateMachine.Configure(ArmStateMachineStates.States.WaitingForTrigger)
.OnEntryFrom(WaitingForTriggerTrigger, o => SetOverallStatus(o))
.Ignore(Triggers.DataNeverDownloaded)
.Permit(Triggers.DASNotFound, ArmStateMachineStates.States.CheckingForDAS)
.Permit(Triggers.Recording, ArmStateMachineStates.States.Recording)
.Permit(Triggers.DoneRecording, ArmStateMachineStates.States.IDLE)
.Permit(Triggers.ReadyForDownload, ArmStateMachineStates.States.IDLE)
.Permit(Triggers.NoDataToDownload, ArmStateMachineStates.States.IDLE)
.Permit(Triggers.Disarm, ArmStateMachineStates.States.Disarmed)
.Permit(Triggers.Rearming, ArmStateMachineStates.States.Rearming)
.PermitReentry(Triggers.WaitingForTrigger)
.PermitReentry(Triggers.WaitingForSchedule)
.PermitReentry(Triggers.WaitingForInterval);
//--------------------WaitingForSchedule------------------
overallArmStatusStateMachine.Configure(ArmStateMachineStates.States.WaitingForSchedule)
.OnEntryFrom(WaitingForScheduleTrigger, o => SetOverallStatus(o))
.OnEntryFrom(DisarmTrigger, o => SetOverallStatus(o))
.Ignore(Triggers.DataNeverDownloaded)
.Permit(Triggers.DASNotFound, ArmStateMachineStates.States.CheckingForDAS)
.Permit(Triggers.Recording, ArmStateMachineStates.States.Recording)
.Permit(Triggers.DoneRecording, ArmStateMachineStates.States.IDLE)
.Permit(Triggers.WaitingForInterval, ArmStateMachineStates.States.WaitingForInterval)
.Permit(Triggers.ReadyForDownload, ArmStateMachineStates.States.IDLE)
.Permit(Triggers.NoDataToDownload, ArmStateMachineStates.States.IDLE)
.Permit(Triggers.Disarm, ArmStateMachineStates.States.Disarmed)
.PermitReentry(Triggers.WaitingForSchedule);
//--------------------WaitingForInterval------------------
overallArmStatusStateMachine.Configure(ArmStateMachineStates.States.WaitingForInterval)
.OnEntryFrom(WaitingForIntervalTrigger, o => SetOverallStatus(o))
.OnEntryFrom(DisarmTrigger, o => SetOverallStatus(o))
.Ignore(Triggers.DataNeverDownloaded)
.Permit(Triggers.DASNotFound, ArmStateMachineStates.States.CheckingForDAS)
.Permit(Triggers.Recording, ArmStateMachineStates.States.Recording)
.Permit(Triggers.DoneRecording, ArmStateMachineStates.States.IDLE)
.Permit(Triggers.ReadyForDownload, ArmStateMachineStates.States.IDLE)
.Permit(Triggers.NoDataToDownload, ArmStateMachineStates.States.IDLE)
.Permit(Triggers.Disarm, ArmStateMachineStates.States.Disarmed)
.PermitReentry(Triggers.WaitingForInterval);
//--------------------Recording--------------------------
overallArmStatusStateMachine.Configure(ArmStateMachineStates.States.Recording)
.OnEntryFrom(RecordingTrigger, o => SetOverallStatus(o))
.OnEntryFrom(DoneRecordingTrigger, o => SetOverallStatus(o))
.OnEntryFrom(WaitingForIntervalTrigger, o => SetOverallStatus(o))
.Permit(Triggers.DASNotFound, ArmStateMachineStates.States.CheckingForDAS)
.Permit(Triggers.DoneRecording, ArmStateMachineStates.States.PostTestProcessing)
.Permit(Triggers.WaitingForTrigger, ArmStateMachineStates.States.WaitingForTrigger)
.Permit(Triggers.WaitingForInterval, ArmStateMachineStates.States.WaitingForInterval)
.Permit(Triggers.Rearming, ArmStateMachineStates.States.Rearming)
.Permit(Triggers.ReadyForDownload, ArmStateMachineStates.States.IDLE)
.Permit(Triggers.NoDataToDownload, ArmStateMachineStates.States.IDLE)
.Permit(Triggers.DataNeverDownloaded, ArmStateMachineStates.States.ReadyForDownload)
.Permit(Triggers.Disarm, ArmStateMachineStates.States.Disarmed)
.PermitReentry(Triggers.Recording);
//--------------------Rearming-----------------
overallArmStatusStateMachine.Configure(ArmStateMachineStates.States.Rearming)
.OnEntryFrom(RecordingTrigger, o => SetOverallStatus(o))
.OnEntryFrom(WaitingForTriggerTrigger, o => SetOverallStatus(o))
.Permit(Triggers.WaitingForTrigger, ArmStateMachineStates.States.WaitingForTrigger)
.Permit(Triggers.WaitingForInterval, ArmStateMachineStates.States.WaitingForInterval)
.Permit(Triggers.Recording, ArmStateMachineStates.States.Recording)
.PermitReentry(Triggers.Rearming);
//--------------------Disarmed-----------------
overallArmStatusStateMachine.Configure(ArmStateMachineStates.States.Disarmed)
.OnEntryFrom(DisarmTrigger, o => SetOverallStatus(o))
.Permit(Triggers.DASNotFound, ArmStateMachineStates.States.CheckingForDAS)
.Permit(Triggers.NoDataToDownload, ArmStateMachineStates.States.IDLE)
.Permit(Triggers.ReadyForDownload, ArmStateMachineStates.States.IDLE)
.Permit(Triggers.DataNeverDownloaded, ArmStateMachineStates.States.IDLE)
.Permit(Triggers.FlashClear, ArmStateMachineStates.States.ClearingFlash);
//--------------------PostTestProcessing-----------------
overallArmStatusStateMachine.Configure(ArmStateMachineStates.States.PostTestProcessing)
.OnEntryFrom(DoneRecordingTrigger, o => SetOverallStatus(o))
.Permit(Triggers.GettingEventInfo, ArmStateMachineStates.States.GettingEventInfo)
.PermitReentry(Triggers.PostTestProcessing);
//--------------------CheckingForData-----------------
overallArmStatusStateMachine.Configure(ArmStateMachineStates.States.CheckingForData)
.OnEntryFrom(DoneRecordingTrigger, o => SetOverallStatus(o))
.OnEntryFrom(CheckingForDataTrigger, o => SetOverallStatus(o))
.Permit(Triggers.GettingEventInfo, ArmStateMachineStates.States.GettingEventInfo)
.PermitReentry(Triggers.DoneRecording)
.PermitReentry(Triggers.CheckingForData);
//--------------------GettingEventInfo-----------------
overallArmStatusStateMachine.Configure(ArmStateMachineStates.States.GettingEventInfo)
.OnEntryFrom(GettingEventInfoTrigger, o => SetOverallStatus(o))
.OnEntryFrom(DataNeverDownloadedTrigger, o => SetOverallStatus(o))
.Permit(Triggers.DataNeverDownloaded, ArmStateMachineStates.States.ReadyForDownload);
//--------------------ReadyForDownload-----------------
overallArmStatusStateMachine.Configure(ArmStateMachineStates.States.ReadyForDownload)
.OnEntryFrom(DataNeverDownloadedTrigger, o => SetOverallStatus(o))
.OnEntryFrom(ReadyForDownloadTrigger, o => SetOverallStatus(o))
.OnEntryFrom(FlashClearTrigger, o => SetOverallStatus(o))
.OnEntryFrom(WaitingForTriggerTrigger, o => SetOverallStatus(o)) //In case Flash Clear finishes very quickly
.OnEntryFrom(WaitingForScheduleTrigger, o => SetOverallStatus(o))
.OnEntryFrom(WaitingForIntervalTrigger, o => SetOverallStatus(o))
.Permit(Triggers.DASNotFound, ArmStateMachineStates.States.IDLE)
.Permit(Triggers.Downloading, ArmStateMachineStates.States.Downloading)
.Permit(Triggers.FlashClear, ArmStateMachineStates.States.ClearingFlash)
.Permit(Triggers.WaitingForTrigger, ArmStateMachineStates.States.WaitingForTrigger)
.Permit(Triggers.WaitingForSchedule, ArmStateMachineStates.States.WaitingForSchedule)
.Permit(Triggers.WaitingForInterval, ArmStateMachineStates.States.WaitingForInterval)
.Ignore(Triggers.DataNeverDownloaded)
.PermitReentry(Triggers.ReadyForDownload);
string graph = Stateless.Graph.UmlDotGraph.Format(overallArmStatusStateMachine.GetInfo());
graph = graph.Replace("DTS.DASLib.Service.StateMachine.", "");
}
public delegate void OverallStatusStateChangeDelegate(ArmStateMachineStates.States previousState, ArmStateMachineStates.States nextState);
/// <summary>
/// Handler for consumers to be notified when overall state transitions
/// </summary>
public event OverallStatusStateChangeDelegate OverallStatusStateChange;
/// <summary>
/// Display a message in the Global Status field.
/// </summary>
/// <param name="newState"></param>
private void SetOverallStatus(ArmStateMachineStates.States newState)
{
if (newState != CurrentOverallStatusState)
{
APILogger.Log($"Transitioning from {CurrentOverallStatusState} to {newState}");
OverallStatusStateChange?.Invoke(CurrentOverallStatusState, newState);
CurrentOverallStatusState = newState;
}
}
public ArmStateMachineStates.States GetDASStatus()
{
return CurrentOverallStatusState;
}
public void FireTrigger(Triggers trigger, ArmStateMachineStates.States state)
{
try
{
//why specify state here? shouldn't that be done based on current state/trigger?
switch (trigger)
{
case Triggers.DASNotFound:
overallArmStatusStateMachine.Fire(DASNotFoundTrigger, state);
break;
case Triggers.NoDataToDownload:
overallArmStatusStateMachine.Fire(NoDataToDownloadTrigger, state);
break;
case Triggers.DataNeverDownloaded:
overallArmStatusStateMachine.Fire(DataNeverDownloadedTrigger, state);
break;
case Triggers.DoneRecording:
overallArmStatusStateMachine.Fire(DoneRecordingTrigger, state);
break;
case Triggers.FlashClear:
overallArmStatusStateMachine.Fire(FlashClearTrigger, state);
break;
case Triggers.WaitingForTrigger:
overallArmStatusStateMachine.Fire(WaitingForTriggerTrigger, state);
break;
case Triggers.WaitingForSchedule:
overallArmStatusStateMachine.Fire(WaitingForScheduleTrigger, state);
break;
case Triggers.WaitingForInterval:
overallArmStatusStateMachine.Fire(WaitingForIntervalTrigger, state);
break;
case Triggers.Recording:
overallArmStatusStateMachine.Fire(RecordingTrigger, state);
break;
case Triggers.PostTestProcessing:
overallArmStatusStateMachine.Fire(DoneRecordingTrigger, state);
break;
case Triggers.CheckingForData:
overallArmStatusStateMachine.Fire(CheckingForDataTrigger, state);
break;
case Triggers.GettingEventInfo:
overallArmStatusStateMachine.Fire(GettingEventInfoTrigger, state);
break;
case Triggers.ReadyForDownload:
overallArmStatusStateMachine.Fire(ReadyForDownloadTrigger, state);
break;
case Triggers.Error:
overallArmStatusStateMachine.Fire(ErrorTrigger, state);
break;
case Triggers.Streaming:
overallArmStatusStateMachine.Fire(StreamingTrigger, state);
break;
case Triggers.Disarm:
overallArmStatusStateMachine.Fire(DisarmTrigger, state);
break;
case Triggers.Rearming:
overallArmStatusStateMachine.Fire(RearmingTrigger, state);
break;
default:
break;
}
}
catch (Exception ex)
{
APILogger.Log(ex.Message);
}
}
}
}