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,182 @@
---
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-16T11:47:07.484549+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "ce57e1c33a0387ff"
---
# EQX Import Parsers Documentation
## 1. Purpose
This module provides parsing functionality for EQX (Equipment Exchange) format files, enabling import of sensor data and test setup configurations into the DTS system. It consists of three main components: `EQXSensorsParser` for parsing sensor definitions and calibrations, `EQXTestSetupParser` for constructing test setups with associated groups and channels, and `EQXGroupImport` for handling group creation and sensor-to-group mapping logic. The module bridges the proprietary EQX XML format with the internal `ImportObject` data model.
---
## 2. Public Interface
### EQXTestSetupParser
**Constructor:**
```csharp
public EQXTestSetupParser(
IImportNotification importNotification,
EqxImportOptions eqxImportOptions,
IGroupImport groupImport,
EquipmentExchange.EQXSensorDatabase eqxSensorDatabase,
bool createDynamicGroups)
```
**Public Methods:**
```csharp
public override void Parse(ref ImportObject importObject)
```
Parses the EQX file specified by `FileName` (inherited from `ParseVariantBase`) and populates the `importObject` with test setup data, groups, and sensors. Validates that the file contains test setup data (checks `GroupNameTestObjectLookup`). Aborts with a critical error if no test setup data is present.
---
### EQXGroupImport
**Implements:** `IGroupImport`
**Public Properties:**
```csharp
public ParseParameters ParseParameters { get; set; }
```
**Public Methods:**
```csharp
public Tuple<TestTemplate, List<IGroup>> CreateGroups(
List<SensorData> sensors,
Dictionary<string, List<TsetSetupImportSensorInfo>> groupSensorLookup,
TestTemplate testTemplate,
bool createDynamicGroups,
List<IGroup> staticGroups,
Action<double> setProgress)
```
Creates groups and populates a `TestTemplate` from sensor data. Returns a tuple containing the configured test template and list of static groups. Returns `null` if `groupSensorLookup` is null or empty. Groups are sorted by sensor count (descending), then by name (ascending) for tie-breaking.
```csharp
public Dictionary<string, List<TsetSetupImportSensorInfo>> GetGroupSensorLookup(
List<SensorData> sensors,
Dictionary<string, string> sensorGroupNameLookup,
Dictionary<string, List<string>> groupNameSensorListLookup)
```
Builds a lookup dictionary mapping group names to sensor information. Mutually exclusive: either `sensorGroupNameLookup` or `groupNameSensorListLookup` should be populated (per FB 30358).
---
### EQXSensorsParser
**Constructor:**
```csharp
public EQXSensorsParser(
IImportNotification importNotification,
User user,
EqxImportOptions eqxImportOptions,
EquipmentExchange.EQXSensorDatabase eqxSensorDatabase)
```
**Constants:**
```csharp
const float MAX_EQX_VERSION_SUPPORT = 1.5F;
```
**Public Properties:**
```csharp
public bool ImportCreateDynamicGroups { get; set; }
public bool EQXUseSerialNumberFieldForSN { get; set; }
public bool UseZeroForUnfiltered { get; set; }
```
**Public Methods:**
```csharp
public override void Parse(ref ImportObject importObject)
```
Parses the EQX file for sensor data. Validates XML structure and EQX format version (must be ≤ 1.5). Populates `importObject` with sensors, calibrations, and sensor model lookups.
---
## 3. Invariants
- **EQX Version Constraint:** `EQXSensorsParser` only supports EQX files with `DataFormatEdition``MAX_EQX_VERSION_SUPPORT` (1.5). Files with higher versions trigger an error and abort parsing.
- **Test Setup Presence:** `EQXTestSetupParser.Parse()` requires `GroupNameTestObjectLookup` to be non-null and non-empty. If empty, the import aborts with a critical error (`Import_EQXFileNotForTestSetup`).
- **Null Argument Handling:** Both `Parse()` methods throw `ArgumentNullException` if `importObject` is null. `EQXTestSetupParser.Parse()` returns early (no-op) if `FileName` is null or empty.
- **Calibration Sorting:** In `FixCalibrations()`, calibrations are sorted before the first one is assigned to a sensor. This implies calibrations have a defined sort order (likely by date or version).
- **Group Ordering:** In `EQXGroupImport.CreateGroups()`, groups are sorted by sensor count (descending), then alphabetically by name for equal counts.
- **Mutually Exclusive Lookups:** Per FB 30358, `GetGroupSensorLookup()` expects either `sensorGroupNameLookup` OR `groupNameSensorListLookup` to be populated, not both.
- **Sensor Uniqueness in Groups:** In `CreateGroups()`, a `HashSet<string>` (`sensorSerialHash`) ensures each sensor serial number is only counted once per group for `testGroupChannels`.
---
## 4. Dependencies
### Direct Dependencies (Imports):
**EQXTestSetupParser:**
- `DataPROWin7.DataModel` - `ImportObject`, `ImportError`, `ImportSeverityError`, `TestTemplate`, `SensorData`
- `DTS.Common.Import.ImportOptions` - `EqxImportOptions`
- `DTS.Common.Import.Parsers` - `ParseVariantBase`
- `DTS.Common.Interface.Groups.GroupList` - `IGroupImport`, `IGroup`
- `DTS.Common.SharedResource.Strings` - `StringResources`
- `DTS.Common.Utilities.Logging` - `APILogger`
- `DTS.Common.Utils` - `GroupHelper`
- `DTS.SensorDB` - `EquipmentExchange.EQXSensorDatabase`
- `System.Xml.Linq` - XML parsing
**EQXGroupImport:**
- `DataPROWin7.DataModel` - `TestTemplate`, `SensorData`, `TsetSetupImportSensorInfo`
- `DTS.Common.Classes.Groups` - Group-related classes
- `DTS.Common.Classes.Sensors` - `GroupChannel`
- `DTS.Common.Interface.Groups.GroupList` - `IGroupImport`, `IGroup`
- `DTS.Common.Interface.Channels` - `IGroupChannel`
- `DTS.Common.Storage` - `DbOperations`
- `DTS.SensorDB` - Sensor database types
**EQXSensorsParser:**
- `DTS.Common.Enums` - `BridgeType`, `SquibMeasurementType`, `ExcitationVoltageOptions`
- `DTS.Common.Import.ImportOptions` - `EqxImportOptions`
- `DTS.Common.Import.Parsers` - `ParseVariantBase`
- `DTS.Common.Storage` - `DbOperations`
- `DTS.Common.Classes.Sensors` - `FactorySensorModel`, `SensorsCollection`
- `DTS.Common.Interface.Sensors` - `ISensorData`
- `DTS.Common.SharedResource.Strings` - `StringResources`
- `DTS.Slice.Users` - `User`
- `DTS.SensorDB` - `EquipmentExchange.EQXSensorDatabase`
### Consumers:
- The module is designed to be consumed by the DTS import infrastructure via `ParseVariantBase` inheritance pattern.
- `EQXGroupImport` implements `IGroupImport`, suggesting it's injected into consumers that depend on that interface.
---
## 5. Gotchas
1. **Calibration Reset Bug (Case 44105):** `NormalizeSensorIds()` in `GroupHelper` can reset sensor calibrations. `EQXTestSetupParser.AssignGroupsToTestSetup()` calls `FixCalibrations()` after `NormalizeSensorIds()` to restore them. This is a known workaround documented in the source.
2. **Duplicate Sensor Addition:** In `EQXSensorsParser.ParseSensor()`, sensors are added to `importObject` via both `AddSensorLookup()` and `AddSensor()`. The comment "this is for compatability for import test setups" suggests legacy behavior being maintained.
3. **EID Preservation (Case 18467):** If an EQX file has a null `IDModuleString`, the parser attempts to preserve the existing EID from the sensor database to avoid wiping it out.
4. **Excitation Errors Not Reported:** `GetExcitationErrors()` collects excitation validation errors, but the method includes a `//TODO Report the errors` comment, indicating these errors may not be surfaced to users.
5. **Silent XML Parsing Failure:** `ParseSetupName()` catches all exceptions and returns `string.Empty` without logging, making setup name extraction failures invisible.
6. **Static Group Mutation:** `EQXGroupImport.CreateGroups()` modifies the `staticGroups` list parameter in-place (calls `staticGroups.Add(newGroup)`) rather than returning a new collection.
7. **Progress Callback Frequency:** In `EQXSensorsParser.ParseSensor()`, progress updates only occur every 10 iterations (`if (0 == currentDone % 10)`), which may cause UI staleness for small imports.
8. **Zero Method Hardcoded Index:** In `CreateGroups()`, zero method properties are accessed via `Methods[0]` without bounds checking, assuming at least one method exists in `ZeroMethods.Methods`.