init
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
---
|
||||
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.<StateName>`).
|
||||
- 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.
|
||||
@@ -0,0 +1,127 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/IService/StateMachine/StatusAndParameters/IStatusInfo.cs
|
||||
- DataPRO/IService/StateMachine/StatusAndParameters/IStatusParameters.cs
|
||||
- DataPRO/IService/StateMachine/StatusAndParameters/GlobalStatusParameters.cs
|
||||
- DataPRO/IService/StateMachine/StatusAndParameters/Status.cs
|
||||
- DataPRO/IService/StateMachine/StatusAndParameters/GlobalStatusInformation.cs
|
||||
generated_at: "2026-04-16T04:00:12.173977+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "9b91ae827f1dd2a6"
|
||||
---
|
||||
|
||||
# StatusAndParameters
|
||||
|
||||
## Documentation: State Machine Status and Parameters Module
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
This module defines the core data structures and interfaces for tracking and managing the runtime state and configuration parameters of a distributed acquisition system (DAS) within the state machine framework. It provides typed containers for *status information* (read-only or observation-oriented state, e.g., device presence in certain operational modes) and *status parameters* (configurable settings that influence behavior, e.g., multicast or auto-sense flags). The `Status` class aggregates all such state and parameter objects into a single, resettable snapshot used by the state machine to make decisions and coordinate subsystems.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### Interfaces
|
||||
- **`IStatusInfo`**
|
||||
```csharp
|
||||
void Reset();
|
||||
```
|
||||
Marker interface for status information types that support resetting to default state. No behavior beyond `Reset()` is defined here.
|
||||
|
||||
- **`IStatusParameters`**
|
||||
```csharp
|
||||
void Reset();
|
||||
```
|
||||
Marker interface for status parameter types that support resetting to default values. No behavior beyond `Reset()` is defined here.
|
||||
|
||||
#### Concrete Classes
|
||||
|
||||
- **`GlobalStatusParameters`** *(implements `IStatusParameters`)*
|
||||
```csharp
|
||||
public bool AllowUDPMulticast { get; set; } = true;
|
||||
public bool DisableAutoSense { get; set; } = SensorConstants.DisableAutoSense;
|
||||
public void Reset();
|
||||
```
|
||||
Holds global configuration flags. `Reset()` restores `AllowUDPMulticast` to `true` and `DisableAutoSense` to `SensorConstants.DisableAutoSense`.
|
||||
|
||||
- **`Status`** *(aggregate container)*
|
||||
```csharp
|
||||
public HardwareDiscoveryParameters HardwareDiscoveryParams;
|
||||
public HardwareDiscoveryStatusInfo HardwareDiscoveryStatusInfo;
|
||||
public GlobalStatusInformation GlobalStatusInformation;
|
||||
public GlobalStatusParameters GlobalStatusParameters;
|
||||
public ConfigureStatusInformation ConfigureStatus;
|
||||
public ConfigureStatusParameters ConfigureParameters;
|
||||
public RealtimeStatusInformation RealtimeStatus;
|
||||
public RealtimeParameters RealtimeParams;
|
||||
public DiagnoseParameters DiagnoseParams;
|
||||
public DownloadParameters DownloadParams;
|
||||
public DownloadStatusInformation DownloadStatusInfo;
|
||||
public void Reset();
|
||||
```
|
||||
Central state container. `Reset()` invokes `Reset()` on all contained sub-objects *except* `DownloadStatusInfo` and `DownloadParams` (note: these are omitted from `Reset()`).
|
||||
> ⚠️ **Observed omission**: `DownloadStatusInfo.Reset()` and `DownloadParams.Reset()` are *not* called in `Status.Reset()`, despite both being declared as fields.
|
||||
|
||||
- **`GlobalStatusInformation`** *(implements `IStatusInfo`)*
|
||||
```csharp
|
||||
public IDASCommunication[] GetUnitsInRealtime();
|
||||
public void AddUnitInRealtime(IDASCommunication device);
|
||||
public IDASCommunication[] GetUnitsInArm();
|
||||
public void AddUnitInArm(IDASCommunication device);
|
||||
public IDASCommunication[] GetUnitsAtLowPower();
|
||||
public void AddUnitAtLowPower(IDASCommunication das);
|
||||
public IDASCommunication[] GetUnitsAtHighPower();
|
||||
public void AddUnitAtHighPower(IDASCommunication das);
|
||||
public bool ExcitationOn { get; set; } = false;
|
||||
public void Reset();
|
||||
```
|
||||
Tracks device presence and power/excitation state.
|
||||
- `AddUnitInRealtime`, `AddUnitInArm`, `AddUnitAtLowPower`, `AddUnitAtHighPower` are idempotent (no-op if device already present).
|
||||
- `AddUnitAtLowPower` removes device from `_unitsAtHighPower` if present.
|
||||
- `AddUnitAtHighPower` removes device from `_unitsAtLowPower` if present.
|
||||
- `Reset()` clears all device lists and sets `ExcitationOn = false`.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
|
||||
- **Thread Safety**: All list-modifying operations in `GlobalStatusInformation` are guarded by a private static `lock (MyLock)`. Reads via `Get*()` methods are also lock-protected.
|
||||
- **Mutual Exclusivity**: A device cannot be simultaneously in `_unitsAtLowPower` and `_unitsAtHighPower`. Adding to one list removes it from the other.
|
||||
- **Idempotency**: `AddUnit*()` methods silently ignore duplicate additions (checked via `Contains()` before adding).
|
||||
- **Reset Scope**: `Status.Reset()` does *not* reset `DownloadStatusInfo` or `DownloadParameters` (per source code).
|
||||
- **Default Values**:
|
||||
- `GlobalStatusParameters.AllowUDPMulticast` defaults to `true`.
|
||||
- `GlobalStatusParameters.DisableAutoSense` defaults to `SensorConstants.DisableAutoSense`.
|
||||
- `GlobalStatusInformation.ExcitationOn` defaults to `false`.
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
#### Imports/References
|
||||
- **`DTS.Common.Enums.Sensors`**
|
||||
Used in `GlobalStatusParameters` to initialize `DisableAutoSense` via `SensorConstants.DisableAutoSense`.
|
||||
- **`DTS.Common.Interface.DASFactory`**
|
||||
Used in `GlobalStatusInformation` for the `IDASCommunication` interface (device abstraction).
|
||||
|
||||
#### Consumed By
|
||||
- The state machine logic (implied by namespace `DTS.DASLib.Service.StateMachine`).
|
||||
- Any component needing to inspect or update device status (e.g., `Status` instance likely passed to state handlers).
|
||||
|
||||
#### Consumed By (Inferred)
|
||||
- `GlobalStatusInformation`’s `IDASCommunication` usage implies integration with a device communication layer (e.g., factory-created units implementing `IDASCommunication`).
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
|
||||
- **Incomplete Reset**: `Status.Reset()` omits `DownloadStatusInfo` and `DownloadParameters`. This is likely unintentional (both have `Reset()` methods per naming convention), and may cause stale download state to persist across resets.
|
||||
- **No Removal Methods**: `GlobalStatusInformation` lacks explicit `RemoveUnit*()` methods. Devices are only removed via `Reset()` or implicitly via `AddUnitAtLowPower`/`AddUnitAtHighPower` (which remove from the *opposite* power list). There is no way to remove a device from `Realtime` or `Arm` lists except via `Reset()`.
|
||||
- **Static Lock Scope**: The `MyLock` object is `static`, meaning all instances of `GlobalStatusInformation` share the same lock. This could cause contention if multiple `GlobalStatusInformation` instances are used concurrently (though only one is used via `Status.GlobalStatusInformation`).
|
||||
- **No Validation in `Add*()`**: Methods like `AddUnitInRealtime` do not validate device state consistency (e.g., allowing a device to be added to both `Realtime` and `Arm` simultaneously is permitted).
|
||||
- **`DisableAutoSense` Initialization**: Default value depends on `SensorConstants.DisableAutoSense`, whose value is not visible here. Its semantics (e.g., `true` = disable auto-sense?) must be verified in `DTS.Common.Enums.Sensors`.
|
||||
|
||||
None identified beyond those above.
|
||||
@@ -0,0 +1,339 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/IService/StateMachine/StatusAndParameters/Configure/GroupChannelWithMeta.cs
|
||||
- DataPRO/IService/StateMachine/StatusAndParameters/Configure/ConfigureStatusParameters.cs
|
||||
- DataPRO/IService/StateMachine/StatusAndParameters/Configure/ConfigureStatusInformation.cs
|
||||
generated_at: "2026-04-16T04:01:25.793483+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "14ca5b532e4bb3a2"
|
||||
---
|
||||
|
||||
# Configure
|
||||
|
||||
## Documentation: `ConfigureStatusParameters` and `ConfigureStatusInformation` Module
|
||||
|
||||
---
|
||||
|
||||
### 1. **Purpose**
|
||||
|
||||
This module provides the state and control logic for the *configuration phase* of the DAS (Data Acquisition System) lifecycle, specifically handling channel assignment resolution, hardware configuration application, and power/excitation state transitions. It enables asynchronous configuration of multiple DAS units with rich metadata about channel conflicts, missing sensors, and hardware incompatibilities, while supporting both production and diagnostic workflows. The module decouples configuration intent (expressed via `ConfigureStatusParameters`) from runtime state and progress tracking (managed by `ConfigureStatusInformation`), allowing integration with UI, testing, or headless environments via delegates.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
|
||||
#### `ConfigureStatusParameters`
|
||||
|
||||
- **`public bool RequireIdFoundForSensorsWithIds { get; set; } = true;`**
|
||||
If `true`, sensors with a non-empty EID must be found on the configured hardware; otherwise, configuration may proceed without them.
|
||||
|
||||
- **`public bool AllowMissingSensors { get; set; } = false;`**
|
||||
If `true`, allows channels to be assigned without a corresponding sensor (e.g., for dummy testing).
|
||||
|
||||
- **`public bool AllowSensorsOutOfPosition { get; set; } = true;`**
|
||||
If `true`, permits sensors to be assigned to channels other than their specified physical position.
|
||||
|
||||
- **`public ITestSetup TestSetupConfiguration { get; set; }`**
|
||||
Reference to the test setup configuration used during channel resolution.
|
||||
|
||||
- **`public delegate ISensorData GetSensorDelegate(IGroupChannel groupChannel);`**
|
||||
Delegate to retrieve sensor metadata (`ISensorData`) for a given group channel.
|
||||
|
||||
- **`public GetSensorDelegate GetSensorAction { get; set; }`**
|
||||
Implementation of `GetSensorDelegate`; required for sensor lookup during channel resolution.
|
||||
|
||||
- **`public delegate ISensorCalibration GetSensorCalibrationDelegate(ISensorData sensor, ExcitationVoltageOptions.ExcitationVoltageOption excitation);`**
|
||||
Delegate to retrieve calibration data for a sensor under a specific excitation.
|
||||
|
||||
- **`public GetSensorCalibrationDelegate GetCalibrationAction { get; set; }`**
|
||||
Implementation of `GetSensorCalibrationDelegate`; used to apply calibration to hardware channels.
|
||||
|
||||
- **`public delegate int GetDatabaseIdDelegate(IDASCommunication das);`**
|
||||
Delegate to map a DAS unit to its database ID.
|
||||
|
||||
- **`public GetDatabaseIdDelegate GetDatabaseIdAction { get; set; }`**
|
||||
Implementation of `GetDatabaseIdDelegate`; used to correlate hardware units with database records.
|
||||
|
||||
- **`public delegate void SetSensorCalibrationDelegate(ISensorData sd, ISensorCalibration sc);`**
|
||||
Delegate to persist calibration data back to the sensor.
|
||||
|
||||
- **`public SetSensorCalibrationDelegate SetSensorCalibrationAction { get; set; }`**
|
||||
Implementation of `SetSensorCalibrationDelegate`.
|
||||
|
||||
- **`public bool AllowSensorIdToBlankChannel { get; set; }`**
|
||||
If `true`, allows assignment of a sensor with an EID to a channel that has no EID (blank channel).
|
||||
|
||||
- **`public bool TurnOffExcitation { get; set; } = false;`**
|
||||
Flag indicating that excitation should be turned off *before* applying configuration. Reverted upon starting the turn-off process.
|
||||
|
||||
- **`public IDASCommunication[] UnitsToConfigure { get; set; } = new IDASCommunication[0];`**
|
||||
Array of DAS units to be configured.
|
||||
|
||||
- **`public bool DoStrictCheck { get; set; } = true;`**
|
||||
If `true`, perform strict validation of configuration (e.g., hardware compatibility, EID match).
|
||||
|
||||
- **`public bool EventConfig { get; set; } = true;`**
|
||||
If `true`, write configuration to the *event* file store (legacy SLICE feature); otherwise, use the *diagnostic* store.
|
||||
|
||||
- **`public bool DummyConfig { get; set; } = false;`**
|
||||
If `true`, perform configuration for dummy (non-data-collecting) mode.
|
||||
|
||||
- **`public double[] MaxAAF { get; set; } = new double[0];`**
|
||||
Array of maximum Anti-Alias Filter (AAF) rates per unit (used for SLICE/TDAS).
|
||||
|
||||
- **`public bool ConfigureDigitalOutputs { get; set; } = true;`**
|
||||
If `true`, configure digital outputs; set to `false` to skip (e.g., for trigger checks).
|
||||
|
||||
- **`public ErrorCallback ErrorRequiringActionAction { get; set; }`**
|
||||
Callback invoked when user interaction is required (e.g., AAF errors).
|
||||
|
||||
- **`public bool TurnOffAAFRealtime { get; set; } = true;`**
|
||||
If `true`, disable AAF for real-time acquisition to reduce latency.
|
||||
|
||||
- **`public bool ResetHardwareEventLines { get; set; } = false;`**
|
||||
If `true`, reset hardware event lines before applying configuration.
|
||||
|
||||
- **`public bool PrepareForDiagnostics { get; set; } = false;`**
|
||||
If `true`, prepare units for diagnostics (e.g., turn on excitation, switches) after configuration.
|
||||
|
||||
- **`public IReadOnlyDictionary<string, double> SampleRateLookup { get; set; } = new Dictionary<string, double>();`**
|
||||
Lookup table mapping unit serial numbers to data collection sample rates.
|
||||
|
||||
- **`public IReadOnlyDictionary<string, float> AAFRateLookup { get; set; } = new Dictionary<string, float>();`**
|
||||
Lookup table mapping unit serial numbers to AAF rates.
|
||||
|
||||
- **`public bool SkipTurnOnPower { get; set; } = false;`**
|
||||
If `true`, skip powering up units after configuration (e.g., to keep units in low-power state).
|
||||
|
||||
- **`public bool SetConfiguration { get; set; } = true;`**
|
||||
If `true`, actually write configuration to hardware; if `false`, only prepare for diagnostics.
|
||||
|
||||
- **`public DSPFilterType DSPFilterType { get; set; }`**
|
||||
DSP filter type to apply during configuration.
|
||||
|
||||
- **`public bool DiscardDiagnostics { get; set; } = true;`**
|
||||
If `true`, discard existing diagnostic data before applying new configuration.
|
||||
|
||||
- **`public ConfigureStatusParameters()`**
|
||||
Constructor; initializes `DSPFilterType` via `ResetDSPFilterType()`.
|
||||
|
||||
- **`public void Reset()`**
|
||||
Resets all properties to their default values.
|
||||
|
||||
- **`public override string ToString()`**
|
||||
Returns a human-readable string representation of all configuration parameters.
|
||||
|
||||
---
|
||||
|
||||
#### `ConfigureStatusInformation`
|
||||
|
||||
- **`public enum StatusValues { ... }`**
|
||||
Enum of possible status notifications (e.g., `ApplyingConfiguration`, `Completed`, `ChannelOutOfPosition`, `EIDNotFound`, `LowPowerSuccess`, etc.).
|
||||
|
||||
- **`public bool NoChannelsAssigned { get; internal set; } = true;`**
|
||||
`true` if no channels have been assigned yet.
|
||||
|
||||
- **`public bool AllChannelsResolved { get; internal set; } = false;`**
|
||||
`true` if all channels requiring resolution have been successfully resolved.
|
||||
|
||||
- **`public bool ChannelsOutOfPosition { get; internal set; } = false;`**
|
||||
`true` if one or more sensors are assigned to channels other than their specified position.
|
||||
|
||||
- **`public bool HaveAppliedConfigAllUnits { get; set; } = false;`**
|
||||
`true` if all units in `UnitsToConfigure` were successfully configured.
|
||||
|
||||
- **`public ManualResetEvent CancelEvent { get; }`**
|
||||
Signaled to request cancellation of ongoing tasks.
|
||||
|
||||
- **`public ManualResetEvent DoneEvent { get; }`**
|
||||
Signaled when all work (configuration, power, diagnostics) is complete.
|
||||
|
||||
- **`public ActionCompleteDelegate CompleteAction { get; set; }`**
|
||||
Callback invoked on completion of the configuration process.
|
||||
|
||||
- **`public SetProgressValueDelegate ProgressAction { get; set; }`**
|
||||
Callback invoked with progress updates (0–100).
|
||||
|
||||
- **`public StatusIntDelegate StatusAction { get; set; }`**
|
||||
Callback invoked with `StatusValues` enum values.
|
||||
|
||||
- **`public StatusExIntDelegate StatusExAction { get; set; }`**
|
||||
Callback invoked with extended status (e.g., per-unit success/failure).
|
||||
|
||||
- **`public IDASCommunication[] UnitsConfigured { get; set; } = new IDASCommunication[0];`**
|
||||
List of units successfully configured.
|
||||
|
||||
- **`public async Task Cancel()`**
|
||||
Initiates cancellation: sets `CancelEvent`, waits for completion, and reports `Cancelling`/`Cancelled` status.
|
||||
|
||||
- **`public void TurnOffExcitation()`**
|
||||
Asynchronously turns off excitation on all units, updates global `ExcitationOn` status, and signals `LowPowerSuccess`/`LowPowerFailure`.
|
||||
|
||||
- **`public void ApplyConfig()`**
|
||||
Starts asynchronous configuration process:
|
||||
- If `TurnOffExcitation` is set, invokes `TurnOffExcitation()` first.
|
||||
- Otherwise, applies configuration via `ConfigurationService.SetConfiguration(...)`.
|
||||
- If `PrepareForDiagnostics` is set and `SkipTurnOnPower` is `false`, calls `PrepareForDiagnostics()`.
|
||||
|
||||
- **`public void ManuallyResolveChannel(IGroupChannel channel, IDASChannel hardwareChannel)`**
|
||||
Manually assigns a hardware channel to a group channel. Validates:
|
||||
- Channel is not blank/disabled.
|
||||
- Sensor exists and is compatible.
|
||||
- Hardware channel is not already assigned.
|
||||
- EID constraints (if sensor has EID, and `AllowSensorIdToBlankChannel` is `false`, EID must match).
|
||||
Throws `InvalidAssignmentException` on failure.
|
||||
|
||||
- **`public void ManuallyUnresolveChannel(IGroupChannel channel)`**
|
||||
Removes manual assignment of a channel. Fails if channel is not resolved or if assignment was EID-locked.
|
||||
Throws `InvalidAssignmentException`.
|
||||
|
||||
- **`public class InvalidAssignmentException : Exception`**
|
||||
Exception thrown on manual assignment errors.
|
||||
- **`Reasons` enum**: `BlankChannel`, `NoSensor`, `ChannelDisabled`, `SensorNotFound`, `IncompatibleHardware`, `ChannelAlreadyAssigned`, `EID_Locked`, `EIDRequiredAndMissing`, `ChannelNotAssigned`.
|
||||
- Contains `GroupChannel` and `Reason`.
|
||||
|
||||
- **`public void Reset()`**
|
||||
Resets all status flags, clears channel resolution lists, and nullifies delegates.
|
||||
|
||||
---
|
||||
|
||||
#### `GroupChannelWithMeta` *(internal helper)*
|
||||
|
||||
- **`public bool ChannelConflict { get; set; }`**
|
||||
`true` if this channel conflicts with another assignment.
|
||||
|
||||
- **`public IGroupChannel ConflictingChannel { get; set; }`**
|
||||
Reference to the conflicting channel (if any).
|
||||
|
||||
- **`public IGroupChannel Channel { get; set; }`**
|
||||
The group channel being described.
|
||||
|
||||
- **`public IGroup Group { get; set; }`**
|
||||
The group containing the channel.
|
||||
|
||||
- **`public bool MissingID { get; set; }`**
|
||||
`true` if sensor EID is missing (but expected).
|
||||
|
||||
- **`public bool MissingSensor { get; set; }`**
|
||||
`true` if no sensor is associated with the channel.
|
||||
|
||||
- **`public bool EIDOutOfPlace { get; set; }`**
|
||||
`true` if the sensor’s EID is present but assigned to a different channel than expected.
|
||||
|
||||
- **`public bool HWNotFound { get; set; }`**
|
||||
`true` if the hardware channel could not be found.
|
||||
|
||||
- **`public bool HWChannelIncompatible { get; set; }`**
|
||||
`true` if the hardware channel is incompatible with the sensor.
|
||||
|
||||
- **`public IDASChannel DASChannel { get; set; }`**
|
||||
The resolved hardware channel (if any).
|
||||
|
||||
- **`public bool AssignedByEID { get; set; }`**
|
||||
`true` if this channel was auto-resolved via EID matching.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
|
||||
- **Channel Resolution State**:
|
||||
A channel is *either* in `_resolvedChannels` *or* `_unresolvedChannels`, never both.
|
||||
`IsResolved(ch)` and `IsUnresolved(ch)` are mutually exclusive.
|
||||
|
||||
- **Hardware Channel Uniqueness**:
|
||||
A hardware channel (`IDASChannel`) may be assigned to *only one* group channel at a time. Enforced in `AddResolvedChannel` and `ManuallyResolveChannel`.
|
||||
|
||||
- **EID Locking**:
|
||||
If a channel is resolved via EID (`AssignedByEID == true`), it cannot be manually reassigned to a different hardware channel (`EID_Locked` exception).
|
||||
|
||||
- **Sensor Compatibility**:
|
||||
`IsSensorHwCompatible` enforces strict compatibility rules:
|
||||
- Bridge mode must match.
|
||||
- Digital input mode must match (if applicable).
|
||||
- Supported excitation must exist *and* have calibration data.
|
||||
- Squib/Digital Output sensors must match their respective hardware types.
|
||||
|
||||
- **Configuration Atomicity**:
|
||||
`ApplyConfig` only proceeds to `PrepareForDiagnostics` if no cancellation occurred (`!CancelEvent.WaitOne(...)`).
|
||||
|
||||
- **Excitation State Consistency**:
|
||||
Global `ExcitationOn` status is updated only after successful `TurnOffExcitation` or `PrepareForDiagnostics`.
|
||||
- `TurnOffExcitation` → sets `ExcitationOn = false` on success.
|
||||
- `PrepareForDiagnostics` → sets `ExcitationOn = true` on success.
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
|
||||
#### **Imports / Dependencies Used**
|
||||
- **`DTS.Common.Interface.*`**:
|
||||
- `Channels` (`IGroupChannel`, `IDASChannel`, `AnalogInputDASChannel`, etc.)
|
||||
- `DASFactory` (`IDASCommunication`, `IDASFactory`)
|
||||
- `Sensors` (`ISensorData`, `ISensorCalibration`)
|
||||
- `StatusAndProgressBar` (`IStatusInfo`, `IStatusParameters`, delegates)
|
||||
- `Groups.GroupList` (`IGroup`)
|
||||
- `TestSetups.TestSetupsList` (`ITestSetup`)
|
||||
|
||||
- **`DTS.Common.Classes.DSP`**: `DSPFilterCollection`, `DSPFilterType`
|
||||
|
||||
- **`DTS.Common.Enums`**: `ExcitationVoltageOptions`
|
||||
|
||||
- **`DTS.DASLib.Service.StateMachine.StatusAndParameters.Configure`**: `GroupChannelWithMeta`
|
||||
|
||||
- **`DTS.DASLib.Service.StateMachine`**: `States.Instance.ConfigureStart.Status.*`, `ConfigurationService`, `DiagnosticsService`, `ArmingService`
|
||||
|
||||
- **`System.Threading.Tasks`**: `Task`, `Task.Run`
|
||||
|
||||
- **`System.Collections.Generic`**, **`System.Linq`**, **`System.Text`**, **`System.Threading`**, **`System`**
|
||||
|
||||
#### **Consumers / Usage**
|
||||
- **`ConfigureStatusParameters`** is used by:
|
||||
- `ConfigurationService.SetConfiguration(...)` (to receive configuration intent)
|
||||
- UI or test harness to configure behavior before invoking `ApplyConfig()`
|
||||
|
||||
- **`ConfigureStatusInformation`** is used by:
|
||||
- `ConfigurationService.SetConfiguration(...)` (to report progress/status)
|
||||
- `DiagnosticsService.PrepareForDiagnostics(...)`
|
||||
- `ArmingService.EnterLowPowerMode(...)`
|
||||
- UI to monitor and control configuration state (via delegates)
|
||||
|
||||
- **`GroupChannelWithMeta`** is used internally by `ConfigureStatusInformation` to track channel resolution state.
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
|
||||
- **`AllChannelsResolved` Logic Inversion**:
|
||||
`AllChannelsResolved` is set to `true` when `_unresolvedChannels.Any()` is `false` (i.e., *no unresolved channels*), but the property name suggests it should be `true` when *all are resolved*. This is counterintuitive and could cause bugs if misread.
|
||||
|
||||
- **`TurnOffExcitation` Flag Reset Timing**:
|
||||
`param.TurnOffExcitation` is reset to `false` *inside* `TurnOffExcitation()` *before* the task completes. If `ApplyConfig()` is called again before `TurnOffExcitation()` finishes, it may skip re-initiating turn-off.
|
||||
|
||||
- **`UnitsToConfigure` Mutability During `ApplyConfig`**:
|
||||
In `ApplyConfig()`, if a unit in `UnitsToConfigure` is not found in `dasFactory.GetDASList()`, it is *removed from the local list* (`unitsToConfigure`) but *not from the original `param.UnitsToConfigure`*. This can cause `HaveAppliedConfigAllUnits` to be `false` even though no error was reported for that unit.
|
||||
|
||||
- **`PrepareForDiagnostics` Spin-Wait**:
|
||||
`PrepareForDiagnostics()` uses a fixed spin-wait loop (`PREPARE_SPIN_TIME = 200`, `EXPECTED_PREPARE_TIME = 8000`) instead of relying solely on `ManualResetEvent`. Progress is updated manually, but this is inefficient and not cancellation-aware.
|
||||
|
||||
- **`InvalidAssignmentException` Message Format**:
|
||||
The exception message includes the `Reason` enum *and* the channel’s `ToString()` representation. If `IGroupChannel.ToString()` is not informative, debugging may be difficult.
|
||||
|
||||
- **`AllowSensorIdToBlankChannel` Default**:
|
||||
Default is `false`, meaning sensors with EIDs *cannot* be assigned to blank channels unless explicitly allowed. This may be unexpected in test scenarios.
|
||||
|
||||
- **`ResetDSPFilterType()` Uses Empty String**:
|
||||
`ResetDSPFilterType()` calls `GetFilter(string.Empty)`. If the filter collection does not define a default for empty string, this may return an unexpected or null filter.
|
||||
|
||||
- **Thread Safety of `UnitsConfigured`**:
|
||||
`AddConfiguredDevice()` uses `lock(MyLock)` to safely append to `UnitsConfigured`, but `UnitsConfigured` is exposed as a public property. External code could modify the array directly, bypassing the lock.
|
||||
|
||||
- **`PrepareForDiagnostics` Fails if `UnitsConfigured` is Empty**:
|
||||
`PrepareForDiagnostics()` checks `!status.UnitsConfigured.Any()` and fails early. However, `UnitsConfigured` is only populated *during* `ApplyConfig()`. If `PrepareForDiagnostics` is called independently (e.g., in diagnostics-only flow), it will always fail.
|
||||
|
||||
- **No Handling of `GetCalibrationAction` Returning `null`**:
|
||||
In `AddResolvedChannel`, if `GetCalibrationAction` returns `null` for all supported excitations, no calibration is applied, but no error is raised. This may silently leave hardware uncalibrated.
|
||||
|
||||
- **`EIDOutOfPlace` Flag Misleading**:
|
||||
`EIDOutOfPlace` is set only in `AddResolvedChannel`, but never set to `true` in `AddUnresolvedChannel`. It is unclear how out-of-position channels are tracked if they are unresolved.
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/IService/StateMachine/StatusAndParameters/Diagnose/DiagnoseParameters.cs
|
||||
generated_at: "2026-04-16T04:01:12.868254+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "df826cad6b98e03f"
|
||||
---
|
||||
|
||||
# Diagnose
|
||||
|
||||
## 1. Purpose
|
||||
The `DiagnoseParameters` class encapsulates configuration and state-tracking data for a diagnostic phase within a state machine. It determines how the system transitions out of the diagnostic state—specifically whether to proceed to the real-time operational state—and tracks whether all units have passed their diagnostics. This class serves as a parameter object passed to or managed by the diagnostic state handler, enabling configurable behavior (e.g., strict vs. permissive pass requirements) and runtime status updates during diagnostics execution.
|
||||
|
||||
## 2. Public Interface
|
||||
- **`class DiagnoseParameters : IStatusParameters`**
|
||||
Implements `IStatusParameters` (interface not shown in source) to provide status-related parameters for a diagnostic state.
|
||||
|
||||
- **`bool ProceedToRealtimeWhenDone { get; set; }`**
|
||||
Controls whether the state machine should transition to the real-time state upon successful completion of diagnostics. Default: `true`.
|
||||
|
||||
- **`bool RequireAllUnitsPassDiagnostic { get; set; }`**
|
||||
If `true`, the diagnostic phase is considered successful only if *all* units pass; if `false`, the phase may succeed even if some units fail. Default: `false`.
|
||||
|
||||
- **`bool AllUnitsPassedDiagnostic { get; set; }`**
|
||||
Reflects the actual outcome of the diagnostic run: `true` if all units passed, `false` otherwise. Initialized to `false`.
|
||||
|
||||
- **`void Reset()`**
|
||||
Resets all properties to their default values:
|
||||
- `ProceedToRealtimeWhenDone` → `true`
|
||||
- `RequireAllUnitsPassDiagnostic` → `false`
|
||||
- `AllUnitsPassedDiagnostic` → `false`
|
||||
|
||||
## 3. Invariants
|
||||
- `AllUnitsPassedDiagnostic` must be set by external logic (e.g., diagnostic execution logic) *before* the state machine evaluates transition conditions based on this flag.
|
||||
- `RequireAllUnitsPassDiagnostic` and `AllUnitsPassedDiagnostic` jointly determine diagnostic success:
|
||||
- If `RequireAllUnitsPassDiagnostic` is `true`, success requires `AllUnitsPassedDiagnostic == true`.
|
||||
- If `RequireAllUnitsPassDiagnostic` is `false`, success is assumed regardless of `AllUnitsPassedDiagnostic` (though the exact semantics depend on downstream state machine logic, which is not provided).
|
||||
- After `Reset()` is called, all properties revert to their documented default values; no partial resets occur.
|
||||
- `DiagnoseParameters` is a mutable class—consumers must be cautious about shared instances and concurrent access (no thread-safety guarantees are implied by the source).
|
||||
|
||||
## 4. Dependencies
|
||||
- **Depends on**:
|
||||
- `System` (core .NET namespaces: `System`, `System.Collections.Generic`, `System.Linq`, `System.Text`, `System.Threading.Tasks`).
|
||||
- `DTS.DASLib.Service.StateMachine` namespace (same assembly/project), specifically the `IStatusParameters` interface.
|
||||
- **Used by**:
|
||||
- State machine logic within `DTS.DASLib.Service.StateMachine` (inferred from namespace and class name), particularly code managing the diagnostic state.
|
||||
- Likely consumed by diagnostic execution components that set `AllUnitsPassedDiagnostic` and by state transition logic that inspects `ProceedToRealtimeWhenDone` and `RequireAllUnitsPassDiagnostic`.
|
||||
|
||||
## 5. Gotchas
|
||||
- **Ambiguous success semantics**: The source does not specify how diagnostic success is determined when `RequireAllUnitsPassDiagnostic` is `false`. It is unclear whether success is automatic, or if other conditions (e.g., `AllUnitsPassedDiagnostic == true`) still apply.
|
||||
- **No validation in `Reset()`**: The method does not validate or guard against invalid states (e.g., resetting mid-diagnostic), potentially leading to inconsistent behavior if called at inappropriate times.
|
||||
- **No thread-safety**: The class is a simple POCO with no synchronization primitives; concurrent use without external locking may cause race conditions.
|
||||
- **No documentation on `IStatusParameters` contract**: Since `IStatusParameters` is not included, it is unknown whether `DiagnoseParameters` is expected to implement additional members or adhere to further constraints.
|
||||
- **Default behavior may be surprising**: `ProceedToRealtimeWhenDone` defaults to `true`, meaning the system *will* proceed to real-time mode unless explicitly configured otherwise—even if diagnostics fail—unless downstream logic overrides this.
|
||||
@@ -0,0 +1,238 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/IService/StateMachine/StatusAndParameters/Download/DownloadParameters.cs
|
||||
- DataPRO/IService/StateMachine/StatusAndParameters/Download/DownloadStatusInformation.cs
|
||||
generated_at: "2026-04-16T04:02:01.449211+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "f0aeebaaaf645cc5"
|
||||
---
|
||||
|
||||
# Documentation: Download Parameters and Status Module
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides the data structures and execution logic for managing and executing data downloads from DAS (Data Acquisition System) units within a state machine workflow. It consists of two core types: `DownloadParameters`, which holds configuration and runtime state for a download operation, and `DownloadStatusInformation`, which orchestrates the asynchronous download process, handles status reporting, cancellation, and directory management—including special handling for ROI (Region of Interest), Recovery, and folder copying scenarios. The module integrates with the broader state machine (via `States.Instance.DownloadStart`) and depends on DAS communication interfaces and logging utilities.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `DownloadParameters`
|
||||
|
||||
- **`bool ProceedWhenDone { get; set; } = false;`**
|
||||
Controls whether the state machine should proceed to the next state after the download completes.
|
||||
|
||||
- **`bool RequireAllDASFinish { get; set; } = false;`**
|
||||
Indicates whether *all* DAS units in `DASList` must successfully finish downloading for the operation to be considered complete.
|
||||
|
||||
- **`string DefaultDownloadFolder { get; set; } = string.Empty;`**
|
||||
Holds the configured base download folder path from the application config file.
|
||||
|
||||
- **`bool DefaultUploadBinaries { get; set; } = false;`**
|
||||
Config flag indicating whether binary data should be uploaded after download.
|
||||
|
||||
- **`bool DefaultUploadExports { get; set; } = false;`**
|
||||
Config flag for uploading exports.
|
||||
|
||||
- **`bool DefaultUploadLogs { get; set; } = false;`**
|
||||
Config flag for uploading logs.
|
||||
|
||||
- **`bool DefaultUploadReports { get; set; } = false;`**
|
||||
Config flag for uploading reports.
|
||||
|
||||
- **`bool DefaultUploadSetups { get; set; } = false;`**
|
||||
Config flag for uploading setup files (e.g., `SETUP`, `DASConfigs`).
|
||||
|
||||
- **`IDASCommunication[] DASList { get; set; } = new IDASCommunication[0];`**
|
||||
Array of DAS units to download data from. Must be non-null and populated before download.
|
||||
|
||||
- **`string CurrentTestTestId { get; set; } = string.Empty;`**
|
||||
Test ID string for the current test session.
|
||||
|
||||
- **`string CurrentTestTestIdNode { get; set; } = string.Empty;`**
|
||||
Test ID node (e.g., folder name) used in the file path hierarchy.
|
||||
|
||||
- **`string CurrentTestTestDirectory { get; set; } = string.Empty;`**
|
||||
Full path to the current test directory.
|
||||
|
||||
- **`string CurrentTestOriginalTestDirectory { get; set; } = string.Empty;`**
|
||||
Full path to the original test directory (used in recovery scenarios).
|
||||
|
||||
- **`bool ROI { get; set; } = false;`**
|
||||
Indicates whether the current download is in ROI mode.
|
||||
|
||||
- **`bool Recovery { get; set; } = false;`**
|
||||
Indicates whether the current download is a recovery operation.
|
||||
|
||||
- **`bool FoldersCopied { get; set; }`**
|
||||
Flag to prevent redundant copying of `DASConfigs`, `SETUP`, `Logs`, `Reports` folders during recovery or re-runs.
|
||||
|
||||
- **`ErrorCallback ErrorCallback { get; set; }`**
|
||||
Callback delegate invoked for user prompts or error notifications (e.g., missing hardware, existing files).
|
||||
|
||||
- **`void Reset()`**
|
||||
Resets all properties to their default values (e.g., empty `DASList`, `false` for all flags, `null` for `ErrorCallback`).
|
||||
*Note:* Does *not* reset `ROI`, `Recovery`, or `FoldersCopied` to defaults—only explicitly listed properties in the method body.
|
||||
|
||||
- **`string ToString()`**
|
||||
Returns an empty string (no-op implementation).
|
||||
|
||||
### `DownloadStatusInformation`
|
||||
|
||||
- **`enum StatusValues`**
|
||||
Defines all possible status messages that can be sent via `StatusAction`:
|
||||
- `Preparing`, `Downloading`, `CaptureAttributes`, `Failed`, `ROIFailed`, `Completed`, `Cancelling`, `Cancelled`, `CancelledPartial`, `DownloadDirectory`, `MissingHardware`, `NoDataToDownload`, `NotAllChannelsDownloaded`, `ExistingFiles`, `CleaningUp`, `QueryEventData`.
|
||||
|
||||
- **`ManualResetEvent CancelEvent = new ManualResetEvent(false);`**
|
||||
Signaled to request cancellation of the download.
|
||||
|
||||
- **`ManualResetEvent DoneEvent = new ManualResetEvent(false);`**
|
||||
Signaled when the download task completes (successfully, cancelled, or failed).
|
||||
|
||||
- **`ActionCompleteDelegate CompleteAction { get; set; }`**
|
||||
Callback invoked upon successful completion of the download task.
|
||||
|
||||
- **`SetProgressValueDelegate ProgressAction { get; set; }`**
|
||||
Callback to report progress (currently unused in `Download()`).
|
||||
|
||||
- **`StatusIntDelegate StatusAction { get; set; }`**
|
||||
Callback to report status updates (takes `int` cast of `StatusValues`).
|
||||
|
||||
- **`StatusExIntDelegate StatusExAction { get; set; }`**
|
||||
Callback for extended status (e.g., `NoDataToDownload` passes array of DAS with missing config).
|
||||
|
||||
- **`bool AllDASFinished { get; set; } = false;`**
|
||||
Set to `true` if *all* DAS in `param.DASList` have finished downloading (only checked if `RequireAllDASFinish` is true).
|
||||
|
||||
- **`void Reset()`**
|
||||
Clears all delegate references and resets `AllDASFinished` to `false`.
|
||||
|
||||
- **`void Download()`**
|
||||
Starts the download process asynchronously on a background thread. Key behaviors:
|
||||
- Invokes `StatusAction(StatusValues.Preparing)` at start.
|
||||
- Validates DAS availability against `DASFactory.GetDASList()`, calls `ErrorCallback(StatusValues.MissingHardware)` if missing.
|
||||
- Fails if `DASList` is empty or any DAS lacks `ConfigData`.
|
||||
- Retrieves event info via `GetOneEvent()`; fails if no event found.
|
||||
- Constructs download directory:
|
||||
`<DownloadFolder>/<EventId>/<CurrentTestTestId>/Binary/<ROI|ALL>`.
|
||||
- In **Recovery mode**, reuses the original `CurrentTestTestIdNode` path if test ID changed, and copies folders (`DASConfigs`, `Logs`, `Reports`, `SETUP`) from original test directory if needed (unless `FoldersCopied` is true).
|
||||
- Uses a `ManualResetEvent` (`mre`) that waits indefinitely—**no actual download logic is implemented**; the task exits after setting `CompleteAction` and `StatusAction(Completed)`.
|
||||
- Sets `DoneEvent` upon completion.
|
||||
|
||||
- **`Task Cancel()`**
|
||||
Asynchronously cancels the download:
|
||||
- Sets `CancelEvent`.
|
||||
- Reports `StatusValues.Cancelling`.
|
||||
- Waits 100ms (simulated delay).
|
||||
- Waits for `DoneEvent`.
|
||||
- Reports `StatusValues.Cancelled`.
|
||||
|
||||
- **`bool DirectoryCopy(...)`**
|
||||
Copies files from `sourceDirName` to `destDirName`, with filtering based on upload flags (`DefaultUpload*`).
|
||||
- Overwrites existing files (uses `File.Copy(..., true)`).
|
||||
- Skips files if corresponding upload flag is `false` (e.g., skips `Binary` if `DefaultUploadBinaries` is `false`).
|
||||
- Prompts user via `ErrorCallback(StatusValues.ExistingFiles)` if destination files exist.
|
||||
- Logs success/failure via `APILogger`.
|
||||
- Returns `true` only if *uploading data* (`uploadingData == true`) and copy succeeds; otherwise `false`.
|
||||
|
||||
- **`private static string GetHash(DownloadReport.EventInfo)`**
|
||||
Helper: returns `"TestID_EventNumber"` formatted as uppercase (e.g., `"T123_05"`).
|
||||
|
||||
- **`private IEventInfoAggregate GetOneEvent(List<IDASCommunication>)`**
|
||||
Helper: aggregates event info from DAS units.
|
||||
- Collects unique events by hash (`TestID_EventNumber`).
|
||||
- Returns the first aggregated event (or `null` if none found).
|
||||
*Note:* The `TODO` comment indicates incomplete event aggregation logic.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **`DASList` must be non-null and populated before calling `Download()`**
|
||||
The method checks for empty `dasList` and fails if `!dasList.Any()`.
|
||||
|
||||
- **Each DAS in `DASList` must have non-null `ConfigData`**
|
||||
Checked via `das.ConfigData == null`; triggers `StatusExAction(StatusValues.NoDataToDownload)`.
|
||||
|
||||
- **At least one DAS must have valid `EventInfo` with events**
|
||||
`GetOneEvent()` must return non-null; otherwise, `StatusAction(StatusValues.Failed)` is invoked.
|
||||
|
||||
- **Download directory must be creatable**
|
||||
If `Directory.CreateDirectory(directory)` throws, `StatusAction(StatusValues.Failed)` is invoked.
|
||||
|
||||
- **`StatusAction` must be assigned for status reporting**
|
||||
All status updates are conditional on `StatusAction?.Invoke(...)`.
|
||||
|
||||
- **`ErrorCallback` must handle user prompts synchronously**
|
||||
The code calls `errorCallback?.Invoke(...)` and expects a `DialogResult` return.
|
||||
|
||||
- **Recovery mode path reuse**
|
||||
When `Recovery == true` and `CurrentTestTestId != CurrentTestTestIdNode`, the download directory reuses `currentTestTestIdNode` (original test ID node) to avoid duplicating folders.
|
||||
|
||||
- **`FoldersCopied` prevents redundant copying**
|
||||
Folder copying only occurs if `Recovery && (!foldersCopied)`.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Imports/References
|
||||
- **`DTS.Common.Interface.DASFactory`**
|
||||
Provides `IDASCommunication`, `IDASFactory`, and `IEventInfoAggregate`.
|
||||
- **`DTS.Common.Interface.StatusAndProgressBar`**
|
||||
Provides `IStatusParameters`, `IStatusInfo`, `ErrorCallback`, `ActionCompleteDelegate`, `SetProgressValueDelegate`, `StatusIntDelegate`, `StatusExIntDelegate`.
|
||||
- **`DTS.Common.Utilities.Logging`**
|
||||
Provides `APILogger`.
|
||||
- **`System.Windows.Forms`**
|
||||
Used for `DialogResult` (e.g., `DialogResult.OK` in `ErrorCallback` usage).
|
||||
- **`System.IO`**
|
||||
For `Directory`, `DirectoryInfo`, `File`, `Path`, `Uri`.
|
||||
|
||||
### Internal Dependencies
|
||||
- **`States.Instance.DownloadStart`**
|
||||
Accessed to retrieve:
|
||||
- `Status.DownloadParams` (`DownloadParameters`)
|
||||
- `Status.GlobalStatusParameters`
|
||||
- `DASFactory` (`IDASFactory`)
|
||||
|
||||
- **`Common.Constants`**
|
||||
Used for folder names: `DAS_CONFIGS`, `REPORT_DIR_NAME` (values not visible in source).
|
||||
|
||||
- **`Resources.UploadData_Files_Exist`**
|
||||
String resource used in `DirectoryCopy` for existing files prompt.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **`DirectoryCopy` does not actually upload data**
|
||||
Despite the name and upload-related flags, it only copies files *within the local filesystem*. The `uploadingData` parameter controls filtering but not network upload.
|
||||
|
||||
- **No actual download logic in `Download()`**
|
||||
The method sets up directories and runs validation, but the core download loop is missing—`mre.WaitOne()` blocks indefinitely, and the task exits without performing I/O. This suggests incomplete implementation or placeholder logic.
|
||||
|
||||
- **`DirectoryCopy` has confusing return semantics**
|
||||
Returns `true` *only* if `uploadingData == true` and copy succeeds; otherwise returns `false`. This makes it unsuitable for generic copying.
|
||||
|
||||
- **`DirectoryCopy` uses `Uri` for relative path calculation**
|
||||
Builds URIs with `"file:\\\\"` prefix and uses `MakeRelativeUri`—non-standard and potentially fragile for Windows paths.
|
||||
|
||||
- **`GetOneEvent` is incomplete**
|
||||
The `TODO` comment and missing `IEventInfoAggregate` constructor call (`new IEventInfoAggregate(...)`) indicate the event aggregation logic is not implemented.
|
||||
|
||||
- **`Reset()` does not reset `ROI`, `Recovery`, or `FoldersCopied`**
|
||||
Only resets explicitly listed properties—these flags retain their values unless manually cleared.
|
||||
|
||||
- **`ToString()` is a no-op**
|
||||
Returns empty string; no debugging value.
|
||||
|
||||
- **`DirectoryCopy` may throw if `sourceDirName`/`destDirName` are invalid**
|
||||
`Uri` construction and `DirectoryInfo` access lack explicit error handling beyond the outer `try-catch`.
|
||||
|
||||
- **Hardcoded folder names**
|
||||
`"Binary"`, `"ROI"`, `"ALL"`, `"Logs"`, `"SETUP"`, `"Reports"`, `"DASConfigs"` are used directly—should be constants.
|
||||
|
||||
- **`Thread.Sleep(100)` and `Thread.Sleep(10)` in async path**
|
||||
Blocking calls in cancellation and upload paths may cause UI freezes or delays.
|
||||
|
||||
- **Missing `NotAllChannelsDownloaded` handling**
|
||||
Status value exists but is never invoked in `Download()`.
|
||||
|
||||
- **`ExistingFiles` prompt may show multiple times**
|
||||
`DirectoryCopy` is called per folder (e.g., `DASConfigs`, `Logs`, etc.), and each may prompt for existing files.
|
||||
|
||||
- **No validation of `CurrentTest*` path components**
|
||||
Invalid characters or null values could cause path construction errors.
|
||||
@@ -0,0 +1,100 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/IService/StateMachine/StatusAndParameters/HardwareDiscovery/HardwareDiscoveryParameters.cs
|
||||
generated_at: "2026-04-16T04:01:01.723717+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "d09b358f05b11ecc"
|
||||
---
|
||||
|
||||
# HardwareDiscovery
|
||||
|
||||
## Documentation: `HardwareDiscoveryParameters`
|
||||
|
||||
---
|
||||
|
||||
### **Purpose**
|
||||
|
||||
The `HardwareDiscoveryParameters` class encapsulates configuration and control flags for the hardware discovery phase within the state machine of the DAS (Data Acquisition System) service. It defines *how* hardware devices (SLICE and TDAS units) are discovered—via explicit IPs, IP ranges, or multicast—and *what* actions should follow discovery (e.g., hardware validation, connection, firmware checks). It serves as the input contract for the discovery state, allowing callers to customize discovery behavior (e.g., skip connection, require specific devices, trigger post-discovery transitions) without modifying the discovery logic itself.
|
||||
|
||||
---
|
||||
|
||||
### **Public Interface**
|
||||
|
||||
#### **Properties**
|
||||
|
||||
| Property | Type | Default | Description |
|
||||
|---------|------|---------|-------------|
|
||||
| `ReadIds` | `bool` | `false` | Whether to read device identifiers (e.g., serial, firmware) after connection. |
|
||||
| `Addresses` | `string[]` | `new string[0]` | Explicit IP addresses to attempt connection to. If not in known lists, tried as both SLICE and TDAS. |
|
||||
| `AddressRanges` | `Tuple<string, string>[]` | `new Tuple<string, string>[0]` | IP ranges to ping (inclusive on last octet). Format: `("aaa.bbb.ccc.ddd", "aaa.bbb.ccc.eee")`. Responding IPs added to connection list. |
|
||||
| `KnownTDASIPAddresses` | `string[]` | `new string[0]` | IPs *confirmed* to be TDAS units. Only tried as TDAS (not SLICE). |
|
||||
| `KnownSLICEIPAddresses` | `string[]` | `new string[0]` | IPs *confirmed* to be SLICE units. Only tried as SLICE (not TDAS). |
|
||||
| `ProceedWhenDone` | `bool` | `false` | If `false`, remain in discovery state after completion (e.g., for inspection). If `true`, proceed to next state. |
|
||||
| `RequireAllDASFound` | `bool` | `false` | If `true`, discovery fails if any device in `Addresses`, `AddressRanges`, or `RequiredSerials` is not found. |
|
||||
| `GoToDownload` | `bool` | `false` | If `true`, transition to *Download* state after successful discovery (implies `ProceedWhenDone = true`). |
|
||||
| `Connect` | `bool` | `false` | If `false`, only perform ICMP ping (no socket connection). If `true`, attempt full connection. |
|
||||
| `UseMulticastDiscover` | `bool` | `false` | Whether to use UDP/Multicast discovery protocol (e.g., SSDP-like). |
|
||||
| `ConnectTimeoutMS` | `int` | `30000` | Timeout (ms) for connection attempts. |
|
||||
| `RunAutoSense` | `bool` | `true` | Whether to run auto-sense logic (e.g., fallback discovery). *Note:* Overridden if `DisableAutoSense` is set elsewhere (not in this class). |
|
||||
| `RequeryDevice` | `IDASCommunication` | `null` | A specific device to re-query (e.g., after config change). If non-null, discovery targets only this device. |
|
||||
| `RequiredSerials` | `string[]` | `new string[0]` | Serial numbers of devices *required* to be discovered. Used for validation (`RequireAllDASFound` may apply). |
|
||||
| `DoHardwareChecks` | `bool` | `false` | Whether to perform hardware validation (voltage, memory, firmware) *after* connection. |
|
||||
| `ExpectedHardware` | `IDASHardware[]` | `new IDASHardware[0]` | Hardware expected to be present post-discovery. Used in `DoHardwareChecks`. |
|
||||
| `DoVoltageChecks` | `bool` | `true` | Whether to include input/battery voltage checks as part of `DoHardwareChecks`. |
|
||||
| `UnitIsInDbQuery` | `UnitIsInDbDelegate` | `null` | Callback: `bool UnitIsInDb(IDASCommunication das)` — checks if device is registered in DB. |
|
||||
| `UnitExpectedFirmwareQuery` | `FirmwareExpectedVersionDelegate` | `null` | Callback: `string ExpectedFirmware(IDASCommunication das)` — returns expected firmware version for device. |
|
||||
| `CalDateExpiredQuery` | `IsCalDateExpiredDelegate` | `null` | Callback: `bool IsCalExpired(IDASCommunication das)` — checks if calibration date is expired. |
|
||||
| `UnitExpectedMaxMemoryDelegate` | `UnitExpectedMaxMemoryDelegate` | `null` | Callback: `long ExpectedMaxMemory(IDASCommunication das)` — returns expected max memory for device. |
|
||||
| `UpdateMaxMemoryAction` | `UpdateMaxMemoryDelegate` | `null` | Callback: `void UpdateMaxMemory(IDASCommunication das)` — updates max memory metadata (e.g., after reflash). |
|
||||
|
||||
#### **Methods**
|
||||
|
||||
| Method | Signature | Description |
|
||||
|--------|-----------|-------------|
|
||||
| `Reset()` | `public void Reset()` | Resets all properties to default values (e.g., empty arrays, `false` flags, `null` delegates). Does *not* reset `ConnectTimeoutMS` (remains `30000`). |
|
||||
| `ToString()` | `public override string ToString()` | Returns a human-readable summary of all properties, including delegate presence (`[null]`/`[defined]`). |
|
||||
|
||||
---
|
||||
|
||||
### **Invariants**
|
||||
|
||||
- **IP Format**: `Addresses`, `AddressRanges.Item1/Item2`, `KnownTDASIPAddresses`, and `KnownSLICEIPAddresses` must be valid IPv4 strings (`aaa.bbb.ccc.ddd`). Invalid formats may cause ping/connection failures but are *not validated* by this class.
|
||||
- **Range Validity**: For `AddressRanges`, `Item1` and `Item2` must share the first three octets; otherwise, iteration logic may behave unexpectedly (no validation enforced).
|
||||
- **Mutual Exclusivity**: `RequeryDevice != null` implies discovery is *device-centric*; `Addresses`, `AddressRanges`, `Known*IPAddresses`, and `RequiredSerials` are likely ignored (behavior depends on consumer).
|
||||
- **Delegate Consistency**: If `DoHardwareChecks = true`, at least one of `UnitIsInDbQuery`, `UnitExpectedFirmwareQuery`, `CalDateExpiredQuery`, `UnitExpectedMaxMemoryQuery`, or `UpdateMaxMemoryAction` *should* be non-null for meaningful checks—but this is not enforced.
|
||||
- **Timeout**: `ConnectTimeoutMS` must be ≥ 0. Negative values are not validated and may cause undefined behavior in connection logic.
|
||||
|
||||
---
|
||||
|
||||
### **Dependencies**
|
||||
|
||||
#### **Imports/References**
|
||||
- `DTS.Common.Interface.DASFactory` → Provides `IDASCommunication` and `IDASHardware`.
|
||||
- `DTS.Common.Interface.DataRecorders` → Likely provides additional DAS-related interfaces (used via `IDASCommunication`/`IDASHardware`).
|
||||
- `System` → Core types (`Tuple`, `StringBuilder`, `Delegate`).
|
||||
|
||||
#### **Consumers (Inferred)**
|
||||
- State machine logic in `DTS.DASLib.Service.StateMachine` (namespace implies usage).
|
||||
- Discovery-related state handlers (e.g., `HardwareDiscoveryState`) that consume this class to configure discovery behavior.
|
||||
- UI or service layer that populates this class before invoking discovery.
|
||||
|
||||
#### **Dependencies on External Types**
|
||||
- `IDASCommunication`: Interface for device communication (used in delegates and `RequeryDevice`).
|
||||
- `IDASHardware`: Interface for hardware metadata (used in `ExpectedHardware`).
|
||||
|
||||
---
|
||||
|
||||
### **Gotchas**
|
||||
|
||||
- **`RequeryDevice` takes precedence**: If `RequeryDevice` is non-null, discovery may *ignore* `Addresses`, `AddressRanges`, `Known*IPAddresses`, and `RequiredSerials`. This is implied by the summary but not enforced—consumers must handle this.
|
||||
- **`GoToDownload` implies `ProceedWhenDone`**: While not enforced in this class, `GoToDownload = true` logically requires `ProceedWhenDone = true` (to transition states). Consumers must ensure this.
|
||||
- **`RunAutoSense` is *not* overridable here**: The summary notes `DisableAutoSense` overrules `RunAutoSense`, but `DisableAutoSense` is *not a property of this class*. Likely set elsewhere (e.g., in discovery state logic).
|
||||
- **No validation of IP ranges**: `AddressRanges` items are used as-is. If `Item1` > `Item2` in the last octet, iteration may produce no results or throw (source not shown).
|
||||
- **`ToString()` omits `ConnectTimeoutMS` and `UseMulticastDiscover`**: These properties are *not* included in the `ToString()` output despite being public—potential debugging pitfall.
|
||||
- **`Reset()` does not reset `ConnectTimeoutMS`**: Despite resetting other properties, `ConnectTimeoutMS` remains `30000` after `Reset()`. Intentional? Unclear from source.
|
||||
- **`Known*IPAddresses` are *additive* to discovery scope**: IPs in `KnownTDASIPAddresses`/`KnownSLICEIPAddresses` are *not* exclusive—they are *preferred* paths, but discovery may still try other methods if `Connect = true` and `Addresses`/`AddressRanges` are also set.
|
||||
|
||||
---
|
||||
|
||||
*Documentation generated from `HardwareDiscoveryParameters.cs` alone. Behavior of discovery logic (e.g., how `AddressRanges` are iterated, how `RequeryDevice` is handled) is inferred from comments and property names but not verifiable without consumer code.*
|
||||
@@ -0,0 +1,144 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/IService/StateMachine/StatusAndParameters/Realtime/RealtimeParameters.cs
|
||||
- DataPRO/IService/StateMachine/StatusAndParameters/Realtime/RealtimeStatusInformation.cs
|
||||
generated_at: "2026-04-16T04:01:39.522280+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "13ae579216023a96"
|
||||
---
|
||||
|
||||
# Realtime
|
||||
|
||||
## Documentation: Realtime Parameters and Status Module
|
||||
|
||||
---
|
||||
|
||||
### 1. **Purpose**
|
||||
|
||||
This module encapsulates the configuration (`RealtimeParameters`) and runtime state management (`RealtimeStatusInformation`) for initiating and controlling *realtime data acquisition* in the DAS (Distributed Acoustic Sensing) system. It serves as the interface between the state machine and the underlying `RealtimeService`, handling parameter propagation, sample rate/AAF (Anti-Alias Filter) configuration, and synchronization primitives for starting/stopping realtime acquisition across multiple DAS units. It enables both single-sample and multi-sample polling modes, with configurable delays, channel selection, and hardware-specific AAF computation.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
|
||||
#### `RealtimeParameters` (class)
|
||||
|
||||
- **`List<IDASCommunication> UnitsToStartRealtime { get; set; }`**
|
||||
List of DAS units to be started in realtime mode.
|
||||
|
||||
- **`int RealtimeDelayBetweenPollsInMilliSecond { get; set; }`**
|
||||
Delay (in ms) between successive polling attempts during realtime acquisition.
|
||||
|
||||
- **`bool AllowMultipleSampleRealtime { get; set; }`**
|
||||
Flag indicating whether multiple samples per poll are allowed.
|
||||
|
||||
- **`bool UseSingleSampleMode { get; set; }`**
|
||||
Flag to enable single-sample mode (overrides multi-sample behavior).
|
||||
|
||||
- **`List<int> ModuleIndices { get; set; }`**
|
||||
List of module indices to be used in realtime acquisition.
|
||||
|
||||
- **`Dictionary<IDASCommunication, byte[]> IdasToActiveChannels { get; set; }`**
|
||||
Mapping from DAS unit to its active channel bitmask (each byte represents 8 channels).
|
||||
|
||||
- **`double RealtimeSampleRate { get; set; }`**
|
||||
Target sample rate (Hz) for realtime acquisition.
|
||||
|
||||
- **`byte RealtimeSampleRateAAFilterRatio { get; set; }`**
|
||||
Ratio used to compute AAF cutoff: `AAF = sampleRate / RealtimeSampleRateAAFilterRatio`.
|
||||
|
||||
- **`bool SliceTurnOffAAFRealtime { get; set; }`**
|
||||
Flag to override AAF and disable it for hardware that supports it (see `DFConstantsAndEnums.SupportsTurnOffAAFRealtime`).
|
||||
|
||||
- **`void Reset()`**
|
||||
Initializes all properties to default values (empty collections, zero numerics, `false` booleans).
|
||||
|
||||
#### `RealtimeStatusInformation` (class)
|
||||
|
||||
- **`bool IsInRealtime { get; }`**
|
||||
Returns `true` if realtime acquisition is currently active (based on `stopRealtimeEvent` state). Uses a 2ms timeout for non-blocking check.
|
||||
|
||||
- **`void StopRealtime()`**
|
||||
Signals termination of realtime acquisition by setting `stopRealtimeEvent`.
|
||||
|
||||
- **`void StartRealtime()`**
|
||||
Overload that reads parameters from `States.Instance.Realtime.Status.RealtimeParams` and invokes the full `StartRealtime(...)` overload on a background `Task`.
|
||||
|
||||
- **`void StartRealtime(List<IDASCommunication> ldas, List<int> moduleArrayIndicies, bool useSingleSampleMode, double realtimeSampleRate, int realtimeDelayBetweenPolls, bool allowMultipleSampleRealtime, Action<double, double> SetRealtimeSampleRateAAF, Action CompleteAction, Dictionary<IDASCommunication, byte[]> idasToActiveChannels, Callback StartRealtimeCallback)`**
|
||||
Core method that:
|
||||
- Wraps `StartRealtimeCallback` in a `Callback` delegate and appends status completion/failure handlers.
|
||||
- Resets `stopRealtimeEvent` and instantiates `RealtimeService`.
|
||||
- If `useSingleSampleMode` is `true`: calls `RealtimeService.StartActivePolling(...)`.
|
||||
- Else: calls `RealtimeService.Start(...)` with computed AAF via `GetRealtimeAAFForHardware`.
|
||||
- Invokes `SetRealtimeSampleRateAAF` with `(sampleRate, AAF)` for the first DAS (or `NaN, NaN` if no DAS).
|
||||
- Waits for either `stopRealtimeEvent` (external stop) or `mr` (service availability), then waits for `realtimeDoneFromService` (service completion).
|
||||
- Logs exceptions, sets `CouldNotStartRealtime = true`, and always invokes `CompleteAction` in `finally`.
|
||||
|
||||
- **`Action<double, double> SetRealtimeSampleRateAAF { get; set; }`**
|
||||
Callback to notify caller of current sample rate and computed AAF (used for UI updates or validation).
|
||||
|
||||
- **`Action CompleteAction { get; set; }`**
|
||||
Action invoked upon completion (success or failure) of `StartRealtime(...)`.
|
||||
|
||||
- **`bool CouldNotStartRealtime { get; set; }`**
|
||||
Set to `true` if an exception occurs during `StartRealtime(...)`.
|
||||
|
||||
- **`Callback StartRealtimeCallback { get; set; }`**
|
||||
User-provided callback invoked by `RealtimeService` during acquisition.
|
||||
|
||||
- **`private float GetRealtimeAAFForHardware(IDASCommunication idas, double samplerate)`**
|
||||
Computes AAF cutoff based on:
|
||||
- If `SliceTurnOffAAFRealtime` is `true` *and* hardware supports it → returns `Common.Constants.SLICE2_NO_AAF_REALTIME_RATE`.
|
||||
- Else if `RealtimeSampleRateAAFilterRatio == 0` → returns `samplerate`.
|
||||
- Else → returns `samplerate / RealtimeSampleRateAAFilterRatio`.
|
||||
|
||||
- **`void Reset()`**
|
||||
Clears `CompleteAction`, resets `realtimeDoneFromService`, sets `stopRealtimeEvent`, and clears `CouldNotStartRealtime`.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
|
||||
- `RealtimeDelayBetweenPollsInMilliSecond` must be ≥ 0 (no validation enforced in code; assumed caller responsibility).
|
||||
- `RealtimeSampleRateAAFilterRatio` must be ≥ 0 (zero implies AAF = sample rate).
|
||||
- `RealtimeSampleRate` must be > 0 when `UseSingleSampleMode == false`, otherwise behavior is undefined (no explicit check).
|
||||
- `UnitsToStartRealtime` and `IdasToActiveChannels` must be consistent: every `IDASCommunication` in `UnitsToStartRealtime` must have an entry in `IdasToActiveChannels` (no enforcement; caller responsibility).
|
||||
- `ModuleIndices` is only used when `UseSingleSampleMode == false`.
|
||||
- `IsInRealtime` is `true` iff `stopRealtimeEvent` is *not* signaled (i.e., `WaitOne(2, false)` returns `false`).
|
||||
- `CompleteAction` is **always** invoked in `StartRealtime(...)`’s `finally` block, regardless of success/failure.
|
||||
- `realtimeDoneFromService.WaitOne()` is called *after* `stopRealtimeEvent.Set()` in `StartRealtime(...)`, ensuring the service has fully stopped before proceeding.
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
|
||||
#### Dependencies *of this module*:
|
||||
- **`DTS.Common.Interface.DASFactory.IDASCommunication`**: Interface for DAS units.
|
||||
- **`DTS.Common.Enums.DASFactory.DFConstantsAndEnums`**: Used for `SupportsTurnOffAAFRealtime`.
|
||||
- **`DTS.Common.Constants.SLICE2_NO_AAF_REALTIME_RATE`**: Hardcoded AAF value when AAF is disabled.
|
||||
- **`DTS.DASLib.Service.StateMachine.States`**: Access to global state (`States.Instance.Realtime.Status.RealtimeParams`).
|
||||
- **`DTS.DASLib.Service.RealtimeService`**: Core service for starting/stopping acquisition.
|
||||
- **`DTS.Common.Interface.StatusAndProgressBar.Callback` & `CallbackData`**: For async completion callbacks.
|
||||
- **`DTS.Common.Utilities.Logging.APILogger`**: For exception logging.
|
||||
- **`System.Threading`**: `ManualResetEvent`, `Task`, `Thread`.
|
||||
|
||||
#### Dependencies *on this module*:
|
||||
- **`RealtimeStatusInformation.StartRealtime()`** is invoked by the state machine (likely via `States.Instance.Realtime.Status.RealtimeStatus.StartRealtime()`).
|
||||
- **`RealtimeParameters`** is used as `RealtimeStatus.RealtimeParams` (inferred from usage in `RealtimeStatusInformation`).
|
||||
- **`SetRealtimeSampleRateAAF`** callback is likely implemented by UI or monitoring components to update sample rate/AAF displays.
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
|
||||
- **`RealtimeDelayBetweenPollsInMilliSecond` is passed as `int` but may be interpreted as `ms` by `RealtimeService`** — ensure caller uses integer milliseconds (no fractional values).
|
||||
- **`GetRealtimeAAFForHardware` uses only the *first DAS* (`ldas[0]`) to compute AAF** when setting `SetRealtimeSampleRateAAF`, even if multiple DAS units are present. This assumes identical AAF behavior across units (not validated).
|
||||
- **`UseSingleSampleMode` bypasses AAF computation and calls `StartActivePolling`**, which may have different behavior than `Start` (e.g., no AAF, no module indices).
|
||||
- **`RealtimeService.ServiceAvailable` event is subscribed inside `StartRealtime(...)`, but the wait loop (`mr.WaitOne`) may exit prematurely if `mr` is set before `stopRealtimeEvent` is signaled**, potentially leading to race conditions if `RealtimeService` becomes available slowly.
|
||||
- **`stopRealtimeEvent` is set twice** — once in `StopRealtime()` and again in `StartRealtime(...)`’s `finally` block. While idempotent for `ManualResetEvent`, this could confuse debugging.
|
||||
- **No validation of `IdasToActiveChannels` entries** — e.g., mismatched channel counts or invalid bitmasks are not caught.
|
||||
- **`CouldNotStartRealtime` is set on *any* exception**, but the `catch` block does *not* rethrow or provide structured error info — callers must inspect this flag after `StartRealtime`.
|
||||
- **`Reset()` does *not* clear `SetRealtimeSampleRateAAF`, `CompleteAction`, or `StartRealtimeCallback`** — only `CompleteAction` is cleared in `Reset()`. Other properties retain their values unless explicitly overwritten.
|
||||
|
||||
None identified beyond these.
|
||||
Reference in New Issue
Block a user