199 lines
14 KiB
Markdown
199 lines
14 KiB
Markdown
|
|
---
|
||
|
|
source_files:
|
||
|
|
- Common/DTS.Common/Classes/Groups/GroupGRPImportError.cs
|
||
|
|
- Common/DTS.Common/Classes/Groups/GroupGRPImportGroup.cs
|
||
|
|
- Common/DTS.Common/Classes/Groups/GroupHardwareDbRecord.cs
|
||
|
|
- Common/DTS.Common/Classes/Groups/TestSetupGroupRecord.cs
|
||
|
|
- Common/DTS.Common/Classes/Groups/GroupDbRecord.cs
|
||
|
|
- Common/DTS.Common/Classes/Groups/GroupGRPImportChannel.cs
|
||
|
|
- Common/DTS.Common/Classes/Groups/ChannelDbRecord.cs
|
||
|
|
- Common/DTS.Common/Classes/Groups/GroupHelper.cs
|
||
|
|
generated_at: "2026-04-16T03:16:28.845582+00:00"
|
||
|
|
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||
|
|
schema_version: 1
|
||
|
|
sha256: "b79a1cdde998f5b5"
|
||
|
|
---
|
||
|
|
|
||
|
|
# Documentation: Groups Module
|
||
|
|
|
||
|
|
## 1. Purpose
|
||
|
|
|
||
|
|
This module provides data structures and helper utilities for representing, importing, and managing group-based test configurations—specifically those sourced from `.GRP` files (TDC format)—and their persistence in the database. It defines import-time models (`GroupGRPImportGroup`, `GroupGRPImportChannel`, `GroupGRPImportError`) for parsing and validating `.GRP` files, database record models (`GroupDbRecord`, `GroupHardwareDbRecord`, `TestSetupGroupRecord`, `ChannelDbRecord`) for ORM-style data access, and a static `GroupHelper` class to cache and manage cross-referenced metadata (e.g., static group names, DAS IDs, channel-group mappings) during runtime. The module serves as the canonical data model layer for group-centric test setups in the DTS system.
|
||
|
|
|
||
|
|
## 2. Public Interface
|
||
|
|
|
||
|
|
### `GroupGRPImportError`
|
||
|
|
|
||
|
|
- **`Errors` enum**: Defines all possible error codes during `.GRP` file import:
|
||
|
|
- `FileEmpty`, `InvalidISOCodeInput`, `InvalidFullScaleInput`, `InvalidSensorInput`, `InvalidInvertInput`, `SensorNotFound`, `InvalidInputMode`, `InvalidDefaultValue`, `InvalidActiveValue`, `InvalidFireMode`, `InvalidDelay`, `InvalidLimitDuration`, `InvalidDuration`, `InvalidCurrent`
|
||
|
|
- **Properties**:
|
||
|
|
- `Errors ErrorCode { get; set; }`: The specific error encountered.
|
||
|
|
- `string File { get; set; }`: Path or name of the `.GRP` file where the error occurred.
|
||
|
|
- `int Line { get; set; }`: Line number in the file where the error occurred.
|
||
|
|
- `string ExtraInfo { get; set; }`: Human-readable error details.
|
||
|
|
- **`override string ToString()`**: Returns `ExtraInfo`.
|
||
|
|
|
||
|
|
### `GroupGRPImportGroup`
|
||
|
|
|
||
|
|
- **Properties**:
|
||
|
|
- `bool Included { get; set; } = true`: Whether the group is included in the current import operation.
|
||
|
|
- `bool Overwrite { get; set; } = true`: Whether existing group data should be overwritten.
|
||
|
|
- `string GroupName { get; set; }`: Name of the group.
|
||
|
|
- `string GroupTags { get; set; }`: Tags associated with the group.
|
||
|
|
- `string ImportingUserTags { get; set; }`: User-provided tags during import.
|
||
|
|
- `string SourceFile { get; set; }`: Path to the source `.GRP` file.
|
||
|
|
- `GroupGRPImportChannel[] Channels { get; set; } = { }`: Array of imported channels.
|
||
|
|
- `GroupGRPImportError[] GroupErrors { get; set; } = null`: Array of errors encountered during import of the entire group.
|
||
|
|
- `bool GroupNameHasError { get; set; }`: UI hint indicating if the group name field has an error (used for visual feedback).
|
||
|
|
|
||
|
|
### `GroupHardwareDbRecord`
|
||
|
|
|
||
|
|
- **Implements**: `IGroupHardwareDbRecord`
|
||
|
|
- **Properties**:
|
||
|
|
- `int Id { get; set; }`: Primary key (database ID).
|
||
|
|
- `int GroupId { get; set; }`: Foreign key to `Group` table.
|
||
|
|
- `int DASId { get; set; }`: Foreign key to DAS (Data Acquisition System) record.
|
||
|
|
- `string SerialNumber { get; set; }`: Serial number of hardware associated with the group.
|
||
|
|
- **Constructors**:
|
||
|
|
- `GroupHardwareDbRecord()`: Default constructor.
|
||
|
|
- `GroupHardwareDbRecord(IGroupHardwareDbRecord copy)`: Copy constructor.
|
||
|
|
- `GroupHardwareDbRecord(IDataReader reader)`: Populates from database reader.
|
||
|
|
|
||
|
|
### `TestSetupGroupRecord`
|
||
|
|
|
||
|
|
- **Implements**: `ITestSetupGroupRecord`
|
||
|
|
- **Properties**:
|
||
|
|
- `int GroupId { get; set; }`: Foreign key to group.
|
||
|
|
- `int DisplayOrder { get; set; }`: Order in which the group appears in a test setup UI.
|
||
|
|
- `string Position { get; set; }`: ISO 13499 position field.
|
||
|
|
- `string TestObjectType { get; set; }`: ISO 13499 test object field.
|
||
|
|
- `int TestSetupId { get; set; }`: Foreign key to test setup.
|
||
|
|
- **Constructors**:
|
||
|
|
- `TestSetupGroupRecord()`: Default constructor.
|
||
|
|
- `TestSetupGroupRecord(IDataReader reader)`: Populates from database reader.
|
||
|
|
- `TestSetupGroupRecord(ITestSetupGroupRecord copy)`: Copy constructor.
|
||
|
|
|
||
|
|
### `GroupDbRecord`
|
||
|
|
|
||
|
|
- **Implements**: `IGroupDbRecord`
|
||
|
|
- **Properties**:
|
||
|
|
- `int Id { get; set; }`: Primary key (database ID).
|
||
|
|
- `string SerialNumber { get; set; }`: Serial number (used as group identifier).
|
||
|
|
- `string Picture { get; set; }`: Path or identifier for group image.
|
||
|
|
- `string DisplayName { get; set; }`: Human-readable name.
|
||
|
|
- `string Description { get; set; }`: Group description.
|
||
|
|
- `bool Embedded { get; set; }`: Whether the group is embedded (system-managed).
|
||
|
|
- `DateTime LastModified { get; set; }`: Timestamp of last modification.
|
||
|
|
- `string LastModifiedBy { get; set; }`: User who last modified the group.
|
||
|
|
- `int? StaticGroupId { get; set; }`: Reference to static group ID if applicable.
|
||
|
|
- `string ExtraProperties { get; set; }`: Serialized JSON of additional properties.
|
||
|
|
- **Constructors**:
|
||
|
|
- `GroupDbRecord()`: Default constructor.
|
||
|
|
- `GroupDbRecord(IGroupDbRecord copy)`: Copy constructor.
|
||
|
|
- `GroupDbRecord(IGroup copy, List<KeyValuePair<string, string>> extraProperties)`: Converts from domain `IGroup` model.
|
||
|
|
- `GroupDbRecord(IDataReader reader)`: Populates from database reader.
|
||
|
|
|
||
|
|
### `GroupGRPImportChannel`
|
||
|
|
|
||
|
|
- **Constants**:
|
||
|
|
- `SerialNumberField = 0`, `DisplayNameField = 1`, `ISOCodeField = 2`, `InvertField = 3`, `CapacityField = 4`, `InputModeField = 5`, `DefaultValueField = 6`, `ActiveValueField = 7`, `FireModeField = 8`, `DelayField = 9`, `LimitDurationField = 10`, `DurationField = 11`, `CurrentField = 12`: Field indices for parsing `.GRP` files.
|
||
|
|
- **Properties**:
|
||
|
|
- `string SensorSerialNumber { get; set; }`: Serial number of the sensor.
|
||
|
|
- `string DisplayName { get; set; }`: Channel display name.
|
||
|
|
- `string ISOCode { get; set; }`: ISO-compliant channel code.
|
||
|
|
- `bool Invert { get; set; }`: Whether the channel signal is inverted.
|
||
|
|
- `double FullScale { get; set; }`: Full-scale value (e.g., for analog channels).
|
||
|
|
- `InputModes? InputMode { get; set; } = null`: Input mode (see enum below).
|
||
|
|
- `FireModes? FireMode { get; set; } = null`: Fire mode (see enum below).
|
||
|
|
- `double? DefaultValue { get; set; } = null`: Default value (e.g., for analog channels).
|
||
|
|
- `double? ActiveValue { get; set; } = null`: Active value (e.g., trigger threshold).
|
||
|
|
- `double? Delay { get; set; } = null`: Delay before firing (seconds).
|
||
|
|
- `bool? LimitDuration { get; set; } = null`: Whether duration is limited.
|
||
|
|
- `double? Duration { get; set; } = null`: Duration of fire pulse (seconds).
|
||
|
|
- `double? Current { get; set; } = null`: Current limit for squib firing.
|
||
|
|
- `GroupGRPImportError Error { get; set; } = null`: Channel-specific import error.
|
||
|
|
- `GroupGRPImportGroup ParentGroup { get; set; }`: Parent group reference.
|
||
|
|
- `string GroupName { get; }`: Derived from `ParentGroup.GroupName`; returns `"---"` if no parent.
|
||
|
|
- **Nested Enums**:
|
||
|
|
- `InputModes`: `na`, `TLH`, `THL`, `CCNO`, `CCNC`
|
||
|
|
- `FireModes`: `na`, `CD`, `CC`
|
||
|
|
- **Constants**:
|
||
|
|
- `DefaultInputMode = InputModes.CCNO`
|
||
|
|
- `DefaultFireMode = FireModes.CD`
|
||
|
|
- `DefaultDefaultValue = 0.0`, `DefaultActiveValue = 1.0`, `DefaultDelay = 0.00`, `DefaultLimitDuration = true`, `DefaultDuration = 10.0`, `DefaultCurrent = 1.5`
|
||
|
|
- **Methods**:
|
||
|
|
- `void GroupNameInvalidate()`: Forces UI refresh for `GroupName` binding.
|
||
|
|
|
||
|
|
### `ChannelDbRecord`
|
||
|
|
|
||
|
|
- **Implements**: `IChannelDbRecord`
|
||
|
|
- **Properties**:
|
||
|
|
- `long Id { get; set; }`: Primary key (database ID).
|
||
|
|
- `int GroupId { get; set; }`: Foreign key to group.
|
||
|
|
- `string IsoCode { get; set; }`: ISO channel code.
|
||
|
|
- `string IsoChannelName { get; set; }`: ISO-compliant channel name.
|
||
|
|
- `string UserCode { get; set; }`: User-defined channel code.
|
||
|
|
- `string UserChannelName { get; set; }`: User-defined channel name.
|
||
|
|
- `int DASId { get; set; }`: Foreign key to DAS.
|
||
|
|
- `int DASChannelIndex { get; set; }`: Channel index on the DAS.
|
||
|
|
- `int GroupChannelOrder { get; set; }`: Order within the group.
|
||
|
|
- `int TestSetupOrder { get; set; }`: Order within a test setup.
|
||
|
|
- `int SensorId { get; set; }`: Foreign key to sensor.
|
||
|
|
- `bool Disabled { get; set; }`: Whether channel is disabled.
|
||
|
|
- `bool IsDisabled { get; set; }`: Backward-compatible alias for `Disabled`.
|
||
|
|
- `DateTime LastModified { get; set; }`: Timestamp of last modification.
|
||
|
|
- `string LastModifiedBy { get; set; }`: User who last modified the channel.
|
||
|
|
- **Constructors**:
|
||
|
|
- `ChannelDbRecord()`: Default constructor.
|
||
|
|
- `ChannelDbRecord(IChannelDbRecord copy)`: Copy constructor.
|
||
|
|
- `ChannelDbRecord(IDataReader reader)`: Populates from database reader.
|
||
|
|
|
||
|
|
### `GroupHelper`
|
||
|
|
|
||
|
|
- **Static utility class** (abstract, non-instantiable).
|
||
|
|
- **Methods**:
|
||
|
|
- `ClearStaticGroupNames()`, `SetStaticGroupName(int id, string name)`, `GetStaticGroupName(int id)`: Manage mapping of static group IDs to names.
|
||
|
|
- `ClearEmbeddedGroupIdList()`, `SetEmbeddedGroupId(int id)`, `IsGroupEmbedded(int id)`: Manage list of embedded group IDs.
|
||
|
|
- `ClearTestSetupGroupIds()`, `SetTestSetupGroupId(int groupId, int testSetupId)`, `GetTestSetupGroupId(int groupId)`: Map group IDs to test setup IDs.
|
||
|
|
- `ClearGroupChannelIds()`, `AddGroupChannelId(int sensorId, int groupId)`, `GetGroupIdsFromChannels(int sensorId)`: Map sensor IDs to associated group IDs.
|
||
|
|
- `ClearDASIds()`, `SetDASId(string serialNumber, int dasId)`, `GetDASId(string serialNumber)`: Map DAS serial numbers to database IDs.
|
||
|
|
- `ClearBaseModuleChannelIndexList()`, `SetBaseModuleChannelIndexList(...)`, `GetChannelIndexes(...)`: Manage channel index mappings for base/module serial number pairs.
|
||
|
|
- `ClearDASIdChannelIndexGroupIdList()`, `SetDASIdChannelIndexGroupIdList(...)`, `GetGroupIds(...)`: Map DAS ID + channel index → group ID.
|
||
|
|
- `ClearTestSetupHardwareIds()`, `AddTestSetupHardwareId(int dasId, int testSetupId)`, `GetTestSetupHardwareIds(int DASId)`: Map DAS IDs to associated test setup IDs.
|
||
|
|
- `ClearGroupHardwareIds()`, `AddGroupHardwareId(int dasId, int groupId)`, `GetGroupHardwareIds(int DASId)`: Map DAS IDs to associated group IDs.
|
||
|
|
|
||
|
|
## 3. Invariants
|
||
|
|
|
||
|
|
- **`GroupGRPImportGroup.Channels`**: Always initialized to an empty array (`{ }`), never `null`.
|
||
|
|
- **`GroupGRPImportGroup.GroupErrors`**: Initialized to `null` by default; non-null only if errors occurred during import.
|
||
|
|
- **`GroupGRPImportChannel.*` nullable properties** (e.g., `InputMode`, `DefaultValue`, `FireMode`, etc.): May be `null` if not specified in the `.GRP` file; default values are defined as constants (e.g., `DefaultInputMode`, `DefaultFireMode`, etc.).
|
||
|
|
- **`GroupDbRecord.ExtraProperties`**: Serialized as JSON using `JavaScriptSerializer`; deserialization responsibility lies with consumers.
|
||
|
|
- **`ChannelDbRecord.IsDisabled`**: Redirects to `Disabled`; both properties must be kept in sync when set via `IsDisabled`.
|
||
|
|
- **`GroupHelper` static caches**: Must be cleared between operations (e.g., import sessions) to avoid stale data; no automatic cleanup is provided.
|
||
|
|
|
||
|
|
## 4. Dependencies
|
||
|
|
|
||
|
|
### Dependencies *of* this module:
|
||
|
|
- **`DTS.Common.Base`**: Base classes (`BasePropertyChanged`) used by `GroupGRPImportGroup`, `GroupGRPImportChannel`, `GroupHardwareDbRecord`, `TestSetupGroupRecord`, `GroupDbRecord`, `ChannelDbRecord`.
|
||
|
|
- **`DTS.Common.Interface.Groups`**: Interfaces `IGroupHardwareDbRecord`, `ITestSetupGroupRecord`, `IGroupDbRecord`.
|
||
|
|
- **`DTS.Common.Interface.Channels`**: Interface `IChannelDbRecord`.
|
||
|
|
- **`System.Data`**: `IDataReader` used in record constructors.
|
||
|
|
- **`System.ComponentModel.DataAnnotations`**: `[Key]` attribute on `Id` fields.
|
||
|
|
- **`System.Web.Script.Serialization.JavaScriptSerializer`**: Used in `GroupDbRecord` constructor to serialize `ExtraProperties`.
|
||
|
|
|
||
|
|
### Dependencies *on* this module:
|
||
|
|
- **Import/Export logic**: `.GRP` file parsing and validation (not included here, but inferred from `GroupGRPImport*` classes).
|
||
|
|
- **Database layer**: `GroupDbRecord`, `ChannelDbRecord`, `GroupHardwareDbRecord`, `TestSetupGroupRecord` are used by data access layers.
|
||
|
|
- **UI layer**: `GroupGRPImportGroup.GroupNameHasError` and `GroupGRPImportChannel.GroupName` suggest binding to UI controls (e.g., textboxes, error indicators).
|
||
|
|
- **Runtime metadata management**: `GroupHelper` is used by other modules to resolve IDs, serial numbers, and mappings without repeated DB queries.
|
||
|
|
|
||
|
|
## 5. Gotchas
|
||
|
|
|
||
|
|
- **`GroupGRPImportChannel.GroupName` is a computed property**: It returns `ParentGroup.GroupName` or `"---"` if `ParentGroup` is `null`. UI bindings must be manually invalidated via `GroupNameInvalidate()` if `ParentGroup` changes after construction.
|
||
|
|
- **`IsDisabled` alias in `ChannelDbRecord`**: While `IsDisabled` redirects to `Disabled`, setting `IsDisabled` only raises `OnPropertyChanged("IsDisabled")`, not `"Disabled"`. This may cause UI binding inconsistencies if consumers bind to `"Disabled"` directly.
|
||
|
|
- **`GroupDbRecord.ExtraProperties` serialization**: Uses legacy `JavaScriptSerializer`; not compatible with modern `System.Text.Json`. Consumers must use the same serializer for round-tripping.
|
||
|
|
- **`GroupHelper` static state**: Caches are global and mutable; failure to call `Clear*()` methods between operations (e.g., import sessions) can lead to incorrect ID lookups or stale mappings.
|
||
|
|
- **`GroupHardwareDbRecord.Id` vs `GroupDbRecord.Id`**: Both use `int Id`, but `ChannelDbRecord.Id` uses `long Id`. Ensure correct type usage in queries.
|
||
|
|
- **`GroupGRPImportGroup.GroupErrors` is nullable**: Consumers must explicitly check for `null` before iterating (e.g., `?.Length` or `GroupErrors?.Any()`).
|
||
|
|
- **`GroupHelper.GetChannelIndexes` and `GetGroupIds`**: Use exact string/ID matching on nested dictionaries; performance may degrade with large datasets due to nested loops.
|
||
|
|
- **`GroupDbRecord.SerialNumber` vs `GroupName`**: In `GroupDbRecord(IGroup copy, ...)`, `SerialNumber` is set to `copy.Name`, but `DisplayName` is set separately. Ensure `Name` and `DisplayName` are distinct in the `IGroup` interface.
|