--- source_files: - DataPRO/IService/StateMachine/States/Arm.cs - DataPRO/IService/StateMachine/States/Arming.cs - DataPRO/IService/StateMachine/States/Realtime.cs - DataPRO/IService/StateMachine/States/Download.cs - DataPRO/IService/StateMachine/States/HardwareDiscovery.cs - DataPRO/IService/StateMachine/States/Prepare.cs - DataPRO/IService/StateMachine/States/ConfigureStart.cs - DataPRO/IService/StateMachine/States/RealtimeStart.cs - DataPRO/IService/StateMachine/States/Configure.cs - DataPRO/IService/StateMachine/States/Diagnose.cs - DataPRO/IService/StateMachine/States/DownloadStart.cs - DataPRO/IService/StateMachine/States/HardwareDiscoveryStart.cs generated_at: "2026-04-16T04:00:35.991960+00:00" model: "Qwen/Qwen3-Coder-Next-FP8" schema_version: 1 sha256: "dc1b1b8c07850591" --- # States ## Documentation: StateMachine States Module ### 1. Purpose This module defines the concrete state implementations for the DAS (Data Acquisition System) service state machine. Each class represents a terminal or selector state in the state transition graph, encapsulating entry actions and transition logic. The states manage transitions between operational modes such as hardware discovery, configuration, arming, real-time acquisition, and data download. The module serves as the behavioral core of the state machine, where transitions are determined by runtime status flags and configuration parameters. ### 2. Public Interface All classes inherit from `DASState` (or `DASStateSelector` for selector states) in the `DTS.DASLib.Service.StateMachine` namespace. Only `Realtime`, `ConfigureStart`, `RealtimeStart`, `Configure`, `Diagnose`, `DownloadStart`, and `HardwareDiscoveryStart` are `public`; the rest are `internal`. #### Terminal States (non-selector, inherit `DASState`) - **`public class Realtime : DASState`** Represents the active real-time acquisition state. Returns `State.Realtime` via the `State` property. No custom entry action. - **`internal class Arm : DASState`** Represents the armed (ready but not yet acquiring) state. Returns `State.Arm`. - **`internal class Arming : DASState`** Represents the transitional arming state. Returns `State.Arming`. - **`internal class Download : DASState`** Represents the data download state. Returns `State.Download`. - **`internal class HardwareDiscovery : DASState`** Represents the hardware discovery state. Returns `State.HardwareDiscovery`. - **`internal class Prepare : DASState`** Represents the prepare state. Overrides `OnEntry` to invoke `PrepareDASFactory`, which detaches all devices and clears host name arrays in `DASFactory` (if non-null). Returns `State.Prepare`. #### Selector States (inherit `DASStateSelector`) - **`public class ConfigureStart : DASStateSelector`** Entry action: `ApplyConfig`, which calls `Status.ConfigureStatus.ApplyConfig()`. Selector logic: Always returns `States.Instance.Diagnose`. Returns `State.ConfigureStart`. - **`public class RealtimeStart : DASStateSelector`** Entry action: `Start`, which calls `Status.RealtimeStatus.StartRealtime()`. Selector logic: - If `Status.RealtimeStatus.CouldNotStartRealtime` is true → returns `States.Instance.RealtimeStart` (retry loop). - Else → returns `States.Instance.Realtime`. Returns `State.RealtimeStart`. - **`public class Configure : DASStateSelector`** Selector logic: - `AllowApplyConfig()` currently always returns `true` (placeholder logic). - If true → returns `States.Instance.ConfigureStart`. - Else → returns `States.Instance.Configure` (self-loop). Returns `State.Configure`. - **`public class Diagnose : DASStateSelector`** Selector logic: - Returns `States.Instance.RealtimeStart` if either: (a) `Status.DiagnoseParams.ProceedToRealtimeWhenDone && Status.DiagnoseParams.AllUnitsPassedDiagnostic`, or (b) `Status.DiagnoseParams.ProceedToRealtimeWhenDone && !Status.DiagnoseParams.RequireAllUnitsPassDiagnostic`. - Else → returns `States.Instance.Diagnose` (self-loop). Returns `State.Diagnose`. - **`public class DownloadStart : DASStateSelector`** Entry action: `Start`, which calls `Status.DownloadStatusInfo.Download()`. Selector logic: - Returns `States.Instance.Prepare` if `CanTransitToPrepare()` is true: `Status.DownloadParams.ProceedWhenDone && (Status.DownloadStatusInfo.AllDASFinished || !Status.DownloadParams.RequireAllDASFinish)`. - Else → returns `States.Instance.Download` (self-loop). Returns `State.DownloadStart`. - **`public class HardwareDiscoveryStart : DASStateSelector`** Entry action: `Start`, which calls either `RequeryDevice()` or `Ping()` on `Status.HardwareDiscoveryStatusInfo`, depending on whether `Status.HardwareDiscoveryParams.RequeryDevice` is non-null. Selector logic (evaluated in order): - `CanTransitToDownload()` → returns `States.Instance.Download` - `CanTransitToConfigure()` → returns `States.Instance.Configure` - `CanTransitToArm()` → returns `States.Instance.Arm` - Else → returns `States.Instance.HardwareDiscovery` (self-loop) Where: - `CanTransitToConfigure()`: `Status.HardwareDiscoveryParams.ProceedWhenDone && (Status.HardwareDiscoveryStatusInfo.AllDASFound || !Status.HardwareDiscoveryParams.RequireAllDASFound)` - `CanTransitToArm()`: `Status.HardwareDiscoveryParams.ProceedWhenDone && Status.HardwareDiscoveryStatusInfo.SomeUnitsInArmState` - `CanTransitToDownload()`: `CanTransitToConfigure() && Status.HardwareDiscoveryParams.GoToDownload` Returns `State.HardwareDiscoveryStart`. ### 3. Invariants - Every state class must override the `State` property to return its corresponding `State` enum value (e.g., `State.Prepare`, `State.Realtime`). - Selector states (`DASStateSelector` subclasses) must implement `StateSelector()` to return an `IDASState` (typically via `States.Instance.`). - Terminal states (`DASState` subclasses) may optionally override `OnEntry` to define entry behavior; if not overridden, no entry action is executed. - The `OnEntry` action (if present) must call `OnEnterState()` as its first operation (observed in `Prepare`, `ConfigureStart`, `RealtimeStart`, `DownloadStart`, `HardwareDiscoveryStart`). - Transition decisions in selector states are based solely on `Status.*` properties and `Status.*Params` configuration objects. - No state class performs side effects outside of `OnEntry` or `StateSelector()`. ### 4. Dependencies - **Internal dependencies (from source):** - `DASState` and `DASStateSelector` base classes (not shown, but implied by inheritance). - `State` enum (used in `State` property overrides). - `States.Instance` singleton (used to reference other states, e.g., `States.Instance.Diagnose`). - `Status` object with nested properties: - `ConfigureStatus`, `RealtimeStatus`, `DiagnoseParams`, `DownloadStatusInfo`, `DownloadParams`, `HardwareDiscoveryParams`, `HardwareDiscoveryStatusInfo`. - `DASFactory` (used in `Prepare.PrepareDASFactory()`; assumed to be a member of the base `DASState` class or accessible via `this`). - **External dependencies (inferred):** - `System` and related namespaces (e.g., `System.Threading.Tasks`). - Likely depends on a larger `DTS.DASLib.Service` assembly containing `Status`, `States`, and base state classes. ### 5. Gotchas - **Incomplete logic in `Configure.AllowApplyConfig()`**: Currently always returns `true`; no actual validation of channel resolution or placement is implemented despite comments indicating intent. - **Selector state ordering matters**: In `HardwareDiscoveryStart`, transitions are evaluated in a specific order (Download → Configure → Arm → self-loop). Changing this order could alter behavior. - **Self-loops may cause infinite loops**: States like `Configure`, `Diagnose`, `Download`, and `HardwareDiscovery` can loop to themselves if conditions are not met; external triggers or status changes are required to exit. - **Ambiguous `DASFactory` usage**: `PrepareDASFactory()` references `DASFactory` without clear scoping—assumed to be a member of the base class, but not declared in the provided source. - **No explicit error handling**: Entry actions (e.g., `StartRealtime()`, `Download()`) may throw exceptions; no try/catch is visible in the source. - **`RealtimeStart` selector logic may retry indefinitely**: If `CouldNotStartRealtime` remains true, the state machine will loop back to `RealtimeStart` without backoff or failure reporting. - **`RequeryDevice()` vs `Ping()` behavior**: The condition `null != Status.HardwareDiscoveryParams.RequeryDevice` suggests `RequeryDevice` is a delegate or method group, but its type and semantics are not evident from this file.