115 lines
8.1 KiB
Markdown
115 lines
8.1 KiB
Markdown
---
|
||
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 parser’s 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). |