Files
DP44/docs/ai/DataPRO/IService/StateMachine.md
2026-04-17 14:55:32 -04:00

12 KiB

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
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
2026-04-17T15:37:51.575714+00:00 zai-org/GLM-5-FP8 1 2906f550f14c0321

State Machine Module Documentation

1. Purpose

This module implements a state machine for managing Data Acquisition System (DAS) hardware lifecycle operations. It orchestrates device discovery, configuration, diagnostics, and realtime data acquisition through a formal state transition model using the Stateless library. The module provides a centralized mechanism for coordinating complex, multi-step hardware interactions while maintaining consistent status reporting and logging throughout the state transitions.


2. Public Interface

Enumerations

Trigger

Defines all valid state transition triggers:

  • PingAndConnect - Initiates device discovery and connection
  • Reset - Returns state machine to initial state
  • ResolveChannelsAuto - Automatic channel resolution (reentry trigger)
  • ResolveChannelsManual - Manual channel resolution (reentry trigger)
  • ApplyConfiguration - Applies configuration to devices
  • TurnOffExcitation - Deactivates excitation on configured units
  • Cancel - Cancels current operation
  • Finish - Completes current state and transitions
  • Arm - Transitions to arming state
  • StartRealtime - Initiates realtime data acquisition
  • RequeryDevice - Refreshes a single connected device
  • Download - Initiates download operation

State

Defines all valid states:

  • Prepare, HardwareDiscovery, HardwareDiscoveryStart, Configure, ConfigureStart, Diagnose, Realtime, Arming, Arm, Download, RealtimeStart, DownloadStart

Interfaces

IDASState

public interface IDASState
{
    Status Status { get; }
    IDASFactory DASFactory { get; set; }
    Action OnEntry { get; }
    Action OnExit { get; }
    State State { get; }
    void OnEnterState();
    void OnExitState();
}

IDASStateWithSelector : IDASState

public interface IDASStateWithSelector : IDASState
{
    IDASState StateSelector();
}

Extends IDASState with dynamic state selection capability via StateSelector().


Abstract Classes

DASState : IDASState

Base implementation for all states. Provides:

  • IDASFactory DASFactory { get; set; } - Factory for DAS hardware operations
  • abstract State State { get; } - Must be implemented by derived classes
  • virtual Action OnEntry { get => OnEnterState; } - Returns OnEnterState method
  • virtual Action OnExit { get => OnExitState; } - Returns OnExitState method
  • virtual void OnEnterState() - Logs entry to console
  • virtual void OnExitState() - Logs exit to console
  • Status Status { get; } - Returns a static, shared Status instance

DASStateSelector : DASState, IDASStateWithSelector

Abstract base for states requiring dynamic transition logic:

  • abstract IDASState StateSelector(); - Must be implemented to determine next state

Classes

States (Singleton)

Registry and factory for all state instances.

Properties:

  • static States Instance - Singleton accessor
  • IDASState Prepare { get; }
  • IDASState HardwareDiscovery { get; }
  • IDASStateWithSelector HardwareDiscoveryStart { get; }
  • IDASState Download { get; }
  • IDASStateWithSelector DownloadStart { get; }
  • IDASStateWithSelector Diagnose { get; }
  • IDASStateWithSelector Configure { get; }
  • IDASState Arming { get; }
  • IDASState Arm { get; }
  • IDASState Realtime { get; }
  • IDASStateWithSelector RealtimeStart { get; }
  • IDASStateWithSelector ConfigureStart { get; }

Methods:

  • static void SetDASFactory(IDASFactory dasFactory) - Propagates factory to all registered states
  • IDASState GetIDASState(State state) - Retrieves state by enum; throws InvalidOperationException if undefined

StateMachineBootstrap

Main orchestrator class that configures and operates the state machine.

Constructor:

public StateMachineBootstrap(IDASFactory dasFactory = null)

Initializes logging, creates state machine starting in Prepare state, and configures all transitions.

Public Methods:

public void TurnOffExcitation(
    ActionCompleteDelegate CompleteAction,
    SetProgressValueDelegate ProgressAction,
    StatusIntDelegate StatusAction,
    StatusExIntDelegate StatusExAction)

Turns off excitation for units in configure state. Waits for any running operation to complete before proceeding.

public void PrepareForDiagnostics(
    ErrorCallback ErrorRequiringActionAction,
    ActionCompleteDelegate CompleteAction,
    SetProgressValueDelegate ProgressAction,
    StatusIntDelegate StatusAction,
    StatusExIntDelegate StatusExAction)

Prepares hardware for diagnostics mode by applying configuration with PrepareForDiagnostics = true.

public void UpdateConfig(
    bool ResetEventLines,
    bool PrepareForDiagnostics,
    bool ConfigureDigitalOutputs,
    bool DoStrictCheck,
    bool DummyConfig,
    bool EventConfig,
    double[] maxAAF,
    bool TurnOffAAFRealtime,
    bool SkipTurnOnPower,
    IDASCommunication[] UnitsToConfigure,
    IReadOnlyDictionary<string, double> SampleRateLookup,
    IReadOnlyDictionary<string, float> AAFRateLookup,
    ErrorCallback ErrorRequiringActionAction,
    ActionCompleteDelegate CompleteAction,
    SetProgressValueDelegate ProgressAction,
    StatusIntDelegate StatusAction,
    StatusExIntDelegate StatusExAction,
    DSPFilterType dspFilterType)

Updates device configuration with full parameter control.

public void PingAndConnectAndCheckHardware(
    string[] Addresses,
    Tuple<string, string>[] AddressRanges,
    bool GoToDownload,
    string[] KnownSLICEIPAddresses,
    string[] KnownTDASIPAddresses,
    bool ProceedWhenDone,
    bool ReadIds,
    bool RequireAllDASFound,
    bool RunAutoSense,
    bool UseUDPDiscovery,
    string[] RequiredSerials,
    HardwareDiscoveryParameters.IsCalDateExpiredDelegate CalDateExpiredQuery,
    IDASHardware[] ExpectedHardware,
    HardwareDiscoveryParameters.FirmwareExpectedVersionDelegate UnitExpectedFirmwareQuery,
    HardwareDiscoveryParameters.UnitExpectedMaxMemoryDelegate UnitExpectedMaxMemoryQuery,
    HardwareDiscoveryParameters.UnitIsInDbDelegate UnitIsInDbQuery,
    HardwareDiscoveryParameters.UpdateMaxMemoryDelegate UpdateMaxMemoryAction,
    ActionCompleteDelegate CompleteAction,
    SetProgressValueDelegate ProgressAction,
    StatusIntDelegate StatusAction,
    StatusExIntDelegate StatusExAction)

Pings, connects, and performs hardware validation (firmware, memory, calibration dates, database presence).

public void PingAndConnect(
    string[] Addresses,
    Tuple<string, string>[] AddressRanges,
    bool GoToDownload,
    string[] KnownSLICEIPAddresses,
    string[] KnownTDASIPAddresses,
    bool ProceedWhenDone,
    bool ReadIds,
    bool RequireAllDASFound,
    bool RunAutoSense,
    bool UseUDPDiscovery,
    string[] RequiredSerials,
    ActionCompleteDelegate CompleteAction,
    SetProgressValueDelegate ProgressAction,
    StatusIntDelegate StatusAction,
    StatusExIntDelegate StatusExAction)

Pings and connects without hardware validation checks.

public void RequeryDevice(
    IDASCommunication device,
    ActionCompleteDelegate CompleteAction,
    SetProgressValueDelegate ProgressAction,
    StatusIntDelegate StatusAction,
    StatusExIntDelegate StatusExAction)

Refreshes a single already-connected device.

public void Ping(
    bool UseUDPDiscovery,
    string[] ipAddresses,
    Tuple<string, string>[] ipRanges,
    ActionCompleteDelegate CompleteAction,
    SetProgressValueDelegate ProgressAction,
    StatusIntDelegate StatusAction,
    StatusExIntDelegate StatusExAction)

Pings devices without connecting (Connect = false).

public void StartRealtime(
    List<IDASCommunication> ldas,
    List<int> moduleIndicies,
    bool useSingleSampleMode,
    double realtimeSampleRate,
    int realtimeDelayBetweenPolls,
    bool allowMultipleSampleRealtime,
    byte realtimeSampleRateAAFilterRatio,
    bool sliceTurnOffAAFRealtime,
    Action<double, double> SetRealtimeSampleRateAAF,
    Action CompleteAction,
    Dictionary<IDASCommunication, byte[]> idasToActiveChannels,
    ServiceBase.Callback StartRealtimeCallback)

Starts realtime data acquisition on specified units and channels.

public void StopRealtime()

Stops realtime acquisition.

public void Reset()

Resets state machine to Prepare state and clears HardwareDiscovery.Status.

Properties:

  • bool IsInRealtime { get; } - Returns current realtime status

3. Invariants

  1. Singleton States: The States class is a singleton with an explicit static constructor to prevent beforefieldinit behavior.

  2. Shared Status Instance: DASState uses a private static readonly Status _status meaning all states share the same Status object. The source explicitly notes this is intentional but may be refactored.

  3. State Categorization: States are partitioned into two dictionaries:

    • _statesDict for IDASState instances
    • _statesSelectableDict for IDASStateWithSelector instances A state cannot exist in both dictionaries; AddState<T> prioritizes _statesSelectableDict.
  4. Initial State: The state machine always starts in States.Instance.Prepare.

  5. Substate Hierarchy:

    • HardwareDiscoveryStart is a substate of HardwareDiscovery
    • ConfigureStart is a substate of Configure
    • RealtimeStart is a substate of Realtime
    • DownloadStart is a substate of Download (commented out)
  6. Async Trigger Firing: Most public methods use FireAsync rather than synchronous Fire.

  7. Log File Size: Maximum log file size is fixed at 4194304 bytes (4 MB).


4. Dependencies

This Module Depends On:

  • Stateless - External state machine library (used for StateMachine<IDASState, Trigger>)
  • DTS.Common.Interface.DASFactory - IDASFactory, IDASCommunication, IDASHardware
  • DTS.Common.Interface.DataRecorders - (imported but specific usage unclear from source)
  • DTS.Common.Interface.StatusAndProgressBar - Delegate types (ActionCompleteDelegate, SetProgressValueDelegate, StatusIntDelegate, StatusExIntDelegate, ErrorCallback)
  • DTS.Common.Utilities.Logging - TextLogger, APILogger
  • DTS.Common.Classes.DSP - DSPFilterType
  • System.Windows.Forms - DialogResult (used in callback handling)
  • System.Collections.Generic, System.Linq, System.Text

What Depends On This Module:

Not determinable from source alone.


5. Gotchas

  1. Shared Status Object: The comment in DASState.cs explicitly warns:

    "for now we enforce that there is just one status object we'll probably want to refactor this at some point how this information is stored and passed, but this will prevent accidents from happening in the short term"

    This means all states share the same Status instance, which could cause data races or unexpected state if not carefully managed.

  2. Download States Disabled: The Download and DownloadStart state configurations in Configure() are commented out, suggesting this functionality is incomplete or deprecated.

  3. Test Methods in Production Code: The Start() method and its helper methods (SimulatePingAndConnectWithCancel, SimulatePingAndConnectComplete, BasicInfoToDiagnostics, BasicInfoToRealtime, StartAndStopRealtime, ResolveChannelsManual, ResolveChannelsAuto, ApplyConfiguration) appear to be test/simulation code included in the production class.

  4. Empty Methods: ResolveChannelsManual() and ResolveChannelsAuto() are empty but called in simulation code.

  5. TurnOffExcitation Wait Behavior: TurnOffExcitation calls status.DoneEvent.WaitOne() which blocks until any running configuration completes—this could cause unexpected blocking if called from a UI thread.

  6. Logger Exception Swallowing: The LogStuff method catches and silently discards all exceptions during logging.

  7. Graph Generation Unused: GenerateStateMachineGraph() generates a DOT graph string but the result is only stored in a local variable and never written to a file or exposed.