--- source_files: - DataPRO/IService/StateMachine/Triggers.cs - DataPRO/IService/StateMachine/IDASState.cs - DataPRO/IService/StateMachine/DASState.cs - DataPRO/IService/StateMachine/States.cs - DataPRO/IService/StateMachine/StateMachineBootstrap.cs generated_at: "2026-04-16T03:56:17.184753+00:00" model: "Qwen/Qwen3-Coder-Next-FP8" schema_version: 1 sha256: "86e0fafc151b8d16" --- # State Machine Module Documentation ## 1. Purpose This module implements a state machine for managing the operational lifecycle of a data acquisition system (DAS), using the `Stateless` library. It defines a finite state machine over a set of discrete states (e.g., `Prepare`, `HardwareDiscovery`, `Configure`, `Realtime`) and triggers (e.g., `PingAndConnect`, `ApplyConfiguration`, `StartRealtime`) that govern transitions between those states. The module centralizes system state management and provides high-level methods (e.g., `PingAndConnect`, `UpdateConfig`, `StartRealtime`) that configure and fire state transitions with associated parameters and callbacks. It acts as the orchestrator for hardware initialization, configuration, diagnostics, and real-time data acquisition workflows. ## 2. Public Interface ### `enum Trigger` - **Definition**: `enum Trigger { PingAndConnect, Reset, ResolveChannelsAuto, ResolveChannelsManual, ApplyConfiguration, TurnOffExcitation, Cancel, Finish, Arm, StartRealtime, RequeryDevice, Download }` - **Behavior**: Defines the set of events that can cause state transitions in the state machine. Each trigger corresponds to a specific user or system-initiated action. ### `interface IDASState` - **Properties**: - `Status Status { get; }` — Returns the shared `Status` object (see `DASState`). - `IDASFactory DASFactory { get; set; }` — Factory used to create DAS components. - `Action OnEntry { get; }` — Action to execute on state entry (defaults to `OnEnterState`). - `Action OnExit { get; }` — Action to execute on state exit (defaults to `OnExitState`). - `State State { get; }` — The enum value representing this state. - **Methods**: - `void OnEnterState()` — Virtual method called on state entry (logs state name). - `void OnExitState()` — Virtual method called on state exit (logs state name). ### `interface IDASStateWithSelector : IDASState` - **Methods**: - `IDASState StateSelector()` — Returns the next state to transition to dynamically (used for conditional transitions). ### `abstract class DASState : IDASState` - **Properties**: - `IDASFactory DASFactory { get; set; }` - `abstract State State { get; }` - `virtual Action OnEntry { get => OnEnterState; }` - `virtual Action OnExit { get => OnExitState; }` - **Properties**: - `Status Status { get; }` — Returns the *shared static* `_status` instance (see **Gotchas**). - **Methods**: - `virtual void OnEnterState()` — Logs `"Enter {State} State"`. - `virtual void OnExitState()` — Logs `"Exit {State} State"`. ### `abstract class DASStateSelector : DASState, IDASStateWithSelector` - **Methods**: - `public abstract IDASState StateSelector();` — Must be implemented to determine dynamic next state. ### `enum State` - **Definition**: `enum State { Prepare, HardwareDiscovery, HardwareDiscoveryStart, Configure, ConfigureStart, Diagnose, Realtime, Arming, Arm, Download, RealtimeStart, DownloadStart }` - **Behavior**: Defines the set of states in the state machine. Some states (`HardwareDiscoveryStart`, `ConfigureStart`, `RealtimeStart`, `DownloadStart`, `Diagnose`, `Configure`) are *selector states* (implement `IDASStateWithSelector`), others are simple states. ### `class States` - **Properties** (singleton access to state instances): - `IDASState Prepare`, `HardwareDiscovery`, `Download`, `Arming`, `Arm`, `Realtime` - `IDASStateWithSelector HardwareDiscoveryStart`, `DownloadStart`, `Diagnose`, `Configure`, `ConfigureStart`, `RealtimeStart` - **Methods**: - `public static void SetDASFactory(IDASFactory dasFactory)` — Assigns the factory to all state instances. - `public IDASState GetIDASState(State state)` — Returns the state object for a given `State` enum. - `public static States Instance { get; }` — Singleton instance. ### `class StateMachineBootstrap` - **Constructor**: - `StateMachineBootstrap(IDASFactory dasFactory = null)` — Initializes the state machine with `Prepare` as the initial state, sets up logging, and calls `Configure()`. - **Public Methods**: - `void TurnOffExcitation(...)` — Configures `ConfigureStart` parameters to skip power and set `TurnOffExcitation = true`, then fires `Trigger.TurnOffExcitation`. - `void PrepareForDiagnostics(...)` — Configures `ConfigureStart` parameters for diagnostics (`PrepareForDiagnostics = true`, `SetConfiguration = false`, etc.), then fires `Trigger.ApplyConfiguration`. - `void UpdateConfig(...)` — Configures `ConfigureStart` parameters for full configuration, then fires `Trigger.ApplyConfiguration`. - `void PingAndConnectAndCheckHardware(...)` — Configures `HardwareDiscovery` parameters with full hardware checks, then fires `Trigger.PingAndConnect`. - `void PingAndConnect(...)` — Same as above, but sets `DoHardwareChecks = false`. - `void RequeryDevice(IDASCommunication device, ...)` — Configures `HardwareDiscovery` to requery a specific device, then fires `Trigger.RequeryDevice`. - `void Ping(bool UseUDPDiscovery, string[] ipAddresses, ...)` — Fires `Trigger.PingAndConnect` with `Connect = false`. - `void StartRealtime(...)` — Configures `Realtime` parameters and fires `Trigger.StartRealtime`. - `void StopRealtime()` — Calls `StopRealtime()` on the `Realtime` state’s status object. - `bool IsInRealtime { get; }` — Returns `IsInRealtime` from `Realtime` state’s status. - `void Reset()` — Fires `Trigger.Reset` and resets the shared `Status` object. - **Private Helper Methods** (used internally by public methods): - `GetConfigureStatus()`, `GetConfigureParameters()` - `GetDiagnoseParameters()` - `GetPingAndConnectParameters()`, `GetPingAndConnectStatus()` - `GetRealtimeParameters()`, `GetRealtimeStatus()` - **Private Methods (internal testing/simulation)**: - `void Configure()` — Defines all state machine transitions (see **Dependencies**). - `void GenerateStateMachineGraph()` — Outputs DOT graph for visualization. - `void Start()`, `SimulatePingAndConnectComplete()`, `SimulatePingAndConnectWithCancel()`, `BasicInfoToDiagnostics()`, `BasicInfoToRealtime()`, `StartAndStopRealtime()`, `ResolveChannelsAuto()`, `ResolveChannelsManual()`, `ApplyConfiguration()` — Internal simulation/test methods. ## 3. Invariants - **Shared Status Object**: All `DASState` instances share the *same* static `Status` instance (`_status`). This is explicitly noted in the source as a temporary design decision to prevent accidental duplication. - **State Hierarchy**: States like `HardwareDiscoveryStart`, `ConfigureStart`, `RealtimeStart`, `DownloadStart` are substates of their parent states (`HardwareDiscovery`, `Configure`, `Realtime`, `Download` respectively). - **Dynamic Transitions**: Transitions using `PermitDynamicIf` (e.g., `Trigger.Finish` from `HardwareDiscoveryStart`, `RealtimeStart`, `Diagnose`) rely on the `StateSelector()` method of the current state to determine the next state. - **Trigger Semantics**: - `Trigger.Finish` always transitions to the parent state (via `StateSelector()`). - `Trigger.Cancel` transitions back to the parent state (e.g., `ConfigureStart` → `Configure`). - `Trigger.Reset` transitions to `Prepare`. - **State Entry/Exit Logging**: Every state logs entry/exit via `Console.WriteLine`, unless overridden. ## 4. Dependencies ### Imports/Usings (from source): - `Stateless` — Core state machine library. - `DTS.Common.Interface.DASFactory` — Defines `IDASFactory`. - `DTS.Common.Interface.StatusAndProgressBar` — Defines `Status`, `StatusIntDelegate`, `StatusExIntDelegate`, `SetProgressValueDelegate`, `ActionCompleteDelegate`. - `DTS.Common.Interface.DataRecorders` — Defines `IDASCommunication`, `IDASHardware`, `IDiscoveredDevice`. - `DTS.Common.Utilities.Logging` — Defines `TextLogger`, `APILogger`. - `DTS.Common.Classes.DSP` — Defines `DSPFilterType`. - `System`, `System.Linq`, `System.Collections.Generic`, `System.Text`, `System.Windows.Forms`, `System` — Standard .NET types. ### Inferred Dependencies: - **External Libraries**: - `Stateless` (NuGet package for state machine). - `DTS.Common.*` — Internal libraries for factory, status, data recorders, utilities, DSP, and logging. - **Consumers**: - `StateMachineBootstrap` is the primary public-facing class; it is instantiated and used by higher-level application logic (e.g., UI or service layer). - `States.Instance` is used by `StateMachineBootstrap` to access state objects and by `Configure()` to set up transitions. ## 5. Gotchas - **Shared Static Status**: All states share the same `Status` instance (`_status`). Modifying status in one state affects all others. This is explicitly flagged in `DASState.cs` as a short-term measure pending refactoring. - **`Trigger.PingAndConnect` Reuse**: The `Ping`, `PingAndConnect`, `PingAndConnectAndCheckHardware`, and `RequeryDevice` methods all fire the *same* trigger (`Trigger.PingAndConnect`) but configure different parameters in `HardwareDiscovery`’s status/params. The behavior is determined entirely by parameter state, not the trigger itself. - **`Trigger.ResolveChannelsAuto`/`ResolveChannelsManual`**: These triggers are `PermitReentry`, meaning they do not change state but re-trigger the current state (`Configure`). Their implementation is empty in `StateMachineBootstrap` (no-op stubs), suggesting logic is elsewhere or incomplete. - **`Download` State Disabled**: The `Download` and `DownloadStart` state configurations are commented out in `Configure()`, indicating this functionality is not currently active. - **Console Logging Only**: `OnEnterState`/`OnExitState` log to `Console.WriteLine`, not the `TextLogger`. Real logging is done manually in public methods via `APILogger.StateLog`. - **Hardcoded Simulation Logic**: Methods like `SimulatePingAndConnectComplete()` and `BasicInfoToRealtime()` contain hardcoded IP ranges and test sequences, suggesting they are for unit testing or demos and should not be used in production. - **`StateSelector()` Implementation Not Visible**: The `StateSelector()` implementations for selector states (e.g., `HardwareDiscoveryStart`, `ConfigureStart`) are not included in the provided source, so their transition logic is unknown. - **`Trigger.Download` Not Used**: The `Download` state exists in the `State` enum but is not wired into the state machine configuration (`Configure()`), and no public method uses `Trigger.Download`.