134 lines
11 KiB
Markdown
134 lines
11 KiB
Markdown
|
|
---
|
|||
|
|
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`.
|