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

170 lines
9.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
source_files:
- DataPRO/TDASCommands/TestTriggerCommands.cs
- DataPRO/TDASCommands/CommandBase.cs
- DataPRO/TDASCommands/TDASCommandPacketBase.cs
generated_at: "2026-04-16T03:47:17.202169+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "095345d9b2c6bf7d"
---
# TDASCommands
**Documentation: TDAS Test Trigger Commands Module**
---
### 1. Purpose
This module implements command classes for interacting with TDAS hardware modules to perform test trigger operations—specifically, arming, querying status, and disabling the trigger. It provides two public command types: `TestTrigger` (single-module, unicast) and `TestTriggerBroadcast` (single-module broadcast, unicast to a specific module index). These commands construct and send ASCII-based protocol commands (`TESTTRIG` or `*<N>TESTTRIG`) to TDAS devices and parse the ASCII response to extract the trigger status (`ARMED` or `OFF`). The module relies on the shared `CommandBase` and `TDASCommandPacketBase` infrastructure for communication, sequencing, and response handling.
---
### 2. Public Interface
#### `TestTrigger` class
*Public, concrete command class for single-module test trigger operations.*
- **`int ModuleIndex`**
Gets or sets the module index (09). Setting it enforces `<10` and disables `RackCommand`.
- **`SubCommandValues SubCommand`**
Gets/sets the subcommand to send: `ARM`, `STATUS`, or `OFF`.
- *Getter* parses `_CommandString.SubCommand` as `SubCommandValues`.
- *Setter* writes the enum value as a string into `_CommandString.SubCommand`.
- **`StatusValues TriggerStatus`**
Gets the parsed trigger status from the last response: `ARMED` or `OFF`.
- *Getter* parses `_CommandString.Status` as `StatusValues`.
- Value is populated during `ProcessData()`.
- **`TestTrigger(ICommunication sock)`**
Constructor with default 30s timeout. Initializes `TDASCommandPacketBase` with `TestTriggerCommandString`, sets `RebuildBytes = true`, `RackCommand = false`, and default `SubCommand = STATUS`.
- **`TestTrigger(ICommunication sock, int msTimeout)`**
Constructor with configurable timeout. Same initialization as above, but uses provided timeout.
#### `TestTriggerBroadcast` class
*Public, concrete command class for broadcast test trigger to a specific module.*
- **`SubCommandValues SubCommand`**
Same semantics as `TestTrigger.SubCommand`, operating on `_CommandString.SubCommand` of the underlying `TestTriggerBroadcastCommandString`.
- **`TestTriggerBroadcast(ICommunication sock, int moduleIndex)`**
Constructor with default timeout. Initializes `TDASCommandPacketBase` with `TestTriggerBroadcastCommandString(moduleIndex)`, sets `RackCommand = false`, `RebuildBytes = true`, and default `SubCommand = STATUS`.
- **`TestTriggerBroadcast(ICommunication sock, int moduleIndex, int msTimeout)`**
Constructor with configurable timeout. Same initialization as above.
#### Internal helper classes (not part of public API, but referenced for completeness)
- **`TestTriggerCommandString`**
*Internal* subclass of `CommandString`.
- `_CommandString => "TESTTRIG"`
- `_CommandDescription => "Test trigger"`
- `SubCommand` and `Status` properties (string) store subcommand and response status.
- `GetParameters()` returns `" <SubCommand>"` as ASCII bytes.
- **`TestTriggerBroadcastCommandString`**
*Internal* subclass of `CommandString`.
- `_CommandString => "*<N>TESTTRIG"` (if `ModuleIndex >= 0`) or `"*TESTTRIG"` otherwise.
- `_CommandDescription` mirrors `_CommandString`.
- `ModuleIndex`, `SubCommand` properties.
- Constructor accepts `moduleIndex`.
- `GetParameters()` same as `TestTriggerCommandString`.
---
### 3. Invariants
- **ModuleIndex constraint**:
`ModuleIndex` must be `<10` (enforced in `TDASCommandPacketBase.ModuleIndex` setter). Setting it to `>=10` throws an exception.
- **RackCommand mutual exclusion**:
Setting `ModuleIndex` in `TDASCommandPacketBase` sets `RackCommand = false`. `RackCommand` is only `true` when `ModuleIndex` is unset (default `' '` space) and not explicitly set to a digit.
- **Default subcommand**:
All constructors initialize `_CommandString.SubCommand = "STATUS"`.
- **Response parsing invariant**:
`ProcessData()` in `TestTrigger` parses the response into tokens; status is assigned from `tokens[1]` if `tokens.Length >= 2`. If parsing fails, `_CommandString.Status` remains unchanged.
- **Response format assumption**:
TDAS responses are ASCII, newline-terminated (`\r\n`), and contain the command string followed by a space and status (e.g., `TESTTRIG ARMED\r\n`). Parsing assumes this format.
- **`RebuildBytes = true`**:
All `TestTrigger*` constructors set `RebuildBytes = true`, ensuring `CommandString.GetBytes()` regenerates the byte array on each `ToBytes()` call (critical for dynamic `SubCommand` changes).
---
### 4. Dependencies
#### Imports / References (from source):
- `DTS.Common.ICommunication``ICommunication` interface for socket communication.
- `DTS.DASLib.Command.TDAS` namespace:
- `CommandBase` (base class for all commands, provides `ProcessData`, `ResponseData`, `SyncExecute`, throttling).
- `TDASCommandPacketBase` (packet construction, verification, MDB mode support).
- `CommandString` (abstract base for command strings).
- `System.Text.Encoding` (ASCII encoding/decoding).
- `System.Threading` (used in `CommandBase` for `SemaphoreSlim` throttling).
#### Inferred callers:
- Likely instantiated by higher-level test or configuration logic (e.g., test harnesses, calibration tools).
- Uses `CommandBase` infrastructure, so depends on:
- `APILogger` (for logging errors and command/response).
- Throttling via `CommandBase.InitializeSemaphore()` (default: 3 concurrent operations, 100ms delay).
#### Dependencies on other modules:
- `TDASCommandPacketBase` → depends on `MDB_BLOCK` (for data mode parsing), `CommandPacketBase` (base), and `CommandString`.
- `CommandBase` → depends on logging infrastructure (`TextLogger`, `APILogger`), threading (`SemaphoreSlim`), and `AbstractCommandBase`.
---
### 5. Gotchas
- **`ModuleIndex` parsing is fragile**:
`ModuleIndex` getter in `TDASCommandPacketBase` uses `int.Parse(new string(_moduleIndex, 1))`. If `_moduleIndex` is `' '` (space), this throws `FormatException`. This is avoided in `TestTrigger` constructors because `ModuleIndex` is never explicitly set, but if used directly, it may fail.
- **`TriggerStatus` may be stale or empty**:
`TriggerStatus` reads `_CommandString.Status`, which is only updated in `ProcessData()`. If `ResponseData` is accessed before `ProcessData()` runs (e.g., via `ResponseData` getter), `ProcessData()` executes—but if the response is malformed or missing, `_CommandString.Status` may remain `null` or unchanged, causing `Enum.Parse` to throw.
- **`ProcessData()` in `TestTrigger` is custom and narrow**:
Unlike `CommandBase.ProcessData()`, `TestTrigger.ProcessData()` manually parses the response using `GetCommandPortion()` and `ResponseData.Split`. It assumes the response contains the command string followed by a space and status. Deviations (e.g., extra whitespace, different order) may cause parsing failure.
- **No validation of `SubCommand` enum values in setter**:
`SubCommand` setter directly assigns `value.ToString()` to `_CommandString.SubCommand`. If an invalid enum value is passed (e.g., via reflection or cast), no validation occurs—though `Enum.Parse` in getter may throw.
- **`TestTriggerBroadcastCommandString.ModuleIndex` is not validated**:
The broadcast command accepts any `moduleIndex`, but the command string uses `*<N>TESTTRIG`. If `moduleIndex < 0`, it falls back to `*TESTTRIG` (broadcast to all modules). This may be unintended.
- **Throttling is global and static**:
`CommandBase` uses static `_pool` and `_semaphoreDelay`. If `InitializeSemaphore()` is not called, defaults (`spots=3`, `delay=100ms`) apply. This affects all `TestTrigger`/`TestTriggerBroadcast` instances.
- **`RebuildBytes` must be `true` for dynamic updates**:
If `RebuildBytes` is accidentally set to `false`, changing `SubCommand` will not affect the outgoing command bytes until `RebuildBytes = true` or `cs.RebuildBytes()` is called.
- **No error handling in `ProcessData()` for malformed responses**:
If `ResponseData` does not contain the expected format (e.g., missing `\r\n`, insufficient tokens), `ProcessData()` silently returns without updating `_CommandString.Status`. This may lead to stale status values.
- **`GetParameters()` returns a leading space**:
Both `TestTriggerCommandString` and `TestTriggerBroadcastCommandString` return `" <SubCommand>"` (note leading space). This matches TDAS protocol expectations but is non-obvious.
- **`ModuleIndex` setter in `TDASCommandPacketBase` throws on `>=10`**:
This is a hard constraint. If future hardware supports >10 modules, this will break.
- **`ExpectsData = true` by default in `CommandString`**:
`TestTrigger`/`TestTriggerBroadcast` do not override this, so `ExpectsData = true`. If the TDAS response for `TESTTRIG` is status-only (no data), `VerifyPacket()` may behave unexpectedly (see `TDASCommandPacketBase.VerifyPacket()` logic).
- **`ToCommandString()` strips control characters**:
`ToCommandString()` removes `\r\n` and `\0`, which may obscure debugging if raw bytes are needed.
- **`CommandBase.ProcessData()` may throw**:
If `ResponseData` contains `"ERR"`, `ProcessData()` throws `InvalidOperationException`. This is caught only if the caller handles it.
- **`TestTriggerBroadcast` does not expose `ModuleIndex`**:
The `moduleIndex` is stored in the internal `TestTriggerBroadcastCommandString`, but not exposed as a property. Callers must track it externally.
---
*End of documentation.*