This commit is contained in:
2026-04-17 14:55:32 -04:00
commit bc3ac1d4c9
18017 changed files with 4371742 additions and 0 deletions

View File

@@ -0,0 +1,117 @@
---
source_files:
- Common/DTS.Common.DataModel/Classes/Enums.cs
generated_at: "2026-04-16T03:31:47.934438+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "a8986c49f9eaee26"
---
# Classes
## Documentation: `DTS.Common.DataModel/Classes/Enums.cs`
### 1. Purpose
This module defines core enumerations used throughout the `DataPROWin7.DataModel` namespace to enforce type safety and semantic clarity for key configuration and interoperability concerns. Specifically, it standardizes:
- **`IsoChannelSensorCompatibilityLevels`**: Controls warning/error behavior when validating compatibility between ISO channels and sensors (e.g., during data import/export).
- **`SupportedExportFormats`**: Lists all export formats supported by the system, with `[Description]` attributes mapping enum values to user-facing format names (e.g., `"csv" → "CSV"`).
- **`StrictLevel`**: Defines operational modes for data validation and checkout workflows, ranging from strict enforcement (`Strict`) to permissive or expedited modes (`QuickCheckout`).
The module exists to centralize these constants, avoiding magic strings/numbers and ensuring consistent interpretation across the codebase.
---
### 2. Public Interface
#### `IsoChannelSensorCompatibilityLevels`
```csharp
public enum IsoChannelSensorCompatibilityLevels
{
DontWarn,
Warn,
DontAllow
}
```
- **Purpose**: Specifies the severity level for ISO channel-sensor compatibility mismatches.
- **Values**:
- `DontWarn`: Mismatches are silently ignored.
- `Warn`: Mismatches trigger a warning (e.g., UI alert, log entry).
- `DontAllow`: Mismatches block the operation (e.g., import/export fails).
#### `SupportedExportFormats`
```csharp
public enum SupportedExportFormats
{
[Description("CSV")] csv,
[Description("Diadem")] diadem,
[Description("ISO")] iso,
[Description("SOMAT")] somat,
[Description("TDAS")] tdas,
[Description("TSV")] tsv,
[Description("TTS")] tts,
[Description("RDF")] rdf,
[Description("TDMS")] tdms,
[Description("DDAS")] ddas,
[Description("HDF5")] hdf,
[Description("XLSX")] xlsx,
[Description("Chapter10")] chapter10, // DataPRO 3.3, IRIG 106 Chapter 10
[Description("ASC")] asc
}
```
- **Purpose**: Represents all export formats supported by the application.
- **Behavior**:
- Each value has a `[Description]` attribute specifying its display name (e.g., `csv` → `"CSV"`).
- `chapter10` is explicitly annotated as supporting *IRIG 106 Chapter 10* (a telemetry data format standard).
- **Note**: `xlsx` uses `// ReSharper disable once InconsistentNaming` to suppress naming convention warnings (likely due to casing mismatch with PascalCase guidelines).
#### `StrictLevel`
```csharp
public enum StrictLevel
{
Strict,
UpdateTable,
CheckoutOnly,
QuickCheckout
}
```
- **Purpose**: Configures the rigor of data validation and checkout operations.
- **Values**:
- `Strict`: Full validation enforced; non-compliant data rejected.
- `UpdateTable`: Validation performed, but table schemas may be updated to accommodate data.
- `CheckoutOnly`: Validation skipped; only checkout (e.g., file locking, metadata update) occurs.
- `QuickCheckout`: Minimal validation; optimized for speed (e.g., bulk operations).
---
### 3. Invariants
- **`IsoChannelSensorCompatibilityLevels`**:
- Values must be used consistently in validation logic (e.g., `DontAllow` must prevent operations, not just log warnings).
- **`SupportedExportFormats`**:
- The `[Description]` attribute value for each enum member is the canonical string representation used in UI/file dialogs.
- `chapter10` is reserved for IRIG 106 Chapter 10 exports (per inline comment).
- **`StrictLevel`**:
- `Strict` is the most restrictive mode; `QuickCheckout` is the least.
- No two modes may have identical behavior in validation/checkout logic.
---
### 4. Dependencies
- **Depends on**:
- `System.ComponentModel` (for `[Description]` attribute).
- **Depended upon**:
- Other modules in `DataPROWin7.DataModel` (inferred from namespace usage).
- Likely used by export pipelines (e.g., format selection), ISO data validation components, and checkout workflows.
- *Not directly referenced in source*, but usage is implied by the enums purpose and naming.
---
### 5. Gotchas
- **`xlsx` enum member**:
- Uses `// ReSharper disable once InconsistentNaming` to override PascalCase convention (likely due to legacy naming or external format specification requiring lowercase). This may cause confusion if developers expect consistent casing.
- **`chapter10` naming**:
- The enum value `chapter10` (lowercase) maps to `"Chapter10"` (PascalCase) via `[Description]`. Developers must use `DescriptionAttribute` to retrieve the display name, not `ToString()`.
- **Ambiguity in `StrictLevel` semantics**:
- The exact behavior differences between `UpdateTable`, `CheckoutOnly`, and `QuickCheckout` are *not specified in this file*. Implementation details (e.g., how `UpdateTable` modifies schemas) must be verified in dependent modules.
- **No validation of enum usage**:
- The enums themselves contain no runtime validation. Invalid combinations (e.g., `DontAllow` with `QuickCheckout`) must be handled by calling code.
*None identified beyond the above.*

View File

@@ -0,0 +1,87 @@
---
source_files:
- Common/DTS.Common.DataModel/Classes/Arming/Arming.cs
generated_at: "2026-04-16T03:33:38.565199+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "030ceff579d3b0a9"
---
# Arming
### **Purpose**
The `Arming` class orchestrates the hardware arming sequence for DAS (Data Acquisition System) units in the TSRAIRGo system. It prepares, configures, clears flash memory, and arms one or more DAS units for data acquisition, handling both success and failure paths—including rollback via disarming—while integrating progress reporting and error handling. It serves as the central coordinator between high-level test configuration (`TestTemplate`), low-level DAS communication (`IDASCommunication`), and the underlying `ArmingService`, ensuring safe, deterministic transitions through the arming workflow.
---
### **Public Interface**
#### **`public bool SetConfigAndFlashClear(...)`**
```csharp
public bool SetConfigAndFlashClear(
DataModel.TestTemplate currentTest,
List<IDASCommunication> dasList,
Dictionary<string, int> dasSampleRateList,
double duration,
StatusHelpers.SetProgressValueDelegate setProgressFunction,
ServiceBase.ServiceCallbackErrorEventHandler onError)
```
- **Behavior**: Public entry point to configure DAS modules (set pre/post-trigger times, event count, wake-up timeout), flash erase, and arm. Internally calls `SetConfigAndStartFlashClear(..., diagnosticsVoltage: false)`. Returns `true` on full success; `false` on any failure (with errors logged and reported via `onError`).
#### **`public void SoftwareTrigger(List<IDASCommunication> dasList)`**
- **Behavior**: Sends a software trigger command to all DAS units in `dasList` via `ArmingService.Trigger`. Logs failures via `APILogger`. Non-blocking with respect to caller (synchronous internally, but no return value or exception propagation to caller).
#### **`public void DisarmAsync(List<IDASCommunication> dasList)`**
- **Behavior**: Public wrapper that invokes `Disarm(dasList)` synchronously. Despite the name, **no actual async behavior**—it blocks until disarm completes.
---
### **Invariants**
1. **Thread Safety**: All arming/disarming operations are guarded by `lock (DASHardware.GetArmStatusLock)`, ensuring only one arming sequence runs at a time across the system.
2. **Flash Erase Completion**: Flash erase is considered successful only if *all* DAS units report `CallbackStatus.Success` or `AllFinished` without `Failure`. Partial failures abort the sequence.
3. **Armed State Consistency**: A DAS unit is marked as armed (`DASArmStatus.IsArmed = true`) *only* after `PreparedArmNow` succeeds for that unit. If any unit fails to arm, the system attempts to disarm *all* units (including those that may have partially armed) to prevent inconsistent states.
4. **Progress Reporting**: Progress callbacks (`setProgressFunction`) are invoked at defined stages: `PREPARING_FOR_ARMING`, `PREPARING_DATA_MEMORY`.
5. **Timeout Enforcement**: All blocking waits use `ManualResetEvent.WaitOne(50, false)` loops with cumulative `timeWaited` tracking, but no explicit timeout enforcement beyond `ARM_NOW_TIMEOUT = 30000` (30s) for `PrepareForArmNow`.
---
### **Dependencies**
#### **Imports/Usings (Direct Dependencies)**
- `DTS.Common.Interface.DASFactory.IDASCommunication` — Interface for DAS unit communication.
- `DTS.DASLib.Service.ArmingService` — Core service for low-level arming operations (`BeginFlashErase`, `GetFlashEraseStatus`, `ReadyForArm`, `PrepareForArmNow`, `PreparedArmNow`, `Trigger`, `Disarm`, `EnableFaultChecking`, `CheckAlreadyLevelTriggered`).
- `DTS.Common.DataModel.Classes.TSRAIRGo.TSRAIR` — Used for `TSRAIR.TSRAIR_MAX_PRE_TRIGGER_SAMPLES`.
- `DTS.Common.Constant.DASSpecific.*`, `DTS.Common.Enums.TSRAIRGo.*`, `DTS.Common.SharedResource.Strings.*` — Constants, enums, and localized strings (e.g., `StringResources.FailedToArm`).
- `DTS.Common.DataModel.Common.*` — Includes `TestTemplate`, `AnalogInputDASChannel`.
- `DTS.Common.Utilities.Logging.APILogger` — For logging exceptions and errors.
#### **Inferred Consumers**
- High-level test orchestration code (e.g., test runner, UI controller) that calls `SetConfigAndFlashClear` to arm hardware before a test.
- Any code needing to trigger acquisition (`SoftwareTrigger`) or abort (`DisarmAsync`/`DisarmSync`).
---
### **Gotchas**
1. **`DisarmAsync` is Misnamed**: Despite the name, `DisarmAsync` calls `DisarmSync`, which blocks until disarm completes. No actual asynchronous behavior is implemented.
2. **Hardcoded Timeout Values**:
- `ARM_NOW_TIMEOUT = 30000` (30s) for `PrepareForArmNow`.
- `30000` (30s) timeout in `PreparedArmNow` call (commented as `///////////fix the 30000 and 1 (at least)`).
These may need tuning per deployment.
3. **`PreTriggerSeconds` Calculation**:
```csharp
mod.PreTriggerSeconds = (double)TSRAIR.TSRAIR_MAX_PRE_TRIGGER_SAMPLES / Convert.ToInt32(dasSampleRateList[das.SerialNumber]);
```
Assumes `dasSampleRateList` contains an entry for `das.SerialNumber`; missing entries will throw `KeyNotFoundException`.
4. **`AlreadyLevelTriggered` Check**:
- Only checks *analog* channels (`ch is AnalogInputDASChannel`).
- Fails arming if *any* channel reports `AlreadyLevelTriggered`, but does not expose which channels beyond logging to `onError`.
5. **Fault Checking Limitation**:
`EnableFaultChecking` is only called for `das.Count > 1`, but the comment notes its limited to *single unit at a time for TDAS*—this logic may be incomplete or inconsistent.
6. **No Cancellation Support**:
`cancelEvent` is created but never set externally (only internally on failure). No mechanism exists for a caller to abort mid-arming.
7. **Flash Erase Failure Handling (FB 39345)**:
If flash erase fails, the system returns `false` but may still attempt `PrepareArmFunc` if `cancelEvent` is not set—though `bFailed` blocks this. The logic is complex and error-prone.
8. **`PreparedArmNow` Modifies State In-Place**:
Sets `cbd.Target.DASArmStatus.IsArmed = true` directly on the DAS object, which could cause race conditions if accessed concurrently outside the lock (though the lock mitigates this).

View File

@@ -0,0 +1,75 @@
---
source_files:
- Common/DTS.Common.DataModel/Classes/Configuration/Configuration.cs
generated_at: "2026-04-16T03:32:33.762922+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "3e9a6cf2611db268"
---
# Configuration
### **Purpose**
This `Configuration` class is responsible for applying hardware-specific voltage thresholds and configuration settings to a list of Data Acquisition System (DAS) units (`IDASCommunication` instances) prior to test execution or diagnostics. It orchestrates the configuration process by reading threshold values from a centralized settings store (`BatteryAndInputVoltageDefaults`), applying them to each DAS object, resetting hardware lines to a known state, and then invoking `ConfigurationService.SetConfiguration` to push the updated configuration to the hardware. It also ensures that the resulting configuration files are persisted locally per test by copying them from a global configuration directory to the current tests directory.
---
### **Public Interface**
#### **`public void SetConfig(DataModel.TestTemplate currentTest, List<IDASCommunication> dasList, bool calledDuringDiagnostics, StatusHelpers.SetProgressValueDelegate setProgressFunction)`**
- **Behavior**: Applies DAS-specific voltage thresholds (input and battery) based on hardware type, using different thresholds depending on whether the call is for diagnostics (`calledDuringDiagnostics == true`) or normal operation. After setting thresholds on each `IDASCommunication` object, it resets hardware lines via `ConfigurationService.ResetHardwareLines`, then calls `ConfigurationService.SetConfiguration` to commit the configuration to hardware. Progress is reported via `StatusHelpers.SetStatus2`. On success, it copies DAS and module configuration XML files to the test directory. Thread-safe via `lock` on `DASHardware.GetArmStatusLock`.
- **Parameters**:
- `currentTest`: The active test context; used to determine the destination directory for config file copying.
- `dasList`: List of DAS units to configure.
- `calledDuringDiagnostics`: If `true`, uses *diagnostic* thresholds (e.g., `BatteryHighDiagnosticsThreshold`); otherwise uses *armed* thresholds (e.g., `BatteryHighArmedThreshold`).
- `setProgressFunction`: Delegate used to report progress during configuration.
#### **`public static DialogResult ErrorCallback(string errorString, string units)`**
- **Behavior**: A static callback used by `ConfigurationService.SetConfiguration` to handle configuration errors. Logs the error via `APILogger.Log`, and currently returns `DialogResult.OK` (commented as a TODO: “Fix this”).
- **Note**: Does not throw or re-raise the error; caller must rely on exception handling in `SetConfig` to detect failure.
---
### **Invariants**
- **Thread Safety**: The entire `SetConfig` method body is guarded by `lock (DASHardware.GetArmStatusLock)`, ensuring only one configuration operation occurs at a time.
- **Voltage Threshold Assignment**: For each `IDASCommunication das` in `dasList`, the following six properties are *always* set:
- `MinimumValidInputVoltage`, `MaximumValidInputVoltage`
- `MinimumValidBatteryVoltage`, `MaximumValidBatteryVoltage`
- `BatteryHighVoltage`, `BatteryMediumVoltage`, `BatteryLowVoltage`
- `InputHighVoltage`, `InputMediumVoltage`, `InputLowVoltage`
The values are derived from `BatteryAndInputVoltageDefaults.InputAndBatterySettings.GetValue(type.ToString(), ...)`, where `type = das.GetHardwareType()`.
- **Hardware Reset Precedes Configuration**: `ConfigurationService.ResetHardwareLines` is *always* called before `SetConfiguration`, per the comment: “setting the configuration checks the hardware lines so make sure we reset them prior to setting configuration.”
- **Config File Copying**: After successful configuration, XML files for each DAS and its modules are copied from a global `Constants.DAS_CONFIGS` directory to `currentTest.TestDirectory`, overwriting existing files.
---
### **Dependencies**
- **Imports/Usings**:
- `DTS.Common.Interface.DASFactory.IDASCommunication`: Interface for DAS communication objects.
- `DTS.DASLib.Service.ConfigurationService`: Core service used to perform hardware reset and configuration.
- `DTS.Common.DataModel.Common.StatusHelpers`: Provides `SetStatus2` and `SetProgressValueDelegate`.
- `DTS.Common.Utilities.Logging.APILogger`: Used for logging errors and exceptions.
- `DTS.Common.DataModel.Classes.TSRAIRGo.TSRAIRGoStatus`: Defines `StatusTypes.UPDATING_DAS_CONFIG`.
- `DTS.Common.Enums.TSRAIRGo`: Enum namespace (used via `TSRAIRGoStatus`).
- `System.Windows.Forms.DialogResult`: Used in `ErrorCallback`.
- `DTS.Common.DataModel.Common.DataModel.BatteryAndInputVoltageDefaults`: Static source of voltage thresholds.
- `DTS.Common.Constants`: Defines `DAS_CONFIGS` (directory name).
- `DTS.Common.SerializedSettings`: Provides `MaxAAFRate_TDAS`, `MaxAAFRate_G5`, and `GetDefaultDSP()`.
- **External Dependencies**:
- `DASHardware.GetArmStatusLock`: A static lock object used for synchronization.
- `Environment.CurrentDirectory`: Base path for global config directory.
- File system: Requires existence of `DAS_CONFIGS` directory (via `Constants.DAS_CONFIGS`) and read access to XML files.
- **Called By**: Presumably invoked by higher-level test orchestration logic (e.g., before test start or diagnostics run). Not referenced in source, but usage is implied by test context (`currentTest`) and progress reporting.
---
### **Gotchas**
- **Hardcoded Threshold Keys**: Threshold keys (e.g., `"BatteryHighDiagnosticsThreshold"`) are string literals; no compile-time safety. A mismatch in key names in `BatteryAndInputVoltageDefaults` will result in default fallback values (via `GetValue`s second parameter), potentially leading to incorrect thresholds.
- **Blocking Wait Loop**: The `while (!done.WaitOne(50, false)) { elapsed += 50; }` loop is a polling-based wait. While functional, it may be inefficient or mask timing issues; no timeout is enforced beyond the loops implicit duration (no `elapsed`-based timeout check).
- **`ErrorCallback` Does Not Propagate Errors**: Returns `DialogResult.OK` unconditionally; actual failure detection relies on exceptions thrown in `SetConfig` or `SetConfiguration`. If `SetConfiguration` fails silently (e.g., via `CallbackStatus.Failure` without throwing), this may go unnoticed.
- **Assumes `das.DASInfo` is `InfoResult`**: In `CopyGlobalConfigsToLocalFolder`, `((InfoResult)das.DASInfo).OwningDAS` and `module.SerialNumber` are cast without type checking. If `das.DASInfo` is not an `InfoResult`, this will throw at runtime.
- **No Validation of `dasList`**: `SetConfig` does not check for null or empty `dasList`, which could lead to no-op or unexpected behavior.
- **`AggregateProgress = false`**: Indicates per-DAS progress reporting is expected, but the callback logic uses `cbd.Target` (a DAS instance) to report progress—this is consistent, but the setting may be easy to overlook.
- **Commented TODO**: `//Fix this` next to `return DialogResult.OK;` in `ErrorCallback` indicates known technical debt.

View File

@@ -0,0 +1,186 @@
---
source_files:
- Common/DTS.Common.DataModel/Classes/Diagnostics/Diagnostics.cs
generated_at: "2026-04-16T03:34:15.620410+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "9ad8e7542b559d55"
---
# Diagnostics
**Documentation Page: `Diagnostics` Class (`DataPROWin7.DataModel.Classes.Diagnostics`)**
---
### 1. **Purpose**
The `Diagnostics` class orchestrates the initialization and configuration of Data Acquisition System (DAS) hardware and associated channels for diagnostic testing. It handles the transition from test setup definition to a state where DAS units are ready for real-time data collection or diagnostics execution. Specifically, it queries DAS configurations, validates hardware/sensor compatibility, synchronizes test setup metadata (e.g., XML export to DAS and local storage), and prepares channel-level configurations (analog, CAN, squib, TOM digital) for diagnostics. It serves as the central coordinator between the high-level test template and low-level DAS communication interfaces.
---
### 2. **Public Interface**
#### `public class LevelTriggerCapableChannel`
Encapsulates level-triggering configuration for a single hardware channel, enabling conversion to/from ISO-level `LevelTriggerChannel` objects.
- **`public LevelTriggerCapableChannel(HardwareChannel hwch, SensorData sd, SensorCalibration sc, IGroup group, IGroupChannel groupChannel)`**
Constructor. Initializes the channel with hardware, sensor, calibration, and group context. Stores calibration on `sd`.
- **`public HardwareChannel HardwareChannel { get; }`**
Immutable reference to the underlying hardware channel.
- **`public string DASOrModuleSerialNumber { get; }`**
Returns the DAS serial number for most hardware types, but returns the *module* serial number for `TDAS_Pro_Rack` and `TDAS_LabRack`.
- **`public double LessThanValue { get; private set; }`**
Threshold value for "less than" triggering (EU).
- **`public double GreaterThanValue { get; private set; }`**
Threshold value for "greater than" triggering (EU).
- **`public bool IsLessThanThresholdEnabled { get; set; }`**
Enables/disables the "less than" threshold. Updates `_testSetupLevelTrigger` if present.
- **`public bool IsGreatherThanThresholdEnabled { get; set; }`**
Enables/disables the "greater than" threshold. Updates `_testSetupLevelTrigger` if present.
- **`public double InsideUpperBoundValue`, `InsideLowerBoundValue`, `OutsideUpperBoundValue`, `OutsideLowerBoundValue { get; private set; }`**
Bound values for window-based triggering.
- **`public DTS.Common.ISO.LevelTriggerChannel ToISOLevelTriggerChannel()`**
Constructs and returns an ISO `LevelTriggerChannel` object, applying special handling for TSRAIRGo high-G sensors (e.g., disabling thresholds by default).
- **`public void FromISOLevelTriggerChannel(DTS.Common.ISO.LevelTriggerChannel channel)`**
Populates internal state from an ISO `LevelTriggerChannel`. Sets `_testSetupLevelTrigger` reference.
---
#### `public class Diagnostics`
- **`public bool Reset(TestTemplate currentTest, List<IDASCommunication> dasList, Dictionary<string, int> dasSampleRateList, DASHardware[] hardware, StatusHelpers.SetProgressValueDelegate setProgressFunction, User currentUser)`**
Performs initial reset steps: marks all DAS as unclean, attempts partial configuration query (with timeout), and returns `false` if no data has ever been downloaded (`DataNeverDownloaded(dasList)`). Does *not* perform full diagnostics.
- **`public void ContinueReset(TestTemplate currentTest, List<IDASCommunication> dasList, Dictionary<string, int> dasSampleRateList, DASHardware[] hardware, StatusHelpers.SetProgressValueDelegate setProgressFunction, User currentUser)`**
Continues reset: calls `UpdateConfigAndPrepareForDiagnostics`, then `RunDiagnostics`. (Note: `RunDiagnostics` is not defined in this file—its implementation is external.)
---
#### `public static bool SortOutConfigAnalog(...)`
- **`public static bool SortOutConfigAnalog(AnalogInputDASChannel dasChannel, string key, int moduleChannelNumber, IDASCommunication das, DASHardware h, IDASModule mod, SortOutConfigParams soParams, ReportErrorsDelegate ReportErrors = null)`**
Configures an `AnalogInputDASChannel` using test setup metadata (sensor, calibration, group channel). Handles:
- Excitation, coupling, filter bypass, zero point, sensitivity, linearization, IEPE mode, trigger thresholds (via `LevelTriggerCapableChannel`), and more.
- Special logic for TSRAIR low-G (AC coupling), non-linear calibrations, and IEPE channels.
- Reports errors via `ReportErrors` if IEPE state mismatch cannot be reprogrammed.
- Returns `false` if no valid calibration found.
---
#### `public static void SortOutConfigCAN(...)`
- **`public static void SortOutConfigCAN(IDASChannel c, int moduleChannelNumber, SortOutConfigParams soParams)`**
Configures a `CANInputDASChannel` with CAN-specific parameters (FD, bitrate, SJW, file type) from the first channel in `soParams.TestTemplate.ChannelsForGroup`.
---
#### `public static void SortOutConfigSquib(...)`
- **`public static void SortOutConfigSquib(ref int currentChannelIdx, IDASModule mod, string key, ref int moduleChannelNumber, IDASChannel c, IDASCommunication das, SortOutConfigParams soParams)`**
Configures a squib pair (voltage and current channels) from test setup. Handles fire delay/duration, tolerance, output current, filter bypass, and channel naming (`.1`/`.2` suffix handling). Requires both VO and CU channels.
---
#### `public static void SortOutConfigTOMDigitalChannel(...)`
- **`public static void SortOutConfigTOMDigitalChannel(IDASChannel c, string key, int moduleChannelNumber, SortOutConfigParams soParams)`**
Configures an `OutputTOMDigitalChannel` with delay, duration, limit duration, and output mode from test setup.
---
#### `public static void SortOutConfig(...)`
- **`public static void SortOutConfig(TestTemplate currentTest, List<IDASCommunication> ldas, bool clearDiagnostics, DASHardware[] allHardware, User currentUser)`**
Top-level configuration entry point. Orchestrates channel ordering, DAS-specific configuration (`SortOutConfigDAS`), and sets DAS order indices for TMATS support.
---
#### `public static void SortOutConfigDAS(...)`
- **`public static void SortOutConfigDAS(IDASCommunication das, User currentUser, SortOutConfigParams soParams, ReportErrorsDelegate reportErrors = null)`**
Applies `SortOutConfig*` methods to each channel in a DASs module configuration. Handles clock, UART, stream in/out, and normal modes. Sets module-level properties (AA filter rate, pre/post-trigger, recording mode, sample rate, etc.). Disables channels not in the test.
---
### 3. **Invariants**
- **`LevelTriggerCapableChannel`**:
- `IsLessThanThresholdEnabled` and `IsGreatherThanThresholdEnabled` default to `true` and `false`, respectively.
- For TSRAIRGo high-G sensors (`SensorConstants.IsTSRAirHighGChannel`), thresholds are *disabled by default* in `ToISOLevelTriggerChannel`, and `TriggerOutsideBounds` is forced `true` if the sensor is high-G.
- `_testSetupLevelTrigger` is only updated when set via `FromISOLevelTriggerChannel`.
- **`Diagnostics`**:
- `Reset` *must* be called before `ContinueReset`; `ContinueReset` assumes partial configuration (via `Reset`) has occurred.
- `SortOutConfigAnalog` requires a valid `SensorCalibration` (`sc`) matching the sensors supported excitation; otherwise, it returns `false`.
- Squib configuration (`SortOutConfigSquib`) requires *both* voltage and current output channels to exist in the DAS module (throws `NotSupportedException` otherwise).
- IEPE status mismatch between sensor and DAS channel is only auto-corrected if `CanReProgram()` returns `true`; otherwise, errors are reported and the channel may be left in an invalid state.
---
### 4. **Dependencies**
#### **Imports / Dependencies Used**
- `DataPROWin7.Common`, `DTS.Common.*` (core data model, enums, utilities, logging, hardware interfaces)
- `DTS.DASLib.Service.ConfigurationService` (for `GetConfiguration`, `StoreTestSetupXML`)
- `DTS.Slice.Users.UserSettings`, `DTS.Common.Constant.DASSpecific`, `DTS.Common.DAS.Concepts.*`
- `DTS.Common.Interface.*` (e.g., `IDASCommunication`, `IDASModule`, `IGroup`, `IGroupChannel`)
- `DTS.Slice.Users.User`, `DTS.Common.Interface.Sensors.AnalogDiagnostics`
- `DTS.Slice.Users.UserSettings`, `DTS.Common.SharedResource.Strings`
- `DataPROWin7.DataModel.Classes.Hardware`, `DTS.Common.Classes.*`, `DTS.Slice.*`
#### **Key External Components**
- `ConfigurationService`: Used for querying DAS configuration and storing test setup XML.
- `SensorConstants`, `SensorCalibration`, `MeasurementUnitList`, `SerializedSettings`, `APILogger`, `Defaults`, `ExportTestSetup`.
- `DASHardware`, `HardwareChannel`, `AnalogInputDASChannel`, `CANInputDASChannel`, `OutputSquibChannel`, `OutputTOMDigitalChannel`, `IDASCommunication`.
#### **Depended Upon By**
- Likely called by higher-level test orchestration (e.g., `TestTemplate.RunDiagnostics`, `TestSetupBuilder`).
- `LevelTriggerCapableChannel` is used internally in `SortOutConfigAnalog` to map test-level level triggers to DAS channel properties.
---
### 5. **Gotchas**
- **Timeout Handling**: `QueryConfigurationPartial` uses a hardcoded 150-second timeout for TSRAIRGo (`TSRAIRGO_QUERYCONFIG_TIMEOUT = 150000 ms`); other systems use `SerializedSettings.ResolveChannels_SLICE_QueryConfigTimeoutSec * 1000`. Timeout exceptions are logged and rethrown.
- **IEPE Mismatch**: If `dasChannel.IEPEChannel` differs from `sensor.Bridge == IEPE`, and `CanReProgram()` is `false`, errors are reported via `ReportErrors`, but the method does *not* return `false`—execution continues, potentially leaving the channel misconfigured.
- **Non-Linear Calibration Logic**: The `bUseNonLinear` flag logic is complex:
- Uses non-linear calibration if `!sc.NonLinear || !sc.LinearAdded || CalibrationBehaviors.LinearIfAvailable != TestTemplate.CalibrationBehavior`.
- Zero point and sensitivity calculations differ for linear vs. non-linear calibrations.
- Special handling for `IRTraccCalculationType.IRTraccCalFactor` and `Polynomial`.
- **Squib Channel Naming**: Squib current channel description suffix `.1` is replaced with `.2`, and `ChannelName2` is updated accordingly.
- **TSRAIRGo High-G Sensors**: Thresholds are disabled by default in `ToISOLevelTriggerChannel`, and `TriggerOutsideBounds` is forced `true` if the sensor is high-G—even if `channel.TriggerOutsideBounds` is `false`.
- **`Reset` Returns `false` on `DataNeverDownloaded`**: This check is not defined in the source file—behavior is inferred from usage. Its implementation is unknown.
- **`SortOutConfigAnalog` Does Not Short-Circuit on Failure**: If calibration lookup fails, it logs and returns `false`, but the caller (`SortOutConfigDAS`) continues to the next channel (per comment: *"for instance if we fail to sort out this channel because of support excitation you still want to go onto the next channel"*).
- **`SortOutConfigDAS` Disables Channels Not in Test**: If a DAS is not in `soParams`, *all* its channels are disabled via `DisableChannel(c)`. The `DisableChannel` method is not defined in this file.
- **`ExportCurrentTestSetupFields` Clears Groups**: A temporary `TestTemplate` is created with `Groups.Clear()` before exporting DAS/Fields-only XML—this may affect downstream logic if `currentTest` is reused.
- **`LevelTriggerCapableChannel` Constructor Parameter Order**: The constructor order is `(HardwareChannel, SensorData, SensorCalibration, IGroup, IGroupChannel)`. `IGroup` is unused in the constructor body (per source), but included—could be legacy or for future use.
- **`DiagnosticsMode` Handling**: For analog channels, `DiagnosticsMode` is taken directly from `sensor.DiagnosticsMode`. For squib/TOM digital, it is *hardcoded to `false`*.
- **`SortOutConfigParams` Incomplete Source**: The class definition is truncated mid-method (`SetHard...`). Full behavior of `SetHard*` methods is unknown.
- **`RunDiagnostics` Not Defined**: `ContinueReset` calls `RunDiagnostics`, but its implementation is not in this file—behavior is undefined here.
---
*End of Documentation.*

View File

@@ -0,0 +1,210 @@
---
source_files:
- Common/DTS.Common.DataModel/Classes/Export/ExportHeader.cs
- Common/DTS.Common.DataModel/Classes/Export/ExportTestSetup.cs
generated_at: "2026-04-16T03:34:31.793274+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "e1688a84f19142ea"
---
# Export
## Documentation: `ExportTestSetup` Module
---
### **Purpose**
The `ExportTestSetup` static class orchestrates the preparation and serialization of test configuration data for export to XML. It aggregates test templates, associated groups, sensors, calibrations, DAS hardware, sensor models, ISO metadata (customer, engineer, lab), users, and global settings into dictionaries, validates and deduplicates entries, and writes them to an XML file using a structured writer. This module serves as the core export engine for test setup data, supporting both full exports and field-only exports (e.g., for partial updates or migrations). It bridges domain models (`TestTemplate`, `IGroup`, `SensorData`, etc.) with serialization infrastructure (`IExportHeader`-like patterns, XML writers) and database abstractions.
---
### **Public Interface**
#### **1. `PrepareForExport`**
```csharp
public static void PrepareForExport(
DataModel.TestTemplate t,
Dictionary<string, DataModel.TestTemplate> includedTests,
Dictionary<string, IGroup> includedGroups,
Dictionary<string, DataModel.DASHardware> includedDAS,
Dictionary<string, SensorData> includedSensors,
HashSet<int> sensorsAlreadyAdded,
Dictionary<string, SensorModel> includedSensorModels,
Dictionary<string, SensorCalibration[]> includedCalibration,
Dictionary<string, DTS.Common.ISO.CustomerDetails> includedCustomerDetails,
Dictionary<string, DTS.Common.ISO.TestEngineerDetails> includedTestEngineerDetails,
Dictionary<string, DTS.Common.ISO.LabratoryDetails> includedLabDetails,
bool savingRunningTest,
bool savingTTSImport
)
```
**Behavior**: Populates the provided dictionaries with data derived from the input `TestTemplate` `t`.
- Adds `t` to `includedTests`.
- Extracts and deduplicates ISO metadata (customer, engineer, lab) into respective dictionaries.
- Iterates over embedded groups in `t.Groups`, collects associated sensors (via channels), calibrations, and DAS hardware, skipping test-specific digital outputs/squibs/digital inputs.
- Resolves and processes non-embedded (static) groups via `GetNonEmbeddedGroup`, ensuring thread-safe dispatcher invocation.
- Deduplicates sensors and calibrations using `sensorsAlreadyAdded`.
- Collects sensor models and calibrations for non-test-specific sensors.
- Adds hardware from `t.GetHardware()`.
- If `savingTTSImport` is `true`, *also* includes *all* sensors (even unused ones) and their calibrations/models.
- Mutates all input dictionaries and sets in-place.
#### **2. `ExportToFile`**
```csharp
public static string ExportToFile(
Dictionary<string, DataModel.TestTemplate> includedTests,
Dictionary<string, IGroup> includedGroups,
Dictionary<string, DataModel.DASHardware> includedDAS,
Dictionary<string, SensorData> includedSensors,
Dictionary<string, SensorModel> includedSensorModels,
Dictionary<string, SensorCalibration[]> includedCalibration,
Dictionary<string, DTS.Common.ISO.CustomerDetails> includedCustomerDetails,
Dictionary<string, DTS.Common.ISO.TestEngineerDetails> includedTestEngineerDetails,
Dictionary<string, DTS.Common.ISO.LabratoryDetails> includedLabDetails,
Dictionary<string, DTS.Slice.Users.User> includedUsers,
Dictionary<string, string> includedGlobalSettings,
string exportFile,
string originalImportFile,
bool bUseFirstUseDate = true
)
```
**Behavior**: Serializes the aggregated data into an XML document and optionally writes it to `exportFile`.
- Uses `FileUtils.GetExportWriter(...)` to create an `XmlWriter` with progress tracking.
- Writes `OriginalImportFile` as an attribute on the root element.
- Iterates over `TopLevelFields` enum values, writing only non-empty sections in a fixed order (e.g., `Calibrations`, `DASList`, `Groups`, `Sensors`, `TestSetups`, etc.).
- Calls `WriteXML(ref writer)` on each item in the dictionaries (e.g., `SensorData.WriteXML`, `SensorCalibration.WriteXML`).
- Returns the full XML string (via `StringBuilder`) and writes it to `exportFile` if non-null.
- Logs exceptions via `APILogger.Log` and returns `string.Empty` on failure.
#### **3. `PrepareForExportFields`**
```csharp
public static void PrepareForExportFields(
DataModel.TestTemplate t,
Dictionary<string, DataModel.TestTemplate> includedTests,
Dictionary<string, DataModel.DASHardware> includedDAS
)
```
**Behavior**: A *lightweight* variant of `PrepareForExport` that only populates `includedTests` and `includedDAS`.
- Adds `t` to `includedTests`.
- Collects embedded and non-embedded group hardware into `includedDAS`.
- Does *not* process sensors, calibrations, groups, or metadata.
- Includes logic to remove unused DAS sample rates from `t.DASSampleRateList`.
- Intended for scenarios where only test setup and hardware metadata need updating (e.g., field-level sync).
#### **4. `ExportToFileFields`**
```csharp
public static string ExportToFileFields(
Dictionary<string, DataModel.TestTemplate> includedTests,
Dictionary<string, DataModel.DASHardware> includedDAS,
string originalImportFile
)
```
**Behavior**: Serializes *only* `TestSetups` and `DASList` sections (no sensors, calibrations, groups, etc.).
- Uses the same XML writer infrastructure as `ExportToFile`.
- Skips all `TopLevelFields` except `DASList` and `TestSetups`.
- Returns the XML string (no file write).
- Used for minimal exports (e.g., updating only test and hardware definitions).
#### **5. `ExportHeader` (Class)**
```csharp
public class ExportHeader : IExportHeader
```
**Behavior**: A simple data model for UI-level export header selection.
- Implements `INotifyPropertyChanged`.
- Properties:
- `HeaderName` (`string`): Name of the export section/group.
- `IsSelected` (`bool`): Whether the header is selected for export.
- Raises `PropertyChanged` on property changes.
- Used to drive UI checkboxes or toggles for export sections (e.g., in a configuration dialog).
---
### **Invariants**
1. **Deduplication by Key**:
- `includedTests`, `includedGroups`, `includedDAS`, `includedSensors`, `includedSensorModels`, `includedCalibration`, `includedCustomerDetails`, `includedTestEngineerDetails`, `includedLabDetails`, `includedUsers`, and `includedGlobalSettings` use string keys (e.g., `Name`, `SerialNumber`) to avoid duplicates.
- `sensorsAlreadyAdded` uses `DatabaseId` (int) to prevent reprocessing sensors.
2. **Hardware Deduplication**:
- `includedDAS` uses `SerialNumber` as the key. Hardware is added only if not already present.
3. **Sensor Exclusion Rules**:
- Sensors marked `IsTestSpecificDigitalOutput`, `IsTestSpecificSquib`, or `IsTestSpecificDigitalIn` are *excluded* from `includedSensors` and `includedCalibration` *unless* `savingTTSImport` is `true`.
4. **Static Group Resolution**:
- Non-embedded groups must exist in the database (resolved via `GetNonEmbeddedGroup`). If not, `embeddedGroup.StaticGroupId` is set to `null` and processing continues (no exception thrown).
5. **Thread Safety for Dispatcher**:
- Access to `Application.Current.Dispatcher` for static group resolution uses `CheckAccess()` and `BeginInvoke` with `ManualResetEvent` to block on non-UI threads.
6. **XML Serialization Order**:
- Sections are written in the order defined by `TopLevelFields` enum (via `Enum.GetValues`). Unsupported/empty sections are skipped.
---
### **Dependencies**
#### **Imports/Usings (Direct Dependencies)**
- `DTS.Common.Interface.ExportData` (`IExportHeader`)
- `DTS.Common.Interface.Groups.GroupList` (`IGroup`, `IGroupChannel`)
- `DTS.SensorDB` (`SensorData`, `SensorCalibration`)
- `DTS.Common.Interface.Sensors` (`ISensorData`)
- `DTS.Common.Interface.Channels` (`IGroupChannel`)
- `DTS.Common.Interface.DataRecorders` (`IDASHardware`)
- `DTS.Common.Storage` (`DbOperations`, `FileUtils`)
- `Prism.Ioc`, `Unity` (`ContainerLocator`, `IUnityContainer`)
- `DTS.Common.ISO` (`CustomerDetails`, `TestEngineerDetails`, `LabratoryDetails`, `Hardware`, `SensorModel`)
- `DTS.Common.Utils`, `DTS.Common.Utilities.Logging` (`APILogger`)
- `DTS.Common.Enums.DBExport` (`TopLevelFields`)
- `System`, `System.Linq`, `System.Windows`, `System.Threading`, `System.Text`, `System.Xml`
#### **External Services/Modules Used**
- `SensorsCollection.SensorsList` (static): For sensor lookup (`GetAllSensors`, `GetOriginalSensorBySensorId`).
- `SensorModelCollection.SensorModelList` (static): For sensor model lookup.
- `DbOperations`: For DAS (`DASGet`), channel defaults (`GetChannelSettingDefaults`).
- `ContainerLocator.Container`: For resolving `IUnityContainer``IGroupListViewModel`.
- `FileUtils.GetExportWriter`: For XML writer creation.
- `APILogger`: For exception logging.
#### **Depended Upon By**
- UI layers (e.g., export dialogs) that use `ExportHeader` for section selection.
- Export workflows (e.g., full export, TTS import, field sync) that call `PrepareForExport` or `PrepareForExportFields` before `ExportToFile`/`ExportToFileFields`.
---
### **Gotchas**
1. **`savingTTSImport` Behavior**:
- When `savingTTSImport` is `true`, *all* sensors (including unused ones) are added to `includedSensors`/`includedCalibration`/`includedSensorModels`. This may significantly increase export size and processing time.
2. **Static Group Resolution Failure**:
- If a static group referenced by `embeddedGroup.StaticGroupId` no longer exists in the database, `GetNonEmbeddedGroup` returns `null`, and `embeddedGroup.StaticGroupId` is set to `null`. This silently discards the groups channels/hardware. Pre-existing database records may be affected.
3. **Thread-Safe Dispatcher Usage**:
- `GetNonEmbeddedGroup` uses `ManualResetEvent.WaitOne()` to block on non-UI threads. This can cause deadlocks if the UI thread is blocked or the dispatcher is unavailable.
4. **Hardware Serial Number Fallback**:
- `GetHardwareSerialNumber` returns `string.Empty` if `hardwareId` is not found. This may cause `GetDAS` to return `null`, skipping hardware inclusion (no error raised).
5. **`bUseFirstUseDate` Parameter**:
- Passed to `SensorData.WriteXML`. Its effect is not documented in the source—behavior depends on `SensorData.WriteXML` implementation.
6. **`TopLevelFields` Enum Gaps**:
- Many `TopLevelFields` enum values (e.g., `CustomChannels`, `CustomDirections`) are skipped in both export methods. This is intentional but may confuse readers expecting completeness.
7. **No Validation of Input Dictionaries**:
- The methods assume input dictionaries are properly initialized (not `null`). Passing `null` will cause `NullReferenceException`.
8. **`ExportHeader` Not Used in Export Logic**:
- Despite being in the same namespace (`Export`), `ExportHeader` is *not* used by `ExportTestSetup`. It is likely used in UI layers for export section selection, but this is not evident from the source.
9. **`ExportToFileFields` Does Not Write to File**:
- Unlike `ExportToFile`, `ExportToFileFields` returns the XML string but does *not* write to `exportFile` (parameter is unused). This is inconsistent and may cause confusion.
10. **Hardcoded XML Version**:
- `FileUtils.CurrentXmlVersion` and assembly version (`.ToString(4)`) are hardcoded in writer initialization. Changes to versioning may break compatibility.
11. **Calibration Null Handling**:
- In `PrepareForExport`, if `SensorCalibration.GetCalibrationsBySerialNumber(sd)` returns `null`, the sensor is skipped. In `savingTTSImport` mode, a `Trace.WriteLine` logs `"calibration record is null"` but processing continues.

View File

@@ -0,0 +1,284 @@
---
source_files:
- Common/DTS.Common.DataModel/Classes/Hardware/DASSettings.cs
- Common/DTS.Common.DataModel/Classes/Hardware/DASHardwareList.cs
- Common/DTS.Common.DataModel/Classes/Hardware/BatteryAndInputVoltageDefaults.cs
generated_at: "2026-04-16T03:33:19.361594+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "ea5a7a11d2e6d80b"
---
# Documentation: DAS Hardware and Configuration Data Models
## 1. Purpose
This module provides core data models and utility classes for managing Data Acquisition System (DAS) hardware configuration and settings within the DataPROWin7 system. It defines structured representations of DAS hardware components (`DASHardware`, referenced indirectly), their specific settings (`DASSettings`), and battery/input voltage thresholds (`DasBatteryInputSettings`), enabling serialization to/from the database (`tblTestSetupDASSettings`), caching for performance optimization during bulk operations, and type-specific default configuration retrieval. The module serves as the data layer abstraction for DAS hardware state and configuration across test setup, validation, and execution workflows.
## 2. Public Interface
### `DASSettings` (in `DataPROWin7.DataModel` namespace)
- **`DASSettings()`**
Default constructor. Initializes an empty instance.
- **`DASSettings(DASSettings setting)`**
Copy constructor. Copies all property values from the provided `setting` instance.
- **`string DASSerialNumber { get; set; }`**
Serial number of the DAS device. Serialized to `tblTestSetupDASSettings`.
- **`double SampleRate { get; set; }`**
Sample rate in Hz. Serialized to `tblTestSetupDASSettings`.
- **`int ExcitationWarmupTimeMS { get; set; }`**
Excitation warm-up time in milliseconds. Serialized to `tblTestSetupDASSettings`.
- **`double HardwareAAF { get; set; }`**
Hardware Anti-Aliasing Filter (AAF) setting. Serialized to `tblTestSetupDASSettings`.
- **`double PreTriggerSeconds { get; set; }`**
Duration of pre-trigger buffer in seconds. Serialized to `tblTestSetupDASSettings`.
- **`double PostTriggerSeconds { get; set; }`**
Duration of post-trigger buffer in seconds. Serialized to `tblTestSetupDASSettings`.
- **`bool StatusLineCheck { get; set; }`**
Flag indicating whether status line monitoring is enabled. Serialized to `tblTestSetupDASSettings`.
- **`bool BatteryCheck { get; set; }`**
Flag indicating whether battery voltage checks are enabled. Serialized to `tblTestSetupDASSettings`.
- **`double InputVoltageMin { get; set; }`**
Minimum acceptable input voltage threshold. Serialized to `tblTestSetupDASSettings`.
- **`double InputVoltageMax { get; set; }`**
Maximum acceptable input voltage threshold. Serialized to `tblTestSetupDASSettings`.
- **`double BatteryVoltageMin { get; set; }`**
Minimum acceptable battery voltage threshold. Serialized to `tblTestSetupDASSettings`.
- **`double BatteryVoltageMax { get; set; }`**
Maximum acceptable battery voltage threshold. Serialized to `tblTestSetupDASSettings`.
> **Note**: All properties use `SetProperty` (inherited from `BasePropertyChanged`) for change notification.
---
### `DASHardwareList` (in `DataPROWin7.DataModel.Classes.Hardware` namespace)
- **`static bool Cache { get; set; }`**
Enables/disables database caching. When `true`, hardware lookups use in-memory cache instead of querying the database. Setting to `false` clears `_cachedDASHardware`.
- **`static DASHardwareList GetList()`**
Returns the singleton instance of `DASHardwareList`. Does *not* auto-populate hardware (commented-out `PopulateHardware()` call).
- **`void ReloadAll()`**
Placeholder method (implementation commented out). Intended to reload hardware list.
- **`void SetCache(ICachedContainer container)`**
Sets the `_cachedHardware` field for use in `GetHardware(string, bool, out bool, bool)`.
- **`void ClearCache()`**
Clears `_cachedHardware`.
- **`string GetDASSerialNumberFromId(int id)`**
Retrieves the serial number for a given DAS ID by querying `DbOperations.DASGet`. Returns empty string if not found.
- **`DASHardware GetHardware(int id)`**
Retrieves `DASHardware` by ID using `GetDASSerialNumberFromId(id)``GetHardware(string)`.
- **`DASHardware GetHardware(string id, bool bUseCache = true)`**
Retrieves `DASHardware` by serial number (or key like `"SN_type"`), optionally using cache.
- **`DASHardware[] GetHardware(string[] ids, bool bUseCache = true)`**
Batch retrieval of `DASHardware` instances.
- **`DASHardware GetHardware(string id, bool bThrowExceptionIfChanged, out bool changed, bool bUseCache = true)`**
Core retrieval logic. Checks `_cachedHardware` and `_cachedDASHardware` if caching is enabled. Falls back to `DTS.Common.ISO.Hardware.GetAllDAS(id, null)`. Sets `changed = false` unconditionally.
- **`class HardwareTypeChangedException : Exception`**
Exception type declared but never thrown in source.
- **`DASHardware GetHardware(string serialNumber, string ipaddress)`**
Ignores `ipaddress` and delegates to `GetHardware(serialNumber)`.
- **`void UpdateMaxMemory(DASHardware h, long newMaxMemory)`**
Updates `MaxMemory` on the underlying `DTS.Common.ISO.Hardware` object and calls `Update()`.
- **`DASHardware GetPrototypeHardware(string serial, int type)`**
Retrieves prototype hardware using key `"{serial}_{type}"` and `DbOperations.DAS.PROTOTYPE_POSITION`. Sets `CalDate = DateTime.MinValue`.
- **`static DASHardware[] GetAllHardware()`**
Retrieves all DAS hardware via `DTS.Common.ISO.Hardware.GetAllDAS()`. Caches result if `Cache == true`.
- **`static List<int> GetEmbeddedModules(IDASHardware[] hardware, int id)`**
Returns list of `DASId`s of modules whose `Connection` starts with the serial number of the hardware identified by `id`.
- **`static Dictionary<string, double> GetEmbeddedModuleInfo(DASHardware[] hardware, int id)`**
Returns dictionary mapping serial numbers of embedded modules to their `GetMaxSampleRateDouble()` values.
- **`enum Tags { Hardware }`**
Tag used in `OnPropertyChanged` calls.
- **`void Commit(DASHardware hardware, bool bExisting = false, bool bCheckExisting = true, bool Unassociate = true)`**
Persists `DASHardware` state to database via `DTS.Common.ISO.Hardware`.
- If `Unassociate == true` and `IsPseudoRack()`, calls `UnassociateParentDAS`.
- If `bCheckExisting == true`, sets `bExisting` based on `DASHardware.GetDataBaseID`.
- Inserts if `!bExisting`, otherwise updates with incremented `Version`.
- Raises `OnPropertyChanged(Tags.Hardware.ToString())`.
- **`void Delete(IHardware hardware)`**
Deletes via `IISOHardware.Delete()` if supported.
- **`void Delete(DASHardware hardware)`**
Deletes underlying `ISO.Hardware`, and if `IsPseudoRack()`, calls `UnassociateParentDAS`.
- **`void Delete(IHardware[] hardware)` / `void Delete(DASHardware[] hardware)`**
Batch deletion helpers.
- **`static void UnassociateParentDAS(string distributorSerialNumber)`**
Executes stored procedure `sp_DASChildrenUnAssociate` to remove child associations for the given distributor.
---
### `DasBatteryInputSettings` (in `DataPROWin7.DataModel.BatteryAndInputVoltageDefaults` namespace)
- **`enum Settings`**
Ordered list of 14 battery/input voltage thresholds. **Order matters for serialization**:
- `BatteryLowDiagnosticsThreshold`
- `BatteryHighDiagnosticsThreshold`
- `BatteryLowArmedThreshold`
- `BatteryHighArmedThreshold`
- `InputLowDiagnosticsThreshold`
- `InputHighDiagnosticsThreshold`
- `InputLowArmedThreshold`
- `InputHighArmedThreshold`
- `MinimumValidBatteryThreshold`
- `MinimumValidInputThreshold`
- `MaximumValidBatteryThreshold`
- `MaximumValidInputThreshold`
- `BatteryMediumDiagnosticsThreshold`
- `BatteryMediumArmedThreshold`
- `InputMediumDiagnosticsThreshold`
- `InputMediumArmedThreshold`
- **Properties (14 total)**
Each has a `get`/`set` that wraps `GetValue(Settings)` / `SetValue(Settings, double)`.
- **`Dictionary<Settings, double> SettingsProperty { get; }`**
Internal storage for settings.
- **`DasBatteryInputSettings(string s)`**
Parses comma-separated string into settings (assumes order matches `Settings` enum). Uses `double.TryParse(..., CultureInfo.InvariantCulture)`.
- **`DasBatteryInputSettings(DasBatteryInputSettings copy)`**
Copy constructor.
- **`DasBatteryInputSettings()`**
Initializes with hardcoded defaults (e.g., `BatteryLowArmedThreshold = 6.8`, `InputHighArmedThreshold = 15.3`, etc.). Throws `NotSupportedException` for unknown settings.
- **`string ToSerializedString()`**
Serializes settings in `Settings` enum order to comma-separated string.
- **`double GetValue(Settings setting)`**
Returns value for `setting`. Throws `NotSupportedException` if missing.
- **`void SetValue(Settings setting, double d)`**
Sets value for `setting`.
---
### `InputAndBatterySettings` (static class, same namespace)
- **`static Dictionary<HardwareTypes, DasBatteryInputSettings> _cache`**
Cache of settings per hardware type.
- **`static void ClearCache()`**
Clears `_cache`.
- **`static double GetValue(string DasType, DasBatteryInputSettings.Settings setting)`**
Parses `DasType` to `HardwareTypes`, then calls `GetValue(HardwareTypes, Settings)`. Returns `double.NaN` on parse failure.
- **`static DasBatteryInputSettings GetDefaultSettingForHWType(HardwareTypes type)`**
Returns *default* settings for `type` from `Common.SerializedSettings.*_PowerSetting_Default` fields. Caches if `RunTestVariables.InRunTest && CacheVoltageSettingsInRunTest`. Throws `NotSupportedException` if type unsupported.
- **`static void SetSettingForHWType(HardwareTypes type, DasBatteryInputSettings setting)`**
Assigns `setting` to corresponding `Common.SerializedSettings.*_PowerSetting` field.
- **`static DasBatteryInputSettings GetSettingForHWType(HardwareTypes type)`**
Returns *current* (possibly overridden) settings for `type` from `Common.SerializedSettings.*_PowerSetting` fields. Caches if applicable. Throws `NotSupportedException` if type unsupported.
- **`static double GetValue(HardwareTypes type, DasBatteryInputSettings.Settings setting)`**
Returns `GetSettingForHWType(type).GetValue(setting)`.
## 3. Invariants
- **`DASSettings`**
- All properties are nullable (no validation constraints enforced in class).
- Serialization format is fixed: properties map directly to columns in `tblTestSetupDASSettings`.
- Property names match exactly those used in `SetProperty` calls (case-sensitive).
- **`DASHardwareList`**
- `Cache` flag controls whether `_cachedDASHardware` is populated/used. Setting `Cache = false` clears `_cachedDASHardware`.
- `GetHardware(string, bool, out bool, bool)` *always* sets `changed = false`; the `bThrowExceptionIfChanged` parameter is unused.
- `Commit` assumes `DASHardware` wraps a valid `DTS.Common.ISO.Hardware` instance.
- `UnassociateParentDAS` is called only for pseudo-rack hardware during `Commit` or `Delete`.
- **`DasBatteryInputSettings`**
- `Settings` enum order *must not change* without updating serialization logic (`ToSerializedString`, constructor from string).
- Default constructor initializes all 14 settings; missing cases throw `NotSupportedException`.
- `GetValue`/`SetValue` assume key exists; missing keys throw `NotSupportedException`.
## 4. Dependencies
### Imports/References (from source):
- `DTS.Common.Base` → Provides `BasePropertyChanged`.
- `DTS.Common.ISO.Hardware` → Core hardware data model (`GetAllDAS`, `Hardware`, `HardwareChannel`).
- `DTS.Common.Storage``DbOperations`, `DbOperationsEnum.StoredProcedure`.
- `DTS.Common.Interface.DASFactory.Diagnostics`, `DTS.Common.Interface.DataRecorders`, `DTS.Common.Interface.DASFactory.Diagnostics.HardwareList` → Interfaces for hardware diagnostics and storage.
- `System`, `System.Linq`, `System.Collections.Generic`, `System.Windows`, `System.Configuration` → Standard libraries.
- `DataPROWin7.DataModel.Classes.TestTemplate` → Test template classes.
- `DTS.Common.Enums`, `DTS.Common.Enums.Hardware``HardwareTypes` enum.
- `Common.SerializedSettings` → Static class holding default/overridden settings per hardware type.
- `RunTestVariables` → Controls caching behavior during run tests.
### Inferred Usage:
- `DASSettings` is serialized to `tblTestSetupDASSettings` (database table).
- `DASHardwareList` interacts with `DASHardware` (not shown here but referenced).
- `InputAndBatterySettings` relies on `Common.SerializedSettings` and `RunTestVariables` for runtime configuration.
## 5. Gotchas
- **`DASHardwareList.GetHardware(...)` always sets `changed = false`**
Despite having an `out bool changed` parameter and a `HardwareTypeChangedException` type, the implementation never detects changes or throws the exception.
- **`DASHardwareList.GetHardware(string id, bool bThrowExceptionIfChanged, out bool changed, bool bUseCache)` ignores `bThrowExceptionIfChanged`**
The parameter is unused in the method body.
- **`DASHardwareList.GetHardware(string serialNumber, string ipaddress)` discards `ipaddress`**
Only uses `serialNumber`.
- **`DASHardwareList.Commit` assumes `hardware.GetHardware()` is non-null**
No null-check before accessing `hardware.GetHardware()` properties.
- **`DASHardwareList.UnassociateParentDAS` is called only for pseudo-rack hardware**
Logic depends on `IsPseudoRack()` (not defined here), but no validation ensures this condition is checked correctly.
- **`DasBatteryInputSettings` serialization order is fragile**
Constructor from string assumes exact enum order; reordering `Settings` will break deserialization.
- **`InputAndBatterySettings._cache` is shared globally**
`ClearCache()` affects all callers; caching behavior depends on `RunTestVariables` flags.
- **`DASSettings` copy constructor copies private fields directly**
No deep-copy or validation; mutable reference types (if added later) could cause side effects.
- **`DASHardwareList.GetAllHardware()` may return stale data if `Cache = true`**
Once cached, `_cachedDASHardware` persists until `Cache` is set to `false`.
- **No validation of numeric ranges**
Properties like `SampleRate`, `PreTriggerSeconds`, or voltage thresholds accept any `double`/`int` without bounds checking.
- **`GetEmbeddedModules`/`GetEmbeddedModuleInfo` use `hardware.First(...).SerialNumber` without null-check**
If no hardware matches `DASId == id`, `First()` throws `InvalidOperationException`.

View File

@@ -0,0 +1,117 @@
---
source_files:
- Common/DTS.Common.DataModel/Classes/TSRAIRGo/TSRAIRGoStatus.cs
generated_at: "2026-04-16T03:32:34.714926+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "7a39c7d31659462f"
---
# TSRAIRGo
## Documentation Page: `TSRAIRGoStatus` Class
---
### 1. **Purpose**
The `TSRAIRGoStatus` class defines a comprehensive enumeration of status states for the TSRAIRGo hardware discovery, configuration, arming, and streaming lifecycle within the DTS data model. It serves as a canonical source of status type identifiers used across the system to represent the current state of a TSRAIRGo device or subsystem (e.g., during auto-detection, connection, hardware validation, arming, recording, streaming, and download operations). The enum values are annotated with `Description` attributes referencing localized string keys, indicating this status is intended for UI display and logging purposes.
---
### 2. **Public Interface**
#### `enum TSRAIRGoStatus.StatusTypes`
A public nested enum defined inside `TSRAIRGoStatus`, decorated with `[TypeConverter(typeof(EnumDescriptionTypeConverterShared))]`. Each member represents a discrete status state.
| Member | Description Key (from `[Description]`) | Brief Behavior |
|--------|----------------------------------------|----------------|
| `UNKNOWN` | `"Table_NA"` | Initial or indeterminate state. |
| `PING_FAILED` | `"HardwareDiscoveryControl_PingFailed"` | Ping attempt to device failed. |
| `PINGING` | `"AutoDetectDASControl_Pinging"` | Actively pinging device. |
| `PING_SUCCESS` | `"AutoDetectDASControl_Ping_Good"` | Ping succeeded; device reachable. |
| `CONNECT_FAILED` | `"HardwareDiscoveryControl_FailedToConnect"` | Connection attempt failed. |
| `CONNECTING` | `"AutoDetectDASControl_Connecting"` | Establishing connection. |
| `QUERY_FAILED` | `"AutoDetectDASControl_QueryFailed"` | Query to device failed. |
| `QUERY_TIMEDOUT` | `"HardwareDiscoveryControl_QueryTimedOut"` | Query timed out. |
| `DONE` | `"AutoDetectDASControl_Done"` | Auto-detection complete. |
| `QUERYING` | `"AutoDetectDASControl_Querying"` | Querying device for information. |
| `UPDATED` | `"AutoDetectDASControl_Updated"` | Device information updated. |
| `ADDED` | `"AutoDetectDASControl_Added"` | Device added to system. |
| `ONLINE` | `"HardwareDiscoveryControl_Online"` | Device is online. |
| `CONNECTED` | `"HardwareDiscoveryControl_Connected"` | Device is connected. |
| `UNEXPECTED_MAX_MEMORY` | `"CheckHardware_UnexpectedMaxMemory"` | Hardware memory exceeds expected value. |
| `UNEXPECTED_FIRMWARE_VERSION` | `"CheckHardware_FirmwareMismatch"` | Firmware version mismatch detected. |
| `PASSED` | `"CheckHardwareStatus_Passed"` | Hardware check passed. |
| `EXPIRED_CAL_DATE` | `"CheckHardware_CalDateOverdue"` | Calibration date is overdue. |
| `CHANNEL_COUNT_MISMATCH` | `"CheckHardware_ChannelCountMismatch"` | Channel count mismatch. |
| `MISSING_MODULES` | `"Table_NA"` | Required hardware modules missing. |
| `CANCELED` | *(none)* | Operation canceled by user/system. |
| `NO_MEMORY` | `"CheckHardware_NoMemory"` | Insufficient memory available. |
| `ARMED` | `"ArmSystem_Armed"` | System armed and ready. |
| `AUTOARMED` | `"AutoArmed"` | System auto-armed. |
| `REALTIME` | `"Admin_SystemSettings_Page_Realtime"` | System in real-time mode. |
| `READYTOSTREAM` | `"ReadyToStream"` | System ready to begin streaming. |
| `STREAMING` | `"ArmSystem_CurrentlyStreaming"` | Data streaming is active. |
| `LOST_DOCK` | `"LostDock"` | Dock connection lost. |
| `REBOOTING` | `"Status_Rebooting"` | Device is rebooting. |
| `SETTING_CLOCK` | `"CheckHardwareStatus_SettingClockSources"` | Clock sources are being configured. |
| `UNEXPECTED_FIRSTUSE_DATE` | `"CheckHardware_UnexpectedFirstUseDate"` | First-use date unexpected (e.g., in future/past). |
| `INVALID_RECORDING_MODE` | `"InvalidRecordingMode"` | Recording mode configuration invalid. |
| `INVALID_STREAMING_MODE` | `"InvalidStreamMode"` | Streaming mode configuration invalid. |
| `STREAMING_NOT_AVAILABLE` | `"StreamingNotAvailable"` | Streaming functionality unavailable. |
| `ARMING` | *(none)* | Arming process in progress. |
| `DISARMING` | *(none)* | Disarming process in progress. |
| `DISARMED` | `"ArmSystem_Disarmed"` | System disarmed. |
| `ARM_FAILED` | `"ArmSystem_ArmFailed"` | Arming operation failed. |
| `UPDATING_DAS_CONFIG` | `"ArmSystem_SettingConfiguration"` | DAS configuration is being applied. |
| `PREPARING_DATA_MEMORY` | `"ArmSystem_ClearingFlash"` | Data memory (e.g., flash) is being cleared. |
| `REARMING` | `"ArmSystem_Rearming"` | Re-arming process in progress. |
| `PREPARING_FOR_ARMING` | `"ArmSystem_PreparingForArming"` | Preparing for arming (e.g., final checks). |
| `WAITING_FOR_INTERVAL` | `"ArmSystem_WaitingForInterval"` | Waiting for scheduled interval to start. |
| `WAITING_FOR_TRIGGER` | `"ArmSystem_WaitingForTrigger"` | Waiting for external trigger. |
| `WAITING_FOR_SCHEDULE` | `"ArmSystem_WaitingForScheduleStartTime"` | Waiting for scheduled start time. |
| `RECORDING` | `"ArmSystem_Recording"` | Data recording is active. |
| `OFFLINE` | `"Offline"` | Device is offline. |
| `DOWNLOADING` | `"Downloading"` | Data download in progress. |
| `GETTINGEVENTDATA` | `"Download_StatusTypes_GettingEventData"` | Downloading event metadata. |
> **Note**: Enum members without a `[Description]` attribute (`CANCELED`, `ARMING`, `DISARMING`, `DISARMED`, `ARM_FAILED`, `RECORDING`, `OFFLINE`, `DOWNLOADING`, `GETTINGEVENTDATA`) are assumed to use their literal name or a fallback display mechanism.
---
### 3. **Invariants**
- **All enum values are mutually exclusive**: At any given time, a device or subsystem should be in exactly one `StatusTypes` state.
- **State transitions are sequential and context-dependent**: While not enforced by this class, the enum is designed to reflect logical progression (e.g., `PINGING``PING_SUCCESS``CONNECTING``CONNECTED``QUERYING``DONE`).
- **`[Description]` attributes map to localized string resources**: Keys (e.g., `"AutoDetectDASControl_Pinging"`) are resource identifiers, not literal display strings. The actual UI text is resolved at runtime via `EnumDescriptionTypeConverterShared`.
- **No validation or state machine logic resides in this class**: This is a *data model* enum only; state transitions and validity are handled elsewhere.
---
### 4. **Dependencies**
- **Imports**:
- `DTS.Common.Converters.EnumDescriptionTypeConverterShared` — Used for UI localization of enum values.
- `DTS.Common.SharedResource.Strings` — Source of localized string resources (keys referenced in `[Description]`).
- `System.ComponentModel` — Provides `DescriptionAttribute` and `TypeConverterAttribute`.
- **Consumers (inferred)**:
- UI layers (WPF/XAML) using `EnumDescriptionTypeConverterShared` for binding.
- Hardware discovery, arming, and streaming services that set/report status.
- Logging and diagnostics modules that consume status for audit trails.
- Serialization/deserialization logic (e.g., JSON, XML) likely uses the enums underlying integer or string representation.
---
### 5. **Gotchas**
- **Mixed localization key patterns**: Some descriptions use `"Table_NA"` (generic placeholder), while others reference specific control names (e.g., `"AutoDetectDASControl_Pinging"`). This suggests inconsistent naming conventions or legacy resource keys.
- **Missing `[Description]` attributes**: Several enum values (`CANCELED`, `ARMING`, `DISARMING`, `DISARMED`, `ARM_FAILED`, `RECORDING`, `OFFLINE`, `DOWNLOADING`, `GETTINGEVENTDATA`) lack `[Description]`. These may fall back to the enum name or cause runtime issues if `EnumDescriptionTypeConverterShared` is strictly enforced.
- **Ambiguous semantics**: Some states (e.g., `ONLINE`, `CONNECTED`, `READYTOSTREAM`, `ARMED`) overlap in meaning and may require context (e.g., device type, mode) to disambiguate.
- **No explicit ordering or hierarchy**: The enum is unordered; developers must not assume `PASSED < FAILED` or similar ordering semantics.
- **Historical artifacts**: Values like `AUTOARMED` and `REALTIME` suggest legacy or specialized modes that may be deprecated or rarely used.
> **None identified from source alone.**
> *(Note: While above points are inferred from the source, they are not explicit bugs—just observations.)*

View File

@@ -0,0 +1,246 @@
---
source_files:
- Common/DTS.Common.DataModel/Classes/TestMetaData/CustomerDetails.cs
- Common/DTS.Common.DataModel/Classes/TestMetaData/LabratoryDetails.cs
- Common/DTS.Common.DataModel/Classes/TestMetaData/TestEngineerDetails.cs
generated_at: "2026-04-16T03:33:20.750893+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "9acc3ac2395ce04b"
---
# TestMetaData
## Documentation: Test Metadata Domain Models
---
### 1. Purpose
This module provides domain models for managing test-related metadata entities—specifically `CustomerDetails`, `LabratoryDetails`, and `TestEngineerDetails`—within the DataPROWin7 system. Each class wraps a corresponding low-level ISO-compliant data object (`DTS.Common.ISO.*`) and exposes a property-change-aware interface for UI binding and data entry. The module also provides static/list management classes (`*DetailsList`) for CRUD operations (create, read, delete, list) against persisted metadata, with special handling for caching in run-test scenarios (only for `TestEngineerDetails`). Its role is to abstract persistence and change tracking while enabling data binding in WPF UIs.
---
### 2. Public Interface
#### `CustomerDetails` (inherits `BasePropertyChanged`)
- **`bool IsBlank()`**
Returns `true` if no property has been set since construction (initial state only).
- **`string Name { get; set; }`**
Gets/sets the display name of the customer. Setting triggers `_blank = false` and `OnPropertyChanged("Name")`.
- **`string CustomerName { get; set; }`**
Gets/sets the full customer name.
- **`string CustomerTestRefNumber { get; set; }`**
Gets/sets the customers test reference number.
- **`string ProjectRefNumber { get; set; }`**
Gets/sets the associated project reference number.
- **`string CustomerOrderNumber { get; set; }`**
Gets/sets the customer order number.
- **`string CustomerCostUnit { get; set; }`**
Gets/sets the cost center or unit.
- **`bool LocalOnly { get; }`**
Gets the `LocalOnly` flag from the underlying ISO object.
- **`DateTime LastModified { get; }`**
Gets the last modification timestamp.
- **`string LastModifiedBy { get; }`**
Gets the user who last modified the record.
- **`int Version { get; }`**
Gets the version number of the record.
- **`bool HasBlankName()`**
Returns `true` if `Name` equals `StringResources.TestTemplate_EmptyListName`.
- **`CustomerDetails()`**
Default constructor: initializes `_customerDetails` with a new `DTS.Common.ISO.CustomerDetails`, sets `Name` to `TestTemplate_EmptyListName`, and `_blank = true`.
- **`CustomerDetails(DTS.Common.ISO.CustomerDetails customerDetails)`**
Wraps an existing ISO object; sets `_blank = false`.
- **`DTS.Common.ISO.CustomerDetails GetISOCustomer()`**
Returns the underlying ISO object.
- **`override string ToString()`**
Returns `Name`.
#### `CustomerDetailsList`
- **`static void Delete(CustomerDetails customer)`**
Calls `customer.GetISOCustomer().Delete(currentUser)`.
- **`static void Delete(CustomerDetails[] customers)`**
Deletes each customer in the array.
- **`static CustomerDetails[] GetAllCustomers()`**
Fetches all ISO customers via `DTS.Common.ISO.CustomerDetails.GetAllCustomerDetails()`, wraps each in `CustomerDetails`, sorts by `Name` (ordinal), and returns as array.
- **`static void DeleteAll()`**
Calls `DTS.Common.ISO.CustomerDetails.DeleteCustomerDetails()`.
- **`static CustomerDetails GetCustomerDetail(string name)`**
Returns a wrapped `CustomerDetails` for the given `name`, or `null` if not found or `name` is null/empty.
#### `LabratoryDetails` (inherits `BasePropertyChanged`)
- **`bool IsBlank()`**
Returns `_isBlank`, initialized `true`, set to `false` on first property mutation.
- **`string Name { get; set; }`**
Display name; triggers `_isBlank = false` and `OnPropertyChanged("Name")`.
- **`string LabratoryName { get; set; }`**
Laboratory name.
- **`string LabratoryContactName { get; set; }`**
Contact person name.
- **`string LabratoryContactPhone { get; set; }`**
Contact phone number.
- **`string LabratoryContactFax { get; set; }`**
Contact fax number.
- **`string LabratoryContactEmail { get; set; }`**
Contact email address.
- **`string LabratoryTestRefNumber { get; set; }`**
Laboratory test reference number.
- **`string LabratoryProjectRefNumber { get; set; }`**
Laboratory project reference number.
- **`bool LocalOnly { get; }`**
Gets `LocalOnly` from underlying ISO object.
- **`DateTime LastModified { get; }`**
Gets last modification timestamp.
- **`string LastModifiedBy { get; }`**
Gets last modifier username.
- **`int Version { get; }`**
Gets record version.
- **`bool HasBlankName()`**
Returns `true` if `Name == StringResources.TestTemplate_EmptyListName`.
- **`LabratoryDetails()`**
Default constructor: initializes `_lab` with new `DTS.Common.ISO.LabratoryDetails`, sets `Name` to `TestTemplate_EmptyListName`, `_isBlank = true`.
- **`LabratoryDetails(DTS.Common.ISO.LabratoryDetails lab)`**
Wraps an existing ISO object; sets `_isBlank = false`.
- **`DTS.Common.ISO.LabratoryDetails GetIsoLab()`**
Returns the underlying ISO object.
- **`override string ToString()`**
Returns `Name`.
#### `LabratoryDetailsList`
- **`static LabratoryDetails[] GetAllLabs()`**
Fetches all ISO labs via `DTS.Common.ISO.LabratoryDetails.GetAllLabratoryDetails()`, wraps each, sorts by `Name`, returns array.
- **`static void DeleteAll()`**
Calls `DTS.Common.ISO.LabratoryDetails.DeleteLabratoryDetails()`.
- **`static void Delete(LabratoryDetails lab)`**
Calls `lab?.GetIsoLab().Delete(currentUser)`.
- **`static void Delete(LabratoryDetails[] labs)`**
Deletes each lab in the array.
- **`static LabratoryDetails GetLab(string name)`**
Returns a wrapped `LabratoryDetails` for the given `name`, or `null` if not found or `name` is null/empty.
#### `TestEngineerDetails` (inherits `BasePropertyChanged`)
- **`bool IsBlank()`**
Returns `_blank`, initialized `true`, set to `false` on first mutation.
- **`string Name { get; set; }`**
Display name; triggers `_blank = false` and `OnPropertyChanged("Name")`.
- **`string TestEngineerName { get; set; }`**
Full test engineer name.
- **`string TestEngineerPhone { get; set; }`**
Phone number.
- **`string TestEngineerFax { get; set; }`**
Fax number.
- **`string TestEngineerEmail { get; set; }`**
Email address.
- **`bool LocalOnly { get; }`**
Gets `LocalOnly` from underlying ISO object.
- **`DateTime LastModified { get; }`**
Gets last modification timestamp.
- **`string LastModifiedBy { get; }`**
Gets last modifier username.
- **`int Version { get; }`**
Gets record version.
- **`bool HasBlankName()`**
Returns `true` if `Name == StringResources.TestTemplate_EmptyListName`.
- **`TestEngineerDetails()`**
Default constructor: initializes `_testEngineerDetails` with new `DTS.Common.ISO.TestEngineerDetails`, sets `Name` to `TestTemplate_EmptyListName`, `_blank = true`.
- **`TestEngineerDetails(DTS.Common.ISO.TestEngineerDetails testEngineerDetails)`**
Wraps an existing ISO object; sets `_blank = false`.
- **`DTS.Common.ISO.TestEngineerDetails GetISOTestEngineer()`**
Returns the underlying ISO object.
- **`override string ToString()`**
Returns `Name`.
#### `TestEngineerDetailsList` (inherits `BasePropertyChanged`)
- **`static TestEngineerDetailsList TestEngineerList { get; }`**
Singleton instance of `TestEngineerDetailsList`.
- **`void Delete(TestEngineerDetails testEngineer)`**
Deletes from ISO store, removes from internal `_testEngineers` dictionary, and raises `OnPropertyChanged("TestEngineers")`.
- **`void Delete(TestEngineerDetails[] testEngineers)`**
Deletes each engineer in the array.
- **`TestEngineerDetails[] TestEngineers { get; }`**
Returns all engineers sorted by `Name`. Lazily populates from `GetAllTestEngineers()` if `_testEngineers` is null/empty (thread-safe via lock).
- **`void ReloadAll()`**
Clears `_testEngineers` and repopulates from `GetAllTestEngineers()`.
- **`void DeleteAll()`**
Clears `_testEngineers`, calls `DTS.Common.ISO.TestEngineerDetails.DeleteAllTestEngineerDetails()`.
- **`TestEngineerDetails GetTestEngineerDetail(string name)`**
Returns engineer by `Name` from in-memory cache (`TestEngineers`), or `null` if not found or `name` is null/whitespace.
- **`void AddTestEngineer(TestEngineerDetails testEngineer)`**
Commits to ISO store, adds/updates in `_testEngineers` dictionary, and raises `OnPropertyChanged("TestEngineers")`.
- **`static TestEngineerDetails[] GetAllTestEngineers()`**
Returns all engineers. **Special behavior**: if `RunTestVariables.InRunTest` is `true` and `TestTemplateList.TestTemplatesList.CachedTestEngineerDetails` is populated, returns cached data (converted to ISO objects and wrapped); otherwise fetches from `DTS.Common.ISO.TestEngineerDetails.GetAllTestEngineerDetails()`.
---
### 3. Invariants
- **`_blank` / `_isBlank` state**:
- For `CustomerDetails` and `TestEngineerDetails`, `_blank` starts `true` and is set to `false` on first property setter invocation.
- For `LabratoryDetails`, `_isBlank` behaves identically.
- `IsBlank()` returns this state, but it is *not* reset by any operation (e.g., `DeleteAll()` does not reset it).
- **`Name` field semantics**:
- Default constructor sets `Name` to `StringResources.TestTemplate_EmptyListName`.
- `HasBlankName()` checks for this exact string.
- `Name` is used as the primary key for lookup (`GetCustomerDetail`, `GetLab`, `GetTestEngineerDetail`, `CompareCustomers`, etc.).
- **Sorting**:
- `GetAllCustomers()`, `GetAllLabs()`, and `TestEngineers` getter sort by `Name` using `string.Compare(..., StringComparison.Ordinal)`.
- **Persistence layer**:
- All mutations (`set` on properties, `Add*`, `Delete*`) ultimately call methods on `DTS.Common.ISO.*` types (e.g., `Commit`, `Delete`).
- `Commit` and `Delete` are called with `ApplicationProperties.CurrentUser.UserName`.
- **Caching for run-test mode**:
- `TestEngineerDetailsList.GetAllTestEngineers()` uses cached data *only* when `RunTestVariables.InRunTest` is `true` *and* `CachedTestEngineerDetails` is non-null/non-empty.
- This cache is *not* used by `CustomerDetailsList` or `LabratoryDetailsList`.
---
### 4. Dependencies
#### Internal Dependencies (from source)
- **`DTS.Common.ISO.*`**
Core data models: `CustomerDetails`, `LabratoryDetails`, `TestEngineerDetails` (ISO layer).
- **`DTS.Common.Base.BasePropertyChanged`**
Base class for `INotifyPropertyChanged` implementation.
- **`DTS.Common.SharedResource.Strings.StringResources`**
Used for `TestTemplate_EmptyListName`.
- **`DTS.Common.Storage.ApplicationProperties`**
Used to get `CurrentUser.UserName`.
- **`DTS.Common.Enums.RunTestVariables`**
Used in `TestEngineerDetailsList.GetAllTestEngineers()` to check `InRunTest`.
- **`DTS.Common.DataModel.TestTemplateList.TestTemplatesList`**
Used in `TestEngineerDetailsList.GetAllTestEngineers()` to access `CachedTestEngineerDetails`.
#### External Dependencies (inferred)
- **WPF (`System.Windows`)**
Used for `ApplicationProperties.CurrentUser` (likely tied to WPF app context).
- **.NET Core/Standard runtime**
Standard libraries (`System`, `System.Collections.Generic`, `System.Linq`).
#### What depends on this module?
- UI layers (WPF) binding to `CustomerDetails`, `LabratoryDetails`, `TestEngineerDetails` properties.
- Any code managing test metadata (e.g., test setup, reporting) via `*DetailsList` static methods.
- `TestTemplateList.TestTemplatesList` (indirectly via caching dependency).
---
### 5. Gotchas
- **Inconsistent naming**:
- Class is named `LabratoryDetails` (misspelled "Laboratory") in all files. This is preserved in ISO layer and must be used as-is.
- **`IsBlank()` behavior is one-way**:
- Once set to `false`, `_blank`/`_isBlank` is never reset (e.g., by `Delete`, `Clear`, or `ReloadAll`). A deleted record may still report `IsBlank() == false`.
- **`TestEngineerDetailsList` is a singleton with mutable state**:
- `_testEngineerList` is static; `TestEngineerList` returns the same instance.
- `TestEngineers` property caches data in `_testEngineers` dictionary, which is lazily populated and cleared only by `DeleteAll()` or `ReloadAll()`.
- Concurrent access is partially protected by `lock (_testEngineerLock)` in `TestEngineers` getter and `AddTestEngineer`, but `GetTestEngineerDetail` uses `AsParallel()` on `TestEngineers` without locking—potential race condition if `TestEngineers` is being repopulated.
- **`GetAllTestEngineers()` has conditional caching logic**:
- Behavior changes based on `RunTestVariables.InRunTest` and `CachedTestEngineerDetails`. This is not obvious from the class alone and may cause inconsistent data if caching is stale or misconfigured.
- **`CustomerDetailsList` and `LabratoryDetailsList` lack instance methods**:
- All operations are `static`. Only `TestEngineerDetailsList` provides instance methods (e.g., `AddTestEngineer`, `Delete(TestEngineerDetails)`), suggesting inconsistent design or incomplete refactoring.
- **No validation on property setters**:
- Setting `Name` to `null` or empty is allowed (though `HasBlankName()` checks only for `TestTemplate_EmptyListName`).
- `GetCustomerDetail`, `GetLab`, `GetTestEngineerDetail` return `null` for `null`/empty/whitespace input, but no validation prevents setting such values on `Name`.
- **`ToString()` returns `Name`**:
- If `Name` is `null`, this may cause `NullReferenceException` in UI bindings or `string.Format` calls.
None identified beyond the above for `CustomerDetails` and `LabratoryDetails`.

View File

@@ -0,0 +1,179 @@
---
source_files:
- Common/DTS.Common.DataModel/Classes/TestObject/TemplateChannelUI.cs
- Common/DTS.Common.DataModel/Classes/TestObject/TestObjectTemplateCollection.cs
- Common/DTS.Common.DataModel/Classes/TestObject/TestObjectList.cs
- Common/DTS.Common.DataModel/Classes/TestObject/TestTestObject.cs
- Common/DTS.Common.DataModel/Classes/TestObject/TestObjectTemplate.cs
generated_at: "2026-04-16T03:34:52.105415+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "600a818df3b392d9"
---
# Documentation: DataModel.TestObject Module
## 1. Purpose
This module provides data model abstractions for ISO 13499-compliant test objects, templates, and related UI wrappers within the DataPROWin7 application. It serves as the bridge between low-level ISO database entities (`DTS.Common.ISO.*`) and high-level WPF UI components, enabling template management, test object instantiation, and channel configuration. The module supports both system-built and user-defined templates, embedded vs. external template references, and test-specific overrides (e.g., excitation settings, position assignments). It is central to test setup definition, serialization, and runtime configuration.
## 2. Public Interface
### `TemplateChannelUI`
- **`TemplateChannelUI(DTS.Common.ISO.TestObjectTemplateChannel channel)`**
Constructor that wraps an ISO `TestObjectTemplateChannel` instance. Stores the channel in the `Channel` property.
- **`Channel` (property)**
Gets/sets the underlying `DTS.Common.ISO.TestObjectTemplateChannel`. Implements `INotifyPropertyChanged` via `BasePropertyChanged`.
### `TestObjectTemplateCollection`
- **`TemplateCollection` (static property)**
Singleton accessor. Returns the single instance of `TestObjectTemplateCollection`, lazily initialized.
- **`SysBuiltTestObjectTemplate` (property)**
Returns the read-only system-built template (note: `_sysBuiltTestObjectTemplate` is declared but *never initialized* in the source — likely incomplete).
- **`GetTemplate(string templateId)` (method)**
Retrieves a `TestObjectTemplate` by `templateId` from the ISO database (`ApplicationProperties.IsoDb`). Returns `null` if not found.
### `TestObjectList`
- **`TestObjectsList` (static property)**
Singleton accessor. Thread-safe (uses `lock(MyLock)`). Returns the single instance of `TestObjectList`.
- **`Add(TestObject to, bool bNotify)` (method)**
Adds a `TestObject` to the list. Sets `LastModifiedBy` and `LastModified` on the object, calls `Commit()`, and optionally raises `OnPropertyChanged("TestObjects")` if `bNotify` is `true`.
- **`UpdateAll()` (method)**
Raises `OnPropertyChanged("TestObjects")` to notify UI of changes (e.g., after bulk operations).
### `TestTestObject`
- **Constructors**
- `TestTestObject(TestObject obj)`
Base constructor wrapping a `TestObject`.
- `TestTestObject(TestTestObject obj, bool convertToEmbedded)`
Copy constructor with support for converting to embedded mode (generates new GUIDs for template and serial number).
- `TestTestObject(TestObject obj, bool convertToEmbedded)`
Constructor for non-`TestTestObject` inputs with embedded conversion support.
- `TestTestObject(TestTestObject to)`
Copy constructor for metadata (calls `MetaCommonConstructor`).
- **Properties**
- `Position` (`DTS.Common.ISO.MMEPositions`)
Gets/sets the group position. When set to `UserSetKey` (`"@"`), UI shows a button instead of a combo box. When set to a standard position, propagates the position to all required channels sensors.
- `TestObject` (`DTS.Common.ISO.MMETestObjects`)
Gets/sets the test object type. When set, propagates the test object to all required channels sensors.
- `GroupPositionComboBoxVisible`, `GroupPositionButtonVisible` (`Visibility`)
Controls UI visibility based on `Position` value. *Note: Non-ISO mode support is commented out.*
- `AvailableGroupPositions` (`MMEPositions[]`)
Returns an array containing `_channelDefaultsGUID` (`#`) and all positions from `ApplicationProperties.IsoDb.GetPositions()`.
- `AvailablePositions` (`MMEPositions[]`)
Returns positions from `ApplicationProperties.IsoDb.GetPositions()`.
- `ChannelTypes` (`string[]`)
Returns `["(no channels)"]` + unique channel types from `ApplicationProperties.IsoDb`.
- `AddedGroups` (`TestObject[]`)
Gets/sets a list of added system-built test objects; raises `OnPropertyChanged("AddedSysBuiltTestObjects")` and `OnPropertyChanged("AddedSysBuiltTestObjectsMME")`.
- `DisplayOrder`, `IsAdd`, `SysBuilt`, `SerialNumberConverted`
Metadata properties (no explicit backing fields beyond `DisplayOrder` and `IsAdd`).
- `ExcitationWarmupTimeMS`, `TargetSampleRate`, `PreTriggerSeconds`, `PostTriggerSeconds`
Test-specific configuration properties.
- **Methods**
- `Rename(string oldName, string newName)`
Updates `SerialNumber`, `OriginalSerialNumber`, `OriginalTemplate`, `TestSetupName`, and generates new GUIDs for `TemplateName` and `OriginalTemplateName`.
- `SetTestObject(string s)`, `SetPosition(string s)`
Low-level setters that bypass property change notifications for `Position`/`TestObject` UI visibility logic.
- `CompareTo(TestTestObject other)`
Compares by `DisplayOrder`, then falls back to base comparison.
### `TestObjectTemplate`
- **Constructors**
- `TestObjectTemplate()`
Default constructor; initializes with empty strings and first available test object.
- `TestObjectTemplate(TestObjectTemplate copy, ref ISO13499FileDb db)`
Deep copy constructor.
- `TestObjectTemplate(DTS.Common.ISO.TestObjectTemplate template, ref ISO13499FileDb db)`
Wraps an ISO template.
- `TestObjectTemplate(DTS.Common.ISO.TestObjectTemplate template, ref ISO13499FileDb db, List<MMETestObjects> testObjects)`
Wraps an ISO template, preferring a provided list of `MMETestObjects`.
- **Properties**
- `TemplateName`, `TemplateDescription`, `LastModified`, `LastModifiedBy`, `TemplateParent`, `SysBuilt`, `IsLocalOnly`, `Embedded`, `OriginalTemplateName`
Standard metadata properties. `Embedded` and `OriginalTemplateName` synchronize with the underlying `_template` object.
- `TestObject` (`MMETestObjects`), `TestObjectType` (`string`)
Gets/sets test object and type. Setting `TestObjectType` triggers channel list regeneration and order assignment.
- `RequiredChannels` (`List<TestObjectTemplateChannel>`)
List of required channels (not auto-populated; must be set explicitly).
- `TemplateAllChannels` (`TestObjectTemplateChannel[]`), `TemplateAllUIChannels` (`TemplateChannelUI[]`)
Arrays of all channels. `TemplateAllChannels` stores the raw ISO channels; `TemplateAllUIChannels` wraps them in `TemplateChannelUI` for UI binding.
- `AvailableTestObjectTypes` (`string[]`)
Derived from `TestObject` via `ApplicationProperties.IsoDb.GetTestObjectTypeForTestObject(...)`.
- `TestObjectTypeIndex` (`int`)
Index into `AvailableTestObjectTypes`; setting it updates `TestObjectType`.
- **Methods**
- `AssignOrders()`
Sorts `TemplateAllChannels` and assigns `DisplayOrder` to channels with `-1`.
- `ToISOTestObjectTemplate()`
Converts to a standalone `DTS.Common.ISO.TestObjectTemplate` (for persistence/export).
- `MarkChanged(string tag)`
Raises `OnPropertyChanged(tag)`.
- `CompareTo(TestObjectTemplate rhs)`
Compares by `TemplateName` (ordinal).
- `ReadXML(XmlElement root, Dictionary<long, MMEPossibleChannels> importChannels)` (static)
Deserializes an ISO template from XML. Delegates to `ProcessXMLElement` and `ProcessChannelXMLNode`.
- `ProcessXMLElement`, `ProcessChannelXMLNode` (private static)
XML parsing helpers. `ProcessChannelXMLNode` handles channel-specific fields (e.g., `Required`, `DisplayOrder`, `LocalOnly`, `NameOfTheChannel`).
## 3. Invariants
- **Singleton Consistency**:
`TestObjectTemplateCollection.TemplateCollection` and `TestObjectList.TestObjectsList` are singletons. `TestObjectsList` uses explicit locking for thread safety; `TemplateCollection` does not (potential race condition on first access).
- **Template Identity**:
`TestObjectTemplate.TemplateName` and `OriginalTemplateName` must be non-null. `Embedded` templates use `OriginalTemplateName` for display (`ToString()` override).
- **Channel Ordering**:
`TestObjectTemplate.AssignOrders()` ensures `DisplayOrder` is non-decreasing and ≥ 0 for all channels after assignment.
- **Position Propagation**:
Setting `TestTestObject.Position` to a non-`UserSetKey` value propagates the position to all required channels sensors via `SetSensor(...)`.
- **Test Object Propagation**:
Setting `TestTestObject.TestObject` propagates the test object to all required channels sensors.
- **XML Field Validation**:
`ProcessChannelXMLNode` requires `MMEChannelId` and `MMEChannelType` to be present and parseable; otherwise, the channel is skipped.
- **Metadata Copying**:
`TestTestObject` copy constructors call `MetaCommonConstructor` to ensure test-specific metadata (e.g., `ExcitationWarmupTimeMS`, `Position`) is preserved.
## 4. Dependencies
### Internal Dependencies
- **Base Classes**:
`BasePropertyChanged` (for `INotifyPropertyChanged` implementation).
- **ISO Layer**:
`DTS.Common.ISO.TestObjectTemplate`, `TestObjectTemplateChannel`, `MMEPositions`, `MMETestObjects`, `MMEPossibleChannels`, `ISO13499FileDb`.
- **Application Context**:
`ApplicationProperties.IsoDb` (central database access), `ApplicationProperties.CurrentUser` (for `LastModifiedBy`).
- **WPF**:
`System.Windows.Visibility` (for UI state).
### External Dependencies
- **Logging**: `DTS.Common.Utilities.Logging` (imported but no usage observed in source).
- **DataModel**: `DTS.Common.DataModel` (namespace for shared types).
- **Utilities**: `System`, `System.Collections.Generic`, `System.Linq`, `System.Xml`.
### Usage by Other Modules
- `TestObjectTemplateCollection` is used to retrieve templates by ID (e.g., during test setup loading).
- `TestObjectList` is used to manage test objects in a list (e.g., during test execution).
- `TestTestObject` is used for test-specific test objects with override capabilities.
- `TemplateChannelUI` is used in UI bindings for template channel properties.
## 5. Gotchas
- **Uninitialized `SysBuiltTestObjectTemplate`**:
`_sysBuiltTestObjectTemplate` is declared but never assigned in `TestObjectTemplateCollection`. Accessing `SysBuiltTestObjectTemplate` will return `null`.
- **Thread Safety Gap**:
`TestObjectTemplateCollection.TemplateCollection` is not thread-safe on first access (no locking), while `TestObjectList.TestObjectsList` is.
- **Non-ISO Mode Code Commented Out**:
`GroupPositionComboBoxVisible` and `GroupPositionButtonVisible` getters contain commented-out logic for `NO_ISO` mode. This may cause unexpected UI behavior if non-ISO mode is active.
- **Channel Display Order Logic**:
`AssignOrders()` and `ProcessChannelXMLNode` both assign `DisplayOrder` to `-1` channels, but `AssignOrders()` uses the *current* max + 1, while `ProcessChannelXMLNode` uses the *newly added* channels max + 1. This can lead to inconsistent ordering if channels are added incrementally.
- **Template Name Overwrite in `Rename`**:
`Rename` replaces `TemplateName` and `OriginalTemplateName` with new GUIDs, but does not update `TemplateParent`. This may break template hierarchy references.
- **`TestObjectTemplateChannel` Duplication**:
`TemplateAllChannels` and `TemplateAllUIChannels` store overlapping data. `TemplateAllChannels` is derived from `_allUIChannels`, but setting one does not automatically sync the other (e.g., `TemplateAllChannels` setter calls `TemplateAllUIChannels = ...`, but not vice versa).
- **`TestTestObject` Constructor Overload Ambiguity**:
Two constructors accept `(TestObject obj, bool convertToEmbedded)`. One is for `TestTestObject`, the other for `TestObject`. This may cause confusion or unintended behavior if misused.
- **`_userSetGUID` and `_channelDefaultsGUID`**:
These static `MMEPositions` instances are created with `Guid.NewGuid()` at type initialization. If multiple app domains or test runs occur, GUIDs may collide or behave unexpectedly (though unlikely in practice).
- **`ToISOTestObjectTemplate` Omits Fields**:
The method does not copy `Version`, `CRC32`, or `Icon` to the resulting ISO template, even though these are part of `GroupTemplateFields`.
- **`ProcessChannelXMLNode` Ignores Many Fields**:
Several `GroupTemplateChannelFields` (e.g., `BitResolution`, `ChannelAmplitudeClass`, `Comments`) are parsed but not applied to the channel. This may lead to data loss during XML import.

View File

@@ -0,0 +1,142 @@
---
source_files:
- Common/DTS.Common.DataModel/Classes/TestTemplate/ICachedContainer.cs
- Common/DTS.Common.DataModel/Classes/TestTemplate/HardwareInclusionInstruction.cs
- Common/DTS.Common.DataModel/Classes/TestTemplate/TSRAIRGoTestSetup.cs
- Common/DTS.Common.DataModel/Classes/TestTemplate/DownloadEvent.cs
- Common/DTS.Common.DataModel/Classes/TestTemplate/BuildTestSetup.cs
generated_at: "2026-04-16T03:33:56.095301+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "899d8d4385eb5461"
---
# Documentation: Test Template Data Model Module
## 1. Purpose
This module defines core data structures and interfaces for configuring and managing test setups in the DataPROWin7 system, specifically for hardware-agnostic test template handling, event download configuration, and build-time test setup generation. It enables programmatic construction of test configurations from XML templates or runtime templates, supports hardware inclusion/exclusion instructions for flexible group-based test composition (e.g., DAS-less groups), and provides caching and singleton access patterns for standardized test setups like `TSRAIR_GO_TEST`. The module serves as the foundational data layer for test configuration, bridging high-level test templates with low-level XML serialization and hardware mapping.
## 2. Public Interface
### `ICachedContainer` (Interface)
- **Namespace**: `DataPROWin7.DataModel.Classes.TestTemplate`
- **Purpose**: Provides cached access to hardware, sensor, and calibration data by serial number, and enumeration of all cached hardware.
- **Methods**:
- `DASHardware GetCachedHardware(string serialNumber)`
Retrieves cached DAS hardware data for the given serial number.
- `SensorData GetCachedSensor(string serialNumber)`
Retrieves cached sensor data for the given serial number.
- `SensorCalibration[] GetCalibrations(string serialNumber)`
Retrieves an array of calibrations associated with the given serial number.
- `IISOHardware[] GetAllCachedHardware()`
Returns all hardware currently in the cache.
### `HardwareInclusionInstruction` (Class)
- **Namespace**: `DataPROWin7.DataModel`
- **Purpose**: Represents an explicit instruction to include or exclude a specific piece of hardware in a test, overriding group-based inclusion logic.
- **Properties**:
- `string HardwareId { get; }`
The identifier of the hardware to which the instruction applies.
- `Actions Action { get; }`
The action to take (`Remove` or `Add`).
- **Constructors**:
- `HardwareInclusionInstruction(string hardwareId, Actions action)`
Creates a new instruction with the specified hardware ID and action.
- `HardwareInclusionInstruction(HardwareInclusionInstruction copy)`
Copy constructor.
### `TSRAIRGoTestSetup` (Class)
- **Namespace**: `DTS.Common.DataModel.Classes.TestTemplate`
- **Purpose**: Implements a singleton test setup for the `"TSRAIR_GO_TEST"` template, with caching and lazy initialization.
- **Constants**:
- `public const string TEST_NAME = "TSRAIR_GO_TEST"`
- **Properties**:
- `public override string Name { get; }`
Always returns `"TSRAIR_GO_TEST"`; setter is a no-op.
- **Methods**:
- `public static TSRAIRGoTestSetup GetInstance(int userId, bool useCache = true)`
Returns a singleton instance of `TSRAIRGoTestSetup`. If `useCache` is true and an instance exists, returns it; otherwise, loads the template named `"TSRAIR_GO_TEST"` from `TestTemplateList`, or falls back to user-specific defaults if the template is not found. Thread-safe via `lock`.
### `DownloadEvent` (Class)
- **Namespace**: `DataPROWin7.DataModel`
- **Purpose**: Represents a downloadable test event with metadata for export and display, implementing `IDownloadEvent` and `INotifyPropertyChanged`.
- **Properties**:
- `int EventNumber { get; set; }`
Event index; setting triggers `EventNumberDisplay` update.
- `bool IsEnabled { get; set; }`
Whether the event is active.
- `bool IsDefault { get; }`
Read-only; indicates if this is the default event.
- `bool IsReadonly { get; set; }`
Indicates if the event is immutable.
- `string EventNumberDisplay { get; }`
Display string of the form `"Event XX"` (e.g., `"Event 01"`), derived from `EventNumber`.
- `string TestItem { get; set; }`
Stores `"<TestSetup>:<TestId>:("<All or ROI>")` for export (see comment: issue #43387).
- `string DTSFile { get; set; }`
Stores the `.DTS` file path for export (see comment: issue #43387).
- `TimeSpan EventLength { get; set; }`
Total time available for the download event.
- `bool ShouldDisplayLength { get; set; }`
Controls whether `EventLength` is displayed.
### `BuildTestSetup` (Class)
- **Namespace**: `DataPROWin7.DataModel`
- **Purpose**: Converts high-level test templates or XML test setup definitions into a structured, serializable representation for UI and export consumption. Implements `IBuildTestSetup` and `INotifyPropertyChanged`.
- **Constructors**:
- `BuildTestSetup(string dasSerialNumber, string testSetupName, ExportFileXMLClass exportFileXML)`
Parses a `ExportFileXMLClass` object to populate properties and groups.
- `BuildTestSetup(string dasSerialNumber, string testSetupName, TestTemplate testTemplate)`
Maps properties from a `TestTemplate` instance to string-based properties.
- **Key Properties** (all `string`-typed for serialization compatibility):
- Hardware/Setup: `DASSerialNumber`, `SetupName`, `SetupDescription`
- Timing/Triggering: `RecordingMode`, `SamplesPerSecond`, `PreTriggerSeconds`, `PostTriggerSeconds`, `NumberOfEvents`, `WakeUpMotionTimeout`, `ScheduledStartDateTime`, `IntervalBetweenEventStartsMinutes`, `StartWithEvent`, `WakeUpWithMotion`, `TriggerCheckStep`
- Diagnostics/Validation: `StrictDiagnostics`, `RequireConfirmationOnErrors`, `WarnOnBatteryFail`, `AllowMissingSensors`, `AllowSensorIdToBlankChannel`, `SuppressMissingSensorsWarning`
- Arm/Checklist Steps: `PerformArmChecklist`, `CheckInputVoltage`, `CheckBatteryVoltage`, `CheckSquibResistance`, `CheckSensorIds`, `CheckStartEventLines`, `CheckTiltSensor`, `CheckTemperature`, `RequireAllUnitsPassArmCheckList`, `ExcitationWarmupTimeMS`
- Export/Download: `ROIDownload`, `ViewROIDownload`, `DownloadAll`, `ViewDownloadAll`, `Export`, `ExportFolder`, `ExportCh10FilteredEUDesired`, `ExportChryslerDDASDesired`, `ExportCSVADCDesired`, `ExportCSVFilteredDesired`, `ExportCSVMVDesired`, `ExportCSVUnfilteredDesired`, `ExportDiademADCDesired`, `ExportASCDesired`, `ExportHDFADCDesired`, `ExportHDFMVDesired`, `ExportHDFUnfilteredDesired`, `ExportISOFilteredDesired`, `ExportISOUnfilteredDesired`, `ExportRDFADCDesired`, `ExportTDASADCDesired`, `ExportTDMSADCDesired`, `ExportToyotaUnfilteredDesired`, `ExportTSVFilteredDesired`, `ExportTSVUnfilteredDesired`, `ExportXLSXFilteredDesired`, `ExportXLSXUnfilteredDesired`
- UI/Display: `ViewRealtime`, `RealtimeCharts`, `ROIStart`, `ROIEnd`, `CommonStatusLine`, `UploadData`, `UploadDataFolder`, `UseLabDetails`, `UseCustomerDetails`, `UseTestEngineerDetails`, `AutoArm`, `Streaming`, `CalibrationBehavior`, `NotAllChannelsRealTime`, `NotAllChannelsViewer`, `QuitTestWithoutWarning`, `MeasureSquibResistances`
- Metadata: `LastModified`, `LastModifiedBy`, `UserTags`
- **Collections**:
- `List<GroupXMLClass> Groups { get; set; }`
List of test groups with channels and settings.
- `List<LevelTriggerXMLClass> LevelTriggers { get; set; }`
List of level trigger definitions.
## 3. Invariants
- **`TSRAIRGoTestSetup` singleton**: Only one instance exists per application domain (enforced via `lock` and `_setup` field). The `Name` property is immutable and always equals `"TSRAIR_GO_TEST"`.
- **`DownloadEvent` defaults**: Default constructor initializes `EventNumber = 0`, `IsEnabled = true`, `IsDefault = true`, `IsReadonly = true`. `EventNumberDisplay` is derived from `EventNumber` and formatted as `"Event XX"`.
- **`BuildTestSetup` property types**: All configuration properties are stored as `string`, even if originally numeric or boolean (e.g., `SamplesPerSecond`, `AutomaticMode`). This is intentional for XML round-tripping.
- **Export format parsing**: In `DecodeExportFormats`, only the following export formats are decoded to boolean flags (others are commented out and ignored):
- `Ch10FilteredEU`, `ChryslerDDAS`, `CSVADC`, `csvfiltered`, `CSVMV`, `csvunfiltered`, `diademadc`, `FIATASC`, `HDFADC`, `HDFMV`, `HDFUnfiltered`, `isofiltered`, `isounfiltered`, `rdfadc`, `tdasadc`, `tdmsadc`, `toyotaunfiltered`, `tsvfiltered`, `tsvunfiltered`, `xlsxfiltered`, `xlsxunfiltered`
- **`HardwareInclusionInstruction.Action`**: Must be either `Remove` or `Add`; no validation is performed at construction, so callers must ensure valid values.
## 4. Dependencies
### Imports/References (from source):
- `DTS.Common.Interface.DASFactory.Diagnostics`
- `DTS.SensorDB`
- `DTS.Slice.Users.UserSettings`
- `DTS.Common.Interface.DownloadEvent`
- `DTS.Common.XMLUtils`
- `DTS.Common.Enums`
- `DTS.Common.SharedResource.Strings`
- `DataPROWin7.DataModel` (internal namespace for `TestTemplate`, `GroupXMLClass`, `ChannelXMLClass`, `LevelTriggerXMLClass`, `ExportFileXMLClass`, `TestSetupDefaults`, `TestTemplateList`, `SupportedExportFormatBitFlags`)
### Inferred Dependencies:
- **`TestTemplate`**: Required by `TSRAIRGoTestSetup` and `BuildTestSetup` constructors.
- **`TestTemplateList`**: Used by `TSRAIRGoTestSetup.GetInstance` to retrieve named templates.
- **`TestSetupDefaults`**: Used by `TSRAIRGoTestSetup.GetInstance` for fallback user settings.
- **`GroupXMLClass`, `ChannelXMLClass`, `LevelTriggerXMLClass`, `ExportFileXMLClass`**: Referenced in `BuildTestSetup` constructors and XML parsing logic.
- **`SupportedExportFormatBitFlags`**: Used in `DecodeExportFormats` to decode export format bitmasks.
## 5. Gotchas
- **`TSRAIRGoTestSetup` caching behavior**: The singleton instance is *not* invalidated on user change unless `useCache = false`. Reusing the instance across different users may lead to incorrect settings if `userId` is not consistent.
- **`BuildTestSetup` string-based properties**: All properties are `string`, even for numeric/boolean values (e.g., `"True"`, `"100"`). Consumers must parse these values appropriately; no runtime type safety is enforced.
- **Export format decoding is incomplete**: In `DecodeExportFormats`, several formats are commented out (`ExportCh10UnfilteredEUDesired`, `ExportHDFFilteredDesired`, `ExportSomatFilteredDesired`, `ExportSomatUnfilteredDesired`, `ExportToyotaFilteredDesired`). This may cause confusion if export formats are expected to be fully symmetric.
- **`HardwareInclusionInstruction` immutability**: `HardwareId` and `Action` are read-only (`get;` only), but the class itself is not immutable (e.g., no `readonly` fields). Copy constructor exists but is not enforced.
- **`DownloadEvent.TestItem` and `DTSFile`**: These properties are documented as being for export (issue #43387), but there is no validation or enforcement of their format or usage. Misuse could break export logic.
- **`BuildTestSetup.ParseSettings`**: Uses hardcoded string prefixes (e.g., `"0="`, `"1="`) to parse settings. If the XML format changes or prefixes are reordered, parsing will silently fail or misassign values.
- **Thread safety**: `TSRAIRGoTestSetup.GetInstance` is thread-safe via `lock`, but no other classes in this module declare thread-safety guarantees. Concurrent access to shared mutable state (e.g., `DownloadEvent` properties) is not protected.

View File

@@ -0,0 +1,166 @@
---
source_files:
- Common/DTS.Common.DataModel/Common/StatusHelpers.cs
- Common/DTS.Common.DataModel/Common/TestObjectHelper.cs
- Common/DTS.Common.DataModel/Common/ChannelHelper.cs
- Common/DTS.Common.DataModel/Common/TestSetupCollection.cs
generated_at: "2026-04-16T03:31:59.768999+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "2101fc7191561021"
---
# Common
## Documentation: `DTS.Common.DataModel.Common` Module
---
### **Purpose**
This module provides utility helpers for managing test setup metadata, channel naming conventions, and status reporting within the DTS data modeling layer. It centralizes logic for caching and refreshing test setup lists (with staleness detection via CRC and time-based invalidation), generating warning channel display names, and exposing legacy TOM channel filter constants. It acts as a coordination layer between data persistence (via SQL queries), UI eventing (via Prisms `IEventAggregator`), and domain-specific constants, enabling consistent behavior across UI and background processes.
---
### **Public Interface**
#### **`StatusHelpers` class**
- **`SetProgressValueDelegate` delegate**
```csharp
public delegate void SetProgressValueDelegate(IDASCommunication idas, double progressValue, TSRAIRGoStatus.StatusTypes? status);
```
Signature for a callback used to set progress and status on a DAS communication interface.
- **`SetStatus2` method**
```csharp
public static void SetStatus2(IDASCommunication das, int progressValue, TSRAIRGoStatus.StatusTypes? status, SetProgressValueDelegate setProgressValue)
```
Invokes the provided `setProgressValue` delegate with the given `das`, `progressValue`, and `status`. This is a thin wrapper—no validation or transformation is performed on inputs.
#### **`TestObjectHelper` class**
- **`TDC_LEGACY_TOM_CUTOFF_SPS` constant**
```csharp
public const double TDC_LEGACY_TOM_CUTOFF_SPS = 8000;
```
Threshold sampling rate (samples per second) used to determine TOM channel filter selection in legacy TDC systems. Channels ≥ 8000 SPS use `TDC_LEGACY_TOM_HIGH_FILTER`.
- **`TDC_LEGACY_TOM_HIGH_FILTER` constant**
```csharp
public const double TDC_LEGACY_TOM_HIGH_FILTER = 1650D;
```
Default high-pass filter frequency (in Hz) applied to TOM channels recorded at >8000 SPS in legacy TDC (CFC1000 equivalent). *Note:* Values ≤8000 SPS are not handled in this module.
#### **`ChannelHelper` class**
- **`GetWarningChannelName` method**
```csharp
public static string GetWarningChannelName(IGroupChannel groupChannel)
```
Generates a human-readable warning label for a channel, using the following logic:
- Uses `TestSetupOrder` if ≥ 0; otherwise uses `GroupChannelOrder`.
- If `GetChannelName(SerializedSettings.ISOViewMode)` returns a non-empty string, uses that quoted (e.g., `'MyChannel'`).
- Otherwise, appends empty string `''`, then optionally appends sensor info (if `SensorValid`) and hardware info (if `HardwareValid`), e.g., `1, '', (SensorA) DAS1`.
#### **`TestSetupCollection` class**
- **`TestSetupIds` property**
```csharp
public static List<string> TestSetupIds { get; }
```
Returns a *copy* of the internal `_testSetupList` (as a `List<string>`), containing names of test setups. Access is thread-safe via `TestSetupListLock`.
- **`TestSetupList` property**
```csharp
public static string[] TestSetupList { get; }
```
Returns an array of test setup names (only *complete* tests if called directly, but behavior differs based on context—see *Gotchas*). Triggers full refresh if `_testSetupList` is null/empty. Uses `ProgressBarEvent` to report progress during refresh.
- **`TestSetups` property**
```csharp
public static TestTemplate[] TestSetups { get; }
```
Returns a snapshot of `_actualTestTemplates` (as `TestTemplate[]`), containing *all* loaded test templates (not filtered by completeness).
- **`UpdateTestSetupListIfStale()` method**
```csharp
public static void UpdateTestSetupListIfStale()
```
Conditionally triggers `UpdateTestSetupList()` if:
- Last update was >30 minutes ago (`MIN_TESTS_UPDATEINTERVAL_MINUTES`), *or*
- CRC of the underlying `TestSetups` table in SQL has changed.
- **`UpdateTestSetupList(TestTemplate test)` method**
```csharp
public static void UpdateTestSetupList(TestTemplate test)
```
Updates the cached list for a *single* `test`:
- If `test.IsDirty` and `!test.IsComplete`, removes `test.Name` from `_testSetupList`.
- If `!test.IsDirty` and `!test.IsComplete`, does nothing.
- Otherwise, adds `test.Name` to `_testSetupList` (if not already present).
- **`UpdateTestSetupList(Action onCompleteAction = null)` method**
```csharp
public static void UpdateTestSetupList(Action onCompleteAction = null)
```
Performs a full refresh of `_testSetupList` and `_actualTestTemplates`:
- Fetches all templates via `TestTemplateList.TestTemplatesList.AllTemplates`.
- Publishes `ProgressBarEvent` with percentage updates.
- Adds *all* templates to `_testSetupList` (regardless of `IsComplete`).
- Computes CRC over `TestSetups` DB table and stores in `_crc`.
- Invokes `onCompleteAction` if provided.
- **`TestSetupListLock` property**
```csharp
public static object TestSetupListLock { get; }
```
Lock object used to synchronize access to `_testSetupList`, `_actualTestTemplates`, `_crc`, and `_lastUpdateTime`.
---
### **Invariants**
1. **Thread Safety**: All public static properties/methods accessing `_testSetupList`, `_actualTestTemplates`, `_crc`, or `_lastUpdateTime` are guarded by `TestSetupListLock`.
2. **Staleness Policy**: `_testSetupList` is considered stale if:
- Time since `_lastUpdateTime` > 30 minutes (`MIN_TESTS_UPDATEINTERVAL_MINUTES`), *or*
- CRC of the `TestSetups` DB table (`GetCRC()`) differs from stored `_crc`.
3. **CRC Computation**: CRC is computed over a byte list derived from `TestSetups` table columns: `[TestSetupName]`, `[Dirty]`, `[Complete]`, `[LastModified]` (binary representation).
4. **Progress Reporting**: Full refresh operations (`UpdateTestSetupList()` and `TestSetupList` getter) publish `ProgressBarEvent` with percentage updates; partial updates (e.g., `UpdateTestSetupList(TestTemplate)`) do not.
---
### **Dependencies**
#### **Imports/References**
- **`DTS.Common.Interface.DASFactory.IDASCommunication`** Used by `StatusHelpers.SetStatus2`.
- **`DTS.Common.Enums.TSRAIRGo.TSRAIRGoStatus.StatusTypes`** Status enum used in `SetStatus2`.
- **`DataPROWin7.Common`** Referenced in `ChannelHelper` (via `SerializedSettings.ISOViewMode`).
- **`DTS.Common.Interface.Channels.IGroupChannel`** Used in `ChannelHelper.GetWarningChannelName`.
- **`DataPROWin7.DataModel`** Provides `TestTemplate`, `TestTemplateList`.
- **`Prism.Ioc.IContainerLocator`, `Prism.Events.IEventAggregator`** Used for eventing and service resolution.
- **`System.Windows.Threading.Dispatcher`, `System.Windows.Application`** Used to check dispatcher access before resolving services.
- **`DTS.Utilities.Crc32`** Custom CRC32 implementation used in `GetCRC()`.
#### **External Dependencies**
- **SQL Database**: `Storage.DbOperations.GetSQLCommand()` queries `[TestSetups]` table.
- **Prism Event Aggregator**: Relies on `ProgressBarEvent` being registered and subscribed to.
---
### **Gotchas**
1. **`TestSetupList` behavior is context-dependent**:
- When accessed *after* a full `UpdateTestSetupList()` call, it returns *all* test names (including incomplete ones).
- When accessed *initially* (empty cache), it filters to *only complete tests* (`if (!t.IsComplete) { continue; }`).
→ This inconsistency may cause unexpected omissions or inclusions depending on call order.
2. **`UpdateTestSetupList(TestTemplate)` silently fails** if `ContainerLocator.Container` or `IEventAggregator` is unavailable (e.g., during cmdline import), returning early without updating the list.
3. **`TestSetupIds` returns a `List<string>` but is documented as `List<string>` in source—however, `TestSetupList` returns `string[]`.** Ensure callers do not assume mutability or shared references.
4. **`SetStatus2` is a trivial wrapper**: It does *not* validate `idas`, `progressValue`, or `status`. Misuse (e.g., null delegate) will throw at runtime.
5. **`TDC_LEGACY_TOM_CUTOFF_SPS` is a legacy constant**: The comment explicitly states that channels ≤8000 SPS are *not handled* in this module. Do not assume support for lower sampling rates.
6. **`TestSetupList` getter may block indefinitely** if `ContainerLocator.Container.Resolve<IEventAggregator>()` fails (e.g., in headless/test environments), since it does not guard against null `eventAggregator` in the fallback path (unlike `UpdateTestSetupList()` methods).
7. **CRC computation is expensive**: `GetCRC()` performs a full table scan and byte marshaling. Avoid calling it frequently outside `UpdateTestSetupListIfStale()`.
8. **No validation of `progressValue` in `SetStatus2`**: The delegate may expect `double` in [0,100] range, but the method accepts any `int` (e.g., negative or >100).

View File

@@ -0,0 +1,123 @@
---
source_files:
- Common/DTS.Common.DataModel/Common/DbWrappers/DASGet.cs
- Common/DTS.Common.DataModel/Common/DbWrappers/TestSetupHardwareGet.cs
generated_at: "2026-04-16T03:34:55.106379+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "65c9860ac4e82586"
---
# DbWrappers
## Documentation: `DASGet` and `TestSetupHardwareGet` DbWrappers
---
### 1. Purpose
This module provides wrapper classes (`DASGet` and `TestSetupHardwareGet`) that encapsulate database retrieval logic for DAS (Data Acquisition System) hardware configuration and test setup hardware associations, respectively. Their primary role is to abstract raw database calls (`DbOperations.DASGet`, `DbOperations.TestSetupHardwareGet`) into strongly-typed, validated, and repaired domain objects—ensuring data integrity by correcting known bad or inconsistent database values (e.g., missing or zero `AntiAliasFilterRate`) in a centralized manner. These wrappers serve as the canonical data-access layer for DAS and test setup hardware metadata within the system.
---
### 2. Public Interface
#### `DASGet` class (`DTS.Common.DataModel.Common.DbWrappers`)
- **`DASGet()`**
Default constructor.
- **`DASGet(IDASDBRecord record)`**
Constructor that initializes the instance from an `IDASDBRecord`. Includes logic to repair `MaxAAFRate` if it is `NaN`: sets `MaxAAFRate = MaxSampleRate / 5`.
- **`int Type { get; set; }`**
Gets/sets the `DASType` property (inherited from base `DASDBRecord`). Maps directly to the underlying `DASType` field.
- **`bool Reprogramable { get; set; }`**
Gets/sets the `IsProgrammable` property (inherited from base `DASDBRecord`). Note: spelling is *Reprogramable* (missing 'm'), matching the source.
- **`bool Reconfigurable { get; set; }`**
Gets/sets the `IsReconfigurable` property (inherited from base `DASDBRecord`).
- **`List<DASGet> DASGet_Wrapper(string serialNumber = null, string position = null)`**
Static-like wrapper method (instance method) that calls `DbOperations.DASGet(serialNumber, position, out var dbDAS)`. Returns a list of `DASGet` instances constructed from the returned `dbDAS` array. If `DbOperations.DASGet` returns non-zero `hResult` or `dbDAS` is null, returns an empty list.
#### `TestSetupHardwareGet` class (`DTS.Common.DataModel.Common.DbWrappers`)
- **`TestSetupHardwareGet()`**
Default constructor.
- **`TestSetupHardwareGet(ITestSetupHardwareRecord copy)`**
Constructor that initializes the instance from an `ITestSetupHardwareRecord`.
- **`bool AddOrRemove { get; set; }`**
Gets/sets the `AddDAS` property (inherited from base `TestSetupHardwareRecord`). On set, raises `OnPropertyChanged("AddOrRemove")`.
- **`List<TestSetupHardwareGet> TestSetupHardwareGet_Wrapper(int? testSetupId, Dictionary<int, IDASHardware> hardwareLookup)`**
Instance method that retrieves test setup hardware records via `DbOperations.TestSetupHardwareGet(testSetupId, out var records)`. For each record:
- If `AntiAliasFilterRate == 0` and `hardwareLookup` is non-null, repairs the rate using `RepairAntiAliasFilterRate` based on the DAS type from `hardwareLookup[record.DASId]`.
- Then, *after* initial construction, performs a second pass over the list to repair any remaining `AntiAliasFilterRate == 0` entries by querying `DASGet_Wrapper()` internally to fetch the DAS type for that `DASId`.
Returns a list of repaired `TestSetupHardwareGet` instances.
- **`private HardwareTypes GetDASTypeEnumFromId(int dasId)`**
Helper method: calls `DASGet_Wrapper()` to fetch all DAS records, then matches on `DASId` to retrieve the `Type` (int), wraps it in a `DTS.Common.ISO.Hardware` instance, and returns its `DASTypeEnum`.
- **`private int RepairAntiAliasFilterRate(HardwareTypes dasTypeEnum, int samplesPerSecond)`**
Helper method: returns a non-zero `AntiAliasFilterRate` based on `dasTypeEnum` and `samplesPerSecond`:
- For `HardwareTypes.DIM`, `G5INDUMMY`, `G5VDS`, `SIM`, `TDAS_Pro_Rack`, `TDAS_LabRack`, `TOM`: returns `0` (no repair—these types allow 0).
- For all other types: returns `SerializedSettings.GetAAFException(SerializableAAF.DAS_TYPE.SLICE, samplesPerSecond)` cast to `int`.
---
### 3. Invariants
- **`DASGet`**
- After construction via `DASGet(IDASDBRecord)`, if `MaxAAFRate` is `NaN`, it is guaranteed to be set to `MaxSampleRate / 5`.
- `Type`, `Reprogramable`, and `Reconfigurable` are direct aliases to underlying base properties (`DASType`, `IsProgrammable`, `IsReconfigurable`), so their values reflect the underlying record.
- **`TestSetupHardwareGet`**
- After calling `TestSetupHardwareGet_Wrapper`, **no element in the returned list will have `AntiAliasFilterRate == 0`**, unless `GetDASTypeEnumFromId` returns `HardwareTypes.UNDEFINED` (in which case `RepairAntiAliasFilterRate` falls through to `default`, i.e., `0`).
- `AddOrRemove` is a computed alias for `AddDAS`, with change notification.
---
### 4. Dependencies
#### `DASGet`
- **Imports/Uses**:
- `DTS.Common.Interface.DataRecorders.IDASDBRecord`
- `DTS.Common.Storage.DbOperations.DASGet(...)`
- `DTS.Common.Classes.Hardware` (namespace, used for base class `DASDBRecord`)
- **Depended on by**:
- `TestSetupHardwareGet.GetDASTypeEnumFromId(...)` calls `DASGet_Wrapper()` to resolve DAS types.
#### `TestSetupHardwareGet`
- **Imports/Uses**:
- `DTS.Common.Interface.DataRecorders.ITestSetupHardwareRecord`
- `DTS.Common.Storage.DbOperations.TestSetupHardwareGet(...)`
- `DTS.Common.Enums.Hardware.HardwareTypes`
- `DTS.Common.Classes.Hardware` (base class `TestSetupHardwareRecord`)
- `DTS.Common.Classes.TestSetups`, `DTS.Common.Interface.TestSetups`, `DataPROWin7.Common` (for `SerializedSettings`)
- `DASGet.DASGet_Wrapper(...)` (indirectly via `GetDASTypeEnumFromId`)
- **Depended on by**:
- Likely used by test setup configuration UI or business logic layers (not evident from source).
---
### 5. Gotchas
- **Spelling**: `Reprogramable` (missing 'm') is used in property names—this is intentional per source.
- **Double repair logic in `TestSetupHardwareGet_Wrapper`**:
- First repair uses `hardwareLookup` if provided.
- Second repair (post-construction loop) *ignores* `hardwareLookup` and instead queries `DASGet_Wrapper()` to resolve DAS type.
→ This may cause inconsistent behavior if `hardwareLookup` is stale/out-of-sync with DB.
- **Fallback to `HardwareTypes.UNDEFINED`**:
If `GetDASTypeEnumFromId` fails to find a matching `DASId`, it returns `HardwareTypes.UNDEFINED`, and `RepairAntiAliasFilterRate` returns `0`. This means `AntiAliasFilterRate` can still be `0` in the final list if the DAS record is missing.
- **Hardcoded DAS type groups**:
The `RepairAntiAliasFilterRate` switch statement assumes specific DAS types allow `0` AAF rate (e.g., TDAS family). Any new DAS type added must be explicitly added to avoid unintended repair.
- **`DASGet_Wrapper()` is an instance method**:
Despite being named like a static utility, it is an instance method on `DASGet` and `TestSetupHardwareGet`. Calling `new DASGet().DASGet_Wrapper()` is required.
- **No null-safety on `hardwareLookup` in first repair pass**:
If `hardwareLookup == null`, the first repair branch is skipped, but the second pass (which queries DB) still runs—so behavior is safe but potentially slower.
None identified beyond the above.

View File

@@ -0,0 +1,33 @@
---
source_files:
- Common/DTS.Common.DataModel/Properties/AssemblyInfo.cs
generated_at: "2026-04-16T03:32:08.688522+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "35833e634d97c22d"
---
# Properties
## 1. Purpose
This module (`DTS.Common.DataModel`) is an assembly containing shared data model definitions for the DTS (presumably *Data Transfer System* or domain-specific equivalent) platform. Its role is to centralize core data contracts (e.g., classes, structs, enums) used across other components in the system—ensuring consistency, reducing duplication, and enabling decoupled consumption of data structures. As indicated by its name and structure, it is a foundational library intended for reuse across multiple projects or services.
## 2. Public Interface
**No public types are defined in this file.**
The file `AssemblyInfo.cs` contains only assembly-level metadata attributes (e.g., title, version, COM visibility). It does not declare any public classes, interfaces, structs, enums, or methods. Therefore, there is **no public API surface** exposed by this file.
## 3. Invariants
- The assembly identity is fixed at version `1.0.0.0` (both `AssemblyVersion` and `AssemblyFileVersion`).
- The assembly is **not visible to COM** (`ComVisible(false)`), meaning it is not intended for interop with legacy COM clients.
- The GUID `2a2f03a9-bf85-4360-a06a-cf3016d2633b` uniquely identifies the typelib for COM exposure *if* `ComVisible` were enabled (which it is not).
- No runtime behavior or state is managed by this file; it is purely declarative metadata.
## 4. Dependencies
- **Dependencies**: None (this file only references standard .NET attributes from `System.Reflection`, `System.Runtime.CompilerServices`, and `System.Runtime.InteropServices`).
- **Dependents**: This assembly (`DTS.Common.DataModel`) is almost certainly referenced by other projects in the codebase (e.g., `DTS.Server`, `DTS.Client`, or similar), but such references are not visible in this file alone.
## 5. Gotchas
- **Misleading filename**: Despite the name `DTS.Common.DataModel`, this file does *not* contain any data model types. Actual data model definitions (classes, structs, enums) are expected to reside in other files within the same project (e.g., `Models/`, `Entities/`, or similar subdirectories).
- **Versioning rigidity**: The version is hardcoded to `1.0.0.0` with no build/revision auto-increment (`1.0.*` is commented out). This may complicate deployment or traceability if not managed externally (e.g., via CI/CD tooling).
- **COM compatibility**: While `ComVisible(false)` is appropriate for modern .NET, teams integrating with legacy COM systems must be aware that this assembly *cannot* be consumed directly without additional interop layers.
- **None identified from source alone.**

View File

@@ -0,0 +1,121 @@
---
source_files:
- Common/DTS.Common.DataModel/StateMachines/OverallArmStatusStateMachine.cs
generated_at: "2026-04-16T03:32:13.517351+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "8fbd8ac85721cb74"
---
# StateMachines
## Documentation: `OverallArmStatusStateMachine`
---
### **1. Purpose**
The `OverallArmStatusStateMachine` class implements a state machine that tracks and manages the high-level operational status of an arm subsystem (likely related to data acquisition or recording hardware) within the DTS system. It uses the `Stateless` library to define transitions between states such as `Recording`, `IDLE`, `WaitingForTrigger`, `Downloading`, and `Disarmed`, based on triggers like `Recording`, `DoneRecording`, `Disarm`, and `DASNotFound`. Its primary role is to maintain a canonical "overall arm status" state, emit notifications on state changes via the `OverallStatusStateChange` event, and serve as a central coordination point for status reporting across the application (e.g., updating a global status UI field). It does *not* manage low-level arm logic but aggregates and reflects higher-level transitions.
---
### **2. Public Interface**
#### **Constructor**
```csharp
public OverallArmStatusStateMachine()
```
- Initializes the `IEventAggregator` via `ContainerLocator.Container.Resolve<IEventAggregator>()`.
- Calls `Initialize()` to configure the underlying `Stateless.StateMachine`.
#### **Events**
```csharp
public event OverallStatusStateChangeDelegate OverallStatusStateChange;
```
- **Delegate**: `public delegate void OverallStatusStateChangeDelegate(ArmStateMachineStates.States previousState, ArmStateMachineStates.States nextState);`
- Fired whenever the overall status transitions to a new state (i.e., `CurrentOverallStatusState` changes). The event includes the previous and next state.
#### **Methods**
```csharp
public ArmStateMachineStates.States GetDASStatus()
```
- Returns the current overall status state (`CurrentOverallStatusState`).
```csharp
public void FireTrigger(Triggers trigger, ArmStateMachineStates.States state)
```
- Fires a named trigger with an associated *target state parameter* (note: this is unusual—see *Gotchas*).
- Internally maps each `Triggers` enum value to a pre-configured `TriggerWithParameters<ArmStateMachineStates.States>` and invokes `StateMachine.Fire(trigger, state)`.
- Logs exceptions via `APILogger.Log(ex.Message)`; does *not* rethrow.
- **Special case**: `Triggers.PostTestProcessing` incorrectly fires `DoneRecordingTrigger` instead of a dedicated `PostTestProcessingTrigger`.
#### **Nested Types**
- `public enum Triggers`: Defines 37+ named triggers (e.g., `Recording`, `Disarm`, `DASNotFound`, `Downloading`, `WaitingForTrigger`, `WaitingForSchedule`, `WaitingForInterval`, `ReadyForDownload`, `DoneRecording`, `NoDataToDownload`, `DataNeverDownloaded`, `Streaming`, `FlashClear`, `Error`, `GettingEventInfo`, `CheckingForData`, `Rearming`, `IDLE`, `IntervalRecording`, `NonIntervalRecording`, `RunButton`, `a`, `c`, `d`, `e`, `h`, `n`, `rr`, `tt`, `uu`, `yy`).
- *Note*: Several triggers (`a`, `c`, `d`, `e`, `h`, `n`, `rr`, `tt`, `uu`, `yy`) appear to be placeholder or legacy names with no documented purpose.
---
### **3. Invariants**
- **Initial State**: The state machine always starts in `ArmStateMachineStates.States.CheckingForDAS`.
- **Current State Tracking**: `CurrentOverallStatusState` is updated *only* via `SetOverallStatus()`, which:
- Compares `newState` to `CurrentOverallStatusState`.
- Logs transitions via `APILogger.Log(...)`.
- Invokes `OverallStatusStateChange` *only if* the state changes.
- **State Machine Library**: Uses `Stateless.StateMachine<ArmStateMachineStates.States, Triggers>`.
- **Parameterized Triggers**: All transitions that accept a state parameter use `SetTriggerParameters<ArmStateMachineStates.States>()`, meaning every trigger expects a *target state* as an argument when fired (e.g., `Fire(trigger, targetState)`).
- **No Explicit Error Handling in Transitions**: Transitions do not define custom `OnEntryFrom`/`OnExit` logic beyond calling `SetOverallStatus()`; no fallback or recovery behavior is defined in the state configuration.
---
### **4. Dependencies**
#### **Imports/Usings**
- `Stateless` Core state machine library.
- `Prism.Ioc.ContainerLocator` For resolving `IEventAggregator`.
- `DTS.Common.Enums.TSRAIRGo` Provides `ArmStateMachineStates.States` (not shown in this file).
- `DTS.Common.Utilities.Logging` Provides `APILogger`.
- `System` and `Prism.Events` For `IEventAggregator`.
#### **External Dependencies**
- **`ArmStateMachineStates.States`**: An external enum defining the valid states (e.g., `CheckingForDAS`, `IDLE`, `Recording`, `Disarmed`, `Downloading`, `ClearingFlash`, `WaitingForTrigger`, `WaitingForSchedule`, `WaitingForInterval`, `PostTestProcessing`, `GettingEventInfo`, `ReadyForDownload`, `Streaming`). Its definition is not included here.
- **`APILogger`**: Static logging utility.
- **`ContainerLocator`**: Prism DI container accessor (assumes `IEventAggregator` is registered).
#### **Consumers**
- Any component needing to update or query the overall arm status (e.g., UI, telemetry, control logic) must:
- Subscribe to `OverallStatusStateChange` to react to state changes.
- Call `FireTrigger()` to signal events.
- Call `GetDASStatus()` to poll the current state.
---
### **5. Gotchas**
- **Unusual Trigger Signature**: All triggers are defined as `TriggerWithParameters<ArmStateMachineStates.States>`, meaning every `Fire()` call *must* supply a target state (e.g., `Fire(RecordingTrigger, ArmStateMachineStates.States.Recording)`). This is atypical—most state machines infer the next state from the transition configuration. The comment in `FireTrigger()` ("why specify state here? shouldn't that be done based on current state/trigger?") confirms this design is questionable and likely error-prone.
- **Incorrect Trigger Mapping**: In `FireTrigger()`, `Triggers.PostTestProcessing` incorrectly fires `DoneRecordingTrigger` instead of a dedicated `PostTestProcessingTrigger`. This may cause unintended state transitions (e.g., skipping `PostTestProcessing` state entirely).
- **Unused Triggers**: The `Triggers` enum includes 10 cryptic triggers (`a`, `c`, `d`, `e`, `h`, `n`, `rr`, `tt`, `uu`, `yy`) with no corresponding configuration in `Initialize()`. These are likely legacy or placeholders and should be removed or documented.
- **No Handling for `ErrorTrigger`**: While `ErrorTrigger` is declared, it is *not* used in any state configuration (no `.Permit()` or `.OnEntryFrom()` references it). Attempting to fire it will throw a `Stateless` exception (trigger not defined for current state).
- **Ignored Triggers May Cause Silent Failures**: Several states use `.Ignore()` for specific triggers (e.g., `ClearingFlash` ignores `ReadyForDownload`, `NoDataToDownload`, `DataNeverDownloaded`). Firing these triggers in those states will throw an exception (not silently ignored), contradicting the intent of `.Ignore()` in `Stateless` (which *does* allow the trigger but prevents transition). Verify `Stateless` behavior—this may be a source of runtime exceptions.
- **No Public Setter for State**: The current state is read-only via `GetDASStatus()`. There is no way to manually override or reset the state machine (e.g., for testing or recovery), which may complicate error recovery.
- **Logging Side Effect**: `SetOverallStatus()` logs *every* transition, which may be excessive in high-frequency scenarios. No filtering or throttling is applied.
- **Missing State Definitions**: The states used (e.g., `ArmStateMachineStates.States.CheckingForDAS`) are referenced but not defined in this file. Their semantics and relationships depend on the external `ArmStateMachineStates.States` enum.
- **No Validation on State Parameter**: `FireTrigger()` accepts any `ArmStateMachineStates.States` as the second parameter. Passing an invalid or inconsistent state (e.g., `Fire(RecordingTrigger, ArmStateMachineStates.States.Disarmed)`) may result in runtime exceptions or undefined behavior.
- **Exception Swallowing**: `FireTrigger()` catches and logs *all* exceptions (including `Stateless` exceptions like `InvalidOperationException` for invalid transitions), but does not propagate them. This can mask critical failures.
- **No Thread Safety**: The class does not indicate thread-safety. Concurrent calls to `FireTrigger()` or state queries may cause race conditions.
- **Graph Generation Side Effect**: `Stateless.Graph.UMLDotGraph.Format(...)` is called but the result is discarded (`string graph = ...; graph = ...;`). This suggests debugging code was left in place.
---
*Documentation generated from source file `Common/DTS.Common.DataModel/StateMachines/OverallArmStatusStateMachine.cs`.*