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,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.