Files
2026-04-17 14:55:32 -04:00

115 lines
8.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
source_files:
- Common/DTS.Common.Import/Parsers/EQX/EQXTestSetupParser.cs
- Common/DTS.Common.Import/Parsers/EQX/EQXGroupImport.cs
- Common/DTS.Common.Import/Parsers/EQX/EQXSensorsParser.cs
generated_at: "2026-04-16T02:08:30.752253+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "ce57e1c33a0387ff"
---
# Documentation: EQX Test Setup Parser Module
## 1. Purpose
This module provides parsing logic for EQX files that contain test setup information (i.e., groupings of sensors into test groups and assignment to a test template). It is part of the `DTS.Common.Import` namespace and is specifically responsible for interpreting group-to-sensor mappings defined in an EQX file, constructing `TestTemplate`, static `IGroup`, and `SensorData` objects accordingly, and integrating them into the `ImportObject`. It depends on prior parsing of sensor and calibration data (handled by `EQXSensorsParser`) and uses `EQXGroupImport` to implement group creation logic. The parser aborts the import if the EQX file lacks test setup data (e.g., no `GroupNameTestObjectLookup`).
## 2. Public Interface
### `EQXTestSetupParser` class
**Constructor**
```csharp
public EQXTestSetupParser(
IImportNotification importNotification,
EqxImportOptions eqxImportOptions,
IGroupImport groupImport,
EquipmentExchange.EQXSensorDatabase eqxSensorDatabase,
bool createDynamicGroups)
```
Initializes the parser with dependencies required for parsing and group creation.
- `importNotification`: Used for reporting errors and progress.
- `eqxImportOptions`: Configuration options for EQX import.
- `groupImport`: Implementation of `IGroupImport` (typically `EQXGroupImport`) for group creation logic.
- `eqxSensorDatabase`: Pre-populated sensor database from `EQXSensorsParser`.
- `createDynamicGroups`: Flag indicating whether dynamic groups should be created (if `false`, static groups are created).
**Override Method**
```csharp
public override void Parse(ref ImportObject importObject)
```
Main entry point for parsing test setup data from the EQX file.
- Validates `FileName` and `importObject` (throws `ArgumentNullException` if `importObject` is `null`).
- Checks for presence of test setup data in `sensorImportData.GroupNameTestObjectLookup`; if missing, adds a critical error and aborts.
- Assigns group-to-object and group-to-sensor lookups from the database to `importObject`.
- Extracts setup name from XML using `ParseSetupName`, falls back to file name.
- Skips if a test setup with the same name already exists in `importObject`.
- Calls `FixCalibrations` to ensure sensors use the correct calibration from import.
- Delegates group creation to `AssignGroupsToTestSetup`.
- Cleans sensor data placeholders, clears existing sensors, adds cleaned sensors, and adds the resulting `TestTemplate` and static groups to `importObject`.
- Sets `importObject.TestSetupImportFileFormat`.
**Private Helper Methods**
```csharp
private void FixCalibrations(ImportObject importObject)
```
For each sensor in `importObject`, retrieves calibrations via `CalibrationLookup(sensor.SerialNumber)`, sorts them, and assigns the first (earliest) calibration to `sensor.Calibration`. Logs exceptions via `APILogger`.
```csharp
private Tuple<TestTemplate, List<IGroup>, List<SensorData>> AssignGroupsToTestSetup(
TestTemplate testTemplate,
ImportObject importObject,
Dictionary<string, List<string>> groupNameSensorListLookup,
IGroupImport groupImport,
IImportNotification importNotification)
```
Implements the group assignment logic (moved here per FB 36879).
- Reverses channel order using `GroupHelper.ReverseChannelOrder`.
- Calls `groupImport.GetGroupSensorLookup` to build `groupSensorLookup`.
- Normalizes sensor IDs via `GroupHelper.NormalizeSensorIds`.
- Re-applies `FixCalibrations` (to revert potential calibration resets from normalization).
- Calls `groupImport.CreateGroups(...)` to generate groups and test setup.
- Returns `Tuple<TestTemplate, List<IGroup>, List<SensorData>>`, or `null` on failure (with error reported via `importNotification`).
- Returns `null` for `testTemplate`/`staticGroups` if `groupImport.CreateGroups` returns `null`.
```csharp
private string ParseSetupName(string filename)
```
Parses the `<SetupName>` value from the first `<Fields>` element under `<Sensors>` in the EQX XML file. Returns empty string on any failure (including missing element or XML parse error).
## 3. Invariants
- **`importObject` must be non-null** at start of `Parse`; otherwise, `ArgumentNullException` is thrown.
- **`GroupNameTestObjectLookup` must be non-null and non-empty** in `sensorImportData`; otherwise, a critical error is added and parsing aborts.
- **Calibrations must be sorted before selecting the first one** in `FixCalibrations`; sorting is performed explicitly.
- **Sensors are cleared and re-added** after cleaning (`GroupHelper.CleanUneededSensorDataPlaceHolder`) to ensure consistency.
- **Test setup name uniqueness is enforced**: if a test setup with the same name already exists in `importObject.TestSetups()`, the method returns early without modifying the object.
- **`EQXGroupImport.CreateGroups` may return `null`**, in which case `AssignGroupsToTestSetup` returns a tuple of `null` values and no groups/test setup are added.
## 4. Dependencies
### Dependencies *of* this module:
- **`EQXSensorsParser`**: Must run first to populate `ImportObject.Sensors()`, `ImportObject.CalibrationsLookup()`, and `EquipmentExchange.EQXSensorDatabase` (via `EQXSensorDatabase.Read`).
- **`EquipmentExchange.EQXSensorDatabase`**: Must be pre-populated with sensor, calibration, and group mapping data from the EQX file.
- **`IGroupImport`**: Typically implemented by `EQXGroupImport`; provides `GetGroupSensorLookup` and `CreateGroups`.
- **`GroupHelper`**: Used for `ReverseChannelOrder`, `NormalizeSensorIds`, and `CleanUneededSensorDataPlaceHolder`.
- **`DbOperations`**: Referenced indirectly (e.g., `GetChannelSettingDefaults`, `TagsGet`, etc.) via `EQXGroupImport` and `EQXSensorsParser`.
- **`APILogger`**: Used for logging failures in `FixCalibrations`.
- **`StringResources`**: Used for error messages (e.g., `Import_EQXFileNotForTestSetup`).
### Dependencies *on* this module:
- **`EQXSensorsParser`**: Must be invoked before `EQXTestSetupParser` to ensure sensor and calibration data are available.
- **`ImportObject` consumers**: Any downstream logic that consumes `TestTemplate`, `StaticGroups`, or `Sensors` after import will depend on this parsers output.
## 5. Gotchas
- **Calibration resets after normalization**: `GroupHelper.NormalizeSensorIds` may reset sensor calibrations; `FixCalibrations` is called *twice* (before and after normalization) to mitigate this (see FB 44105 comment in `AssignGroupsToTestSetup`).
- **Setup name extraction is fragile**: `ParseSetupName` silently returns `string.Empty` on any XML parsing error or missing `<SetupName>` element.
- **No overwrite of existing test setups**: If a test setup with the same name already exists, `Parse` returns early without warning or modification (only silent skip).
- **Group creation may silently fail**: If `groupImport.CreateGroups` throws or returns `null`, `AssignGroupsToTestSetup` returns `null` and no groups/test setup are added, but only the exception message is reported via `importNotification.ReportErrors` (no additional context).
- **`ImportCreateDynamicGroups` flag is not used directly in this class**: It is passed to `EQXGroupImport.CreateGroups` via `EQXTestSetupParser` constructor, but the flag is stored as a property in `EQXSensorsParser`, not `EQXTestSetupParser`.
- **Excitation errors are computed but not reported**: `EQXSensorsParser.GetExcitationErrors()` collects errors but the `TODO Report the errors` comment indicates they are not currently surfaced (only in `EQXSensorsParser`, not here).
- **`SensorData` is modified in-place**: `FixCalibrations` mutates `sensor.Calibration` directly; callers must be aware of side effects.
- **No handling of duplicate sensor serial numbers**: If duplicate serial numbers exist in the import, behavior is undefined (e.g., `sensorLookup` in `EQXGroupImport` will only retain the last one).