Files
DP44/enriched-qwen3-coder-next/DataPRO/IService/StateMachine.md
2026-04-17 14:55:32 -04:00

134 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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` states status object.
- `bool IsInRealtime { get; }` — Returns `IsInRealtime` from `Realtime` states 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`.