init
This commit is contained in:
BIN
enriched-qwen3-coder-next/.DS_Store
vendored
Normal file
BIN
enriched-qwen3-coder-next/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
enriched-qwen3-coder-next/Common/.DS_Store
vendored
Normal file
BIN
enriched-qwen3-coder-next/Common/.DS_Store
vendored
Normal file
Binary file not shown.
146
enriched-qwen3-coder-next/Common/DTS.Common.CPU.md
Normal file
146
enriched-qwen3-coder-next/Common/DTS.Common.CPU.md
Normal file
@@ -0,0 +1,146 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.CPU/CPUModule.cs
|
||||
generated_at: "2026-04-16T14:12:42.546708+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "5a3256f83f5993a9"
|
||||
---
|
||||
|
||||
# Documentation: DTS.Common.CPU Module
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module serves as a Prism-based plugin module for CPU-related functionality within the DTS application framework. It registers the `CPUEngine` implementation with the Unity dependency injection container and provides assembly metadata (name and image) used by the main application shell to display available components. The module follows the Prism modularity pattern, allowing it to be dynamically loaded and initialized at runtime.
|
||||
|
||||
---
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### CPUModule Class
|
||||
|
||||
**Signature:**
|
||||
```csharp
|
||||
[Export(typeof(IModule))]
|
||||
[Module(ModuleName = "CPU")]
|
||||
public class CPUModule : IModule
|
||||
```
|
||||
|
||||
**Constructor:**
|
||||
```csharp
|
||||
public CPUModule(IUnityContainer unityContainer)
|
||||
```
|
||||
Accepts an `IUnityContainer` instance via constructor injection and stores it in a private readonly field `_unityContainer`.
|
||||
|
||||
**Methods:**
|
||||
```csharp
|
||||
public void Initialize()
|
||||
```
|
||||
Registers `ICPUEngine` mapped to `CPUEngine` with the Unity container. Contains a commented-out registration for `IPropertyViewModel` mapped to `PropertyViewModel`.
|
||||
|
||||
---
|
||||
|
||||
### CPUNameAttribute Class
|
||||
|
||||
**Signature:**
|
||||
```csharp
|
||||
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
|
||||
public class CPUNameAttribute : TextAttribute
|
||||
```
|
||||
|
||||
**Constructors:**
|
||||
```csharp
|
||||
public CPUNameAttribute()
|
||||
public CPUNameAttribute(string s)
|
||||
```
|
||||
Both constructors initialize `_assemblyName` to the hardcoded string `"CPUAsssembly"`.
|
||||
|
||||
**Properties:**
|
||||
```csharp
|
||||
public override string AssemblyName { get; }
|
||||
```
|
||||
Returns `_assemblyName` (value: `"CPUAsssembly"`).
|
||||
|
||||
**Methods:**
|
||||
```csharp
|
||||
public override Type GetAttributeType()
|
||||
public override string GetAssemblyName()
|
||||
```
|
||||
`GetAttributeType()` returns `typeof(TextAttribute)`. `GetAssemblyName()` returns the `AssemblyName` property value.
|
||||
|
||||
---
|
||||
|
||||
### CUPImageAttribute Class
|
||||
|
||||
**Signature:**
|
||||
```csharp
|
||||
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
|
||||
public class CUPImageAttribute : ImageAttribute
|
||||
```
|
||||
|
||||
**Constructors:**
|
||||
```csharp
|
||||
public CUPImageAttribute()
|
||||
public CUPImageAttribute(string s)
|
||||
```
|
||||
Both constructors initialize `_img` by calling `AssemblyInfo.GetImage(AssemblyNames.CPU.ToString())`.
|
||||
|
||||
**Properties:**
|
||||
```csharp
|
||||
public override BitmapImage AssemblyImage { get; }
|
||||
public override string AssemblyName { get; }
|
||||
public override string AssemblyGroup { get; }
|
||||
public override eAssemblyRegion AssemblyRegion { get; }
|
||||
```
|
||||
- `AssemblyImage`: Lazily initializes and returns a `BitmapImage` from `AssemblyInfo.GetImage()`.
|
||||
- `AssemblyName`: Returns `AssemblyNames.CPU.ToString()`.
|
||||
- `AssemblyGroup`: Returns `eAssemblyGroups.Viewer.ToString()`.
|
||||
- `AssemblyRegion`: Returns `eAssemblyRegion.NotAssigned`.
|
||||
|
||||
**Methods:**
|
||||
```csharp
|
||||
public override Type GetAttributeType()
|
||||
public override BitmapImage GetAssemblyImage()
|
||||
public override string GetAssemblyName()
|
||||
public override eAssemblyRegion GetAssemblyRegion()
|
||||
public override string GetAssemblyGroup()
|
||||
```
|
||||
All return their corresponding property values. `GetAttributeType()` returns `typeof(ImageAttribute)`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- The `_unityContainer` field is initialized only once via constructor injection and is never null after construction (assuming the DI container provides a valid instance).
|
||||
- `CPUNameAttribute` and `CUPImageAttribute` are applied at the assembly level with `AllowMultiple = false`, meaning only one instance of each should exist per assembly.
|
||||
- The `AssemblyName` property in `CPUNameAttribute` always returns `"CPUAsssembly"` regardless of constructor arguments.
|
||||
- The `AssemblyGroup` in `CUPImageAttribute` is always `eAssemblyGroups.Viewer`.
|
||||
- The `AssemblyRegion` in `CUPImageAttribute` is always `eAssemblyRegion.NotAssigned`.
|
||||
|
||||
---
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### This module depends on:
|
||||
- `System.Windows.Media.Imaging` — For `BitmapImage` type.
|
||||
- `System.ComponentModel.Composition` — For MEF `[Export]` attribute.
|
||||
- `Microsoft.Practices.Prism.Modularity` — For `IModule` interface and `[Module]` attribute.
|
||||
- `Microsoft.Practices.Unity` — For `IUnityContainer` interface.
|
||||
- `DTS.Common.Interface` — For `TextAttribute`, `ImageAttribute`, `ICPUEngine`, `AssemblyInfo`, `AssemblyNames`, `eAssemblyGroups`, and `eAssemblyRegion` (inferred from usage).
|
||||
|
||||
### What depends on this module:
|
||||
- Cannot be determined from this source file alone. Likely consumed by a main application shell that scans for Prism modules and displays assembly metadata.
|
||||
|
||||
---
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
1. **Typo in class name**: `CUPImageAttribute` appears to be a typo for `CPUImageAttribute`. The assembly attribute at line 9 is `[assembly: CUPImage()]` which matches this typo.
|
||||
|
||||
2. **Typo in assembly name string**: `CPUNameAttribute` hardcodes `_assemblyName = "CPUAsssembly"` (note the double 's'). This may cause display issues or lookup failures if other code expects `"CPUAssembly"`.
|
||||
|
||||
3. **Ignored constructor parameter**: Both attribute classes accept a `string s` parameter in their constructors but completely ignore it, always using hardcoded values instead.
|
||||
|
||||
4. **Commented-out registration**: The `Initialize()` method contains a commented-out registration for `IPropertyViewModel`. It is unclear whether this is intentional tech debt or deprecated functionality.
|
||||
|
||||
5. **Side effect in property getter**: The `AssemblyImage` property getter has a side effect—it assigns to `_img` before returning. This is unusual for a property getter and could cause unexpected behavior if the property is accessed multiple times.
|
||||
97
enriched-qwen3-coder-next/Common/DTS.Common.CPU/Classes.md
Normal file
97
enriched-qwen3-coder-next/Common/DTS.Common.CPU/Classes.md
Normal file
@@ -0,0 +1,97 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.CPU/Classes/BREngine.cs
|
||||
- Common/DTS.Common.CPU/Classes/CPUEngine.cs
|
||||
generated_at: "2026-04-16T03:28:53.637809+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "66174fba615f1ce2"
|
||||
---
|
||||
|
||||
# Classes
|
||||
|
||||
## Documentation: `CPUEngine` Module
|
||||
|
||||
---
|
||||
|
||||
### 1. **Purpose**
|
||||
|
||||
The `CPUEngine` class serves as a core infrastructure component responsible for managing cross-cutting concerns in the CPU-related domain of the DTS system—specifically, event-driven UI notifications and status updates via Prism’s interaction patterns and event aggregation. It acts as a bridge between internal system events (e.g., status changes, notifications) and UI-level interaction requests, enabling decoupled communication between backend logic and the presentation layer. It does *not* implement CPU-specific computation logic (as suggested by the empty `BREngine` class), but rather provides a reusable base for UI interaction coordination within the CPU domain.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
|
||||
#### `CPUEngine()`
|
||||
- **Signature**: `public CPUEngine()`
|
||||
- **Behavior**: Constructor. Initializes Prism dependencies (`IUnityContainer`, `IEventAggregator`, `IServiceLocator`) via the current `ServiceLocator`. Registers handlers for `RaiseNotification` and `ShowStatus` events. Instantiates `NotificationRequest` and `ConfirmationRequest` interaction requests.
|
||||
|
||||
#### `NotificationRequest`
|
||||
- **Signature**: `public InteractionRequest<Notification> NotificationRequest { get; private set; }`
|
||||
- **Behavior**: Exposes a Prism `InteractionRequest` for displaying notifications (e.g., informational popups). Triggered internally via `OnRaiseNotification` when a `RaiseNotification` event is published.
|
||||
|
||||
#### `ConfirmationRequest`
|
||||
- **Signature**: `public new InteractionRequest<Confirmation> ConfirmationRequest { get; private set; }`
|
||||
- **Behavior**: Exposes a Prism `InteractionRequest` for confirmation dialogs (e.g., yes/no prompts). *Currently unused*—no code raises this request.
|
||||
|
||||
#### `OnPropertyChanged(string propertyName)`
|
||||
- **Signature**: `public void OnPropertyChanged(string propertyName)`
|
||||
- **Behavior**: Raises the `PropertyChanged` event for data binding (implements `INotifyPropertyChanged` via `ICPUEngine`). Used to notify UI of property changes.
|
||||
|
||||
#### `PropertyChanged`
|
||||
- **Signature**: `public new event PropertyChangedEventHandler PropertyChanged;`
|
||||
- **Behavior**: Standard .NET event for property change notifications. Overridden from base interface `ICPUEngine`.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
|
||||
- **Event Subscription Consistency**: Upon construction, `_eventAggregator` *must* successfully resolve `IEventAggregator` and subscribe to `RaiseNotification` and `ShowStatus` events. Failure to do so would break notification/status handling.
|
||||
- **Service Locator Dependency**: The class *requires* that `ServiceLocator.Current` is set and returns a valid `IServiceLocator` containing registered implementations for `IUnityContainer`, `IServiceLocator`, and `IEventAggregator`. If not, constructor throws.
|
||||
- **Notification Payload Transformation**: When handling `RaiseNotification`, the internal `NotificationContentEventArgs` is *always* transformed into a `NotificationContentEventArgs` (note: same name, likely a typo—see *Gotchas*) with `Title` extracted separately. The `Content` of the `Notification` object is *always* a `NotificationContentEventArgs` (without title), and `Title` is taken from the event args.
|
||||
- **No-op Status Handler**: `OnStatusChange` is currently commented out—no status update logic is active. Thus, `IsBusy`, `IsBusyMessage`, and related properties (if any) are *not* updated.
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
|
||||
#### **External Dependencies (Imports/Usings)**
|
||||
- **Prism Libraries**:
|
||||
- `Microsoft.Practices.Prism.Events` (`IEventAggregator`, `RaiseNotification`, `ShowStatus`)
|
||||
- `Microsoft.Practices.Prism.Interactivity.InteractionRequest` (`InteractionRequest<T>`, `Notification`, `Confirmation`)
|
||||
- `Microsoft.Practices.Prism.Regions` (`IRegionManager`)
|
||||
- `Microsoft.Practices.Unity` (`IUnityContainer`)
|
||||
- `Microsoft.Practices.ServiceLocation` (`IServiceLocator`)
|
||||
- **DTS Internal Libraries**:
|
||||
- `DTS.Common.Events` (`RaiseNotification`, `ShowStatus`, `StatusInfo`, `NotificationContentEventArgs`)
|
||||
- `DTS.Common.Interface` (`ICPUEngine`)
|
||||
- `DTS.Common.Base` (likely contains base types like `NotificationContentEventArgs`)
|
||||
|
||||
#### **Internal Dependencies**
|
||||
- **Consumers**: Any module needing to trigger notifications or status updates can publish `RaiseNotification` or `ShowStatus` events via `_eventAggregator`.
|
||||
- **Consumed By**: UI layers (e.g., views/view models) that bind to `NotificationRequest`/`ConfirmationRequest` for modal dialogs.
|
||||
|
||||
#### **Required Services in Container**
|
||||
- `IUnityContainer`
|
||||
- `IServiceLocator`
|
||||
- `IEventAggregator`
|
||||
- `IRegionManager` (declared but unused in current implementation)
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
|
||||
- **`new` Keyword on `IRegionManager`**: `_regionManager` is declared as `private new IRegionManager _regionManager;` but is *never assigned or used*. This suggests incomplete refactoring or legacy code.
|
||||
- **`NotificationContentEventArgs` Ambiguity**:
|
||||
- In `OnRaiseNotification`, a new `NotificationContentEventArgs` is constructed from `eventArgsWithTitle.Message`, `MessageDetails`, and `Image`.
|
||||
- However, the source does not define whether `NotificationContentEventArgs` has a constructor accepting these parameters—nor is there a `NotificationContentEventArgsWithoutTitle` type (mentioned in the comment) referenced elsewhere. This implies either:
|
||||
- A missing type definition,
|
||||
- Or a naming collision (same class name used for two purposes),
|
||||
- Or a typo (e.g., `NotificationContentEventArgsWithoutTitle` should be `NotificationContentEventArgs`).
|
||||
- **Critical risk**: If `NotificationContentEventArgs` lacks the expected constructor, runtime exceptions occur.
|
||||
- **`ShowStatus` Handler is Dead Code**: `OnStatusChange` is fully commented out. If status tracking is expected, this is a functional gap.
|
||||
- **No `ConfirmationRequest` Usage**: `ConfirmationRequest` is instantiated but never raised—either unused or intended for future implementation.
|
||||
- **`ICPUEngine` Contract Unknown**: Since `ICPUEngine` is not provided, we cannot verify if `OnPropertyChanged` and `PropertyChanged` are correctly implemented per interface expectations (e.g., `new` keyword usage may conflict with interface implementation).
|
||||
- **No Null Checks**: `ServiceLocator.Current` and `_unityContainer.Resolve<T>()` calls lack null/error handling—could throw if services are missing.
|
||||
|
||||
> **Note**: No CPU-specific logic (e.g., instruction execution, register management) is present. The class name `CPUEngine` is likely a domain label, not a functional description.
|
||||
115
enriched-qwen3-coder-next/Common/DTS.Common.CPU/Properties.md
Normal file
115
enriched-qwen3-coder-next/Common/DTS.Common.CPU/Properties.md
Normal file
@@ -0,0 +1,115 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.CPU/Properties/AssemblyInfo.cs
|
||||
- Common/DTS.Common.CPU/Properties/Annotations.cs
|
||||
generated_at: "2026-04-16T03:29:08.777780+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "2ecad58ebc9f0db4"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## Documentation: `DTS.Common.CPU.Annotations` Namespace
|
||||
|
||||
### 1. Purpose
|
||||
This module provides a comprehensive set of JetBrains-style code annotation attributes for use in static analysis (e.g., by ReSharper or Rider) to improve nullability, contract, and usage intent expressiveness in C# code. It does not contain executable logic or business functionality; rather, it serves as a *metadata layer* to guide compiler/tooling behavior and human understanding of API contracts. The attributes are applied via attributes on types, methods, parameters, and properties to convey semantic constraints (e.g., nullability, immutability, usage patterns) that static analyzers interpret to generate warnings or suggestions.
|
||||
|
||||
### 2. Public Interface
|
||||
All types reside in the `DTS.Common.CPU.Annotations` namespace. All attributes are `sealed` and inherit from `Attribute`. Below are the key public types:
|
||||
|
||||
#### Core Nullability Annotations
|
||||
- **`CanBeNullAttribute`**
|
||||
Indicates the marked element *may* be `null`. Applies to methods, parameters, properties, fields, events, delegates, classes, interfaces, and generic parameters.
|
||||
- **`NotNullAttribute`**
|
||||
Indicates the marked element *must never* be `null`. Applies to the same targets as `CanBeNullAttribute`.
|
||||
- **`ItemCanBeNullAttribute`**
|
||||
For `IEnumerable<T>`, `Task<T>`, or `Lazy<T>`: indicates the *item/result/value* may be `null`.
|
||||
- **`ItemNotNullAttribute`**
|
||||
For `IEnumerable<T>`, `Task<T>`, or `Lazy<T>`: indicates the *item/result/value* is guaranteed non-null.
|
||||
- **`ImplicitNotNullAttribute`**
|
||||
Applies to types or assemblies: implicitly enforces `[NotNull]`/`[ItemNotNull]` on all members within scope.
|
||||
|
||||
#### Contract & Behavior Annotations
|
||||
- **`StringFormatMethodAttribute(string formatParameterName)`**
|
||||
Marks a method as building a string from a format string (like `string.Format`). `formatParameterName` specifies which parameter holds the format string.
|
||||
- **`ValueProviderAttribute(string name)`**
|
||||
Indicates a parameter/property/field must be one of a limited set of values, defined by fields of the type specified by `name`.
|
||||
- **`InvokerParameterNameAttribute`**
|
||||
For parameters expected to be string literals matching a caller’s parameter name (e.g., `ArgumentNullException` parameter).
|
||||
- **`NotifyPropertyChangedInvocatorAttribute(string parameterName = null)`**
|
||||
Marks methods used to notify property changes (e.g., `INotifyPropertyChanged`). Supports `NotifyChanged(string)`, `NotifyChanged(params string[])`, expression-based overloads, and `SetProperty` patterns.
|
||||
- **`ContractAnnotationAttribute(string contract, bool forceFullStates = false)`**
|
||||
Declares input-output dependencies (e.g., `"s:null => true"`, `"null => null; notnull => notnull"`). Supports multiple instances per method.
|
||||
- **`MustUseReturnValueAttribute(string justification = null)`**
|
||||
Indicates the return value of a method *must* be used.
|
||||
- **`PureAttribute`**
|
||||
Indicates the method has no observable side effects (like `System.Diagnostics.Contracts.PureAttribute`).
|
||||
- **`InstantHandleAttribute`**
|
||||
For delegate/`IEnumerable` parameters: indicates the parameter is used *immediately* within the method (e.g., executed or enumerated synchronously).
|
||||
- **`ProvidesContextAttribute`**
|
||||
Marks a member as the canonical source for a context value (e.g., a service instance).
|
||||
- **`CollectionAccessAttribute(CollectionAccessType type)`**
|
||||
Describes how a method/constructor/property affects a collection’s content. `CollectionAccessType` values:
|
||||
- `None` (0)
|
||||
- `Read` (1)
|
||||
- `ModifyExistingContent` (2)
|
||||
- `UpdatedContent` (7 = `ModifyExistingContent | 4`)
|
||||
- **`AssertionMethodAttribute`** + **`AssertionConditionAttribute(AssertionConditionType)`**
|
||||
Marks assertion methods (e.g., `Guard.NotNull`). `AssertionConditionType` values: `IS_TRUE`, `IS_FALSE`, `IS_NULL`, `IS_NOT_NULL`.
|
||||
- **`LinqTunnelAttribute`**
|
||||
Marks pure LINQ methods to enable `InstantHandle` inference for delegate parameters in chains.
|
||||
- **`NoEnumerationAttribute`**
|
||||
Indicates an `IEnumerable` parameter is *not* enumerated.
|
||||
- **`LocalizationRequiredAttribute(bool required = true)`**
|
||||
Marks elements requiring localization.
|
||||
- **`CannotApplyEqualityOperatorAttribute`**
|
||||
Indicates `==`/`!=` operators are invalid for the type (except `null` comparisons).
|
||||
- **`UsedImplicitlyAttribute(ImplicitUseKindFlags, ImplicitUseTargetFlags)`** + **`MeansImplicitUseAttribute(...)`**
|
||||
Marks symbols used implicitly (e.g., via reflection) to suppress unused warnings. `ImplicitUseKindFlags`: `Access`, `Assign`, `InstantiatedWithFixedConstructorSignature`, `InstantiatedNoFixedConstructorSignature`. `ImplicitUseTargetFlags`: `Itself`, `Members`, `WithMembers`.
|
||||
- **`PublicAPIAttribute(string comment = null)`**
|
||||
Marks publicly exposed API that must not be removed. Internally uses `[MeansImplicitUse(ImplicitUseTargetFlags.WithMembers)]`.
|
||||
- **`SourceTemplateAttribute`** + **`MacroAttribute`**
|
||||
Marks extension methods as source templates for IDE expansion (e.g., `forEach` snippets).
|
||||
- **`PathReferenceAttribute(string basePath = null)`**
|
||||
Indicates a parameter is a file/folder path in a web project.
|
||||
|
||||
#### ASP.NET MVC & Razor-Specific Annotations
|
||||
- **`AspMvc*Attribute`** (e.g., `AspMvcActionAttribute`, `AspMvcAreaAttribute`, `AspMvcControllerAttribute`, `AspMvcViewAttribute`, `AspMvcSuppressViewErrorAttribute`, etc.)
|
||||
Marks parameters/methods for MVC/Razor view resolution (e.g., action names, areas, controllers, views). Many have optional `anonymousProperty` constructor.
|
||||
- **`AspChildControlTypeAttribute(string tagName, Type controlType)`**
|
||||
Specifies child control types for ASP.NET server controls.
|
||||
- **`AspDataFieldAttribute`**, **`AspDataFieldsAttribute`**, **`AspMethodPropertyAttribute`**, **`AspRequiredAttributeAttribute(string attribute)`**, **`AspTypePropertyAttribute(bool createConstructorReferences)`**
|
||||
ASP.NET-specific metadata for data binding and property resolution.
|
||||
- **`Razor*Attribute`** (e.g., `RazorSectionAttribute`, `RazorImportNamespaceAttribute`, `RazorInjectionAttribute`, `RazorDirectiveAttribute`, `RazorWriteLiteralMethodAttribute`, `RazorWriteMethodAttribute`, `RazorHelperCommonAttribute`, `RazorLayoutAttribute`)
|
||||
Razor view engine metadata for section resolution, imports, and helper methods.
|
||||
- **`XamlItemsControlAttribute`** + **`XamlItemBindingOfItemsControlAttribute`**
|
||||
XAML binding context resolution for `ItemsControl`-derived types.
|
||||
|
||||
#### Utility
|
||||
- **`NoReorder`**
|
||||
Prevents IDE member reordering for the marked class.
|
||||
|
||||
### 3. Invariants
|
||||
- **No runtime behavior**: All attributes are metadata-only. They have no effect at runtime unless consumed by tooling (e.g., ReSharper, analyzers).
|
||||
- **Attribute targets**: Each attribute’s `AttributeUsage` is strictly defined (e.g., `CanBeNullAttribute` targets methods, parameters, properties, etc.). Applying to an unsupported target is a compile-time error.
|
||||
- **Nullability semantics**: `[NotNull]` and `[CanBeNull]` are mutually exclusive for the same element. Tooling expects consistency; mixing them may cause conflicting warnings.
|
||||
- **ContractAnnotation syntax**: The `contract` string must follow the specified FDT (Function Definition Table) syntax. Invalid syntax may cause analyzer errors or ignored annotations.
|
||||
- **`StringFormatMethodAttribute`**: The `formatParameterName` must match an actual parameter name; otherwise, tooling may produce false warnings.
|
||||
- **`AssertionConditionAttribute`**: Only valid on parameters of methods marked with `[AssertionMethod]`.
|
||||
|
||||
### 4. Dependencies
|
||||
- **No external dependencies**: This module is self-contained. It uses only `System` and `System.Runtime.CompilerServices` (via attributes like `AttributeUsage`).
|
||||
- **Consumers**: Any project referencing `DTS.Common.CPU` can use these annotations. They are intended for use in *other* modules within the `DTS.Common.*` family (e.g., `DTS.Common.CPU` itself likely consumes them, though not visible in the provided files).
|
||||
- **Tooling dependency**: Full benefit requires ReSharper/Rider or compatible analyzers (e.g., JetBrains.Annotations NuGet package). Without tooling, attributes are inert.
|
||||
|
||||
### 5. Gotchas
|
||||
- **`AssemblyInfo.cs` is metadata-only**: The assembly version (`1.0.0.0`) and GUID (`a68ef337-debf-4265-8dec-8acf01e76ee6`) are fixed and should not be changed without coordination.
|
||||
- **`Annotations.cs` is a copy of JetBrains.Annotations**: This is a vendored copy of JetBrains’ annotation definitions (MIT-licensed). Do *not* modify it unless aligning with upstream changes.
|
||||
- **`[Obsolete]` on `TerminatesProgramAttribute`**: The `TerminatesProgramAttribute` is deprecated in favor of `[ContractAnnotation("=> halt")]`. Using it will trigger an obsolete warning.
|
||||
- **`AspMvc*` attributes are framework-specific**: These only make sense in ASP.NET MVC/Razor contexts. Using them in non-MVC projects may confuse tooling without benefit.
|
||||
- **`SourceTemplate`/`Macro` require IDE support**: These attributes only function in IDEs that support template expansion (e.g., ReSharper). They are ignored in standard compilation.
|
||||
- **`ImplicitUse*` flags are subtle**: Misusing `ImplicitUseKindFlags` (e.g., omitting `InstantiatedNoFixedConstructorSignature` when constructors are used reflectively) may cause false "unused constructor" warnings.
|
||||
- **No runtime validation**: Attributes like `[NotNull]` do *not* enforce null checks at runtime. Developers must still write defensive code.
|
||||
|
||||
None identified beyond what is apparent from the source.
|
||||
114
enriched-qwen3-coder-next/Common/DTS.Common.Calculations.md
Normal file
114
enriched-qwen3-coder-next/Common/DTS.Common.Calculations.md
Normal file
@@ -0,0 +1,114 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Calculations/ChannelData.cs
|
||||
- Common/DTS.Common.Calculations/Integral.cs
|
||||
- Common/DTS.Common.Calculations/Resultant.cs
|
||||
- Common/DTS.Common.Calculations/HeadInjuryCriterion.cs
|
||||
generated_at: "2026-04-16T14:13:55.996245+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "2d2deac012cb62cf"
|
||||
---
|
||||
|
||||
# DTS.Common.Calculations Module Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides mathematical calculation utilities for signal processing in biomechanical analysis contexts. It contains data structures for holding filtered channel data (`ChannelData`), numerical integration via trapezoidal summation (`Integral`), resultant vector computation from multiple input channels (`Resultant`), and Head Injury Criterion (HIC) calculation used in impact testing scenarios (`HeadInjuryCriterion`). The module is designed to work with pre-filtered engineering unit data sampled at consistent rates.
|
||||
|
||||
---
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `ChannelData` (Class)
|
||||
**Namespace:** `DTS.Common.Calculations`
|
||||
|
||||
Simple data container for filtered channel data.
|
||||
|
||||
| Member | Signature | Description |
|
||||
|--------|-----------|-------------|
|
||||
| `Units` | `public string Units { get; }` | Read-only engineering units of the data. Set via constructor. |
|
||||
| `FilteredEU` | `public double[] FilteredEU { get; set; }` | Pre-filtered engineering unit data array. Mutable. |
|
||||
| Constructor | `public ChannelData(string units)` | Constructs a new `ChannelData` instance with the specified units. `FilteredEU` is not initialized by constructor. |
|
||||
|
||||
---
|
||||
|
||||
### `Integral` (Static Class)
|
||||
**Namespace:** `DTS.Common.Calculations`
|
||||
|
||||
| Method | Signature | Description |
|
||||
|--------|-----------|-------------|
|
||||
| `DefiniteIntegral` | `public static double DefiniteIntegral(double[] input, int start, int end, double SPS)` | Computes the definite integral of `input` from index `start` to `end` (both inclusive) using trapezoidal summation. `SPS` is samples per second (divisor for time normalization). |
|
||||
|
||||
---
|
||||
|
||||
### `Resultant` (Static Class)
|
||||
**Namespace:** `DTS.Common.Calculations`
|
||||
|
||||
| Method | Signature | Description |
|
||||
|--------|-----------|-------------|
|
||||
| `GenerateResultantChannel` | `public static ChannelData GenerateResultantChannel(List<ChannelData> channels)` | Computes the resultant vector from multiple input channels using sum-of-squares: `√(Σ ch[i]²)`. Returns a new `ChannelData` with the resultant values. Units are taken from the first input channel. |
|
||||
|
||||
---
|
||||
|
||||
### `HeadInjuryCriterion` (Static Class)
|
||||
**Namespace:** `DTS.Common.Calculations`
|
||||
|
||||
| Method | Signature | Description |
|
||||
|--------|-----------|-------------|
|
||||
| `GetHeadInjuryCriterion` | `public static HICResult GetHeadInjuryCriterion(ChannelData resultant, double SPS, int clipLengthMS)` | Calculates the maximum Head Injury Criterion over the input data for the specified clip length. Uses brute-force exhaustive search across all clip lengths from 1 sample up to `clipLengthMS`. |
|
||||
|
||||
#### `HeadInjuryCriterion.HICResult` (Nested Class)
|
||||
|
||||
| Member | Signature | Description |
|
||||
|--------|-----------|-------------|
|
||||
| `StartSample` | `public int StartSample { get; }` | Start sample index of the maximum HIC window. |
|
||||
| `EndSample` | `public int EndSample { get; }` | End sample index of the maximum HIC window. |
|
||||
| `HicLengthMS` | `public int HicLengthMS { get; }` | Length of the HIC window in milliseconds. |
|
||||
| `HIC` | `public double HIC { get; }` | The calculated HIC value. |
|
||||
| Constructor | `public HICResult(double hic, int hicLength, int startSample, int endSample)` | Constructs a new `HICResult`. Note: parameter order is `hic`, `hicLength`, `startSample`, `endSample`. |
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **`ChannelData.Units`** is immutable after construction; it can only be set via the constructor.
|
||||
- **`ChannelData.FilteredEU`** is not initialized by the constructor and must be set before use.
|
||||
- **`Integral.DefiniteIntegral`** assumes input data is tightly time-aligned (uniform sampling interval).
|
||||
- **`Resultant.GenerateResultantChannel`** requires all input channels to have identical `FilteredEU.Length` values.
|
||||
- **`Resultant.GenerateResultantChannel`** requires all input channels to have identical `Units` values.
|
||||
- **`HeadInjuryCriterion.GetHeadInjuryCriterion`** requires `SPS > 0` and `clipLengthMS > 0`.
|
||||
- **`HeadInjuryCriterion.GetHeadInjuryCriterion`** requires `resultant.FilteredEU.Length` to be at least as many samples as `clipLengthMS` represents at the given `SPS`.
|
||||
|
||||
---
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### This module depends on:
|
||||
- `System` (for `Math`, `Convert`, `DateTime`-related types)
|
||||
- `System.Collections.Generic` (for `List<T>`)
|
||||
- `System.Linq` (for `Distinct()`, `Max()`, `First()`, `Select()`)
|
||||
- `System.Diagnostics` (for `Trace.Assert`)
|
||||
|
||||
### What depends on this module:
|
||||
- **Unclear from source alone** — no internal module references indicate consumers. This appears to be a low-level calculation library intended for use by higher-level analysis or data processing modules.
|
||||
|
||||
---
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
1. **`HICResult` constructor parameter order differs from property order**: The constructor signature is `(double hic, int hicLength, int startSample, int endSample)`, but the XML documentation comments incorrectly describe the parameters in a different order. The actual parameter mapping is:
|
||||
- `hic` → `HIC`
|
||||
- `hicLength` → `HicLengthMS`
|
||||
- `startSample` → `StartSample`
|
||||
- `endSample` → `EndSample`
|
||||
|
||||
2. **Assertions in production code**: Both `Resultant.GenerateResultantChannel` and `HeadInjuryCriterion.GetHeadInjuryCriterion` use `System.Diagnostics.Trace.Assert` for input validation. These assertions may not throw exceptions in release builds depending on configuration, potentially allowing invalid states to propagate silently.
|
||||
|
||||
3. **Brute-force HIC algorithm**: `GetHeadInjuryCriterion` uses an O(n²) brute-force approach, recalculating integrals exhaustively. The source explicitly acknowledges this inefficiency with a comment: *"we can do this much better without a doubt, but lets get the first method done (brute force)"*.
|
||||
|
||||
4. **`ChannelData.FilteredEU` is unset after construction**: The constructor only sets `Units`. Callers must manually assign `FilteredEU` after instantiation, or the property will be `null`.
|
||||
|
||||
5. **`Integral.DefiniteIntegral` boundary behavior**: The loop iterates from `start + 1` to `end - 1` (exclusive of `end`), then adds `input[start]` and `input[end]` separately. This is correct trapezoidal integration but may be counterintuitive compared to typical half-open interval patterns in C#.
|
||||
|
||||
6. **Future parallelization comment in `Resultant`**: The source contains a comment indicating intent to parallelize the loop in a future version, noting that `values.Add` would need to be replaced with an indexer. Current implementation is single-threaded.
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Calculations/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T03:31:32.903407+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "c147c56cfcc8d0da"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## 1. Purpose
|
||||
This module is the `DTS.Common.Calculations` assembly, specifically titled *HeadInjuryCriterion*, and serves as a dedicated library for computing head injury metrics—most likely the Head Injury Criterion (HIC), a standard biomechanical measure used in automotive safety and crash analysis to assess the risk of head trauma from impact events. Its role is to encapsulate calculation logic for this criterion, likely operating on time-series acceleration data (e.g., from crash test dummies), and expose it as reusable components for downstream safety assessment systems.
|
||||
|
||||
## 2. Public Interface
|
||||
**No public API surface is exposed in this file.**
|
||||
This file (`AssemblyInfo.cs`) is purely metadata for the .NET assembly and contains *no* type declarations, classes, methods, or functions. All public interfaces (e.g., classes like `HicCalculator`, methods, constants) would reside in other source files (e.g., `.cs` files in the same project), which are not provided here. Therefore, no public interface entries can be documented from this source alone.
|
||||
|
||||
## 3. Invariants
|
||||
**None applicable.**
|
||||
This file contains only assembly-level metadata attributes and does not define logic, state, or behavior. Consequently, no runtime invariants, validation rules, or ordering guarantees can be inferred from this file.
|
||||
|
||||
## 4. Dependencies
|
||||
**Dependencies of this assembly (from imports/includes):**
|
||||
- `System.Reflection`
|
||||
- `System.Runtime.CompilerServices`
|
||||
- `System.Runtime.InteropServices`
|
||||
These are standard .NET framework namespaces used for reflection, compiler services, and COM interop. No external or third-party dependencies are evident from this file.
|
||||
|
||||
**Dependents (inferred):**
|
||||
This assembly is referenced by its title *HeadInjuryCriterion*, suggesting it is consumed by other modules in the DTS (likely *DTS* = *Data Transfer System* or similar domain-specific name) ecosystem—e.g., safety analysis or simulation tools that require HIC computation. However, the actual consumers are not visible in this file and must be determined via external dependency analysis (e.g., project references in the solution).
|
||||
|
||||
## 5. Gotchas
|
||||
**None identified from source alone.**
|
||||
The file is standard boilerplate for a .NET assembly and reveals no behavioral quirks, legacy workarounds, or non-obvious constraints. Potential gotchas (e.g., HIC calculation specifics, data format expectations, numerical precision issues) would reside in the *implementation* files (e.g., `HicCalculator.cs`), which are not included here.
|
||||
63
enriched-qwen3-coder-next/Common/DTS.Common.Core.md
Normal file
63
enriched-qwen3-coder-next/Common/DTS.Common.Core.md
Normal file
@@ -0,0 +1,63 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Core/DTSConstants.cs
|
||||
generated_at: "2026-04-16T14:07:39.111868+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "481b6b8f305c2ca6"
|
||||
---
|
||||
|
||||
# Documentation: DTSConstants.cs
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides a centralized location for constant values used across the DTS system. It currently exposes hardcoded file paths to configuration files for the DTS Viewer application. As a static class, it serves as a simple key-value store for string constants that need to be referenced from multiple locations in the codebase.
|
||||
|
||||
---
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Class: `DTSConstants`
|
||||
- **Kind**: `public static class`
|
||||
- **Namespace**: `DTS.Common.Core`
|
||||
|
||||
#### Members:
|
||||
|
||||
| Name | Type | Value |
|
||||
|------|------|-------|
|
||||
| `CustomConfigPath` | `public const string` | `@"C:\dev\DTS.Viewer\bin\Debug\DTS.Viewer.exe.config"` |
|
||||
| `ViewerConfigPath` | `public const string` | `@"C:\dev\DTS.Viewer\bin\Debug\DTS.Viewer.exe.config"` |
|
||||
|
||||
Both members are compile-time constants accessible via `DTSConstants.CustomConfigPath` and `DTSConstants.ViewerConfigPath`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- Both constants are compile-time literals (`const`), meaning their values are embedded directly into calling assemblies at compile time—not resolved at runtime.
|
||||
- Both constants reference Windows-style absolute file paths.
|
||||
- Both constants currently reference the **identical path**, despite having different names.
|
||||
|
||||
---
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### This module depends on:
|
||||
- **None** — No `using` directives or external references are present.
|
||||
|
||||
### What depends on this module:
|
||||
- **Cannot be determined from source alone.** Any code referencing `DTS.Common.Core.DTSConstants` may depend on these constants. The paths suggest consumers are related to `DTS.Viewer` configuration loading.
|
||||
|
||||
---
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
1. **Duplicate values with different names**: `CustomConfigPath` and `ViewerConfigPath` are named differently but contain the exact same path value. The intended semantic difference is unclear from source alone.
|
||||
|
||||
2. **Hardcoded development paths**: Both constants point to `C:\dev\DTS.Viewer\bin\Debug\`, which is clearly a local development directory. This will fail on any machine without this exact path structure and appears unsuitable for production deployment.
|
||||
|
||||
3. **Debug build reference**: The path explicitly references `Debug` build output, suggesting these constants may be placeholder/development-only values.
|
||||
|
||||
4. **Compile-time constant behavior**: Because these are `const` (not `static readonly`), changing these values requires recompilation of all dependent assemblies. A runtime configuration approach would be more flexible.
|
||||
|
||||
5. **Suppressed naming convention**: The file includes `// ReSharper disable InconsistentNaming`, suggesting the naming of these constants may deviate from project conventions.
|
||||
68
enriched-qwen3-coder-next/Common/DTS.Common.Core/Config.md
Normal file
68
enriched-qwen3-coder-next/Common/DTS.Common.Core/Config.md
Normal file
@@ -0,0 +1,68 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Core/Config/DTSConfig.cs
|
||||
generated_at: "2026-04-16T02:05:43.907445+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "2693b2d1a0d0acee"
|
||||
---
|
||||
|
||||
# Config
|
||||
|
||||
### **1. Purpose**
|
||||
The `DTSConfig` class provides a centralized, thread-safe mechanism for loading and accessing an *alternate* application configuration file (e.g., for plugin-specific or test-specific configs), overriding the default `app.config`/`web.config`. It enables runtime configuration of the config file path via `DTSConfigInit`, then exposes typed accessors (`GetAppSetting`, `GetSection`) to read settings and custom sections from that alternate file using .NET’s `System.Configuration` APIs. This supports scenarios like plugin isolation or environment-specific overrides without modifying the main executable’s config.
|
||||
|
||||
---
|
||||
|
||||
### **2. Public Interface**
|
||||
|
||||
- **`static void DTSConfigInit(string path)`**
|
||||
Initializes the alternate configuration by setting the config file path and loading the configuration. Internally calls `SetAltConfigPath(path)`. If `path` is `null` or empty, falls back to `DTSConstants.CustomConfigPath`. Must be called before other config accessors to ensure `AltConfig` is populated.
|
||||
|
||||
- **`static string GetAppSetting(string key)`**
|
||||
Retrieves the value of an `<add key="..." value="..."/>` entry from the `appSettings` section of the alternate configuration. Returns `string.Empty` if the key is not found. Logs a warning via `APILogger` when the key is absent.
|
||||
|
||||
- **`static object GetSection(string sectionName)`**
|
||||
Retrieves a custom configuration section (e.g., `<section name="..." type="..." />`) by name from the alternate configuration. Returns `null` if the section is not defined. Logs a warning via `APILogger` when the section is absent.
|
||||
|
||||
- **`static string AltConfigPathGet()`**
|
||||
Thread-safe getter for the current alternate config file path (stored in `AltConfigPath`). Returns the path string (may be `null` or empty if not set or reset).
|
||||
|
||||
- **`static void AltConfigPathSet(string path)`**
|
||||
Thread-safe setter for the alternate config file path. Updates `AltConfigPath` but *does not reload* the configuration—`SetAltConfigPath` must be called to apply the new path and reinitialize `AltConfig`.
|
||||
|
||||
---
|
||||
|
||||
### **3. Invariants**
|
||||
|
||||
- **Thread Safety**: All access to `AltConfigPath` and `AltConfig` is guarded by a private static lock object (`MyLock`). Reads (`AltConfigPathGet`, `GetAltConfig`, `GetAppSetting`, `GetSection`) and writes (`AltConfigPathSet`, `SetAltConfigPath`) are serialized.
|
||||
- **Fallback Behavior**: When `AltConfigPath` is `null` or empty, `SetAltConfigPath` uses `DTSConstants.CustomConfigPath` as the config file path.
|
||||
- **Configuration Loading**: `AltConfig` is lazily initialized on first call to `SetAltConfigPath` (via `DTSConfigInit` or direct invocation) and *not* reloaded automatically on subsequent path changes—`SetAltConfigPath` must be called again to refresh it.
|
||||
- **Error Handling**: Missing keys/sections are *not* thrown as exceptions; instead, they return `string.Empty`/`null` with a log message. No fallback to default config is attempted.
|
||||
|
||||
---
|
||||
|
||||
### **4. Dependencies**
|
||||
|
||||
- **Internal Dependencies**:
|
||||
- `DTS.Common.Utilities.Logging.APILogger` — Used for logging missing config entries/sections.
|
||||
- `System.Configuration.ConfigurationManager`, `ExeConfigurationFileMap`, `ConfigurationUserLevel` — For loading and accessing configuration files.
|
||||
- `DTSConstants.CustomConfigPath` — Fallback path when `AltConfigPath` is unset.
|
||||
|
||||
- **External Dependencies**:
|
||||
- `System.Configuration` assembly (standard .NET Framework/Standard).
|
||||
- No direct runtime dependencies beyond .NET config APIs.
|
||||
|
||||
- **Depended Upon By**:
|
||||
- Plugin code (per `GetSection`’s XML comment) to access plugin-specific configuration sections.
|
||||
- Any module requiring runtime-configurable settings without modifying the main executable’s config.
|
||||
|
||||
---
|
||||
|
||||
### **5. Gotchas**
|
||||
|
||||
- **`AltConfigPathSet` does not reload config**: Calling `AltConfigPathSet` alone updates the stored path but *does not* reinitialize `AltConfig`. The configuration must be reloaded via `SetAltConfigPath` (e.g., `DTSConfigInit`) to apply changes.
|
||||
- **No fallback to main config**: If the alternate config file is missing, invalid, or lacks a requested key/section, the system logs a warning but returns `string.Empty`/`null`—it does *not* fall back to the default `app.config`.
|
||||
- **`DTSConstants.CustomConfigPath` is assumed but not defined here**: The fallback path relies on an external constant (`DTSConstants.CustomConfigPath`). Its value and behavior are not visible in this file.
|
||||
- **Thread-safety only covers state, not config validity**: While access to `AltConfig` is thread-safe, concurrent calls to `SetAltConfigPath` may cause transient inconsistencies (e.g., one thread sets a path while another reads `AltConfig` before reinitialization completes).
|
||||
- **No validation of config file path**: `SetAltConfigPath` does not validate whether the provided path exists or is readable; `ConfigurationManager.OpenMappedExeConfiguration` will throw if the file is inaccessible (e.g., `FileNotFoundException`), but this is not handled internally.
|
||||
@@ -0,0 +1,97 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Core/EventManager/EventManager.cs
|
||||
generated_at: "2026-04-16T02:06:02.522135+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "59cbfaadaa1e572f"
|
||||
---
|
||||
|
||||
# EventManager
|
||||
|
||||
## Documentation: `EventManager` Module
|
||||
|
||||
### 1. Purpose
|
||||
The `EventManager` module provides a lightweight, type-safe event pub/sub mechanism that decouples event publishers from subscribers. It enables components to publish events of arbitrary types without compile-time knowledge of listeners, and allows subscribers to register callbacks—optionally with predicate-based filters—to receive only relevant events. Diagnostic instrumentation is built-in to track subscription lifecycle events (add, remove, publish) for observability. This module serves as a core infrastructure component for in-process event-driven communication within the DTS system.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `delegate void SubscriberCallbackDelegate<in T>(T item) where T : class`
|
||||
A generic delegate for event listeners. Receives the event data (`item`) and returns `void`. Contravariant in `T`.
|
||||
|
||||
#### `delegate void DiagnosticCallbackDelegate(EventDiagnosticType eventType, Type t, object eventData, string listener)`
|
||||
A delegate for diagnostic event handlers. Invoked on all diagnostic events with:
|
||||
- `eventType`: the diagnostic action (`EventDiagnosticType`)
|
||||
- `t`: the event type being subscribed/published/unsubscribed (or `null` for global operations)
|
||||
- `eventData`: the event payload (or `null` for subscription lifecycle events)
|
||||
- `listener`: fully qualified method name and assembly info (e.g., `"MyNamespace.MyClass.MyMethod, MyAssembly, Version=..."`)
|
||||
|
||||
#### `static class EventManager`
|
||||
A static class managing event subscriptions and publishing.
|
||||
|
||||
- **`static void Publish<T>(T eventData) where T : class`**
|
||||
Publishes `eventData` to all subscribers registered for type `T`. Filters (if any) are applied before invoking callbacks. Diagnostic events are emitted for each callback invocation.
|
||||
|
||||
- **`static void Subscribe<T>(SubscriberCallbackDelegate<T> listener) where T : class`**
|
||||
Registers `listener` for all events of type `T` (no filtering). Equivalent to `Subscribe(listener, null)`.
|
||||
|
||||
- **`static void Subscribe<T>(SubscriberCallbackDelegate<T> listener, Predicate<T> eventFilter) where T : class`**
|
||||
Registers `listener` for events of type `T`, but only invokes it when `eventFilter(eventData)` returns `true`. Internally wraps listener and filter in an `EventMetaData<T>` instance.
|
||||
|
||||
- **`static void UnSubscribe<T>(SubscriberCallbackDelegate<T> listener) where T : class`**
|
||||
Removes *all* registrations of `listener` for type `T`. Uses reference equality on the delegate.
|
||||
|
||||
- **`static void Clear()`**
|
||||
Removes *all* event subscriptions (all types, all listeners). Emits a diagnostic event with `EventDiagnosticType.RemoveListener`.
|
||||
|
||||
- **`static void SubscribeToDiagnosticEvents(DiagnosticCallbackDelegate listener)`**
|
||||
Registers a diagnostic listener. Invoked on *every* diagnostic event (including those triggered by diagnostic subscription itself).
|
||||
|
||||
- **`static void UnSubscribeToDiagnosticEvents(DiagnosticCallbackDelegate listener)`**
|
||||
Removes a specific diagnostic listener.
|
||||
|
||||
- **`static void ClearDiagnosticEvents()`**
|
||||
Removes *all* diagnostic listeners.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
|
||||
- **Type-based isolation**: Subscriptions and publications are strictly keyed by the *exact* runtime type `T`. Subscribing to `BaseEvent` does not receive events of type `DerivedEvent : BaseEvent`.
|
||||
- **Filter semantics**: Filters are applied *per subscription* during `Publish`. If `EventFilter` is `null`, the callback is always invoked.
|
||||
- **Reference equality for unsubscription**: `UnSubscribe<T>` uses `==` (reference equality) on the delegate instance. Two different delegate instances—even if pointing to the same method—will not be considered equal.
|
||||
- **Diagnostic event ordering**: Diagnostic events are emitted *synchronously* and in the order of subscription:
|
||||
- `AddListener` when `Subscribe` is called
|
||||
- `PublishEvent` for each callback invocation during `Publish`
|
||||
- `RemoveListener` when `UnSubscribe` is called
|
||||
- `RemoveListener` (global) when `Clear` is called
|
||||
- Diagnostic-specific events (`AddListenerDiagnostic`, `RemoveListenerDiagnostic`) follow the same pattern for diagnostic listeners.
|
||||
- **No null safety for `eventData`**: `Publish<T>` does *not* validate `eventData` is non-null. If `eventData` is `null`, it is passed as-is to callbacks and filters.
|
||||
- **No thread-safety**: The module makes no guarantees about concurrent access. `SubscriberList` and `DiagnosticList` are not thread-safe collections.
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
#### Dependencies *of* `EventManager`
|
||||
- **`System`**: Core runtime (`System`, `System.Collections.Generic`, `System.Reflection`)
|
||||
- **No external libraries**: Pure .NET Framework/BCL usage.
|
||||
|
||||
#### Dependencies *on* `EventManager`
|
||||
- **Inferred consumers**: Any component in the codebase that uses `EventManager.Subscribe`, `EventManager.Publish`, or diagnostic hooks.
|
||||
- **No direct reverse dependencies** are visible in this file, but the presence of `DiagnosticCallbackDelegate` and `EventDiagnosticType` suggests integration with logging, telemetry, or debugging infrastructure (e.g., a diagnostic monitor or test harness).
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
|
||||
- **No deduplication on subscription**: Calling `Subscribe` multiple times with the *same* listener and filter results in multiple registrations. `UnSubscribe` must be called the same number of times to fully remove it.
|
||||
- **Filter method reference in diagnostics**: The `listener` string passed to `DiagnosticCallbackDelegate` includes the *filter method* (if present) during `PublishEvent` diagnostics—not the callback method. This is because `metaData.EventFilter?.Method` is used.
|
||||
- **Diagnostic listener recursion risk**: A diagnostic listener that itself calls `EventManager.Publish` or `EventManager.Subscribe` will trigger *nested* diagnostic events (e.g., publishing an event while processing a diagnostic event). This is not prevented.
|
||||
- **`Clear()` is global and destructive**: `Clear()` removes *all* subscriptions across *all* event types. Use with caution in long-lived systems (e.g., during shutdown).
|
||||
- **`EventMetaData<T>` is internal**: While `EventManager` is public, the `EventMetaData<T>` class is internal. This means external code cannot introspect or manipulate subscription metadata directly.
|
||||
- **No weak references**: Subscribers are held via strong references. If a subscriber object is not explicitly `UnSubscribe`d, it may be kept alive indefinitely (memory leak risk).
|
||||
- **`DiagnosticCallbackDelegate` signature mismatch in `ClearDiagnosticEvents`**: When `UnSubscribeToDiagnosticEvents` is called, it passes `listener.Method` to `SendDiagnosticEvent`, but `listener` may be `null` if the listener was already removed. However, `UnSubscribeToDiagnosticEvents` only removes existing entries, so `listener` is non-null *at the time of call*. Still, `SendDiagnosticEvent` handles `listenerMethod == null` gracefully.
|
||||
- **No async support**: All callbacks are invoked synchronously. Long-running callbacks will block `Publish`.
|
||||
112
enriched-qwen3-coder-next/Common/DTS.Common.Core/PluginLib.md
Normal file
112
enriched-qwen3-coder-next/Common/DTS.Common.Core/PluginLib.md
Normal file
@@ -0,0 +1,112 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Core/PluginLib/PluginConfigData.cs
|
||||
- Common/DTS.Common.Core/PluginLib/PluginConfig.cs
|
||||
- Common/DTS.Common.Core/PluginLib/PluginConfigSectionHandler.cs
|
||||
- Common/DTS.Common.Core/PluginLib/PluginManager.cs
|
||||
generated_at: "2026-04-16T02:06:04.645753+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "698a84042cfeb418"
|
||||
---
|
||||
|
||||
# PluginLib
|
||||
|
||||
## Documentation: Plugin Configuration and Management Module
|
||||
|
||||
---
|
||||
|
||||
### 1. **Purpose**
|
||||
|
||||
This module provides infrastructure for loading, configuring, and resolving plugins using the Managed Extensibility Framework (MEF). It reads plugin folder paths from a custom configuration section (`DTS.Common.Core.PluginLib.Config`) in `App.config`, initializes MEF catalogs and containers over those directories, and exposes static methods to retrieve plugin instances by exported contract type. It supports both singleton and multiple-plugin resolution patterns, and includes custom assembly resolution logic to handle dependencies across plugin directories.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
|
||||
#### `PluginConfigData`
|
||||
- **`string[] PluginFolders`**
|
||||
XML-serialized array of plugin folder paths, populated from `<Folder>` elements under the `<DatPro.Core.PluginLib.Config>` root in `App.config`.
|
||||
|
||||
#### `PluginConfig`
|
||||
- **`const string DTSPlugins = "DTSPlugins"`**
|
||||
Hardcoded configuration key name used to retrieve the base plugin namespace prefix from `AppSettings`.
|
||||
- **`string GetDTSPluginsSetting(string setting)`**
|
||||
Concatenates the value of the `"DTSPlugins"` app setting (retrieved via `DTSConfig.GetAppSetting`) with the provided `setting` using `"."` as separator.
|
||||
*Example:* If `"DTSPlugins"` = `"DTS.Equipment"`, then `GetDTSPluginsSetting("Exporter")` returns `"DTS.Equipment.Exporter"`.
|
||||
|
||||
#### `PluginManager`
|
||||
- **`AggregateCatalog PluginCatalog { get; set; }`**
|
||||
MEF catalog aggregating plugin assemblies from configured directories.
|
||||
- **`CompositionContainer PluginContainer { get; set; }`**
|
||||
MEF composition container built from `PluginCatalog`.
|
||||
- **`static T GetPlugin<T>() where T : class`**
|
||||
Returns a single exported instance of type `T`. Throws if zero or more than one export of `T` exists.
|
||||
- **`static T GetPlugin<T>(string configPluginSetting) where T : class`**
|
||||
Returns a specific exported instance of type `T`, selected by matching `item.Value.ToString()` to `configPluginSetting`.
|
||||
*Note:* This relies on the plugin instance’s `ToString()` returning the expected identifier.
|
||||
- **`static IEnumerable<Lazy<T>> GetPlugins<T>() where T : class`**
|
||||
Returns all exported instances of type `T`.
|
||||
- **`List<Assembly> GetPluginList<T>() where T : class`**
|
||||
Returns a deduplicated list of assemblies containing MEF parts (plugin types), *not* necessarily those that export `T`.
|
||||
*Implementation detail:* Iterates over `DirectoryCatalog.Parts`, extracts the `Assembly` from each part’s type, and returns distinct entries.
|
||||
- **`static PluginManager GetPluginManager(string appPath)`**
|
||||
Returns the singleton `PluginManager` instance. Initializes it once per process if not already created.
|
||||
*Note:* `appPath` is validated (as `DirectoryInfo`) but not used beyond that in the current implementation.
|
||||
|
||||
#### `PluginConfigSectionHandler`
|
||||
- **`FilterHashKeyCollection HashKeys { get; }`**
|
||||
Configuration property mapping to the `PluginFolders` element in the custom config section. Contains `FilterHashElement` entries.
|
||||
|
||||
#### `FilterHashKeyCollection`
|
||||
- **`FilterHashElement this[int idx] => (FilterHashElement)BaseGet(idx);`**
|
||||
Indexer to access `FilterHashElement` items by zero-based index.
|
||||
|
||||
#### `FilterHashElement`
|
||||
- **`string Key { get; set; }`**
|
||||
Required, key-only configuration property (e.g., unused in current logic).
|
||||
- **`string Value { get; set; }`**
|
||||
Optional string value, used in `PluginManager` constructor as the plugin directory path.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
|
||||
- **Singleton enforcement:** `PluginManager` is a singleton; only one instance exists per AppDomain, enforced via `lock(THREAD_LOCK)` in `GetPluginManager`.
|
||||
- **Configuration dependency:** `PluginManager` constructor *requires* the `DTS.Common.Core.PluginLib.Config` section to be present in `App.config`; otherwise, it logs and throws.
|
||||
- **Directory existence:** Each `FilterHashElement.Value` must point to an existing directory; otherwise, an `IOException` is thrown during initialization.
|
||||
- **Assembly loading constraints:** Assemblies named with prefixes `"DTS.Common"`, `"C1"`, or `"Xceed"` are *excluded* from explicit `Assembly.LoadFrom` calls in the constructor (though they may still be loaded via MEF or `AssemblyResolve`).
|
||||
- **MEF contract resolution:** `GetPlugin<T>()` expects exactly one export of `T`; otherwise, MEF throws (not explicitly handled in code).
|
||||
- **Plugin selection via `ToString()`:** `GetPlugin<T>(string)` matches plugins by `item.Value.ToString() == configPluginSetting`, which is fragile and undocumented in plugin contracts.
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
|
||||
#### **Imports / Uses**
|
||||
- `DTS.Common.Core.Config.DTSConfig` — for reading config sections (`GetSection`) and app settings (`GetAppSetting`).
|
||||
- `DTS.Common.Utilities.Logging.APILogger` — for logging errors and warnings.
|
||||
- `System.ComponentModel.Composition.*` — MEF types (`AggregateCatalog`, `CompositionContainer`, `DirectoryCatalog`, `ReflectionModelServices`).
|
||||
- `System.Configuration` — for `ConfigurationSection`, `ConfigurationElementCollection`, `ConfigurationElement`.
|
||||
|
||||
#### **Consumers (inferred)**
|
||||
- Any module requiring plugin discovery/resolution (e.g., equipment exporters, data processors) likely calls `PluginManager.GetPlugin<T>()` or `GetPlugins<T>()`.
|
||||
- Configuration infrastructure (`DTSConfig`) must register the `DTS.Common.Core.PluginLib.Config` section handler (not shown here).
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
|
||||
- **`appPath` parameter in `GetPluginManager(string appPath)` is unused after validation.** The constructor uses `DTSConfig.DTSConfigInit(appPath)`, but subsequent calls to `GetPluginManager` ignore `appPath` entirely — only the first call’s `appPath` matters.
|
||||
- **`GetPlugin<T>(string)` uses `ToString()` for identification**, which is unreliable and not part of MEF’s contract model. Plugins must override `ToString()` to return the expected identifier — a hidden coupling.
|
||||
- **Assembly filtering is hardcoded and incomplete:** Exclusion of `"DTS.Common"`, `"C1"`, `"Xceed"` is done via string prefix on filename, not strong name or version — may break if filenames change or include versioned suffixes.
|
||||
- **Redundant assembly loading:** The constructor calls `Assembly.LoadFrom` for each `.dll` *after* adding `DirectoryCatalog` (which loads assemblies lazily). This may cause duplicate loads or conflicts.
|
||||
- **`GetPluginList<T>()` ignores the generic constraint `T`** — it returns *all* plugin assemblies, not just those exporting `T`.
|
||||
- **`CurrentDomain_AssemblyResolve` is defined but never subscribed.** The event handler is unused — assembly resolution failures may occur if plugins depend on other plugins not in the GAC.
|
||||
- **No cleanup/disposal logic:** `PluginCatalog` and `PluginContainer` are not disposed, risking resource leaks in long-running processes.
|
||||
- **Thread-safety is partial:** While `GetPluginManager` is thread-safe, `PluginCatalog` and `PluginContainer` are mutable properties — external modification after initialization is possible (though discouraged by design).
|
||||
- **`FilterHashElement.Key` is unused** — present in config schema but never referenced in code.
|
||||
|
||||
---
|
||||
|
||||
*Documentation generated from provided source files. No behavior inferred beyond explicit code.*
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Core/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T02:06:09.629305+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "f157b2a2cacdeb5d"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## 1. Purpose
|
||||
This module (`DTS.Common.Core`) is an assembly-level configuration file for a .NET class library. Its purpose is to define metadata attributes for the assembly—such as title, version, and COM visibility—without exposing any executable logic or public APIs. It serves as a foundational infrastructure component, ensuring consistent assembly identity and interop behavior across the broader DTS (likely *Data Tracking System* or similar domain) codebase.
|
||||
|
||||
## 2. Public Interface
|
||||
**No public types, functions, classes, or methods are defined in this file.**
|
||||
The file contains only assembly-level attributes via `System.Reflection` and `System.Runtime.InteropServices`. There are no public members to document.
|
||||
|
||||
## 3. Invariants
|
||||
- The assembly is **not visible to COM** (`ComVisible(false)`), meaning it cannot be consumed by COM clients unless explicitly overridden on individual types (none present here).
|
||||
- The assembly version is fixed at `1.0.0.0` for both `AssemblyVersion` and `AssemblyFileVersion`.
|
||||
- The `Guid` attribute is set to `"bdf5ad7a-51db-4ad0-8186-d1ead7405848"` for COM type library identification (though irrelevant since `ComVisible` is `false`).
|
||||
- All assembly attributes conform to standard .NET conventions (e.g., `AssemblyTitle`, `AssemblyCopyright`, etc.).
|
||||
|
||||
## 4. Dependencies
|
||||
- **Depends on**:
|
||||
- `System.Runtime.InteropServices` (for `ComVisible`, `Guid`)
|
||||
- `System.Reflection` (for assembly metadata attributes)
|
||||
- **Depended on by**:
|
||||
- Other projects/solutions referencing `DTS.Common.Core.dll` (inferred from assembly name and GUID).
|
||||
- No direct runtime dependencies are declared in this file.
|
||||
|
||||
## 5. Gotchas
|
||||
- **No executable logic**: This file does not contain any runtime behavior—its sole purpose is metadata. Misinterpreting it as a source of functional code is a common mistake for new developers.
|
||||
- **COM interop disabled**: If COM exposure is later required, `ComVisible(true)` must be set *and* individual types must be explicitly marked with `[ComVisible(true)]`, as the assembly-level setting does not propagate to types.
|
||||
- **Versioning rigidity**: The fixed version `1.0.0.0` (with no wildcard `*` for build/revision) may indicate legacy or manually managed versioning; teams should verify whether this aligns with current CI/CD practices.
|
||||
- **No public surface area**: This assembly likely has no direct consumers beyond internal tooling or build-time tooling (e.g., strong-name signing, assembly resolution).
|
||||
|
||||
*None identified beyond the above.*
|
||||
@@ -0,0 +1,99 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Core/ServiceManager/IServicePublishedEvent.cs
|
||||
- Common/DTS.Common.Core/ServiceManager/ServicePublishedEvent.cs
|
||||
- Common/DTS.Common.Core/ServiceManager/ServiceManager.cs
|
||||
generated_at: "2026-04-16T02:06:21.064356+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "a01f75e5b963dd9f"
|
||||
---
|
||||
|
||||
# ServiceManager
|
||||
|
||||
## Documentation: ServiceManager Module
|
||||
|
||||
### 1. Purpose
|
||||
The `ServiceManager` module provides a centralized registry for singleton service implementations, enabling decoupled service discovery and lifecycle management. Components can publish implementations of service interfaces (e.g., `IMyService`) and other components can retrieve them by interface type without knowledge of the concrete publisher. It also emits `IServicePublishedEvent` notifications via `EventManager` whenever services are published or unpublished, supporting reactive integration patterns.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `ServiceManager` (static class)
|
||||
|
||||
- **`void Publish<T>(T item) where T : class`**
|
||||
Publishes a singleton service implementation `item` for interface type `T`. Throws `ArgumentException` if `T` is already published. Fires a `ServicePublishedEvent` with `IsPublished = true`.
|
||||
|
||||
- **`void Publish(object item, IEnumerable<Type> interfaceList, bool skipPublishedInterfaces)`**
|
||||
Publishes `item` for each interface type in `interfaceList`. If `skipPublishedInterfaces` is `false`, throws `ArgumentException` on encountering an already-published interface; otherwise, skips it. Fires `ServicePublishedEvent` for newly published interfaces.
|
||||
|
||||
- **`bool Exists<T>() where T : class`**
|
||||
Returns `true` if interface type `T` has a published service; `false` otherwise.
|
||||
|
||||
- **`bool Exists(Type t)`**
|
||||
Returns `true` if interface type `t` has a published service; `false` otherwise.
|
||||
|
||||
- **`T Get<T>() where T : class`**
|
||||
Returns the published service instance for interface type `T`. Throws `ArgumentException` if `T` is not published.
|
||||
|
||||
- **`void Clear<T>() where T : class`**
|
||||
Unpublishes the service for interface type `T`. Fires a `ServicePublishedEvent` with `IsPublished = false` before removal. No-op if `T` is not published.
|
||||
|
||||
- **`void Clear(IEnumerable<Type> interfaceList)`**
|
||||
Unpublishes services for all interface types in `interfaceList`. Fires `ServicePublishedEvent` with `IsPublished = false` for each successfully removed service.
|
||||
|
||||
#### `IServicePublishedEvent` (interface)
|
||||
|
||||
- **`Type ServiceType { get; }`**
|
||||
Read-only property returning the `Type` of the service interface being published/unpublished.
|
||||
|
||||
- **`bool IsPublished { get; }`**
|
||||
Read-only property: `true` if the event indicates publication; `false` if unpublishing.
|
||||
|
||||
#### `ServicePublishedEvent` (class)
|
||||
|
||||
- **`Type ServiceType { get; internal set; }`**
|
||||
Gets or sets (internally) the service interface `Type`.
|
||||
|
||||
- **`bool IsPublished { get; internal set; }`**
|
||||
Gets or sets (internally) the publication status.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
|
||||
- **Uniqueness per interface**: Each interface type `T` may have at most one published service instance. Attempting to publish a second implementation for the same interface throws `ArgumentException` (unless `skipPublishedInterfaces = true` in the bulk `Publish` overload).
|
||||
- **Consistency of `Exists`/`Get`/`Clear`**: `Exists<T>()` and `Exists(Type)` return `true` if and only if `Services.ContainsKey(typeof(T))` is `true`. `Get<T>()` will throw if `Exists<T>()` is `false`.
|
||||
- **Event emission order**: For `Publish`/`Clear` operations, the `ServicePublishedEvent` is fired *before* the service is added/removed from the internal dictionary. Specifically:
|
||||
- `Publish` → `Services.Add(...)` → `SendServicePublishedEvent(...)`
|
||||
- `Clear` → `SendServicePublishedEvent(...)` → `Services.Remove(...)`
|
||||
- **No null services**: The `Services` dictionary stores only non-null references. `Publish` accepts any `class`, but the dictionary does not explicitly validate non-nullability beyond standard dictionary behavior.
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
- **Internal dependencies**:
|
||||
- `System.Collections.Generic.Dictionary<Type, object>` for service storage.
|
||||
- `EventManager.EventManager` (from `DTS.Common.Core` namespace) to publish `IServicePublishedEvent` instances via `EventManager.EventManager.Publish<IServicePublishedEvent>(...)`.
|
||||
|
||||
- **External dependencies**:
|
||||
- `System` (for `Type`, `ArgumentException`, `IEnumerable<T>`, etc.).
|
||||
|
||||
- **Depended upon by**:
|
||||
- Any component requiring service discovery (e.g., via `ServiceManager.Get<T>()`).
|
||||
- Event subscribers listening for `IServicePublishedEvent` to react to service lifecycle changes.
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
|
||||
- **No thread-safety guarantees**: The `Services` dictionary is not thread-safe. Concurrent `Publish`/`Clear`/`Get` calls may cause race conditions or exceptions (e.g., `InvalidOperationException` during enumeration or dictionary mutation).
|
||||
- **`Publish(object, ...)` allows multiple interfaces per instance**: The same object instance may be published under multiple interface types, but this is not validated beyond the existence check per interface.
|
||||
- **`Get<T>()` uses `as T` cast**: If the stored object is not actually assignable to `T` (e.g., due to type mismatch or casting issues), `Get<T>()` returns `null` *without throwing*—but only if the key exists. However, the current implementation first checks `ContainsKey`, so `null` return is impossible *if* the stored object is non-null and correctly typed. If the stored object is `null`, `ContainsKey` would still be `true`, and `Get<T>()` would return `null`. This edge case is not explicitly guarded against.
|
||||
- **Event emission timing**: Subscribers receive `ServicePublishedEvent` *before* the service is available (for `Publish`) or *after* it is removed (for `Clear`). This may cause race conditions if subscribers immediately call `Get<T>()`—they will succeed for `Publish`, but fail for `Clear`.
|
||||
- **No support for service versioning or replacement**: Once published, a service cannot be replaced without explicit `Clear<T>()` followed by `Publish<T>()`.
|
||||
- **`internal set` on `ServicePublishedEvent` properties**: While the properties are public, their setters are `internal`, meaning only code within the same assembly can construct/modify `ServicePublishedEvent` instances. This is consistent with the design but limits extensibility.
|
||||
|
||||
None identified beyond the above.
|
||||
181
enriched-qwen3-coder-next/Common/DTS.Common.Core/Settings.md
Normal file
181
enriched-qwen3-coder-next/Common/DTS.Common.Core/Settings.md
Normal file
@@ -0,0 +1,181 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Core/Settings/SettingsChangedEventArgs.cs
|
||||
- Common/DTS.Common.Core/Settings/SettingsCollection.cs
|
||||
generated_at: "2026-04-16T02:05:44.714308+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "e48bcdd1082dba01"
|
||||
---
|
||||
|
||||
# Settings Collection Module Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides a dictionary-based settings collection (`SettingsCollection<TKey, TItem>`) that extends standard dictionary functionality by raising events whenever items are added, removed, modified, or the entire collection is cleared. It exists to enable reactive UIs or other subsystems to respond to configuration changes in real time, without requiring manual polling or external event coordination. The module is part of the core settings infrastructure in the DTS system and is designed for use in scenarios where settings changes must be tracked and propagated.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `SettingsCollection<TKey, TItem>` Class
|
||||
|
||||
A generic collection implementing `IDictionary<TKey, TItem>` that fires events on modifications.
|
||||
|
||||
#### Public Events
|
||||
|
||||
- **`event EventHandler<SettingsChangedEventArgs<TKey, TItem>> CollectionItemPropertyChanged`**
|
||||
Fired whenever an item is added, removed, modified, or the collection is cleared. Subscribers receive detailed information about the change via `SettingsChangedEventArgs`.
|
||||
|
||||
#### Public Methods (from `IDictionary<TKey, TItem>`)
|
||||
|
||||
- **`void Add(TKey key, TItem value)`**
|
||||
Adds a new key-value pair to the collection. Fires `CollectionItemPropertyChanged` with `ChangeSettingType.Add`, including `key` and `value`.
|
||||
|
||||
- **`bool ContainsKey(TKey key)`**
|
||||
Returns `true` if the specified key exists in the collection.
|
||||
|
||||
- **`bool Remove(TKey key)`**
|
||||
Removes the entry with the specified key. Returns `true` if removal succeeded. Fires `CollectionItemPropertyChanged` with `ChangeSettingType.Remove` and the `key`.
|
||||
|
||||
- **`bool TryGetValue(TKey key, out TItem value)`**
|
||||
Attempts to retrieve the value for a given key. Returns `true` if found.
|
||||
|
||||
- **`void Clear()`**
|
||||
Removes all entries from the collection. Fires `CollectionItemPropertyChanged` with `ChangeSettingType.ClearAll`.
|
||||
|
||||
- **`bool Remove(KeyValuePair<TKey, TItem> item)`**
|
||||
Removes the specified key-value pair (by key only). Fires `CollectionItemPropertyChanged` with `ChangeSettingType.Remove` and the key.
|
||||
|
||||
- **`void Add(KeyValuePair<TKey, TItem> item)`**
|
||||
Adds the specified key-value pair. Fires `CollectionItemPropertyChanged` with `ChangeSettingType.Add`, including key and value.
|
||||
|
||||
#### Public Properties (from `IDictionary<TKey, TItem>`)
|
||||
|
||||
- **`TItem this[TKey key] { get; set; }`**
|
||||
Indexer for getting/setting values.
|
||||
- **Getter**: Returns the value for the given key (throws `KeyNotFoundException` if not present).
|
||||
- **Setter**: Sets or overwrites the value for the key. **Note**: Always fires `ChangeSettingType.Add`, even when overwriting an existing key (see *Gotchas*).
|
||||
|
||||
- **`ICollection<TKey> Keys`**
|
||||
Returns a read-only collection of all keys.
|
||||
|
||||
- **`ICollection<TItem> Values`**
|
||||
Returns a read-only collection of all values.
|
||||
|
||||
- **`int Count`**
|
||||
Returns the number of entries in the collection.
|
||||
|
||||
- **`bool IsReadOnly`**
|
||||
Always `false`; this collection is mutable.
|
||||
|
||||
#### Public Properties (non-interface)
|
||||
|
||||
- **`ICollection<TKey> Keys`**
|
||||
(Same as above.)
|
||||
|
||||
- **`ICollection<TItem> Values`**
|
||||
(Same as above.)
|
||||
|
||||
> **Note**: `CopyTo` throws `NotImplementedException`.
|
||||
|
||||
### `SettingsChangedEventArgs<TKey, TItem>` Class
|
||||
|
||||
Event arguments providing context for a change.
|
||||
|
||||
#### Constructors
|
||||
|
||||
- **`SettingsChangedEventArgs(ChangeSettingType changeType)`**
|
||||
For changes that do not involve a specific key or item (e.g., `ClearAll`).
|
||||
|
||||
- **`SettingsChangedEventArgs(ChangeSettingType changeType, TKey key)`**
|
||||
For changes involving a key but no value (e.g., `Remove`).
|
||||
|
||||
- **`SettingsChangedEventArgs(ChangeSettingType changeType, TKey key, TItem item)`**
|
||||
For changes involving both key and value (e.g., `Add`, `Modified`, or indexer set).
|
||||
|
||||
#### Public Properties
|
||||
|
||||
- **`ChangeType`** (`ChangeSettingType`)
|
||||
The type of change that occurred.
|
||||
|
||||
- **`Key`** (`TKey`)
|
||||
The key associated with the change. May be default (`null`/`0`/etc.) for `ClearAll`.
|
||||
|
||||
- **`Item`** (`TItem`)
|
||||
The value associated with the change. May be default for `Remove` or `ClearAll`.
|
||||
|
||||
### `ChangeSettingType` Enum
|
||||
|
||||
- **`Add = 0`**
|
||||
A new item was added.
|
||||
|
||||
- **`Remove = 1`**
|
||||
An item was removed.
|
||||
|
||||
- **`Modified = 3`**
|
||||
An item was modified.
|
||||
> **Note**: This value exists but is *never used* in the current implementation.
|
||||
|
||||
- **`ClearAll = 4`**
|
||||
The entire collection was cleared.
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Event Firing Guarantee**:
|
||||
Every mutation operation (`Add`, `Remove`, `Clear`, indexer set) *always* fires `CollectionItemPropertyChanged` exactly once per operation.
|
||||
|
||||
- **Event Payload Consistency**:
|
||||
- `Add`, `Modified`, and indexer set → `ChangeType = Add`, with `Key` and `Item` populated.
|
||||
- `Remove` → `ChangeType = Remove`, with `Key` populated, `Item = default`.
|
||||
- `Clear` → `ChangeType = ClearAll`, with `Key = default`, `Item = default`.
|
||||
|
||||
- **No `Modified` Events**:
|
||||
Although `ChangeSettingType.Modified` is defined, it is *never* used. The indexer setter always fires `Add`, even when overwriting an existing key.
|
||||
|
||||
- **Read-only properties are enforced**:
|
||||
`IsReadOnly` is always `false`; the collection is fully mutable.
|
||||
|
||||
- **No deep copy on `CopyTo`**:
|
||||
`CopyTo` is unimplemented and throws `NotImplementedException`.
|
||||
|
||||
---
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Dependencies *of* this module:
|
||||
- **`System`** (core .NET types: `EventArgs`, `EventHandler`, `Dictionary<TKey, TValue>`, `ICollection<TKey>`, `IEnumerator`, etc.)
|
||||
|
||||
### Dependencies *on* this module:
|
||||
- **`DTS.Common.Core.Settings` namespace** (self-contained; no external references beyond `System`).
|
||||
- **Consumers**: Based on naming and design, this module is intended to be used by higher-level settings management components (e.g., `ISettingsService`, UI binding layers) that need to react to configuration changes. No explicit usages are visible in the provided source.
|
||||
|
||||
---
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **`Modified` is unused**:
|
||||
The `ChangeSettingType.Modified` enum value is defined but never emitted. If a change is made via the indexer (`collection[key] = value`), it fires `ChangeSettingType.Add`, not `Modified`. This may mislead consumers expecting `Modified` for updates.
|
||||
|
||||
- **Indexer setter mislabels overwrites as `Add`**:
|
||||
Setting an existing key via `collection[key] = newValue` fires `ChangeSettingType.Add`, not `Modified`. This could cause incorrect behavior in listeners that distinguish between *new* additions and *updates*.
|
||||
|
||||
- **`CopyTo` is unimplemented**:
|
||||
Calling `CopyTo` throws `NotImplementedException`. This violates the `ICollection<KeyValuePair<TKey, TItem>>` contract and may break serialization or bulk-copy scenarios.
|
||||
|
||||
- **No validation on `Key` or `Item`**:
|
||||
The collection does not enforce non-null keys (unless `TKey` is a value type) or validate item values. Behavior with `null` keys depends on `Dictionary<TKey, TItem>`’s implementation (throws if `TKey` is a reference type and `null` is passed, unless a custom comparer is used—but none is provided).
|
||||
|
||||
- **No thread-safety guarantees**:
|
||||
The module uses a private `Dictionary<TKey, TItem>` without synchronization. Concurrent access (e.g., from multiple threads) may cause race conditions or exceptions.
|
||||
|
||||
- **`Contains(KeyValuePair<TKey, TItem>)` is inefficient**:
|
||||
It checks both `ContainsKey` *and* `ContainsValue`, which is O(n) for the value check. This may be unexpected for a dictionary-like structure.
|
||||
|
||||
- **No `Modified` event overload**:
|
||||
The private `FireItemChangedEvent` overloads do not distinguish between `Add` and `Modified`—they only dispatch based on `ChangeSettingType`. Since `Modified` is unused, this is consistent but limits extensibility.
|
||||
|
||||
- **Event subscribers may receive stale data**:
|
||||
If a subscriber modifies the collection during event handling (e.g., in response to `Add`), it may trigger nested events or reentrancy issues. No recursion guard is present.
|
||||
|
||||
None identified beyond the above.
|
||||
108
enriched-qwen3-coder-next/Common/DTS.Common.DAS.Concepts.md
Normal file
108
enriched-qwen3-coder-next/Common/DTS.Common.DAS.Concepts.md
Normal file
@@ -0,0 +1,108 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.DAS.Concepts/AvailableArmModes.cs
|
||||
- Common/DTS.Common.DAS.Concepts/ArmStatus.cs
|
||||
- Common/DTS.Common.DAS.Concepts/ITriggerable.cs
|
||||
- Common/DTS.Common.DAS.Concepts/IDataCollectionEnabled.cs
|
||||
- Common/DTS.Common.DAS.Concepts/ILargeDataAware.cs
|
||||
- Common/DTS.Common.DAS.Concepts/ICalibratable.cs
|
||||
- Common/DTS.Common.DAS.Concepts/IGpioEnabled.cs
|
||||
- Common/DTS.Common.DAS.Concepts/IRealtimeable.cs
|
||||
- Common/DTS.Common.DAS.Concepts/DataScaler.InvalidExcitationVoltageException.cs
|
||||
- Common/DTS.Common.DAS.Concepts/ShuntModeType.cs
|
||||
- Common/DTS.Common.DAS.Concepts/TsrEvent.cs
|
||||
- Common/DTS.Common.DAS.Concepts/IDownloadEnabled.cs
|
||||
- Common/DTS.Common.DAS.Concepts/IArmable.cs
|
||||
- Common/DTS.Common.DAS.Concepts/LinearizationFormula.cs
|
||||
generated_at: "2026-04-16T14:07:33.942936+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "c415f64680b9e4be"
|
||||
---
|
||||
|
||||
# Documentation: DTS.Common.DAS.Concepts
|
||||
|
||||
## 1. Purpose
|
||||
This module defines the core conceptual interfaces, enumerations, and data structures for a Data Acquisition System (DAS). It establishes the abstract contracts for hardware capabilities such as arming, triggering, calibration, real-time data streaming, GPIO manipulation, and event downloading. The module serves as a shared vocabulary between hardware implementations and higher-level application logic, enabling polymorphic treatment of different DAS devices (e.g., TSR, HEADS, NASCAR hardware mentioned in comments).
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Enumerations
|
||||
* **`AvailableArmModes`** (Namespace: `DTS.Common.DAS.Concepts` & `DTS.DAS.Concepts`)
|
||||
* Values: `LowPower`, `CircularBuffer`.
|
||||
* **`ArmStatus`** (Namespace: `DTS.Common.DAS.Concepts` & `DTS.DAS.Concepts`)
|
||||
* Values: `Disarming`, `Disarmed`, `Arming`, `Armed`, `Recording`.
|
||||
* **`Directions`** (Namespace: `DTS.DAS.Concepts.GPIOPin`)
|
||||
* Values: `Output` (0x00), `Peripheral` (0x01), `Input` (0x02), `InputPulledUp` (0x03), `InputPulledDown` (0x04).
|
||||
* **`ShuntModeType`** (Namespace: `DTS.Common.DAS.Concepts.Test.Module.Channel.Sensor`)
|
||||
* Values: `Internal`, `External`, `Emulation`, `None`. Decorated with `DescriptionAttribute`.
|
||||
|
||||
### Interfaces
|
||||
* **`IArmable`** (Namespace: `DTS.DAS.Concepts`)
|
||||
* `void Arm()`: Initiates the arming process.
|
||||
* `void Disarm()`: Initiates the disarming process.
|
||||
* `ArmStatus ArmStatus { get; }`: Gets the current status.
|
||||
* `AvailableArmModes ArmMode { get; }`: Gets the current mode.
|
||||
* **`ITriggerable`** (Namespace: `DTS.DAS.Concepts`)
|
||||
* `void Trigger()`: Triggers the object.
|
||||
* **`IDownloadEnabled`** (Namespace: `DTS.DAS.Concepts`)
|
||||
* `TsrEvent[] EventList { get; }`: List of available events.
|
||||
* `double[][] GetEventData(TsrEvent Event, UInt64 FirstSample, UInt64 LastSample)`: Retrieves data for a specific sample range.
|
||||
* `bool DataHasBeenDownloaded { get; }`: Indicates if data has been downloaded.
|
||||
* **`IDataCollectionEnabled`** (Namespace: `DTS.DAS.Concepts`)
|
||||
* Inherits: `IArmable`, `ITriggerable`, `IDownloadEnabled`.
|
||||
* `double[] AvailableSampleRates { get; }`: Supported sample rates.
|
||||
* `double SampleRate { get; set; }`: Current sample rate.
|
||||
* **`ICalibratable`** (Namespace: `DTS.DAS.Concepts`)
|
||||
* Properties: `SerialNumber`, `Sensitivity`, `BatteryVolts`, `VddVolts`, `SignalConditioningVolts`.
|
||||
* **`IGpioEnabled`** (Namespace: `DTS.DAS.Concepts`)
|
||||
* `void SetGpio(uint Port, uint Pin, GPIOPin.Directions Direction, bool State)`: Configures a GPIO pin.
|
||||
* `bool GetGpio(uint Port, uint Pin)`: Reads the state of a GPIO pin.
|
||||
* **`IRealtimeable`** (Namespace: `DTS.DAS.Concepts`)
|
||||
* `void StartRealtime(double sampleRate)`: Starts real-time capture.
|
||||
* `void StopRealtime()`: Stops real-time capture.
|
||||
* `RealtimeSample[] GetRealtimeSamples()`: Retrieves buffered samples.
|
||||
* **`ILargeDataAware`** (Namespace: `DTS.DAS.Concepts.DAS.Channel`)
|
||||
* `bool IsDataArraySized { get; }`: Indicates if data fits safely in an array for the application context.
|
||||
|
||||
### Classes
|
||||
* **`TsrEvent`** (Namespace: `DTS.Common.DAS.Concepts` & `DTS.DAS.Concepts`)
|
||||
* Abstract class inheriting from `Exceptional` and `ICloneable`.
|
||||
* Properties (all `protected set`): `EventId` (UInt64, 1-based), `TimeStamp` (DateTime), `SerialNumber`, `AlternateSerialNumber`, `DurationSeconds`, `MaxSampleRate`, `TemperatureC`, `PreTriggerSeconds`.
|
||||
* `public abstract object Clone()`: Creates a shallow copy.
|
||||
* **`RealtimeSample`** (Namespace: `DTS.DAS.Concepts`)
|
||||
* Fields: `double[] DataEU` (indexed by channel), `UInt64 SampleNumber`.
|
||||
* **`LinearizationFormula`** (Namespace: `DTS.Common.DAS.Concepts`)
|
||||
* Manages conversion of raw voltage to Engineering Units (EU).
|
||||
* Key Properties: `NonLinearStyle` (enum), `PolynomialCoefficients`, `PolynomialExponents`, `PolynomialSensitivity`, `MMPerV`, `Slope`, `Intercept`, `CalibrationFactor`.
|
||||
* Key Methods:
|
||||
* `double GetLinearizedValue(double input, double excitation)`: Main conversion method.
|
||||
* `void FromSerializeString(string s)`: Parses a string configuration.
|
||||
* `string ToSerializeString()`: Serializes configuration.
|
||||
* `string ToDisplayString()`: Human-readable representation.
|
||||
* **`DataScaler.InvalidExcitationVoltageException`** (Namespace: `DTS.Common.DAS.Concepts`)
|
||||
* Nested class inside `DataScaler` (partial). Standard Exception implementation.
|
||||
|
||||
## 3. Invariants
|
||||
* **Identifiers:** `TsrEvent.EventId` is defined as 1-based.
|
||||
* **Immutability:** Properties on `TsrEvent` are read-only publicly (`protected set`).
|
||||
* **Input Units:** `LinearizationFormula.GetLinearizedValue` assumes the `input` argument is in millivolts (mV); it divides by 1000 internally to convert to Volts.
|
||||
* **Data Bounds:** In `LinearizationFormula.GetLinearizedValue`, if `NonLinearStyle` is not `Polynomial` and `input <= 0`, the input is coerced to `0.001` to prevent math errors.
|
||||
* **Polynomial Defaults:** `LinearizationFormula` initializes with 4 coefficients and exponents (0, 1, 2, 3) by default.
|
||||
|
||||
## 4. Dependencies
|
||||
* **Internal Dependencies:**
|
||||
* `DTS.Common.Utilities`: Used by `TsrEvent` (base class `Exceptional`).
|
||||
* `DTS.Utilities`: Referenced in `IDownloadEnabled.cs` (though `TsrEvent` in the same file inherits from `Exceptional` in `DTS.Common.Utilities`).
|
||||
* `DTS.Common.Enums.Sensors`: Used by `LinearizationFormula` for `NonLinearStyles` and `NonLinearSLICEWareStyles`.
|
||||
* **System Dependencies:**
|
||||
* `System`, `System.Collections.Generic`, `System.Text`, `System.Globalization`, `System.ComponentModel`.
|
||||
|
||||
## 5. Gotchas
|
||||
* **Namespace Duplication:** There is significant duplication of types across two namespaces: `DTS.Common.DAS.Concepts` and `DTS.DAS.Concepts`.
|
||||
* `AvailableArmModes`, `ArmStatus`, and `TsrEvent` are defined in both namespaces.
|
||||
* This may cause compiler ambiguity or maintenance confusion if both namespaces are imported.
|
||||
* **Duplicate Definitions:** The enums `AvailableArmModes` and `ArmStatus` are defined in their own files *and* inside `IArmable.cs`. The class `TsrEvent` is defined in its own file *and* inside `IDownloadEnabled.cs`. The definitions appear identical but this violates DRY (Don't Repeat Yourself).
|
||||
* **Unit Assumptions in Linearization:** The property `MMPerV` is documented in comments as "THIS IS MM/V", but the backing field is named `_mmPerMV`. The `GetLinearizedValue` method performs an implicit division by 1000 on the input, requiring callers to know the method expects mV, not V.
|
||||
* **Partial Classes:** `DataScaler` and `Test` are defined as partial classes here. Their counterparts are located in other files not present in this source set (e.g., `DTS.Slice.Control.DataScaler.cs`, `Test.cs`).
|
||||
* **Historical Comments:** `IArmable.cs` contains a large block of commented-out email correspondence discussing specific hardware models (NASCAR, TSRPRO, NGI, HEADSII) and design
|
||||
196
enriched-qwen3-coder-next/Common/DTS.Common.DAS.Concepts/DAS.md
Normal file
196
enriched-qwen3-coder-next/Common/DTS.Common.DAS.Concepts/DAS.md
Normal file
@@ -0,0 +1,196 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.DAS.Concepts/DAS/DAS.Channel.cs
|
||||
- Common/DTS.Common.DAS.Concepts/DAS/DAS.Channel.IIsoCodeAware.cs
|
||||
- Common/DTS.Common.DAS.Concepts/DAS/DAS.Channel.ISerialNumberAware.cs
|
||||
- Common/DTS.Common.DAS.Concepts/DAS/DAS.Channel.IEngineeringUnitAware.cs
|
||||
- Common/DTS.Common.DAS.Concepts/DAS/DecimationMethod.cs
|
||||
- Common/DTS.Common.DAS.Concepts/DAS/DAS.Channel.IInversionAware.cs
|
||||
- Common/DTS.Common.DAS.Concepts/DAS/DTS.DAS.Concepts.IVoltageInsertAware.cs
|
||||
- Common/DTS.Common.DAS.Concepts/DAS/DAS.Channel.ILevelTriggerable.cs
|
||||
- Common/DTS.Common.DAS.Concepts/DAS/DAS.Channel.Data.cs
|
||||
- Common/DTS.Common.DAS.Concepts/DAS/DAS.DAS.Concepts.IShuntAware.cs
|
||||
- Common/DTS.Common.DAS.Concepts/DAS/DAS.Channel.IDecimatable.cs
|
||||
- Common/DTS.Common.DAS.Concepts/DAS/DAS.Id.cs
|
||||
generated_at: "2026-04-16T13:24:05.408874+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "f40aa120b967ad3e"
|
||||
---
|
||||
|
||||
# Documentation: DTS.DAS.Concepts.DAS Module
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides the core domain abstractions for a Data Acquisition System (DAS). It defines the foundational types for modeling DAS channels, their identifiers, data containers, and optional capabilities (such as decimation, level triggering, calibration awareness, and metadata properties). The module uses interfaces and abstract generic classes to establish a flexible, composable type system that can be extended by concrete implementations.
|
||||
|
||||
---
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Classes
|
||||
|
||||
#### `Channel<DataType>`
|
||||
- **Namespace:** `DTS.DAS.Concepts.DAS`
|
||||
- **Signature:** `public abstract class Channel<DataType> : Exceptional`
|
||||
- **Description:** Abstract base class representing a DAS channel. Generic over `DataType`, which defines the type of data contained by channels of this DAS. Inherits from `Exceptional` (from `DTS.Utilities`).
|
||||
|
||||
#### `Data<DatumType>`
|
||||
- **Namespace:** `DTS.DAS.Concepts.DAS.Channel`
|
||||
- **Signature:** `public abstract class Data<DatumType> : ExceptionalList<DatumType>`
|
||||
- **Description:** Abstract base class representing a list of channel data. Inherits from `ExceptionalList<DatumType>`. Provides three protected constructors:
|
||||
- `protected Data()` — Default constructor.
|
||||
- `protected Data(int capacity)` — Initializes with specified capacity.
|
||||
- `protected Data(IEnumerable<DatumType> collection)` — Initializes from an existing collection.
|
||||
|
||||
#### `Id`
|
||||
- **Namespace:** `DTS.Common.DAS.Concepts.DAS`
|
||||
- **Signature:** `public sealed class Id : Exceptional, IComparable<Id>, IEquatable<Id>`
|
||||
- **Description:** Represents a DAS identifier, encapsulating a string value. Supports implicit bidirectional conversion to/from `string`. Comparison and equality operations are case-insensitive (`StringComparison.OrdinalIgnoreCase`).
|
||||
- **Key Members:**
|
||||
- `public Id(string value)` — Constructor.
|
||||
- `public static implicit operator string(Id id)` — Converts `Id` to `string`.
|
||||
- `public static implicit operator Id(string id)` — Converts `string` to `Id`.
|
||||
- `public bool Equals(Id that)` — Case-insensitive equality check.
|
||||
- `public int CompareTo(Id that)` — Case-insensitive comparison.
|
||||
- `public override string ToString()` — Returns the underlying string value.
|
||||
- `public override int GetHashCode()` — Returns hash of the underlying string (or 0 if null).
|
||||
- Static comparison operators: `==`, `!=`, `<`, `>`, `<=`, `>=`.
|
||||
|
||||
---
|
||||
|
||||
### Interfaces
|
||||
|
||||
#### `IIsoCodeAware`
|
||||
- **Namespace:** `DTS.DAS.Concepts.DAS.Channel`
|
||||
- **Members:** `string IsoCode { get; set; }`
|
||||
- **Description:** Defines ISO code awareness for an object.
|
||||
|
||||
#### `ISerialNumberAware`
|
||||
- **Namespace:** `DTS.DAS.Concepts.DAS.Channel`
|
||||
- **Members:** `string SerialNumber { get; set; }`
|
||||
- **Description:** Defines serial number awareness for an object.
|
||||
|
||||
#### `IEngineeringUnitAware`
|
||||
- **Namespace:** `DTS.DAS.Concepts.DAS.Channel`
|
||||
- **Members:** `string EngineeringUnits { get; set; }`
|
||||
- **Description:** Defines engineering unit description awareness for an object.
|
||||
|
||||
#### `IInversionAware`
|
||||
- **Namespace:** `DTS.DAS.Concepts.DAS.Channel`
|
||||
- **Members:** `bool IsInverted { get; set; }`
|
||||
- **Description:** Defines inversion state awareness for an object.
|
||||
|
||||
#### `ILinearized`
|
||||
- **Namespace:** `DTS.DAS.Concepts.DAS.Channel`
|
||||
- **Members:** `LinearizationFormula LinearizationFormula { get; set; }`
|
||||
- **Description:** Defines linearization formula awareness. (Note: `LinearizationFormula` type is referenced but not defined in the provided sources.)
|
||||
|
||||
#### `IVoltageInsertionAware`
|
||||
- **Namespace:** `DTS.DAS.Concepts.DAS.Channel`
|
||||
- **Members:**
|
||||
- `double ExpectedGain { get; set; }` — Measured shunt deflection value.
|
||||
- `double MeasuredGain { get; set; }` — Target shunt deflection value.
|
||||
- **Description:** Defines voltage insertion (shunt-check) awareness.
|
||||
|
||||
#### `ILevelTriggerable`
|
||||
- **Namespace:** `DTS.DAS.Concepts.DAS.Channel`
|
||||
- **Members:**
|
||||
- `double? TriggerBelowThresholdEu { get; set; }` — "Trigger below" threshold; set to `null` to deactivate.
|
||||
- `double? TriggerAboveThresholdEu { get; set; }` — "Trigger above" threshold; set to `null` to deactivate.
|
||||
- `LevelTriggerTypes LevelTriggerType { get; set; }` — The level trigger type.
|
||||
- **Description:** Defines level triggerability for a channel.
|
||||
|
||||
#### `IShuntAware`
|
||||
- **Namespace:** `DTS.DAS.Concepts.DAS.Channel`
|
||||
- **Members:**
|
||||
- `double MeasuredShuntDeflectionMv { get; set; }` — Measured shunt deflection in millivolts.
|
||||
- `double TargetShuntDeflectionMv { get; set; }` — Target shunt deflection in millivolts.
|
||||
- **Description:** Defines shunt-check awareness.
|
||||
|
||||
#### `ICalSignalAware`
|
||||
- **Namespace:** `DTS.DAS.Concepts.DAS.Channel`
|
||||
- **Members:**
|
||||
- `double MeasuredCalSignalMv { get; set; }` — Measured calibration signal in millivolts.
|
||||
- `double TargetCalSignalMv { get; set; }` — Target calibration signal in millivolts.
|
||||
- **Description:** Defines calibration signal awareness.
|
||||
|
||||
#### `IDecimatable<out T>`
|
||||
- **Namespace:** `DTS.DAS.Concepts.DAS.Channel`
|
||||
- **Members:**
|
||||
- `uint PointsPerPoint { get; set; }` — Number of points to squeeze into a single index point.
|
||||
- `DecimationMethod DecimationType { get; set; }` — Decimation method to apply.
|
||||
- `T[] ToDecimatedArray()` — Generates a decimated array using the current `DecimationMethod`.
|
||||
- `T this[long i] { get; }` — Indexer returning values from the decimated set.
|
||||
- **Description:** Defines decimation capability for a DAS channel. Covariant in `T` (`out T`).
|
||||
|
||||
---
|
||||
|
||||
### Enums
|
||||
|
||||
#### `DecimationMethod`
|
||||
- **Namespace:** `DTS.Common.DAS.Concepts.DAS` (also defined in `DTS.DAS.Concepts.DAS.Channel`)
|
||||
- **Values:**
|
||||
- `Point` — Use the value of the `PointsPerPoint`-th point as the representative value.
|
||||
- `Average` — Use the average of the `PointsPerPoint` values.
|
||||
- `PeakMagnitude` — Use the peak magnitude value of the `PointsPerPoint` values.
|
||||
- **Description:** Specifies how to determine the representative value for decimated data sets.
|
||||
|
||||
#### `LevelTriggerTypes`
|
||||
- **Namespace:** `DTS.DAS.Concepts.DAS.Channel`
|
||||
- **Signature:** `[Flags] public enum LevelTriggerTypes`
|
||||
- **Values:**
|
||||
- `NONE = 0x00`
|
||||
- `OutsideWindow = 0x01`
|
||||
- `InsideWindow = 0x02`
|
||||
- `LessThan = 0x04`
|
||||
- `GreaterThan = 0x08`
|
||||
- **Description:** Bitwise flags for specifying level trigger behavior.
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- `Channel<DataType>` is abstract and cannot be instantiated directly; it must be subclassed.
|
||||
- `Data<DatumType>` is abstract and cannot be instantiated directly; it must be subclassed.
|
||||
- `Id` is sealed and cannot be inherited.
|
||||
- `Id.value` is `readonly` — once constructed, the underlying string cannot be changed.
|
||||
- `Id` equality and comparison operations are always case-insensitive (`StringComparison.OrdinalIgnoreCase`).
|
||||
- `IDecimatable<out T>` is covariant in `T`, allowing assignment compatibility for derived types.
|
||||
- `LevelTriggerTypes` is a flags enum; values can be combined with bitwise operations.
|
||||
- Nullable thresholds (`TriggerBelowThresholdEu`, `TriggerAboveThresholdEu`) use `null` to indicate deactivation.
|
||||
|
||||
---
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### This module depends on:
|
||||
- `DTS.Utilities` — Provides `Exceptional` (base class for `Channel<DataType>`) and `ExceptionalList<DatumType>` (base class for `Data<DatumType>`).
|
||||
- `DTS.Common.Utilities` — Provides `Exceptional` (base class for `Id`).
|
||||
- `System` — For `IComparable<T>`, `IEquatable<T>`, `FlagsAttribute`, `StringComparison`.
|
||||
- `System.Collections.Generic` — For `IEnumerable<T>`.
|
||||
|
||||
### What depends on this module:
|
||||
- Not determinable from the provided sources alone. Consumers would typically be concrete DAS channel implementations, data processing pipelines, or configuration systems that implement these interfaces and extend these base classes.
|
||||
|
||||
---
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
1. **Duplicate `DecimationMethod` enum definition:** This enum is defined in two different namespaces:
|
||||
- `DTS.Common.DAS.Concepts.DAS` (in `DecimationMethod.cs`)
|
||||
- `DTS.DAS.Concepts.DAS.Channel` (in `DAS.Channel.IDecimatable.cs`)
|
||||
|
||||
This could cause ambiguity or require explicit namespace qualification when both namespaces are imported.
|
||||
|
||||
2. **Developer uncertainty about `Id` class:** The source contains a comment questioning the class's existence: `"DTM - why does this class exist? it's only encapsulating a string"` and `"why does this class even exist?"` in the XML documentation. This suggests possible tech debt or historical artifact.
|
||||
|
||||
3. **Misleading XML summary in `IVoltageInsertionAware`:** The file header comment references "shunt-check awareness," but the interface is named `IVoltageInsertionAware` and deals with gain values, not shunt deflection directly.
|
||||
|
||||
4. **Undocumented `LinearizationFormula` type:** The `ILinearized` interface references a `LinearizationFormula` type that is not defined in any of the provided source files. Its structure and behavior are unknown from the source alone.
|
||||
|
||||
5. **Namespace inconsistency:** Files use different namespace roots:
|
||||
- `DTS.DAS.Concepts.DAS` (most files)
|
||||
- `DTS.Common.DAS.Concepts.DAS` (`DecimationMethod.cs`, `DAS.Id.cs`)
|
||||
|
||||
This may cause confusion or require multiple `using` directives.
|
||||
@@ -0,0 +1,115 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.DAS.Concepts/DAS/Channel/LevelTriggerTypes.cs
|
||||
- Common/DTS.Common.DAS.Concepts/DAS/Channel/Channel.cs
|
||||
- Common/DTS.Common.DAS.Concepts/DAS/Channel/TimestampPartTypes.cs
|
||||
- Common/DTS.Common.DAS.Concepts/DAS/Channel/Data.cs
|
||||
generated_at: "2026-04-16T02:05:03.519331+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "0f3b00d01b342d9f"
|
||||
---
|
||||
|
||||
# Channel
|
||||
|
||||
## Documentation: DAS Channel Concepts Module
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
This module defines core conceptual types used to represent data acquisition system (DAS) channel behavior and data structures within the DTS Common library. It provides foundational enums (`LevelTriggerTypes`, `TimestampPartTypes`) for configuring trigger conditions and interpreting timestamp components, and abstract base classes (`Channel<TDataType>`, `Data<TDatumType>`) that serve as the basis for concrete channel and data implementations in the DAS subsystem. The module exists to standardize how channel-level logic (e.g., threshold triggers) and data containers are modeled internally, decoupling high-level application logic (e.g., slice control app) from hardware-specific implementations.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### Enums
|
||||
- **`LevelTriggerTypes`** (`[Flags]` enum)
|
||||
Represents configurable trigger conditions for a channel. Values are bit flags:
|
||||
- `NONE = 0x00`: No trigger condition.
|
||||
- `OutsideWindow = 0x01`: Trigger when value is outside a specified window.
|
||||
- `InsideWindow = 0x02`: Trigger when value is inside a specified window.
|
||||
- `LessThan = 0x04`: Trigger when value is less than a threshold.
|
||||
- `GreaterThan = 0x08`: Trigger when value is greater than a threshold.
|
||||
*Note:* Combinations (e.g., `LessThan | GreaterThan`) are valid per `[Flags]` semantics, though semantic validity (e.g., `OutsideWindow` + `InsideWindow`) is not enforced here.
|
||||
|
||||
- **`TimestampPartTypes`** (`[Flags]` enum with `[Description]` attributes)
|
||||
Represents components of a timestamp, typically used for parsing or reconstructing high-precision timestamps. Values are bit flags:
|
||||
- `Marker = 1 << 0` (value `1`): A marker bit (description: `"Marker"`).
|
||||
- `Seconds_High = 1 << 1` (value `2`): High-order bits of seconds (description: `"Seconds"`).
|
||||
- `Seconds_Low = 1 << 2` (value `4`): Low-order bits of seconds (description: `"Seconds"`).
|
||||
- `Nanoseconds_High = 1 << 3` (value `8`): High-order bits of nanoseconds (description: `"Nanoseconds"`).
|
||||
- `Nanoseconds_Low = 1 << 4` (value `16`): Low-order bits of nanoseconds (description: `"Nanoseconds"`).
|
||||
- `Reserved = 1 << 5` (value `32`): Reserved bit (description: `"Reserved"`).
|
||||
*Note:* `Seconds_High` and `Seconds_Low` share the same description `"Seconds"`; similarly for nanosecond components.
|
||||
|
||||
#### Abstract Classes
|
||||
- **`Channel<TDataType>`**
|
||||
Abstract base class representing a DAS channel in the slice control app. Inherits from `Exceptional` (from `DTS.Common.Utilities`).
|
||||
- *Generic parameter:* `TDataType` specifies the type of data the channel carries (e.g., `double`, `int`, custom struct).
|
||||
- *Behavior:* No public methods or properties defined in this source; intended as a base for concrete channel implementations (e.g., `AnalogChannel`, `DigitalChannel`).
|
||||
|
||||
- **`Data<TDatumType>`**
|
||||
Abstract base class representing a list of channel data samples. Inherits from `ExceptionalList<TDatumType>` (from `DTS.Common.Utilities`).
|
||||
- *Generic parameter:* `TDatumType` specifies the type of individual data samples (e.g., `double`, `SampleRecord`).
|
||||
- *Constructors:*
|
||||
- `protected Data()`: Default constructor.
|
||||
- `protected Data(int capacity)`: Constructor with initial list capacity.
|
||||
- `protected Data(IEnumerable<TDatumType> collection)`: Constructor that copies elements from a collection.
|
||||
- *Behavior:* Provides no additional functionality beyond its base list class; intended as a base for concrete data container implementations (e.g., `SampleData`, `EventList`).
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
- **`LevelTriggerTypes`**:
|
||||
- Values are strictly bit flags (`0x00`, `0x01`, `0x02`, `0x04`, `0x08`).
|
||||
- Valid combinations must be powers-of-two or bitwise ORs thereof.
|
||||
- No validation is performed on combinations (e.g., `OutsideWindow | InsideWindow` is syntactically valid but semantically ambiguous).
|
||||
|
||||
- **`TimestampPartTypes`**:
|
||||
- Values are strictly bit flags with explicit bit positions (bits 0–5).
|
||||
- `Seconds_High` and `Seconds_Low` are distinct flags despite sharing a description; similarly for `Nanoseconds_High`/`Low`.
|
||||
- The `Reserved` flag is defined but its usage is unspecified.
|
||||
|
||||
- **`Channel<TDataType>` and `Data<TDatumType>`**:
|
||||
- Both are abstract; direct instantiation is impossible.
|
||||
- No invariants are enforced in the provided source (e.g., no validation of `TDatumType` constraints).
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
#### This module depends on:
|
||||
- `DTS.Common.Utilities`:
|
||||
- Provides `Exceptional` (base class for `Channel<TDataType>`).
|
||||
- Provides `ExceptionalList<T>` (base class for `Data<TDatumType>`).
|
||||
- `System`:
|
||||
- Core types (`System.FlagsAttribute`, `System.ComponentModel.DescriptionAttribute`, `System.ComponentModel.TypeConverterAttribute`).
|
||||
- `DTS.Common.Converters`:
|
||||
- Provides `EnumDescriptionTypeConverter` for `TimestampPartTypes`.
|
||||
|
||||
#### This module is depended on by:
|
||||
- **Inferred consumers**:
|
||||
- Any code referencing `DTS.Common.DAS.Concepts.DAS.Channel` namespace (e.g., concrete channel implementations, trigger logic, timestamp parsers).
|
||||
- The `slice control app` (explicitly mentioned in `Channel<TDataType>` summary) is a direct consumer.
|
||||
- Serialization/deserialization logic likely uses `TimestampPartTypes` (given `TypeConverter` attribute).
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
- **`LevelTriggerTypes` combinations**:
|
||||
- `OutsideWindow` and `InsideWindow` are mutually exclusive in practice but not enforced. Combining them (`OutsideWindow | InsideWindow = 0x03`) may lead to undefined behavior in downstream logic.
|
||||
- `LessThan` and `GreaterThan` can be combined (e.g., for hysteresis), but this is not documented.
|
||||
|
||||
- **`TimestampPartTypes` descriptions**:
|
||||
- `Seconds_High` and `Seconds_Low` share the same `[Description("Seconds")]`; UI/tooling relying solely on `DescriptionAttribute` may not distinguish them.
|
||||
- `Reserved` flag is defined but its purpose is unspecified—avoid using it unless documented elsewhere.
|
||||
|
||||
- **Abstract base classes**:
|
||||
- `Channel<TDataType>` and `Data<TDatumType>` provide no implementation details beyond inheritance. Behavior (e.g., thread safety, sample ordering) must be inferred from concrete subclasses.
|
||||
- `Data<TDatumType>` inherits from `ExceptionalList<T>`, but no information about `ExceptionalList<T>`’s behavior (e.g., exception handling semantics) is provided here.
|
||||
|
||||
- **No versioning or deprecation markers**:
|
||||
- No attributes (e.g., `[Obsolete]`) or version comments indicate deprecated/legacy usage patterns.
|
||||
|
||||
*None identified from source alone.*
|
||||
@@ -0,0 +1,238 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.DAS.Concepts/Interfaces/ITriggerable.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Interfaces/IDataCollectionEnabled.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Interfaces/ICalibratable.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Interfaces/ILargeDataAware.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Interfaces/IRealtimeable.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Interfaces/IGpioEnabled.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Interfaces/IDownloadEnabled.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Interfaces/IArmable.cs
|
||||
generated_at: "2026-04-16T13:24:49.910550+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "097989360eebf93b"
|
||||
---
|
||||
|
||||
# Documentation: DTS.Common.DAS.Concepts Interfaces
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module defines a set of core interfaces that describe the capabilities of Data Acquisition System (DAS) hardware devices. These interfaces model behaviors such as arming, triggering, calibration, real-time data capture, data download, and GPIO manipulation. The design enables polymorphic treatment of different hardware models (TSR, HEADS, NASCAR variants) through capability-based composition rather than inheritance from a monolithic base class.
|
||||
|
||||
---
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `ITriggerable`
|
||||
**Namespace:** `DTS.Common.DAS.Concepts`
|
||||
|
||||
```csharp
|
||||
public interface ITriggerable
|
||||
{
|
||||
void Trigger();
|
||||
}
|
||||
```
|
||||
A minimal interface representing an object that can be triggered. The `Trigger()` method initiates the trigger action on the implementing object.
|
||||
|
||||
---
|
||||
|
||||
### `IArmable`
|
||||
**Namespace:** `DTS.Common.DAS.Concepts`
|
||||
|
||||
```csharp
|
||||
public interface IArmable
|
||||
{
|
||||
void Arm();
|
||||
void Disarm();
|
||||
ArmStatus ArmStatus { get; }
|
||||
AvailableArmModes ArmMode { get; }
|
||||
}
|
||||
```
|
||||
Defines the ability to be armed and disarmed. Implementers must provide:
|
||||
- `Arm()` — transitions the device to an armed state
|
||||
- `Disarm()` — transitions the device to a disarmed state
|
||||
- `ArmStatus` (read-only) — current arm status of type `ArmStatus`
|
||||
- `ArmMode` (read-only) — available arm modes of type `AvailableArmModes`
|
||||
|
||||
**Note:** Types `ArmStatus` and `AvailableArmModes` are referenced but not defined in the provided source files.
|
||||
|
||||
---
|
||||
|
||||
### `IDownloadEnabled`
|
||||
**Namespace:** `DTS.Common.DAS.Concepts`
|
||||
|
||||
```csharp
|
||||
public interface IDownloadEnabled
|
||||
{
|
||||
TsrEvent[] EventList { get; }
|
||||
double[][] GetEventData(TsrEvent Event, ulong FirstSample, ulong LastSample);
|
||||
bool DataHasBeenDownloaded { get; }
|
||||
}
|
||||
```
|
||||
Represents an object from which data can be downloaded:
|
||||
- `EventList` (read-only) — array of `TsrEvent` objects available for download
|
||||
- `GetEventData(TsrEvent Event, ulong FirstSample, ulong LastSample)` — retrieves event data for the specified sample range; returns a jagged array of `double[]` where each inner array corresponds to a channel
|
||||
- `DataHasBeenDownloaded` (read-only) — indicates whether data has been downloaded
|
||||
|
||||
**Note:** Type `TsrEvent` is referenced but not defined in the provided source files.
|
||||
|
||||
---
|
||||
|
||||
### `IDataCollectionEnabled`
|
||||
**Namespace:** `DTS.Common.DAS.Concepts`
|
||||
|
||||
```csharp
|
||||
public interface IDataCollectionEnabled : IArmable, ITriggerable, IDownloadEnabled
|
||||
{
|
||||
double[] AvailableSampleRates { get; }
|
||||
double SampleRate { get; set; }
|
||||
}
|
||||
```
|
||||
Combines arming, triggering, and download capabilities with data collection-specific properties:
|
||||
- `AvailableSampleRates` (read-only) — array of sample rates supported by the device
|
||||
- `SampleRate` (read/write) — the currently configured sample rate
|
||||
|
||||
---
|
||||
|
||||
### `ICalibratable`
|
||||
**Namespace:** `DTS.Common.DAS.Concepts`
|
||||
|
||||
```csharp
|
||||
public interface ICalibratable
|
||||
{
|
||||
string SerialNumber { get; set; }
|
||||
double Sensitivity { get; set; }
|
||||
double BatteryVolts { get; set; }
|
||||
double VddVolts { get; set; }
|
||||
double SignalConditioningVolts { get; set; }
|
||||
}
|
||||
```
|
||||
Defines properties required for rudimentary calibration. All properties are read/write.
|
||||
|
||||
---
|
||||
|
||||
### `IRealtimeable`
|
||||
**Namespace:** `DTS.Common.DAS.Concepts`
|
||||
|
||||
```csharp
|
||||
public class RealtimeSample
|
||||
{
|
||||
public double[] DataEU; // Indexes by channel
|
||||
public ulong SampleNumber;
|
||||
}
|
||||
|
||||
public interface IRealtimeable
|
||||
{
|
||||
void StartRealtime(double sampleRate);
|
||||
void StopRealtime();
|
||||
RealtimeSample[] GetRealtimeSamples();
|
||||
}
|
||||
```
|
||||
Represents the ability to perform real-time data capture:
|
||||
- `StartRealtime(double sampleRate)` — begins real-time capture at the specified rate
|
||||
- `StopRealtime()` — stops real-time capture
|
||||
- `GetRealtimeSamples()` — retrieves an array of `RealtimeSample` objects captured since the last call
|
||||
|
||||
`RealtimeSample` is a companion class containing:
|
||||
- `DataEU` — array of engineering unit values indexed by channel
|
||||
- `SampleNumber` — the sample sequence number (`ulong`)
|
||||
|
||||
---
|
||||
|
||||
### `ILargeDataAware`
|
||||
**Namespace:** `DTS.Common.DAS.Concepts.DAS.Channel`
|
||||
|
||||
```csharp
|
||||
public interface ILargeDataAware
|
||||
{
|
||||
bool IsDataArraySized { get; }
|
||||
}
|
||||
```
|
||||
Defines whether a DAS channel's data set is small enough to safely fit into an array within a "slice" application context (e.g., for filtering or viewer display).
|
||||
|
||||
---
|
||||
|
||||
### `IGpioEnabled`
|
||||
**Namespace:** `DTS.Common.DAS.Concepts`
|
||||
|
||||
```csharp
|
||||
public enum Directions
|
||||
{
|
||||
Output = 0x00,
|
||||
Peripheral = 0x01,
|
||||
Input = 0x02,
|
||||
InputPulledUp = 0x03,
|
||||
InputPulledDown = 0x04
|
||||
}
|
||||
|
||||
public interface IGpioEnabled
|
||||
{
|
||||
void SetGpio(uint Port, uint Pin, Directions Direction, bool State);
|
||||
bool GetGpio(uint Port, uint Pin);
|
||||
}
|
||||
```
|
||||
Represents GPIO functionality:
|
||||
- `SetGpio(uint Port, uint Pin, Directions Direction, bool State)` — configures a GPIO pin with the specified direction and state
|
||||
- `GetGpio(uint Port, uint Pin)` — retrieves the state of the specified GPIO pin
|
||||
|
||||
The `Directions` enum is defined in `DTS.Common.Common.DAS.Concepts.GPIOPin` namespace.
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
1. **Interface Composition:** `IDataCollectionEnabled` requires implementation of `IArmable`, `ITriggerable`, and `IDownloadEnabled`. Any class implementing `IDataCollectionEnabled` must provide all members from these three parent interfaces.
|
||||
|
||||
2. **Sample Rate Validity:** `SampleRate` on `IDataCollectionEnabled` should presumably be one of the values in `AvailableSampleRates`, though this constraint is not explicitly enforced in the interface.
|
||||
|
||||
3. **Sample Range Ordering:** `GetEventData(TsrEvent Event, ulong FirstSample, ulong LastSample)` implies `FirstSample <= LastSample`, but this is not documented.
|
||||
|
||||
4. **Realtime State Machine:** `IRealtimeable` implementations should require `StartRealtime()` to be called before `GetRealtimeSamples()` returns valid data, and `StopRealtime()` to halt sample accumulation.
|
||||
|
||||
5. **GPIO Pin Identification:** GPIO pins are identified by `(Port, Pin)` tuple; valid ranges for these parameters are not specified in the interface.
|
||||
|
||||
---
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### External Types Referenced (Not Defined in Source)
|
||||
| Type | Used In | Notes |
|
||||
|------|---------|-------|
|
||||
| `ArmStatus` | `IArmable` | Enum or class representing arm state |
|
||||
| `AvailableArmModes` | `IArmable` | Enum or class representing arm mode options |
|
||||
| `TsrEvent` | `IDownloadEnabled` | Class representing a downloadable event |
|
||||
|
||||
### Namespace Dependencies
|
||||
- `DTS.Common.Common.DAS.Concepts.GPIOPin` — provides `Directions` enum used by `IGpioEnabled`
|
||||
- `System` — referenced in `IRealtimeable` and `IDownloadEnabled`
|
||||
|
||||
### Interface Inheritance Hierarchy
|
||||
```
|
||||
ITriggerable
|
||||
IArmable
|
||||
IDownloadEnabled
|
||||
└── IDataCollectionEnabled : IArmable, ITriggerable, IDownloadEnabled
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
1. **Undefined Types:** The types `ArmStatus`, `AvailableArmModes`, and `TsrEvent` are referenced in interfaces but not defined in the provided source files. Their definitions must exist elsewhere in the codebase.
|
||||
|
||||
2. **Namespace Inconsistency:** The `Directions` enum is defined in `DTS.Common.Common.DAS.Concepts.GPIOPin` (note the double "Common"), while the interface using it is in `DTS.Common.DAS.Concepts`. This appears to be a naming quirk.
|
||||
|
||||
3. **TODO Comments in `IGpioEnabled`:** The source contains a TODO comment: *"Well have to bring these in as soon as we figure out where to get that enum from."* suggesting the GPIO interface may have been incomplete at the time of writing.
|
||||
|
||||
4. **Commented-Out Members in `IDownloadEnabled`:** Several properties are commented out with a TODO questioning their universal applicability:
|
||||
- `MaximumStoredEventSizeSeconds`
|
||||
- `DownloadIncrementSamples`
|
||||
- `ChannelDescription`
|
||||
- `TimeOffsetMilliseconds`
|
||||
|
||||
5. **Historical Context in `IArmable.cs`:** The file contains extensive email discussion comments regarding TSR model variants (NASCAR, TSRPRO, BlastTestTSR, TSRBasic, HEADSII, NGI) and their channel configurations. This suggests the interfaces were designed to accommodate multiple hardware variants with differing capabilities (e.g., mixed sample rates, varying channel counts and bit depths).
|
||||
|
||||
6. **RealtimeSample Fields Are Public:** The `RealtimeSample` class exposes `DataEU` and `SampleNumber` as public fields rather than properties, which is inconsistent with typical C# property conventions used elsewhere in these interfaces.
|
||||
|
||||
7. **Multi-Rate Data Handling:** Historical comments indicate that some systems (e.g., BlastTestTSR) have channels at different sample rates (40 ksps vs 1 ksps). The current interfaces do not explicitly address how multi-rate scenarios are handled; comments suggest interpolation may occur at a lower level.
|
||||
@@ -0,0 +1,78 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.DAS.Concepts/Interfaces/DAS/Channel/ITimestampAware.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Interfaces/DAS/Channel/ILinearized.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Interfaces/DAS/Channel/IIsoCodeAware.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Interfaces/DAS/Channel/ISerialNumberAware.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Interfaces/DAS/Channel/IInversionAware.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Interfaces/DAS/Channel/IEngineeringUnitAware.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Interfaces/DAS/Channel/ICalSignalAware.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Interfaces/DAS/Channel/IVoltageInsertAware.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Interfaces/DAS/Channel/IShuntAware.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Interfaces/DAS/Channel/ILevelTriggerable.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Interfaces/DAS/Channel/IDecimatable.cs
|
||||
generated_at: "2026-04-16T02:05:30.336536+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "b4d2ceb184c9ded4"
|
||||
---
|
||||
|
||||
# Documentation: DAS Channel Concept Interfaces
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module defines a set of lightweight, composable interfaces that express *concepts*—behavioral or metadata capabilities—applicable to Data Acquisition System (DAS) channels. Each interface encapsulates a single concern (e.g., timestamping, linearization, shunt calibration awareness) to enable flexible, duck-typed composition of channel implementations without requiring deep inheritance hierarchies. These interfaces are used throughout the DAS framework to conditionally apply logic (e.g., calibration validation, decimation, inversion) based on what capabilities an object advertises at runtime.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
All interfaces are *read-write* property containers; none define methods beyond indexers where noted.
|
||||
|
||||
| Interface | Property / Indexer | Type | Description |
|
||||
|-----------|---------------------|------|-------------|
|
||||
| `ITimestampAware` | `TimestampPartType` | `TimestampPartTypes` | Indicates which part(s) of a timestamp (e.g., sample time, acquisition time) are relevant for this channel. |
|
||||
| `ILinearized` | `LinearizationFormula` | `DTS.Common.Classes.Sensors.LinearizationFormula` | Specifies the formula (e.g., polynomial, table-based) used to convert raw ADC values to engineering units. |
|
||||
| `IIsoCodeAware` | `IsoCode` | `string` | Stores the ISO standard code (e.g., "ISO 6876") associated with the channel or sensor. |
|
||||
| `ISerialNumberAware` | `SerialNumber` | `string` | Stores the hardware serial number of the sensor or channel. |
|
||||
| `IInversionAware` | `IsInverted` | `bool` | Indicates whether the channel’s output should be inverted (e.g., for negative-slope sensors). |
|
||||
| `IEngineeringUnitAware` | `EngineeringUnits` | `string` | Human-readable description of the engineering unit (e.g., "psi", "°C"). |
|
||||
| `ICalSignalAware` | `MeasuredCalSignalMv` | `double` | Measured shunt-deflection voltage (in mV) during calibration verification. |
|
||||
| | `TargetCalSignalMv` | `double` | Expected (target) shunt-deflection voltage (in mV) for calibration verification. |
|
||||
| `IVoltageInsertionAware` | `ExpectedGain` | `double` | Expected gain (ratio of output change to input change) during voltage insertion/shunt check. |
|
||||
| | `MeasuredGain` | `double` | Measured gain (ratio of output change to input change) during voltage insertion/shunt check. |
|
||||
| `IShuntAware` | `MeasuredShuntDeflectionMv` | `double` | Measured shunt-deflection voltage (in mV) during shunt calibration. |
|
||||
| | `TargetShuntDeflectionMv` | `double` | Target (nominal) shunt-deflection voltage (in mV) for shunt calibration. |
|
||||
| `ILevelTriggerable` | `SampleAverageADC` | `double?` | Cached ADC sample average used for level-triggering; `null` if not cached. |
|
||||
| | `TriggerBelowThresholdEu` | `double?` | Lower bound threshold (in engineering units); `null` disables below-threshold triggering. |
|
||||
| | `TriggerAboveThresholdEu` | `double?` | Upper bound threshold (in engineering units); `null` disables above-threshold triggering. |
|
||||
| | `LevelTriggerType` | `LevelTriggerTypes` | Specifies the trigger mode (e.g., rising, falling, window). |
|
||||
| `IDecimatable<T>` | `PointsPerPoint` | `uint` | Number of raw data points compressed into one decimated point. |
|
||||
| | `DecimationType` | `DecimationMethod` | Algorithm used for decimation (e.g., mean, min/max, median). |
|
||||
| | `ToDecimatedArray()` | `T[]` | Returns a new array of decimated data using current settings. |
|
||||
| | `this[long i]` | `T` | Indexer returning the *i*-th decimated value (post-decimation indexing). |
|
||||
|
||||
> **Note**: `IDecimatable<T>` is generic. The type parameter `T` represents the data type handled by the channel (e.g., `double`, `float`, or custom sample structs).
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Property semantics**: All properties are *read-write* (get/set) unless explicitly marked nullable (`?`)—in which case `null` is a valid state indicating absence or deactivation (e.g., `TriggerBelowThresholdEu = null` disables that trigger).
|
||||
- **Threshold semantics**: For `ILevelTriggerable`, thresholds in engineering units (`TriggerBelowThresholdEu`, `TriggerAboveThresholdEu`) must be `null` to disable their respective triggers; non-null values are assumed valid and active.
|
||||
- **Decimation indexing**: Implementations of `IDecimatable<T>` must ensure that `this[i]` returns the *i*-th element of the *decimated* sequence, not the raw data. The indexer is read-only and must reflect the current `PointsPerPoint` and `DecimationType`.
|
||||
- **No implicit defaults**: Interfaces do not define default values; consumers must handle `null`, `0`, or `false` explicitly where appropriate.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
- **Internal dependencies**:
|
||||
- `DTS.Common.DAS.Concepts` namespace (inferred from `using` and namespace).
|
||||
- `System` (only `ILevelTriggerable` imports `System`).
|
||||
- Types `TimestampPartTypes`, `LevelTriggerTypes`, `DecimationMethod`, and `LinearizationFormula` are referenced but not defined here—likely defined in `DTS.Common.Classes.Sensors` or adjacent namespaces.
|
||||
- **Consumers**: These interfaces are intended to be *implemented* by channel types (e.g., `Channel`, `SensorChannel`) elsewhere in the DAS framework. They are used for runtime type checking (e.g., `if (channel is IShuntAware) { ... }`) and dependency injection or visitor-style logic.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Naming inconsistency**: `IVoltageInsertAware` (file name) vs. `IVoltageInsertionAware` (interface name in source)—likely a typo in the file name (`IVoltageInsertionAware.cs` is correct per interface declaration).
|
||||
- **Ambiguous `ILevelTriggerable` comment**: The comment about "14042 Flash Clear turns of excitation for s6" is highly specific and may be legacy documentation; its relevance to current implementations is unclear without context.
|
||||
- **Missing `using` directives**: None of the interfaces import external namespaces beyond `System` in `ILevelTriggerable`, so all referenced types (`TimestampPartTypes`, `DecimationMethod`, etc.) must be in the same namespace or globally accessible—no explicit `using` is declared.
|
||||
- **No validation semantics**: Interfaces impose no validation (e.g., `MeasuredShuntDeflectionMv` could be negative or NaN). Consumers must enforce domain constraints.
|
||||
- **`IDecimatable<T>` indexing**: The indexer `this[long i]` is read-only and *must* return decimated values. Implementers must not conflate raw vs. decimated indexing—this is a common source of off-by-one or scale errors.
|
||||
|
||||
None identified beyond those noted above.
|
||||
@@ -0,0 +1,42 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.DAS.Concepts/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T13:24:25.527422+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "b609c89cbf8012d6"
|
||||
---
|
||||
|
||||
# Documentation: AssemblyInfo.cs (DTS.DAS.Concepts)
|
||||
|
||||
## 1. Purpose
|
||||
This file provides assembly-level metadata and configuration for the `DTS.DAS.Concepts` library. It defines the assembly's identity, version information, copyright details, and COM visibility settings. It acts as the manifest header for the compiled component, ensuring the library is correctly identified by the .NET runtime and host applications.
|
||||
|
||||
## 2. Public Interface
|
||||
This file does not contain public classes, methods, or functions. It applies assembly-level attributes that affect the compiled DLL.
|
||||
|
||||
**Attributes Defined:**
|
||||
* **`AssemblyTitle`**: Set to `"DTS.DAS.Concepts"`. Provides a friendly name for the assembly.
|
||||
* **`AssemblyDescription`**: Set to an empty string.
|
||||
* **`AssemblyCompany`**: Set to `"DTS"`.
|
||||
* **`AssemblyProduct`**: Set to `"DTS.DAS.Concepts"`.
|
||||
* **`AssemblyCopyright`**: Set to `"Copyright © DTS 2008"`.
|
||||
* **`AssemblyVersion`**: Set to `"1.06.0081"`. Defines the version used by the common language runtime.
|
||||
* **`AssemblyFileVersion`**: Set to `"1.06.0081"`. Defines the version displayed in the file properties.
|
||||
* **`ComVisible`**: Set to `false`. Makes types in this assembly invisible to COM components.
|
||||
* **`Guid`**: Set to `"9b6f7402-27d3-4cc9-9ff3-3cfe16e0b429"`. Unique identifier for the assembly if exposed to COM.
|
||||
|
||||
## 3. Invariants
|
||||
* **COM Visibility:** All types within this assembly are not visible to COM components by default (`ComVisible(false)`). This must be explicitly overridden on specific types if COM interop is required.
|
||||
* **Version Synchronization:** The `AssemblyVersion` and `AssemblyFileVersion` are maintained as identical strings (`"1.06.0081"`).
|
||||
|
||||
## 4. Dependencies
|
||||
* **Internal Dependencies:**
|
||||
* `System.Reflection`: Required for the assembly metadata attributes.
|
||||
* `System.Runtime.InteropServices`: Required for the `ComVisible` and `Guid` attributes.
|
||||
* **External Dependencies:** None identified from this file alone. The assembly described (`DTS.DAS.Concepts`) is likely a domain-level library, but its specific code dependencies are not visible here.
|
||||
|
||||
## 5. Gotchas
|
||||
* **Naming Discrepancy:** The source file path includes `DTS.Common.DAS.Concepts`, but the `AssemblyTitle` and `AssemblyProduct` attributes define the name as `"DTS.DAS.Concepts"` (omitting "Common"). This may cause confusion when referencing the DLL versus the project folder.
|
||||
* **Legacy Structure:** The use of an explicit `AssemblyInfo.cs` for versioning suggests an older .NET Framework project structure (pre-SDK style). Modern projects often auto-generate this information, so manual updates here might be ignored if the project SDK is configured to override them, or conversely, this file might be the source of truth requiring manual updates during releases.
|
||||
* **Hardcoded Version:** The version `1.06.0081` is hardcoded. Developers must remember to update this string manually for new releases; it does not appear to use automatic versioning (e.g., wildcard `1.0.*`).
|
||||
177
enriched-qwen3-coder-next/Common/DTS.Common.DAS.Concepts/Test.md
Normal file
177
enriched-qwen3-coder-next/Common/DTS.Common.DAS.Concepts/Test.md
Normal file
@@ -0,0 +1,177 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.DAS.Concepts/Test/Test.Module.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Test/Test.Module.Channel.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Test/Test.Module.Channel.Sensor.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Test/Test.Module.Channel.Sensor.Bridge.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Test/Test.Module.Channel.Sensor.SensorUnits.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Test/Test.Module.Channel.Sensor.ZeroMethod.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Test/Test.Module.RecordingMode.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Test/Test.Module.Channel.Sensor.ExcitationVoltage.cs
|
||||
generated_at: "2026-04-16T13:23:48.867702+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "f6582d95b5debe26"
|
||||
---
|
||||
|
||||
# Documentation: DTS.DAS.Concepts.Test Module
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides a hierarchical container structure for Data Acquisition System (DAS) concepts related to test configuration. It defines enumerations and utility classes for sensor configuration (bridge types, coupling modes, excitation voltages, sensitivity units, zero methods) and module recording modes. The structure follows a containment hierarchy of `Test` → `Module` → `Channel` → `Sensor`, where each level serves as a static container for related concepts rather than an instantiable object.
|
||||
|
||||
---
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Container Classes (Non-instantiable)
|
||||
|
||||
| Class | Location | Description |
|
||||
|-------|----------|-------------|
|
||||
| `Test` | namespace root | Partial class; outer container. See `Test.cs` (not provided). |
|
||||
| `Test.Module` | nested in `Test` | Sealed partial class; container for module concepts. Private constructor. |
|
||||
| `Test.Module.Channel` | nested in `Module` | Sealed partial class; container for channel concepts. Private constructor. |
|
||||
| `Test.Module.Channel.Sensor` | nested in `Channel` | Sealed partial class; container for sensor concepts. Private constructor. |
|
||||
|
||||
### Enumerations
|
||||
|
||||
#### `Test.Module.Channel.Sensor.CouplingModes`
|
||||
IEPE coupling modes.
|
||||
- `AC` — Description: "AC"
|
||||
- `DC` — Description: "AC/DC"
|
||||
|
||||
#### `Test.Module.Channel.Sensor.BridgeType`
|
||||
Bridge/sensor types using bit-flag values.
|
||||
- `IEPE` = `1 << 0` — Description: "IEPE"
|
||||
- `QuarterBridge` = `1 << 1` — Description: "Quarter"
|
||||
- `HalfBridge` = `1 << 2` — Description: "Bridge-Half"
|
||||
- `FullBridge` = `1 << 3` — Description: "Bridge-Full"
|
||||
- `DigitalInput` = `1 << 4` — Description: "DigitalInput"
|
||||
- `SQUIB` = `1 << 5` — Description: "SQUIB"
|
||||
- `TOMDigital` = `1 << 6` — Description: "TOMDigital"
|
||||
|
||||
#### `Test.Module.Channel.Sensor.SensUnits`
|
||||
Sensitivity unit types.
|
||||
- `NONE` = 0 — Description: "NONE" (Polynomial Sensor)
|
||||
- `mV` = 1 — Description: "mV"
|
||||
- `mVperV` = 2 — Description: "mV/V"
|
||||
- `mVperVperEU` = 3 — Description: "mV/V/EU"
|
||||
- `mVperEU` = 4 — Description: "mV/EU"
|
||||
|
||||
#### `Test.Module.Channel.Sensor.ZeroMethodType`
|
||||
Zero calculation methods (explicit values for legacy compatibility).
|
||||
- `AverageOverTime` = 0 — Description: "Average Over Time"
|
||||
- `UsePreEventDiagnosticsZero` = 1 — Description: "Use Diagnostics Zero"
|
||||
- `None` = 2 — Description: "Absolute Zero"
|
||||
|
||||
#### `Test.Module.Channel.Sensor.OriginalZeroMethodType`
|
||||
Original version of zero method types (implicit values).
|
||||
- `AverageOverTime` — Description: "Average Over Time"
|
||||
- `UsePreCalZero` — Description: "Use Diagnostics Zero"
|
||||
- `None` — Description: "Absolute Zero"
|
||||
|
||||
#### `Test.Module.RecordingMode`
|
||||
Recording mode options.
|
||||
- `InvalidArmMode` = 0 — Description: "Invalid arm mode"
|
||||
- `CircularBuffer` = 1 — Description: "Circular buffer"
|
||||
- `RecorderMode` = 2 — Description: "Recorder mode"
|
||||
- `AutoCircularBufferMode` = 4 — Description: "Circular buffer Multiple-Events"
|
||||
- `AutoRecorderMode` = 5 — Description: "Recorder mode Multiple-Events"
|
||||
- `ImmediateMode` = 0x06 — Description: "Immediate mode"
|
||||
- `HighPowerRecorderMode` = 0x07 — Description: "High Power mode"
|
||||
- `LowPowerRecorderMode` = 0x08 — Description: "Low Power mode"
|
||||
- `ContinuousRecorderMode` = 0x09 — Description: "Continuous mode"
|
||||
- `HybridRecorderMode` = 0x0A — Description: "Hybrid mode"
|
||||
- `MultiHybridRecorderMode` = 0x0B — Description: "Hybrid mode Multiple-Events"
|
||||
|
||||
#### `Test.Module.Channel.Sensor.ExcitationVoltageOption`
|
||||
Excitation voltage options with associated magnitude attributes.
|
||||
- `Undefined` = 1 — `[VoltageMagnitude(0.0)]` — Description: "Undefined"
|
||||
- `Volt2` = 2 — `[VoltageMagnitude(2.0)]` — Description: "2.0"
|
||||
- `Volt2_5` = 4 — `[VoltageMagnitude(2.5)]` — Description: "2.5"
|
||||
- `Volt3` = 8 — `[VoltageMagnitude(3.0)]` — Description: "3.0"
|
||||
- `Volt5` = 16 — `[VoltageMagnitude(5.0)]` — Description: "5.0"
|
||||
- `Volt10` = 32 — `[VoltageMagnitude(10.0)]` — Description: "10.0"
|
||||
- `Volt1` = 64 — `[VoltageMagnitude(1.0)]` — Description: "1.0"
|
||||
|
||||
### Public Methods
|
||||
|
||||
#### `Test.Module.GetRecordingModeFromString`
|
||||
```csharp
|
||||
public static RecordingMode GetRecordingModeFromString(string recordingMode)
|
||||
```
|
||||
Converts a string representation of a recording mode enumeration into its corresponding `RecordingMode` value. Throws `Exception` if parsing fails or input is invalid.
|
||||
|
||||
#### `Test.Module.Channel.Sensor.GetExcitationVoltageMagnitudeFromEnum`
|
||||
```csharp
|
||||
public static double GetExcitationVoltageMagnitudeFromEnum(ExcitationVoltageOption target)
|
||||
```
|
||||
Extracts the numeric voltage magnitude from an `ExcitationVoltageOption` using the `VoltageMagnitudeAttribute`. Throws `Exception` on failure.
|
||||
|
||||
#### `Test.Module.Channel.Sensor.GetExcitationVoltageEnumFromMagnitude`
|
||||
```csharp
|
||||
public static ExcitationVoltageOption GetExcitationVoltageEnumFromMagnitude(double magnitude)
|
||||
```
|
||||
Converts a voltage magnitude to the corresponding `ExcitationVoltageOption`. Throws `NotSupportedException` if no matching enum exists.
|
||||
|
||||
### Nested Classes
|
||||
|
||||
#### `Test.Module.Channel.Sensor.VoltageMagnitudeAttribute`
|
||||
```csharp
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class VoltageMagnitudeAttribute : System.Attribute
|
||||
```
|
||||
Custom attribute for attaching a `double` magnitude value to enum fields.
|
||||
- Constructor: `VoltageMagnitudeAttribute(double value)`
|
||||
- Property: `Value` (readonly `double`)
|
||||
|
||||
#### `Test.Module.Channel.Sensor.VoltageMagnitudeAttributeCoder`
|
||||
```csharp
|
||||
public class VoltageMagnitudeAttributeCoder : AttributeCoder<ExcitationVoltageOption, VoltageMagnitudeAttribute, double>
|
||||
```
|
||||
Utility class for encoding/decoding voltage magnitude values to/from `ExcitationVoltageOption` enum values. Inherits from `AttributeCoder<TEnum, TAttribute, TValue>` (defined in `DTS.Utilities`).
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Non-instantiation**: `Module`, `Channel`, and `Sensor` classes have private constructors and are not intended for instantiation. They serve as static containers only.
|
||||
- **Enum value stability**: `ZeroMethodType` enum values are explicitly defined (0, 1, 2) to maintain legacy compatibility with GM ISF imports. The order/values must not be changed.
|
||||
- **Bit-flag pattern**: `BridgeType` enum uses bit-shifted values (`1 << n`), suggesting these may be used as flags for bitwise operations.
|
||||
- **Non-contiguous enum values**: `ExcitationVoltageOption` uses non-contiguous values (1, 2, 4, 8, 16, 32, 64) that do not follow a simple bit-flag pattern.
|
||||
- `RecordingMode` uses a mix of decimal and hexadecimal explicit values.
|
||||
|
||||
---
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Imports Used by This Module
|
||||
- `System` — Core .NET types, `Exception`, `NotSupportedException`, `AttributeUsage`
|
||||
- `System.ComponentModel` — `DescriptionAttribute` for enum display names
|
||||
- `DTS.Utilities` — `AttributeCoder<TEnum, TAttribute, TValue>` base class
|
||||
|
||||
### External References
|
||||
- `Test.cs` — Referenced in comments but not provided; likely contains the root `Test` partial class definition.
|
||||
|
||||
### Dependents
|
||||
- Cannot be determined from source alone. Other modules likely consume these enums and utility methods for test configuration and sensor setup.
|
||||
|
||||
---
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
1. **Legacy enum compatibility**: The comment in `ZeroMethodType` explicitly warns that "Lots of legacy compatibility (e.g. importing GM ISF) depends on the order/value of this enum." Modifying these values will break backward compatibility.
|
||||
|
||||
2. **Duplicate zero method enums**: Two enums exist for zero methods (`ZeroMethodType` and `OriginalZeroMethodType`) with slightly different member names (`UsePreEventDiagnosticsZero` vs `UsePreCalZero`). The relationship between them and which should be used for new code is unclear from source alone.
|
||||
|
||||
3. **Incomplete documentation**: Several `RecordingMode` enum members have "???" in their XML documentation comments, indicating incomplete or missing descriptions:
|
||||
- `ImmediateMode`
|
||||
- `HighPowerRecorderMode`
|
||||
- `LowPowerRecorderMode`
|
||||
- `ContinuousRecorderMode`
|
||||
- `HybridRecorderMode`
|
||||
- `MultiHybridRecorderMode`
|
||||
|
||||
4. **Non-standard enum values**: `ExcitationVoltageOption` enum values (1, 2, 4, 8, 16, 32, 64) are powers of 2 but `Undefined` starts at 1 rather than 0, and the values don't align with typical bit-flag usage patterns.
|
||||
|
||||
5. **File name mismatch**: The file `Test.Module.Channel.Sensor.SensorUnits.cs` has a header comment referencing "Test.Module.Channel.Sensor.ExcitationVoltage.cs" — appears to be a copy-paste error.
|
||||
@@ -0,0 +1,235 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.DAS.Concepts/Test/Module/RecordingMode.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Test/Module/TiltAxes.cs
|
||||
generated_at: "2026-04-16T02:05:00.800450+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "d40daed59089dfb4"
|
||||
---
|
||||
|
||||
# Module
|
||||
|
||||
## Documentation: `DTS.Common.DAS.Concepts.Test.Module`
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
|
||||
This module provides utility types and methods for handling tilt sensor configuration and computation within the DTS DAS (Data Acquisition System) framework. It encapsulates domain-specific concepts such as axis labeling, polarity inversion, mounting offsets, and calibration-aware conversion of raw ADC values to tilt angles in degrees. The module supports dynamic axis ordering (e.g., `IXYIZ`, `ZYX`) and ignored axes, enabling flexible tilt sensor mounting configurations. It also includes string ↔ enumeration conversion helpers and core tilt calculation logic used in calibration and real-time data processing.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
All public members reside within the nested `Test.Module` class.
|
||||
|
||||
#### **`GetRecordingModeFromString(string recordingMode)`**
|
||||
```csharp
|
||||
public static DFConstantsAndEnums.RecordingMode GetRecordingModeFromString(string recordingMode)
|
||||
```
|
||||
- **Behavior**: Parses the input string into a `DFConstantsAndEnums.RecordingMode` enum value using `Enum.Parse`. Throws an `Exception` (wrapping the original) if parsing fails or input is `null`.
|
||||
|
||||
#### **`TiltAxis` class**
|
||||
```csharp
|
||||
public class TiltAxis
|
||||
{
|
||||
public int AxisNumber { get; set; }
|
||||
public double CurrentTilt { get; set; }
|
||||
public string Label { get; set; }
|
||||
public int Inversion { get; set; } = 1;
|
||||
public bool IsIgnored { get; set; } = false;
|
||||
public double MountedOffset { get; set; } = 0.0;
|
||||
public double TargetOffset { get; set; } = 0.0;
|
||||
}
|
||||
```
|
||||
- **Purpose**: Represents a single tilt sensor axis configuration. Properties define axis identity, current measurement, label (`X`, `Y`, `Z`), inversion factor (`+1` or `-1`), ignore flag, and offset values (in degrees).
|
||||
|
||||
#### **`TiltAxesHelper` class**
|
||||
```csharp
|
||||
public class TiltAxesHelper
|
||||
{
|
||||
public Dictionary<int, TiltAxis> AxisConfigurations { get; set; }
|
||||
public TiltAxis AxisOne { get; set; }
|
||||
public TiltAxis AxisTwo { get; set; }
|
||||
public double LevelTolerance { get; set; } = 0.5;
|
||||
public TiltAxesHelper();
|
||||
public TiltAxesHelper(string TiltAxes, double MountOffsetAxisOne, double MountOffsetAxisTwo,
|
||||
double TargetAxisOne, double TargetAxisTwo, double LevelTolerance,
|
||||
int AxisIgnored, bool UseForTiltCalculation);
|
||||
public string AxesToString();
|
||||
}
|
||||
```
|
||||
- **Behavior**:
|
||||
- Default constructor initializes `AxisConfigurations` with keys `1`, `2`, `3`, each containing a new `TiltAxis`.
|
||||
- Parameterized constructor parses a `TiltAxes` string (e.g., `"IXIYIZ"`) to populate `AxisConfigurations[i].Label` and `Inversion`, sets `IsIgnored` for the specified axis, and assigns `AxisOne`/`AxisTwo` references to the *non-ignored* axes.
|
||||
- **Bug Note**: In the constructor, `AxisOne = AxisConfigurations[2];` is assigned twice when `AxisIgnored == 2` (should likely be `AxisTwo = AxisConfigurations[3];`).
|
||||
- `AxesToString()`: Reconstructs the orientation string from `AxisConfigurations` (e.g., `"IXIYIZ"` → `"IXIYIZ"`).
|
||||
|
||||
#### **`TiltAxesSimple` enum**
|
||||
```csharp
|
||||
public enum TiltAxesSimple
|
||||
{
|
||||
XYZ = 0, XZY = 1, YXZ = 2, YZX = 3, ZXY = 4, ZYX = 5
|
||||
}
|
||||
```
|
||||
- Represents the simplified axis ordering (ignoring inversion markers `I`).
|
||||
|
||||
#### **`SimplifyTiltAxes(TiltAxes axes)`**
|
||||
```csharp
|
||||
public static TiltAxesSimple SimplifyTiltAxes(TiltAxes axes)
|
||||
```
|
||||
- **Behavior**: Strips `I` characters from `axes.ToString()` and parses the result into `TiltAxesSimple`.
|
||||
|
||||
#### **`GetTiltAxesFromString(string tiltAxes)`**
|
||||
```csharp
|
||||
public static TiltAxes GetTiltAxesFromString(string tiltAxes)
|
||||
```
|
||||
- **Behavior**: Parses the input string into a `TiltAxes` enum value using `Enum.Parse`. Throws an `Exception` (wrapping the original) on failure.
|
||||
|
||||
#### **`GetPolaritiesFromTiltAxes(TiltAxes ta)`**
|
||||
```csharp
|
||||
public static int[] GetPolaritiesFromTiltAxes(TiltAxes ta)
|
||||
```
|
||||
- **Behavior**: Returns an array of `+1` or `-1` for each axis, where `-1` corresponds to an `I` (inverted) axis in the `TiltAxes` string.
|
||||
|
||||
#### **`GetBoolPolaritiesFromTiltAxes(TiltAxes tiltAxes)`**
|
||||
```csharp
|
||||
public static bool[] GetBoolPolaritiesFromTiltAxes(TiltAxes tiltAxes)
|
||||
```
|
||||
- **Behavior**: Returns a `bool[3]` where `true` indicates an inverted axis (`I`), `false` indicates non-inverted (`P`). Iterates over the string representation, setting `rv[ax] = true` when encountering `'I'`, and increments `ax` only on non-`I` characters.
|
||||
|
||||
#### **`TiltSensorCalAttributes` enum**
|
||||
```csharp
|
||||
public enum TiltSensorCalAttributes
|
||||
{
|
||||
TILTSENSOR_CAL_1_GainAxis1 = 0,
|
||||
TILTSENSOR_CAL_2_ZeroAxis1 = 1,
|
||||
TILTSENSOR_CAL_3_ZeroDomAxis2PosAxis1 = 2,
|
||||
TILTSENSOR_CAL_4_ZeroDomAxis2NegAxis1 = 3,
|
||||
TILTSENSOR_CAL_5_ZeroDomAxis3PosAxis1 = 4,
|
||||
TILTSENSOR_CAL_6_ZeroDomAxis3NegAxis1 = 5,
|
||||
TILTSENSOR_CAL_7_GainAxis2 = 6,
|
||||
TILTSENSOR_CAL_8_ZeroAxis2 = 7,
|
||||
TILTSENSOR_CAL_9_ZeroDomAxis1PosAxis2 = 8,
|
||||
TILTSENSOR_CAL_10_ZeroDomAxis1NegAxis2 = 9,
|
||||
TILTSENSOR_CAL_11_ZeroDomAxis3PosAxis2 = 10,
|
||||
TILTSENSOR_CAL_12_ZeroDomAxis3NegAxis2 = 11,
|
||||
TILTSENSOR_CAL_13_GainAxis3 = 12,
|
||||
TILTSENSOR_CAL_14_ZeroAxis3 = 13,
|
||||
TILTSENSOR_CAL_15_ZeroDomAxis1PosAxis3 = 14,
|
||||
TILTSENSOR_CAL_16_ZeroDomAxis1NegAxis3 = 15,
|
||||
TILTSENSOR_CAL_17_ZeroDomAxis2PosAxis3 = 16,
|
||||
TILTSENSOR_CAL_18_ZeroDomAxis3NegAxis3 = 17,
|
||||
}
|
||||
```
|
||||
- Defines indices into the `tiltSensorCals` array for calibration parameters.
|
||||
|
||||
#### **`GetTiltDegreesEU(...)` overloads**
|
||||
```csharp
|
||||
public static double[] GetTiltDegreesEU(short[] tiltSensorADC, double[] tiltSensorCals);
|
||||
public static double[] GetTiltDegreesEU(short[] tiltSensorADC, double[] tiltSensorCals,
|
||||
TiltAxes axes, int ignoredAxis, float[] mountOffsetAxis);
|
||||
```
|
||||
- **Behavior**: Converts raw ADC values (`tiltSensorADC`, length ≥ 3) to tilt angles (degrees) using calibration data (`tiltSensorCals`, length ≥ 18). Returns a `double[3]` where the ignored axis is `double.NaN`, and the other two axes are computed and rounded to 3 decimal places (via `SIGNIFICANT_DIGITS = 1000`).
|
||||
- Uses `GetDominantTiltAxis`, `GetTiltGains`, `GetTiltZeroData`, and axis-specific scaling factors (`xFactor`, `yFactor`, `zFactor`) derived from `axes`.
|
||||
- Applies mounting offsets from `mountOffsetAxis[0]` and `mountOffsetAxis[1]` to the non-ignored axes.
|
||||
|
||||
#### **`GetTiltZeroData(...)`**
|
||||
```csharp
|
||||
public static double[] GetTiltZeroData(short[] tiltSensorADC, double[] tiltSensorCals, int dominantAxis)
|
||||
```
|
||||
- **Behavior**: Returns a `double[3]` of zero-point offsets. Uses base zero values (`TILTSENSOR_CAL_2/8/14`) and conditionally overrides them with dominant-axis-specific values (`TILTSENSOR_CAL_3/4`, `9/10`, `15/16`, etc.) based on the sign of `tiltSensorADC[dominantAxis]`.
|
||||
|
||||
#### **`GetDominantTiltAxis(...)`**
|
||||
```csharp
|
||||
public static int GetDominantTiltAxis(short[] tiltSensorADC)
|
||||
```
|
||||
- **Behavior**: Returns the index (`0`, `1`, or `2`) of the axis with the largest absolute ADC value.
|
||||
|
||||
#### **`GetTiltGains(...)`**
|
||||
```csharp
|
||||
public static double[] GetTiltGains(double[] tiltSensorCals)
|
||||
```
|
||||
- **Behavior**: Returns a `double[3]` of gain values (`TILTSENSOR_CAL_1/7/13`). Uses `1.0` if a gain is `0.0`.
|
||||
|
||||
#### **`AxisLabel` enum**
|
||||
```csharp
|
||||
public enum AxisLabel { X = 0, Y = 1, Z = 2 }
|
||||
```
|
||||
|
||||
#### **`GetAxisLabelFromTiltAxes(...)` overloads**
|
||||
```csharp
|
||||
public static AxisLabel[] GetAxisLabelFromTiltAxes(TiltAxes tiltAxes);
|
||||
public static AxisLabel[] GetAxisLabelFromTiltAxes(string tiltAxes);
|
||||
```
|
||||
- **Behavior**: Returns an `AxisLabel[3]` array corresponding to the non-`I` characters in the `TiltAxes` string (e.g., `"IXYIZ"` → `[Y, Z, X]`).
|
||||
|
||||
#### **`ConvertBoolToInvertString(bool isInverted)`**
|
||||
```csharp
|
||||
public static string ConvertBoolToInvertString(bool isInverted)
|
||||
```
|
||||
- **Behavior**: Returns `"I"` if `isInverted` is `true`, else `""`.
|
||||
|
||||
#### **`GetOrientationLabelFromAxisInfo(...)`**
|
||||
```csharp
|
||||
public static string GetOrientationLabelFromAxisInfo(string[] axisLabels, bool[] invertAxis)
|
||||
```
|
||||
- **Behavior**: Concatenates `invertAxis[i] ? "I" : ""` + `axisLabels[i]` for each axis (e.g., `["X","Y","Z"]`, `[true,false,false]` → `"IXYZ"`).
|
||||
|
||||
#### **`GetTiltAxesFromAxisInfo(...)`**
|
||||
```csharp
|
||||
public static TiltAxes GetTiltAxesFromAxisInfo(string[] axisLabels, bool[] invertAxis)
|
||||
```
|
||||
- **Behavior**: Calls `GetOrientationLabelFromAxisInfo`, then `GetTiltAxesFromString`.
|
||||
|
||||
#### **`GetMountOffsetsOrTargetsFromAxisInfo(...)`**
|
||||
```csharp
|
||||
public static float[] GetMountOffsetsOrTargetsFromAxisInfo(float[] perAxisValue, int axisToIgnore)
|
||||
```
|
||||
- **Behavior**: Returns a `float[2]` containing the values for the two *non-ignored* axes. `axisToIgnore` is `1`, `2`, or `3` (1-indexed).
|
||||
- Example: `axisToIgnore=1` → `[perAxisValue[1], perAxisValue[2]]`.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
|
||||
- **`TiltAxes` string format**: Must be 6 characters long, alternating axis label (`X`, `Y`, `Z`) and polarity (`P` or `N`). Inversion is represented by `I` (e.g., `IX`), but `I` is *not* a label—it is a polarity marker.
|
||||
- Valid examples: `"IXIYIZ"`, `"IXYZ"`, `"ZYX"`, `"IXZIY"`.
|
||||
- Invalid: `"IXIY"` (length ≠ 6), `"IXIXIX"` (repeated labels), `"IXIYIP"` (invalid polarity).
|
||||
- **`TiltAxesSimple` values**: Derived by removing all `I` characters from `TiltAxes.ToString()`. Must be a permutation of `"XYZ"`.
|
||||
- **`GetTiltDegreesEU` output**: The ignored axis is always `double.NaN`; the other two axes are rounded to 3 decimal places.
|
||||
- **Calibration array indexing**: `tiltSensorCals` must have ≥ 18 elements; indices correspond strictly to `TiltSensorCalAttributes`.
|
||||
- **`GetDominantTiltAxis`**: Uses the axis with the largest absolute value (handles negative ADCs correctly).
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
- **Imports/Usings**:
|
||||
- `DTS.Common.Enums.DASFactory.DFConstantsAndEnums` (for `RecordingMode`, `TiltAxes`)
|
||||
- `DTS.Common.Utilities` (likely contains `DegreesFromADC`)
|
||||
- `System`, `System.Collections.Generic`, `System.Linq`, `System.Text`, `System.ComponentModel`
|
||||
- **External Types Used**:
|
||||
- `DFConstantsAndEnums.RecordingMode` (enum)
|
||||
- `DTS.Common.Enums.DASFactory.DFConstantsAndEnums.TiltAxes` (enum, defined elsewhere)
|
||||
- `DTS.Common.Utilities.DegreesFromADC.GetDegrees(...)` (used in `GetTiltDegreesEU`)
|
||||
- **Depended Upon By**:
|
||||
- Likely used by tilt sensor drivers, calibration tools, and data processing pipelines (e.g., `DataPRO`—per comment in `SIGNIFICANT_DIGITS`).
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
|
||||
- **Constructor Bug in `TiltAxesHelper`**: When `AxisIgnored == 2`, `AxisOne` is assigned twice (`AxisConfigurations[1]`), and `AxisTwo` is never set. Likely should be:
|
||||
```csharp
|
||||
AxisOne = AxisConfigurations[1];
|
||||
AxisTwo = AxisConfigurations[3]; // but note: AxisConfigurations is 1-indexed!
|
||||
```
|
||||
However, `AxisConfigurations` uses keys `1`, `2`, `3`, but `TiltAxis.AxisNumber` is not initialized in the constructor—this may cause off-by-one errors if `AxisNumber` is expected to match the dictionary key.
|
||||
- **`TiltAxes` Enum Values**: The source file does *not* define the `TiltAxes` enum itself (only uses it). Its members (e.g., `IXYIZ`, `ZYX`) are assumed to exist in `DFConstantsAndEnums`. The code assumes all permutations with optional `I` are valid enum values.
|
||||
- **`GetTiltZeroData` Logic**: Uses `dominantAxis` to select *dominant-axis-specific* zero points. This is non-trivial: zero points differ based on which axis is dominant (e.g., `ZeroDomAxis1PosAxis2` vs `ZeroDomAxis1NegAxis2`).
|
||||
- **`SIGNIFICANT_DIGITS = 1000`**: Hardcoded to enforce 3 decimal places (0.001 precision). This is a legacy design choice (see internal case 34373).
|
||||
- **`GetTiltDegreesEU` ADC Indexing**: Assumes `tiltSensorADC[0]`, `[1]`, `[2]` correspond to the physical axes *in the order they appear in the calibration array*, not the `TiltAxes` label order. The `axes` parameter only affects sign and axis assignment in the output array.
|
||||
- **`GetBoolPolaritiesFromTiltAxes`**: The loop increments `ax` only on non-`I` characters, so the resulting `bool[]` is *not* aligned with the original axis order if `I` is present. For `"IXYIZ"`, `rv[0]` corresponds to `Y`, `rv[1]` to `Z`, `rv[2]` to `X`—this may be counterintuitive.
|
||||
- **`GetPolaritiesFromTiltAxes`**: Returns `+1` for `P`, `-1` for `I`, but the mapping is based on the same non-`I`-indexed logic as `GetBoolPolaritiesFromTiltAxes`.
|
||||
@@ -0,0 +1,108 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.DAS.Concepts/Test/Module/Channel/Sensor/SensorUnits.cs
|
||||
- Common/DTS.Common.DAS.Concepts/Test/Module/Channel/Sensor/ExcitationVoltage.cs
|
||||
generated_at: "2026-04-16T02:04:34.963354+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "00bbefe8072cdb62"
|
||||
---
|
||||
|
||||
# Sensor
|
||||
|
||||
## Documentation Page: Sensor Unit and Excitation Voltage Handling in `DTS.Common.DAS.Concepts.Test.Module.Channel.Sensor`
|
||||
|
||||
---
|
||||
|
||||
### 1. **Purpose**
|
||||
|
||||
This module provides supporting infrastructure for sensor channel configuration within the DTS DAS (Data Acquisition System) concepts framework—specifically, it defines the enumeration of sensitivity unit types (`SensUnits`) used to interpret sensor calibration data, and provides utility methods for converting between excitation voltage options and their numeric magnitudes (e.g., 2.0 V, 5.0 V). It exists to standardize how sensor sensitivity and excitation conditions are represented and transformed across the system, enabling consistent scaling and unit conversion for physical measurements.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
|
||||
All public members reside within the nested type hierarchy `Test.Module.Channel.Sensor`.
|
||||
|
||||
#### **`SensUnits` Enum**
|
||||
- **Namespace**: `DTS.Common.DAS.Concepts.Test.Module.Channel.Sensor`
|
||||
- **Definition**:
|
||||
```csharp
|
||||
public enum SensUnits
|
||||
{
|
||||
NONE = 0,
|
||||
mV = 1,
|
||||
mVperV = 2,
|
||||
mVperVperEU = 3,
|
||||
mVperEU = 4
|
||||
}
|
||||
```
|
||||
- **Behavior**:
|
||||
- Represents the unit types for sensor sensitivity.
|
||||
- Each value has a `[Description]` attribute indicating its human-readable form (e.g., `"mV/V/EU"` for `mVperVperEU`).
|
||||
- `NONE` indicates a polynomial sensor (no sensitivity unit).
|
||||
- Values are mutually exclusive and exhaustive for sensitivity unit specification.
|
||||
|
||||
#### **`GetExcitationVoltageMagnitudeFromEnum(ExcitationVoltageOptions.ExcitationVoltageOption target)`**
|
||||
- **Namespace**: `DTS.Common.DAS.Concepts.Test.Module.Channel.Sensor`
|
||||
- **Signature**:
|
||||
```csharp
|
||||
public static double GetExcitationVoltageMagnitudeFromEnum(ExcitationVoltageOptions.ExcitationVoltageOption target)
|
||||
```
|
||||
- **Behavior**:
|
||||
- Converts a given `ExcitationVoltageOptions.ExcitationVoltageOption` enum value to its associated voltage magnitude (in volts).
|
||||
- Uses an internal `VoltageMagnitudeAttributeCoder` (not visible in source but referenced) to decode the magnitude.
|
||||
- Throws `ArgumentException` on failure (e.g., invalid enum or missing attribute).
|
||||
|
||||
#### **`GetExcitationVoltageEnumFromMagnitude(double magnitude)`**
|
||||
- **Namespace**: `DTS.Common.DAS.Concepts.Test.Module.Channel.Sensor`
|
||||
- **Signature**:
|
||||
```csharp
|
||||
public static ExcitationVoltageOptions.ExcitationVoltageOption GetExcitationVoltageEnumFromMagnitude(double magnitude)
|
||||
```
|
||||
- **Behavior**:
|
||||
- Converts a numeric voltage magnitude (e.g., `5.0`) to the corresponding `ExcitationVoltageOptions.ExcitationVoltageOption` enum value.
|
||||
- Uses `VoltageMagnitudeAttributeCoder.EncodeAttributeValue()` internally.
|
||||
- On failure (e.g., magnitude not supported), logs via `APILogger` and returns `ExcitationVoltageOptions.ExcitationVoltageOption.Undefined`.
|
||||
|
||||
> **Note**: The `ExcitationVoltageOptions` type and its `VoltageMagnitudeAttribute`/`VoltageMagnitudeAttributeCoder` classes are *referenced* but *not defined* in the provided source files. Their full definitions must be found elsewhere (e.g., in `DTS.Common.Enums` or related files).
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
|
||||
- **`SensUnits` enum values are exhaustive and mutually exclusive** for sensitivity unit specification; no other unit types are defined in this module.
|
||||
- **`GetExcitationVoltageMagnitudeFromEnum`** requires a valid `ExcitationVoltageOptions.ExcitationVoltageOption` field with a `VoltageMagnitudeAttribute`; otherwise, it throws.
|
||||
- **`GetExcitationVoltageEnumFromMagnitude`** is *permissive*: it returns `Undefined` on failure instead of throwing, and always logs the failure.
|
||||
- Voltage magnitudes are assumed to be in **volts (V)**.
|
||||
- The mapping between enum values and magnitudes is **fixed and pre-defined** (e.g., `Volt5` → `5.0`), and enforced by `VoltageMagnitudeAttribute`.
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
|
||||
#### **Internal Dependencies (within this module)**:
|
||||
- `DTS.Common.DAS.Concepts.Test.Module.Channel.Sensor` (nested class hierarchy).
|
||||
- `System.ComponentModel` (for `[Description]` attributes).
|
||||
- `DTS.Common.Enums` (contains `ExcitationVoltageOptions` type).
|
||||
- `DTS.Common.Utilities.Logging` (for `APILogger`).
|
||||
|
||||
#### **External Dependencies**:
|
||||
- `DTS.Common.Enums.ExcitationVoltageOptions` — defines the `ExcitationVoltageOption` enum and `VoltageMagnitudeAttribute` (not included here).
|
||||
- `DTS.Common.Utilities.AttributeCoder<TEnum, TAttr, TVal>` — base class used by `VoltageMagnitudeAttributeCoder` (not included here).
|
||||
|
||||
#### **Dependents**:
|
||||
- Any code that configures or interprets sensor sensitivity (e.g., calibration, scaling, or unit conversion logic in DAS modules).
|
||||
- Hardware abstraction layers that set or read excitation voltage settings.
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
|
||||
- **Incomplete Source**: The `ExcitationVoltageOptions` type and its `VoltageMagnitudeAttribute`/`VoltageMagnitudeAttributeCoder` are *not defined* in the provided files. Their behavior and supported enum values are inferred from usage and comments, but cannot be verified from this source alone.
|
||||
- **Commented-Out Code**: The `ExcitationVoltageOption` enum and related classes (`VoltageMagnitudeAttribute`, `VoltageMagnitudeAttributeCoder`) are commented out in `ExcitationVoltage.cs`. This suggests possible deprecation or refactoring—**do not assume active use** unless confirmed by other files.
|
||||
- **Error Handling Asymmetry**: `GetExcitationVoltageMagnitudeFromEnum` throws on error, while `GetExcitationVoltageEnumFromMagnitude` silently returns `Undefined`. This inconsistency may lead to unhandled exceptions if callers assume symmetric behavior.
|
||||
- **No Validation on Magnitude Input**: `GetExcitationVoltageEnumFromMagnitude` does not validate input range (e.g., negative voltages), potentially returning `Undefined` for invalid values without clear indication of *why*.
|
||||
- **Hardcoded Enum Values**: The `SensUnits` enum uses explicit integer values (`0`, `1`, `2`, …). Changing or inserting values may break serialization or persistence if values are stored externally (e.g., in config files or databases).
|
||||
|
||||
> **None identified from source alone** for `SensUnits` behavior, but the excitation voltage handling is partially obscured by commented-out code and missing definitions.
|
||||
76
enriched-qwen3-coder-next/Common/DTS.Common.DASResource.md
Normal file
76
enriched-qwen3-coder-next/Common/DTS.Common.DASResource.md
Normal file
@@ -0,0 +1,76 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.DASResource/Settings.Designer.cs
|
||||
generated_at: "2026-04-16T14:08:00.142864+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "944279911ea3f393"
|
||||
---
|
||||
|
||||
# Documentation: DTS.Common.DASResource.Settings
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module is an auto-generated strongly-typed settings class created by Visual Studio's Settings Designer (`SettingsSingleFileGenerator`). It provides a singleton access point for application and user-scoped configuration values within the `DTS.Common.DASResource` namespace. The class persists settings via the .NET configuration system and is intended to be extended through the Visual Studio settings designer UI rather than through direct code modification.
|
||||
|
||||
---
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Class: `Settings`
|
||||
**Signature:** `public sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase`
|
||||
|
||||
A singleton class providing strongly-typed access to configuration settings. Instances should not be created directly; use the `Default` property.
|
||||
|
||||
---
|
||||
|
||||
### Property: `Default`
|
||||
**Signature:** `public static Settings Default { get; }`
|
||||
|
||||
Returns the synchronized singleton instance of the `Settings` class. This is the primary entry point for accessing all settings values.
|
||||
|
||||
---
|
||||
|
||||
### Property: `Samplerate2AAFrequency`
|
||||
**Signature:** `public global::System.Collections.Specialized.OrderedDictionary Samplerate2AAFrequency { get; set; }`
|
||||
|
||||
A user-scoped setting that stores a mapping between sample rates and anti-aliasing (AA) frequencies. Returns an `OrderedDictionary`, suggesting key-value pairs where insertion order matters. The underlying storage is accessed via the indexer key `"Samplerate2AAFrequency"`.
|
||||
|
||||
---
|
||||
|
||||
### Property: `abcd`
|
||||
**Signature:** `public string abcd { get; set; }`
|
||||
|
||||
A user-scoped string setting with a default value of `"hdsa askjhsad kjhsad"`. The property name and default value appear to be placeholder/test data. Marked with `DefaultSettingValueAttribute`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Singleton Pattern:** The `defaultInstance` field is created once via `ApplicationSettingsBase.Synchronized()` and returned for all accesses to `Settings.Default`.
|
||||
- **Thread Safety:** The singleton instance is created through `Synchronized()`, which provides thread-safe access per .NET's `ApplicationSettingsBase` contract.
|
||||
- **Auto-generation:** The file is marked with `CompilerGeneratedAttribute` and `GeneratedCodeAttribute`. Manual modifications will be overwritten when the settings are regenerated.
|
||||
- **User-Scoped Persistence:** Both properties are marked with `UserScopedSettingAttribute`, meaning values are stored per-user and can be modified at runtime without affecting other users.
|
||||
|
||||
---
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### This module depends on:
|
||||
- `System.Configuration.ApplicationSettingsBase` — Base class providing settings persistence and synchronization
|
||||
- `System.Collections.Specialized.OrderedDictionary` — Return type for `Samplerate2AAFrequency`
|
||||
- `System.Runtime.CompilerServices.CompilerGeneratedAttribute`
|
||||
- `System.CodeDom.Compiler.GeneratedCodeAttribute`
|
||||
- `System.Diagnostics.DebuggerNonUserCodeAttribute`
|
||||
|
||||
### What depends on this module:
|
||||
**Cannot be determined from source alone.** Consumers would access `Settings.Default` from within the `DTS.Common.DASResource` namespace or externally if the class is publicly accessible.
|
||||
|
||||
---
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Placeholder Data:** The `abcd` property has a nonsensical default value (`"hdsa askjhsad kjhsad"`) and a non-descriptive name. This appears to be test/placeholder data that may not have been cleaned up before commit.
|
||||
- **Do Not Edit Directly:** The file header explicitly warns that changes will be lost on regeneration. Settings should be modified through the Visual Studio Settings Designer (`.settings` file) or the `app.config`/`user.config` files at runtime.
|
||||
- **OrderedDictionary Type:** The `Samplerate2AAFrequency` property uses `OrderedDictionary`, which is not generic. Consumers must cast values when retrieving from this dictionary.
|
||||
- **Naming Inconsistency:** The property `Samplerate2AAFrequency` uses PascalCase, while `abcd` uses lowercase, suggesting inconsistent naming conventions or different authors/timing of addition.
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.DASResource/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T02:08:34.656885+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "a495054ce85e611b"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## 1. Purpose
|
||||
This module is an assembly metadata definition file (`AssemblyInfo.cs`) for the `DASResource` .NET assembly. Its purpose is to declare core assembly-level attributes—such as title, version, COM visibility, and GUID—used for identification, versioning, and interoperability. It does not contain application logic or executable code; rather, it provides metadata consumed by the .NET runtime, build tools, and COM interop layers.
|
||||
|
||||
## 2. Public Interface
|
||||
This file contains **no public types, functions, classes, or methods**. It only defines assembly-level attributes via attributes applied to the assembly (e.g., `[assembly: AssemblyTitle(...)]`). Therefore, there is no public API surface to document.
|
||||
|
||||
## 3. Invariants
|
||||
- The assembly version is fixed at `1.06.0081` (both `AssemblyVersion` and `AssemblyFileVersion` are identical).
|
||||
- COM visibility is explicitly disabled (`ComVisible(false)`), meaning types in this assembly are not exposed to COM by default.
|
||||
- A specific GUID (`E20CF41A-9884-40f4-AD18-4F06A42FE36D`) is assigned for COM type library identification.
|
||||
- The assembly is titled `"DASResource"` and carries a copyright notice covering years 2008–2009.
|
||||
- No culture-specific attributes (e.g., `AssemblyCulture`) are set, implying this is a neutral (non-localized) assembly.
|
||||
|
||||
## 4. Dependencies
|
||||
- **Depends on**: `System.Reflection` and `System.Runtime.InteropServices` namespaces (via `using` directives), which are part of the .NET Base Class Library.
|
||||
- **Used by**: This assembly’s metadata is consumed by the .NET runtime (e.g., for binding, reflection, and COM interop), build systems (e.g., MSBuild), and tools (e.g., `ildasm`, `sn.exe`). No other *code* in this module depends on external modules, but the assembly itself (`DASResource`) is likely referenced by other modules in the DAS (Data Access Service?) ecosystem—though this cannot be confirmed from the source alone.
|
||||
|
||||
## 5. Gotchas
|
||||
- **Versioning ambiguity**: Both `AssemblyVersion` and `AssemblyFileVersion` are set to the same value (`1.06.0081`). While not incorrect, `AssemblyFileVersion` is typically used for deployment/versioning (e.g., in file properties), while `AssemblyVersion` governs binding—mismatching them is common practice for side-by-side deployments. Here, they are identical, which may limit flexibility in binding redirects or servicing.
|
||||
- **Missing `AssemblyCulture`**: The absence of `[assembly: AssemblyCulture("")]` (or a specific culture like `"en-US"`) means the assembly is treated as *neutral* (no culture-specific resources), but this is implicit and could be made explicit for clarity.
|
||||
- **Copyright year range**: The copyright notice spans 2008–2009. If the assembly is still in active use, this may be outdated and could raise legal/compliance questions.
|
||||
- **No XML documentation file configured**: The assembly does not indicate whether an XML documentation file (e.g., `DASResource.xml`) is generated—this is often controlled elsewhere (e.g., project file), but its absence here means no machine-readable API docs are embedded in the assembly metadata.
|
||||
- **None identified from source alone.**
|
||||
58
enriched-qwen3-coder-next/Common/DTS.Common.DBSyncService.md
Normal file
58
enriched-qwen3-coder-next/Common/DTS.Common.DBSyncService.md
Normal file
@@ -0,0 +1,58 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.DBSyncService/ProjectInstaller.cs
|
||||
- Common/DTS.Common.DBSyncService/Program.cs
|
||||
- Common/DTS.Common.DBSyncService/DBSyncService.Designer.cs
|
||||
- Common/DTS.Common.DBSyncService/DBSyncService.cs
|
||||
- Common/DTS.Common.DBSyncService/ProjectInstaller.Designer.cs
|
||||
generated_at: "2026-04-16T14:10:55.814640+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "5d52988c06d02137"
|
||||
---
|
||||
|
||||
# Documentation: DTS.Common.DBSyncService
|
||||
|
||||
## 1. Purpose
|
||||
This module implements a Windows Service application named `DBSyncService`. It provides a background process capable of executing database synchronization tasks and system monitoring via a configurable timer. The module includes the service logic, installation scaffolding for the Windows Service Control Manager, and a command-line entry point.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `Program` (static class)
|
||||
* **`void Main()`**: The entry point for the application. It instantiates `DBSyncService` and passes it to `System.ServiceProcess.ServiceBase.Run` to start the service lifecycle.
|
||||
|
||||
### `ProjectInstaller` (class)
|
||||
* **`ProjectInstaller()`**: Constructor for the installer class. Calls `InitializeComponent` to configure the service installation metadata.
|
||||
* **`DBSyncServiceProcessInstaller`**: Instance of `System.ServiceProcess.ServiceProcessInstaller`. Configured with `Password` and `Username` set to `null` (defaults to Local System account).
|
||||
* **`DBSyncServiceInstaller`**: Instance of `System.ServiceProcess.ServiceInstaller`. Configured with `ServiceName` set to `"DBSyncService"`.
|
||||
|
||||
### `DBSyncService` (class : `ServiceBase`)
|
||||
* **`DBSyncService()`**: Constructor. Initializes the component, configures the Windows Event Log source (creating it if it doesn't exist using settings `Settings.Default.ServiceName` and `Settings.Default.Service`), and initializes a monitoring timer if `Settings.Default.Monitoring` is true.
|
||||
* **`void OnTimer(object sender, ElapsedEventArgs args)`**: Event handler for the monitoring timer. Writes an informational entry "Monitoring the System" to the Event Log.
|
||||
* **`void OnStart(string[] args)`**: Protected override. Called when the service starts. Logs "{ServiceName} started" to the Event Log.
|
||||
* **`void OnStop()`**: Protected override. Called when the service stops. Logs "{ServiceName} stopped" to the Event Log.
|
||||
* **`void OnCustomCommand(int command)`**: Protected override. Handles custom commands sent to the service.
|
||||
* **`CustomCommands` (enum)**: Defines custom command constants:
|
||||
* `SyncDb = 128`
|
||||
* `Command2 = 129`
|
||||
* `Command3 = 130`
|
||||
|
||||
## 3. Invariants
|
||||
* **Event Log Source**: The Event Log source must exist or the application must have permissions to create it. The constructor attempts to create it using `EventLog.CreateEventSource` if it does not exist.
|
||||
* **Timer Execution**: The monitoring timer is only instantiated and started if `Settings.Default.Monitoring` is `true`.
|
||||
* **Custom Commands**: Custom commands must have values of 128 or higher, as defined in the `CustomCommands` enum, which aligns with Windows Service custom command requirements.
|
||||
|
||||
## 4. Dependencies
|
||||
* **Internal Dependencies**:
|
||||
* `DTS.Common.DBSyncService.Properties.Settings`: Used to access configuration values (`ServiceName`, `Service`, `Monitoring`, `Interval`).
|
||||
* **External Dependencies**:
|
||||
* `System.ServiceProcess`: Used for `ServiceBase` and installer classes.
|
||||
* `System.Configuration.Install`: Used for the `Installer` base class.
|
||||
* `System.Diagnostics`: Used for `EventLog` and `EventLogEntryType`.
|
||||
* `System.Timers`: Used for the monitoring timer.
|
||||
|
||||
## 5. Gotchas
|
||||
* **Timer Garbage Collection**: In `DBSyncService()`, the `Timer` instance is created as a local variable (`var timer = new Timer...`). It is not assigned to a class-level field. Since `System.Timers.Timer` is not kept alive by the system, it is eligible for Garbage Collection once the constructor finishes. This will cause the timer to stop firing unexpectedly (or never fire) after the first GC cycle.
|
||||
* **Service Name Mismatch**: The `ServiceName` property is set to `"Service1"` in `DBSyncService.Designer.cs` (inside `InitializeComponent`), but the installer in `ProjectInstaller.Designer.cs` sets the service name to `"DBSyncService"`. This inconsistency can cause the service to fail to start or be managed correctly by the Service Control Manager, as the service name registered during installation will not match the name the `ServiceBase` instance expects.
|
||||
* **Empty Command Handlers**: The `OnCustomCommand` method contains a switch statement for `SyncDb`, `Command2`, and `Command3`, but all case blocks are empty. The service currently acknowledges these commands but performs no action.
|
||||
* **TODO Implementation**: The `OnTimer` method contains a `TODO` comment, indicating that the actual monitoring logic is not yet implemented.
|
||||
@@ -0,0 +1,76 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.DBSyncService/Properties/AssemblyInfo.cs
|
||||
- Common/DTS.Common.DBSyncService/Properties/Settings.Designer.cs
|
||||
generated_at: "2026-04-16T02:11:21.572661+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "192083dd898290ec"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## Documentation: `DTS.Common.DBSyncService`
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
This module is a .NET assembly (`DTS.Common.DBSyncService`) that provides shared configuration and metadata for a database synchronization service. It does not contain business logic or synchronization implementations itself, but rather defines assembly-level attributes (e.g., version, title, COM visibility) and exposes strongly-typed application settings (e.g., `Monitoring`, `Interval`, `ServiceName`, `Service`) via a generated settings class. Its role is to centralize and standardize configuration and assembly identity for the DB Sync Service across deployment and runtime.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `DTS.Common.DBSyncService.Properties.Settings`
|
||||
A sealed, auto-generated class derived from `System.Configuration.ApplicationSettingsBase`. Provides read-only access to application-scoped configuration values. Accessed via the static property `Settings.Default`.
|
||||
|
||||
- **`public static Settings Default { get; }`**
|
||||
Returns the singleton instance of `Settings`. Thread-safe due to `Synchronized()` wrapping.
|
||||
|
||||
- **`public bool Monitoring { get; }`**
|
||||
Returns the value of the `Monitoring` setting. Default: `false`. Application-scoped; cannot be changed at runtime.
|
||||
|
||||
- **`public int Interval { get; }`**
|
||||
Returns the value of the `Interval` setting (in milliseconds). Default: `60000` (i.e., 60 seconds). Application-scoped.
|
||||
|
||||
- **`public string ServiceName { get; }`**
|
||||
Returns the value of the `ServiceName` setting. Default: `"DTS DB Sync Service"`. Application-scoped.
|
||||
|
||||
- **`public string Service { get; }`**
|
||||
Returns the value of the `Service` setting. Default: `"DB Sync Service"`. Application-scoped.
|
||||
|
||||
> **Note**: All properties are read-only (`get` only), and values are determined at compile-time via `[DefaultSettingValueAttribute]`. No setters or runtime modification is supported.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
- The `Settings` class is **application-scoped** and **immutable at runtime** (no `UserScoped` settings present).
|
||||
- All settings values are validated only at design time (via `Settings.Designer.cs` generation); no runtime validation occurs.
|
||||
- The assembly is **not COM-visible** (`ComVisible(false)`), and the GUID `5f8e95eb-e89c-4fdc-9bde-3e78dd56ad6f` is reserved for typelib identification if exposed to COM.
|
||||
- Assembly version is fixed at `1.0.0.0` (both `AssemblyVersion` and `AssemblyFileVersion`).
|
||||
- Thread-safety of `Settings.Default` is ensured via `ApplicationSettingsBase.Synchronized()`.
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
#### Dependencies *of* this module:
|
||||
- `System.Configuration` (for `ApplicationSettingsBase`, `ApplicationScopedSettingAttribute`, etc.)
|
||||
- `System.Runtime.CompilerServices`, `System.Runtime.InteropServices`, `System.CodeDom.Compiler`, `System.Diagnostics` (for attributes and COM interop)
|
||||
- `System` (implicit base for `AssemblyInfo` and `Settings` types)
|
||||
|
||||
#### Dependencies *on* this module:
|
||||
- Any service or library referencing `DTS.Common.DBSyncService` can access `Properties.Settings.Default` to retrieve configuration.
|
||||
- The assembly is likely referenced by the main DB Sync Service executable or related components (e.g., Windows Service host), though this is inferred from naming and not explicit in the provided files.
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
- **No runtime configuration**: Settings are compile-time constants; changing them requires rebuilding the assembly or modifying the `.config` file *if* the settings were user-scoped (but they are not — they are application-scoped and read from `app.config` only at startup, with no override capability).
|
||||
- **Hardcoded defaults**: The `Interval` value (`60000`) is in milliseconds but not documented as such in code; callers must infer the unit.
|
||||
- **Redundant naming**: Two settings (`ServiceName` and `Service`) both appear to represent the service name, with identical default values (`"DTS DB Sync Service"` vs `"DB Sync Service"`). This may indicate legacy duplication or ambiguity in usage context.
|
||||
- **Auto-generated code**: `Settings.Designer.cs` is explicitly marked as auto-generated; manual edits will be overwritten.
|
||||
- **Version lock**: `AssemblyVersion("1.0.0.0")` with no `*` wildcard disables automatic build/revision incrementing, which may complicate deployment tracking.
|
||||
- **No public API surface beyond `Settings`**: This module provides no executable logic—only configuration metadata—so callers must not expect any other public types or methods.
|
||||
|
||||
> **None identified from source alone** beyond the above.
|
||||
253
enriched-qwen3-coder-next/Common/DTS.Common.DataModel.md
Normal file
253
enriched-qwen3-coder-next/Common/DTS.Common.DataModel.md
Normal file
@@ -0,0 +1,253 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.DataModel/ApplicationProperties.cs
|
||||
- Common/DTS.Common.DataModel/CollectDataProcess.cs
|
||||
- Common/DTS.Common.DataModel/SysBuiltObjectType.cs
|
||||
- Common/DTS.Common.DataModel/DataModelSettings.cs
|
||||
- Common/DTS.Common.DataModel/DataFiles.cs
|
||||
- Common/DTS.Common.DataModel/ChannelRepresentation.cs
|
||||
- Common/DTS.Common.DataModel/DASFactory.cs
|
||||
generated_at: "2026-04-16T14:15:08.439336+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "d315c00965ab6aef"
|
||||
---
|
||||
|
||||
# DTS.Common.DataModel Module Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides the core data model and application-wide state management for the DTS data acquisition system. It contains global application properties, configuration settings, hardware abstraction for channel representation, data file management utilities, and the DAS (Data Acquisition System) factory wrapper for device discovery and communication. The module serves as a central hub connecting hardware abstraction, user context, ISO standards, and file system operations.
|
||||
|
||||
---
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### ApplicationProperties (static class)
|
||||
Global application state container.
|
||||
|
||||
| Property | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `CurrentUser` | `User` | Gets or sets the currently logged-in user. |
|
||||
| `DASFactory` | `DASFactory` | Gets or sets the DAS factory instance for device management. |
|
||||
| `CurrentView` | `User` | Gets or sets the current view context user. |
|
||||
| `IsoDb` | `ISO13499FileDb` | Gets or sets the ISO 13499 database reference. |
|
||||
| `LicenseValidationResult` | `ValidationResult` | Gets or sets the license validation result. |
|
||||
| `CanCurrentUserCommitChannelCodes` | `bool` | Gets or sets whether the current user can commit channel codes. |
|
||||
|
||||
---
|
||||
|
||||
### CollectDataProcess : BasePropertyChanged
|
||||
Represents a data collection process with visual properties.
|
||||
|
||||
| Member | Signature | Description |
|
||||
|--------|-----------|-------------|
|
||||
| Constructor | `CollectDataProcess(string name, Color color)` | Initializes with name and background color. |
|
||||
| `Name` | `string` | Gets or sets the process name. |
|
||||
| `BackgroundColor` | `Color` | Gets or sets the background color. |
|
||||
| `IsEnabled` | `bool` | Gets or sets whether the process is enabled. |
|
||||
|
||||
---
|
||||
|
||||
### SysBuiltObjectType
|
||||
Container for Dynamic Groups of a given test object type (Vehicle 1, Vehicle 2, Sled, etc.).
|
||||
|
||||
| Member | Signature | Description |
|
||||
|--------|-----------|-------------|
|
||||
| Constructor | `SysBuiltObjectType(string testObjectType)` | Initializes with a test object type string. |
|
||||
| `TestObject` | `MMETestObjects` | Gets or sets the test object via ISO database lookup. |
|
||||
| `ISOTestObjectType` | `string` | Gets the ISO test object type text (L1). |
|
||||
| `ToString()` | `override string` | Returns `TestObject.Text_L1`. |
|
||||
|
||||
---
|
||||
|
||||
### DataModelSettings (static class)
|
||||
Configuration settings with default values.
|
||||
|
||||
| Property | Type | Default | Description |
|
||||
|----------|------|---------|-------------|
|
||||
| `UseISOCodeForDiadem200` | `bool` | `false` | ISO code setting for Diadem 200. |
|
||||
| `SampleRateAAFilterRatio` | `byte` | `5` | Anti-aliasing filter ratio. |
|
||||
| `SupportedSquibFireModes` | `string` | `"CAP,CONSTANT"` | Supported squib fire modes. |
|
||||
| `ShowCompactHardware` | `bool` | `true` | Compact hardware display toggle. |
|
||||
| `AllowedVoltageInsertionErrorPercent` | `double` | `1` | Allowed voltage insertion error percentage. |
|
||||
| `AllowedExcitationErrorPercent` | `double` | `2` | Allowed excitation error percentage. |
|
||||
| `AllowedShuntErrorPercent` | `double` | `5` | Allowed shunt error percentage. |
|
||||
| `ShuntToleranceHighOhmPercent` | `double` | `10` | Shunt tolerance high ohm percentage. |
|
||||
| `AllowedGainErrorPercent` | `double` | `2` | Allowed gain error percentage. |
|
||||
| `AllowedGainErrorPercent_SLICE6andSLICE6A` | `double` | `5` | Gain error percentage for SLICE6/SLICE6A. |
|
||||
| `AutoZeroPercentDeviationAllowed` | `double` | `5` | Auto-zero deviation allowance. |
|
||||
| `ShuntToleranceHighOhmResistance` | `double` | `4000` | Shunt tolerance high ohm resistance. |
|
||||
| `DownloadFolder` | `string` | `"..\\..\\Data"` | Default download folder path. |
|
||||
| `RequireXCrashCompatibilityForISOExports` | `bool` | `true` | XCrash compatibility requirement. |
|
||||
| `DisplayDuplicateUDPStreamOutWarning` | `bool` | `true` | Duplicate UDP stream warning toggle. |
|
||||
| `SLICETurnOffAAFRealtime` | `bool` | `true` | SLICE anti-aliasing filter realtime toggle. |
|
||||
| `UseTestChannelOrder` | `bool` | `false` | Test channel order usage. |
|
||||
| `RealtimeSampleRateAAFilterRatio` | `byte` | `1` | Realtime sample rate AA filter ratio. |
|
||||
| `ArmChecklistRequiredIfTOM` | `bool` | `true` | Arm checklist requirement for TOM. |
|
||||
| `TestsRequireLevelTriggers` | `bool` | `false` | Level trigger requirement. |
|
||||
| `CheckUnitsIntervalMillisecond` | `int` | `50` | Units check interval in milliseconds. |
|
||||
| `SemaphoreDelay` | `double` | `10` | Semaphore delay value. |
|
||||
| `SemaphoreSpots` | `int` | `3` | Number of semaphore spots. |
|
||||
| `SLICEConcurrentSpots` | `int` | `999` | SLICE concurrent spots. |
|
||||
| `SLICEConcurrentDelayMs` | `int` | `0` | SLICE concurrent delay in ms. |
|
||||
| `MulticastAutoDiscoveryReceiveTimeoutMS` | `int` | `1500` | Multicast discovery timeout. |
|
||||
| `LocalKeepAliveRetryIntervalMS` | `uint` | `1000` | Local keep-alive retry interval. |
|
||||
| `LocalKeepAliveTimeOutMS` | `uint` | `5000` | Local keep-alive timeout. |
|
||||
| `RemoteKeepAliveRetryIntervalSeconds` | `uint` | `5` | Remote keep-alive retry interval. |
|
||||
| `RemoteKeepAliveSeconds` | `uint` | `60` | Remote keep-alive timeout. |
|
||||
| `ReceiveBufferSizeBytes` | `int` | `65536` | Receive buffer size. |
|
||||
| `SendBufferSizeBytes` | `int` | `65536` | Send buffer size. |
|
||||
| `HeartbeatAsyncConnectTimeoutMS` | `int` | `10000` | Heartbeat async connect timeout. |
|
||||
| `DefaultTDCSensorDatabaseFolder` | `string` | `"..\\SensorDatabase"` | Default TDC sensor database folder. |
|
||||
| `DefaultTDCSensorDatabaseFile` | `string` | `"SensorDatabase.CSV"` | Default TDC sensor database file. |
|
||||
| `TDCSensorDatabaseExportUseCurrentLocale` | `bool` | `false` | TDC export locale setting. |
|
||||
| `TDCSensorDatabaseImportEncoding` | `string` | `"Shift-JIS"` | TDC import encoding. |
|
||||
|
||||
---
|
||||
|
||||
### DataFiles : BasePropertyChanged
|
||||
Represents metadata for a test data file.
|
||||
|
||||
| Member | Signature | Description |
|
||||
|--------|-----------|-------------|
|
||||
| Constructor | `DataFiles(string expandCollapse, string testName, string id, string allOrROI, string lab, string customer, DateTime dateCreated, string description, string numberOfChannels, string testEngineer, bool isTSRAIR, string roiSuffix = "")` | Initializes all file metadata properties. |
|
||||
| `LongString` | `string` | Gets or sets a long string representation. |
|
||||
| `TestSelected` | `bool` | Gets or sets test selection state. |
|
||||
| `ExpandCollapse` | `string` | Gets or sets expand/collapse state ("+", "-", or empty). |
|
||||
| `TestId` | `string` | Gets or sets the test ID. |
|
||||
| `TestName` | `string` | Gets or sets the test name. |
|
||||
| `AllOrROI` | `string` | Gets or sets whether this is "All" or ROI data. |
|
||||
| `Lab` | `string` | Gets or sets the lab name. |
|
||||
| `Customer` | `string` | Gets or sets the customer name. |
|
||||
| `DateCreated` | `DateTime` | Gets or sets the creation date. |
|
||||
| `Description` | `string` | Gets or sets the description. |
|
||||
| `NumberOfChannels` | `string` | Gets or sets the channel count. |
|
||||
| `TestEngineer` | `string` | Gets or sets the test engineer name. |
|
||||
| `ROISuffix` | `string` | Gets or sets the ROI suffix. |
|
||||
| `DTSFile` | `string` | Gets or sets the DTS file location (populated in export tab). |
|
||||
| `IsTSRAIR` | `bool` | Gets or sets whether this is a TSR AIR test. |
|
||||
|
||||
---
|
||||
|
||||
### DataFilesList : BasePropertyChanged
|
||||
Manages collections of `DataFiles` with file system traversal.
|
||||
|
||||
| Member | Signature | Description |
|
||||
|--------|-----------|-------------|
|
||||
| `DownloadFolder` | `string` | Field storing the download folder path. |
|
||||
| `GetAllFiles(string testName)` | `DataFiles[]` | Returns all data files for a given test name by traversing folders. |
|
||||
| `Contract(DataFiles df)` | `DataFiles[]` | Collapses the list, removing expanded items for the given test name. |
|
||||
| `GetAllDataFiles()` | `DataFiles[]` | Returns top-level data file entries for all tests. |
|
||||
| `DataFiles` | `DataFiles[]` | Gets or sets the data files list. |
|
||||
| `DataFileList` | `static DataFilesList` | Singleton instance accessor. |
|
||||
|
||||
---
|
||||
|
||||
### ChannelRepresentation
|
||||
Handles channel number conversion and display for various hardware types.
|
||||
|
||||
| Member | Signature | Description |
|
||||
|--------|-----------|-------------|
|
||||
| `ChannelTypeEnum` | `enum` | Values: `SQUIB`, `TOMDigital`, `DigitalInput`, `Other`. |
|
||||
| Constructor | `ChannelRepresentation(DASHardware h, DASChannel c, int startingChannelNumber)` | Creates representation from DAS hardware and channel. |
|
||||
| Constructor | `ChannelRepresentation(HardwareChannel c, int startingChannelNumber, IDASHardware[] hardwares = null)` | Creates representation from hardware channel. |
|
||||
| `DASSerialNumber` | `string` | Gets or sets the DAS serial number. |
|
||||
| `SerialNumber` | `string` | Gets or sets the module serial number. |
|
||||
| `ChannelNumberString` | `string` | Gets the formatted channel number string with prefix. |
|
||||
| `ChannelNumber` | `int` | Gets the numeric channel number. |
|
||||
|
||||
---
|
||||
|
||||
### DASFactory
|
||||
Wrapper around `DTS.DASLib.DASFactory.DASFactory` for device discovery and management.
|
||||
|
||||
| Member | Signature | Description |
|
||||
|--------|-----------|-------------|
|
||||
| Constructor | `DASFactory()` | Initializes the factory, semaphores, and event handlers. |
|
||||
| `StartMulticastAutoDiscovery()` | `void` | Starts auto-discovery process if not running. |
|
||||
| `StopMulticastAutoDiscovery()` | `void` | Stops auto-discovery process. |
|
||||
| `GetDiscoveredDevices()` | `IDiscoveredDevice[]` | Returns discovered devices. |
|
||||
| `GetDASFactory()` | `IDASFactory` | Returns the underlying IDASFactory interface. |
|
||||
| `TakeOwnership()` | `void` | Takes ownership of devices. |
|
||||
| `DetachAllDevices(bool detachUSB = false)` | `void` | Detaches all devices; USB detaching is conditional. |
|
||||
| `DisposeFactory()` | `void` | Disposes the underlying factory. |
|
||||
| `TDASHostNames` | `string[]` | Gets or sets TDAS host names. |
|
||||
| `SPFDHostNames` | `string[]` | Gets or sets SPFD host names. |
|
||||
| `SDBHostNames` | `string[]` | Gets or sets SliceDB host names. |
|
||||
| `AutoDiscoverMulticast()` | `SortableBindingList<IDiscoveredDevice>` | Performs multicast auto-discovery. |
|
||||
| `DiscoveryThread(DFConstantsAndEnums.MultiCastDeviceClasses[] deviceFilter, CancellationToken ct, bool discoverParents = true)` | `void` | Background thread for continuous discovery. |
|
||||
| `StartQATSListening()` | `void` | Starts QATS listening. |
|
||||
| `StopQATSListening()` | `void` | Stops QATS listening. |
|
||||
| `SendQATSRequest()` | `void` | Sends UDP QATS request. |
|
||||
| `GetQATS()` | `IUDPQATSEntry[]` | Returns waiting QATS entries and clears the list. |
|
||||
| `MulticastAutoDiscoveryReceiveTimeoutMS` | `int` | Gets or sets multicast discovery timeout. |
|
||||
| `MulticastAutoDiscoveryAddress` | `string` | Gets or sets multicast address. |
|
||||
| `MulticastAutoDiscoveryPort` | `int` | Gets or sets multicast transmit port. |
|
||||
| `MulticastAutoDiscoveryResponsePort` | `int` | Gets or sets multicast response port. |
|
||||
| `S6ConnectNewTimeout` | `double` | Gets or sets SLICE6 connect timeout. |
|
||||
| `Refresh(bool wait)` | `void` | Refreshes device list; prevents overlapping refreshes. |
|
||||
| `GetActiveDevices()` | `List<IDASCommunication>` | Returns list of active DAS communications. |
|
||||
| `GetReportedConnections()` | `string[]` | Returns all reported connections from distributors. |
|
||||
| `AutoDiscoverIfNecessary()` | `void` | Runs auto-discovery for SLICE6/SLICE6Db downstream MAC addresses. |
|
||||
| `IsStreaming(IDASCommunication das)` | `static bool` | Returns true if DAS is streaming. |
|
||||
| `IsInRealtime(IDASCommunication das)` | `static bool` | Returns true if unit is in realtime or streaming. |
|
||||
| `AnyInRealtime(List<IDASCommunication> das)` | `static bool` | Returns true if any unit is in realtime or streaming. |
|
||||
|
||||
**Events:**
|
||||
- `OnDeviceArrived` - `DASFactoryEventHandler`
|
||||
- `OnFactoryChanged` - `DASFactoryEventHandler`
|
||||
- `DiscoveredDAS` - `DiscoveredDASEventHandler`
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
1. **ApplicationProperties singleton state**: All properties are static and globally accessible; consumers must ensure thread-safe access patterns.
|
||||
|
||||
2. **DataFilesList singleton**: The `DataFileList` property uses lazy initialization and returns a single shared instance.
|
||||
|
||||
3. **DASFactory refresh concurrency**: The `_bInRefresh` flag prevents overlapping refresh calls. If `Refresh` is called while already refreshing, the second call is logged but ignored.
|
||||
|
||||
4. **ChannelRepresentation hardware type handling**: The `ConvertChannelNumbers` method must receive valid `HardwareTypes` enum values; unknown types fall through to a default case that uses the starting channel number directly.
|
||||
|
||||
5. **DataFiles folder structure**: `GetFoldersWithData` expects folders containing both `.dts` and `.chn` files; folders missing either are excluded.
|
||||
|
||||
6. **SysBuiltObjectType ISO lookup**: The `TestObject` getter relies on `ApplicationProperties.IsoDb` being initialized; null `IsoDb` will cause runtime errors.
|
||||
|
||||
---
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### This module depends on:
|
||||
- `DTS.Slice.Users` - User types
|
||||
- `DTS.Common.ISO` - ISO 13499 database types (`ISO13499FileDb`, `MMETestObjects`)
|
||||
- `DTS.Common.Licensing.Messages` - `ValidationResult`
|
||||
- `DTS.Common.Base` - `BasePropertyChanged` for MVVM support
|
||||
- `DTS.Serialization` - File reading utilities
|
||||
- `DTS.Common.Utilities.Logging` - `APILogger`
|
||||
- `DTS.Common.SharedResource.Strings` - Localized string resources
|
||||
- `DTS.Common.Utils` - Utility classes including `TestUtils`
|
||||
- `DTS.Common.Converters` - `EnumDescriptionTypeConverter`
|
||||
- `DTS.Common.Enums.Hardware` - `HardwareTypes` enum
|
||||
- `DTS.Common.Enums.Sensors` - Sensor-related enums
|
||||
- `DTS.Common.Interface.DataRecorders` - `IDASHardware`
|
||||
- `DTS.Common.Interface.DASFactory` - `IDASFactory`, `IDiscoveredDevice`
|
||||
- `DTS.Common.Enums.DASFactory` - `DFConstantsAndEnums`
|
||||
- `DTS.Common.Constant.DASSpecific` - `SensorConstants`
|
||||
- `DTS.DASLib.DASFactory` - Underlying DAS factory implementation
|
||||
- `DTS.DASLib.Service` - DAS channel and communication types
|
||||
- `DTS.DASLib.Command.TDAS` - TDAS command infrastructure
|
||||
- `System.Windows.Media` - `Color` type
|
||||
- `System.Xml.Linq` - XML parsing
|
||||
|
||||
### What depends on this module:
|
||||
- Unclear from source alone; the module exposes public classes that appear designed for consumption by UI layers, test setup components, and data export functionality.
|
||||
|
||||
---
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
1. **Namespace inconsistency**: `CollectDataProcess`, `SysBuiltObjectType`, `DataFiles`, `DataFilesList`, and `DASFactory` are declared in namespace `DataPROWin7.DataModel` while the file path suggests `DTS.Common.DataModel`. This may cause confusion when importing.
|
||||
|
||||
2. **SysBuiltObjectType fallback value**: The `_
|
||||
117
enriched-qwen3-coder-next/Common/DTS.Common.DataModel/Classes.md
Normal file
117
enriched-qwen3-coder-next/Common/DTS.Common.DataModel/Classes.md
Normal file
@@ -0,0 +1,117 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.DataModel/Classes/Enums.cs
|
||||
generated_at: "2026-04-16T03:31:47.934438+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "a8986c49f9eaee26"
|
||||
---
|
||||
|
||||
# Classes
|
||||
|
||||
## Documentation: `DTS.Common.DataModel/Classes/Enums.cs`
|
||||
|
||||
### 1. Purpose
|
||||
This module defines core enumerations used throughout the `DataPROWin7.DataModel` namespace to enforce type safety and semantic clarity for key configuration and interoperability concerns. Specifically, it standardizes:
|
||||
- **`IsoChannelSensorCompatibilityLevels`**: Controls warning/error behavior when validating compatibility between ISO channels and sensors (e.g., during data import/export).
|
||||
- **`SupportedExportFormats`**: Lists all export formats supported by the system, with `[Description]` attributes mapping enum values to user-facing format names (e.g., `"csv" → "CSV"`).
|
||||
- **`StrictLevel`**: Defines operational modes for data validation and checkout workflows, ranging from strict enforcement (`Strict`) to permissive or expedited modes (`QuickCheckout`).
|
||||
The module exists to centralize these constants, avoiding magic strings/numbers and ensuring consistent interpretation across the codebase.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `IsoChannelSensorCompatibilityLevels`
|
||||
```csharp
|
||||
public enum IsoChannelSensorCompatibilityLevels
|
||||
{
|
||||
DontWarn,
|
||||
Warn,
|
||||
DontAllow
|
||||
}
|
||||
```
|
||||
- **Purpose**: Specifies the severity level for ISO channel-sensor compatibility mismatches.
|
||||
- **Values**:
|
||||
- `DontWarn`: Mismatches are silently ignored.
|
||||
- `Warn`: Mismatches trigger a warning (e.g., UI alert, log entry).
|
||||
- `DontAllow`: Mismatches block the operation (e.g., import/export fails).
|
||||
|
||||
#### `SupportedExportFormats`
|
||||
```csharp
|
||||
public enum SupportedExportFormats
|
||||
{
|
||||
[Description("CSV")] csv,
|
||||
[Description("Diadem")] diadem,
|
||||
[Description("ISO")] iso,
|
||||
[Description("SOMAT")] somat,
|
||||
[Description("TDAS")] tdas,
|
||||
[Description("TSV")] tsv,
|
||||
[Description("TTS")] tts,
|
||||
[Description("RDF")] rdf,
|
||||
[Description("TDMS")] tdms,
|
||||
[Description("DDAS")] ddas,
|
||||
[Description("HDF5")] hdf,
|
||||
[Description("XLSX")] xlsx,
|
||||
[Description("Chapter10")] chapter10, // DataPRO 3.3, IRIG 106 Chapter 10
|
||||
[Description("ASC")] asc
|
||||
}
|
||||
```
|
||||
- **Purpose**: Represents all export formats supported by the application.
|
||||
- **Behavior**:
|
||||
- Each value has a `[Description]` attribute specifying its display name (e.g., `csv` → `"CSV"`).
|
||||
- `chapter10` is explicitly annotated as supporting *IRIG 106 Chapter 10* (a telemetry data format standard).
|
||||
- **Note**: `xlsx` uses `// ReSharper disable once InconsistentNaming` to suppress naming convention warnings (likely due to casing mismatch with PascalCase guidelines).
|
||||
|
||||
#### `StrictLevel`
|
||||
```csharp
|
||||
public enum StrictLevel
|
||||
{
|
||||
Strict,
|
||||
UpdateTable,
|
||||
CheckoutOnly,
|
||||
QuickCheckout
|
||||
}
|
||||
```
|
||||
- **Purpose**: Configures the rigor of data validation and checkout operations.
|
||||
- **Values**:
|
||||
- `Strict`: Full validation enforced; non-compliant data rejected.
|
||||
- `UpdateTable`: Validation performed, but table schemas may be updated to accommodate data.
|
||||
- `CheckoutOnly`: Validation skipped; only checkout (e.g., file locking, metadata update) occurs.
|
||||
- `QuickCheckout`: Minimal validation; optimized for speed (e.g., bulk operations).
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
- **`IsoChannelSensorCompatibilityLevels`**:
|
||||
- Values must be used consistently in validation logic (e.g., `DontAllow` must prevent operations, not just log warnings).
|
||||
- **`SupportedExportFormats`**:
|
||||
- The `[Description]` attribute value for each enum member is the canonical string representation used in UI/file dialogs.
|
||||
- `chapter10` is reserved for IRIG 106 Chapter 10 exports (per inline comment).
|
||||
- **`StrictLevel`**:
|
||||
- `Strict` is the most restrictive mode; `QuickCheckout` is the least.
|
||||
- No two modes may have identical behavior in validation/checkout logic.
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
- **Depends on**:
|
||||
- `System.ComponentModel` (for `[Description]` attribute).
|
||||
- **Depended upon**:
|
||||
- Other modules in `DataPROWin7.DataModel` (inferred from namespace usage).
|
||||
- Likely used by export pipelines (e.g., format selection), ISO data validation components, and checkout workflows.
|
||||
- *Not directly referenced in source*, but usage is implied by the enum’s purpose and naming.
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
- **`xlsx` enum member**:
|
||||
- Uses `// ReSharper disable once InconsistentNaming` to override PascalCase convention (likely due to legacy naming or external format specification requiring lowercase). This may cause confusion if developers expect consistent casing.
|
||||
- **`chapter10` naming**:
|
||||
- The enum value `chapter10` (lowercase) maps to `"Chapter10"` (PascalCase) via `[Description]`. Developers must use `DescriptionAttribute` to retrieve the display name, not `ToString()`.
|
||||
- **Ambiguity in `StrictLevel` semantics**:
|
||||
- The exact behavior differences between `UpdateTable`, `CheckoutOnly`, and `QuickCheckout` are *not specified in this file*. Implementation details (e.g., how `UpdateTable` modifies schemas) must be verified in dependent modules.
|
||||
- **No validation of enum usage**:
|
||||
- The enums themselves contain no runtime validation. Invalid combinations (e.g., `DontAllow` with `QuickCheckout`) must be handled by calling code.
|
||||
|
||||
*None identified beyond the above.*
|
||||
@@ -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 it’s 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).
|
||||
@@ -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 test’s 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 loop’s 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.
|
||||
@@ -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 DAS’s 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 sensor’s 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.*
|
||||
@@ -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 group’s 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.
|
||||
@@ -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`.
|
||||
@@ -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 enum’s 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.)*
|
||||
@@ -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 customer’s 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`.
|
||||
@@ -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* channel’s 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.
|
||||
@@ -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.
|
||||
166
enriched-qwen3-coder-next/Common/DTS.Common.DataModel/Common.md
Normal file
166
enriched-qwen3-coder-next/Common/DTS.Common.DataModel/Common.md
Normal file
@@ -0,0 +1,166 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.DataModel/Common/StatusHelpers.cs
|
||||
- Common/DTS.Common.DataModel/Common/TestObjectHelper.cs
|
||||
- Common/DTS.Common.DataModel/Common/ChannelHelper.cs
|
||||
- Common/DTS.Common.DataModel/Common/TestSetupCollection.cs
|
||||
generated_at: "2026-04-16T03:31:59.768999+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "2101fc7191561021"
|
||||
---
|
||||
|
||||
# Common
|
||||
|
||||
## Documentation: `DTS.Common.DataModel.Common` Module
|
||||
|
||||
---
|
||||
|
||||
### **Purpose**
|
||||
|
||||
This module provides utility helpers for managing test setup metadata, channel naming conventions, and status reporting within the DTS data modeling layer. It centralizes logic for caching and refreshing test setup lists (with staleness detection via CRC and time-based invalidation), generating warning channel display names, and exposing legacy TOM channel filter constants. It acts as a coordination layer between data persistence (via SQL queries), UI eventing (via Prism’s `IEventAggregator`), and domain-specific constants, enabling consistent behavior across UI and background processes.
|
||||
|
||||
---
|
||||
|
||||
### **Public Interface**
|
||||
|
||||
#### **`StatusHelpers` class**
|
||||
- **`SetProgressValueDelegate` delegate**
|
||||
```csharp
|
||||
public delegate void SetProgressValueDelegate(IDASCommunication idas, double progressValue, TSRAIRGoStatus.StatusTypes? status);
|
||||
```
|
||||
Signature for a callback used to set progress and status on a DAS communication interface.
|
||||
|
||||
- **`SetStatus2` method**
|
||||
```csharp
|
||||
public static void SetStatus2(IDASCommunication das, int progressValue, TSRAIRGoStatus.StatusTypes? status, SetProgressValueDelegate setProgressValue)
|
||||
```
|
||||
Invokes the provided `setProgressValue` delegate with the given `das`, `progressValue`, and `status`. This is a thin wrapper—no validation or transformation is performed on inputs.
|
||||
|
||||
#### **`TestObjectHelper` class**
|
||||
- **`TDC_LEGACY_TOM_CUTOFF_SPS` constant**
|
||||
```csharp
|
||||
public const double TDC_LEGACY_TOM_CUTOFF_SPS = 8000;
|
||||
```
|
||||
Threshold sampling rate (samples per second) used to determine TOM channel filter selection in legacy TDC systems. Channels ≥ 8000 SPS use `TDC_LEGACY_TOM_HIGH_FILTER`.
|
||||
|
||||
- **`TDC_LEGACY_TOM_HIGH_FILTER` constant**
|
||||
```csharp
|
||||
public const double TDC_LEGACY_TOM_HIGH_FILTER = 1650D;
|
||||
```
|
||||
Default high-pass filter frequency (in Hz) applied to TOM channels recorded at >8000 SPS in legacy TDC (CFC1000 equivalent). *Note:* Values ≤8000 SPS are not handled in this module.
|
||||
|
||||
#### **`ChannelHelper` class**
|
||||
- **`GetWarningChannelName` method**
|
||||
```csharp
|
||||
public static string GetWarningChannelName(IGroupChannel groupChannel)
|
||||
```
|
||||
Generates a human-readable warning label for a channel, using the following logic:
|
||||
- Uses `TestSetupOrder` if ≥ 0; otherwise uses `GroupChannelOrder`.
|
||||
- If `GetChannelName(SerializedSettings.ISOViewMode)` returns a non-empty string, uses that quoted (e.g., `'MyChannel'`).
|
||||
- Otherwise, appends empty string `''`, then optionally appends sensor info (if `SensorValid`) and hardware info (if `HardwareValid`), e.g., `1, '', (SensorA) DAS1`.
|
||||
|
||||
#### **`TestSetupCollection` class**
|
||||
- **`TestSetupIds` property**
|
||||
```csharp
|
||||
public static List<string> TestSetupIds { get; }
|
||||
```
|
||||
Returns a *copy* of the internal `_testSetupList` (as a `List<string>`), containing names of test setups. Access is thread-safe via `TestSetupListLock`.
|
||||
|
||||
- **`TestSetupList` property**
|
||||
```csharp
|
||||
public static string[] TestSetupList { get; }
|
||||
```
|
||||
Returns an array of test setup names (only *complete* tests if called directly, but behavior differs based on context—see *Gotchas*). Triggers full refresh if `_testSetupList` is null/empty. Uses `ProgressBarEvent` to report progress during refresh.
|
||||
|
||||
- **`TestSetups` property**
|
||||
```csharp
|
||||
public static TestTemplate[] TestSetups { get; }
|
||||
```
|
||||
Returns a snapshot of `_actualTestTemplates` (as `TestTemplate[]`), containing *all* loaded test templates (not filtered by completeness).
|
||||
|
||||
- **`UpdateTestSetupListIfStale()` method**
|
||||
```csharp
|
||||
public static void UpdateTestSetupListIfStale()
|
||||
```
|
||||
Conditionally triggers `UpdateTestSetupList()` if:
|
||||
- Last update was >30 minutes ago (`MIN_TESTS_UPDATEINTERVAL_MINUTES`), *or*
|
||||
- CRC of the underlying `TestSetups` table in SQL has changed.
|
||||
|
||||
- **`UpdateTestSetupList(TestTemplate test)` method**
|
||||
```csharp
|
||||
public static void UpdateTestSetupList(TestTemplate test)
|
||||
```
|
||||
Updates the cached list for a *single* `test`:
|
||||
- If `test.IsDirty` and `!test.IsComplete`, removes `test.Name` from `_testSetupList`.
|
||||
- If `!test.IsDirty` and `!test.IsComplete`, does nothing.
|
||||
- Otherwise, adds `test.Name` to `_testSetupList` (if not already present).
|
||||
|
||||
- **`UpdateTestSetupList(Action onCompleteAction = null)` method**
|
||||
```csharp
|
||||
public static void UpdateTestSetupList(Action onCompleteAction = null)
|
||||
```
|
||||
Performs a full refresh of `_testSetupList` and `_actualTestTemplates`:
|
||||
- Fetches all templates via `TestTemplateList.TestTemplatesList.AllTemplates`.
|
||||
- Publishes `ProgressBarEvent` with percentage updates.
|
||||
- Adds *all* templates to `_testSetupList` (regardless of `IsComplete`).
|
||||
- Computes CRC over `TestSetups` DB table and stores in `_crc`.
|
||||
- Invokes `onCompleteAction` if provided.
|
||||
|
||||
- **`TestSetupListLock` property**
|
||||
```csharp
|
||||
public static object TestSetupListLock { get; }
|
||||
```
|
||||
Lock object used to synchronize access to `_testSetupList`, `_actualTestTemplates`, `_crc`, and `_lastUpdateTime`.
|
||||
|
||||
---
|
||||
|
||||
### **Invariants**
|
||||
|
||||
1. **Thread Safety**: All public static properties/methods accessing `_testSetupList`, `_actualTestTemplates`, `_crc`, or `_lastUpdateTime` are guarded by `TestSetupListLock`.
|
||||
2. **Staleness Policy**: `_testSetupList` is considered stale if:
|
||||
- Time since `_lastUpdateTime` > 30 minutes (`MIN_TESTS_UPDATEINTERVAL_MINUTES`), *or*
|
||||
- CRC of the `TestSetups` DB table (`GetCRC()`) differs from stored `_crc`.
|
||||
3. **CRC Computation**: CRC is computed over a byte list derived from `TestSetups` table columns: `[TestSetupName]`, `[Dirty]`, `[Complete]`, `[LastModified]` (binary representation).
|
||||
4. **Progress Reporting**: Full refresh operations (`UpdateTestSetupList()` and `TestSetupList` getter) publish `ProgressBarEvent` with percentage updates; partial updates (e.g., `UpdateTestSetupList(TestTemplate)`) do not.
|
||||
|
||||
---
|
||||
|
||||
### **Dependencies**
|
||||
|
||||
#### **Imports/References**
|
||||
- **`DTS.Common.Interface.DASFactory.IDASCommunication`** – Used by `StatusHelpers.SetStatus2`.
|
||||
- **`DTS.Common.Enums.TSRAIRGo.TSRAIRGoStatus.StatusTypes`** – Status enum used in `SetStatus2`.
|
||||
- **`DataPROWin7.Common`** – Referenced in `ChannelHelper` (via `SerializedSettings.ISOViewMode`).
|
||||
- **`DTS.Common.Interface.Channels.IGroupChannel`** – Used in `ChannelHelper.GetWarningChannelName`.
|
||||
- **`DataPROWin7.DataModel`** – Provides `TestTemplate`, `TestTemplateList`.
|
||||
- **`Prism.Ioc.IContainerLocator`, `Prism.Events.IEventAggregator`** – Used for eventing and service resolution.
|
||||
- **`System.Windows.Threading.Dispatcher`, `System.Windows.Application`** – Used to check dispatcher access before resolving services.
|
||||
- **`DTS.Utilities.Crc32`** – Custom CRC32 implementation used in `GetCRC()`.
|
||||
|
||||
#### **External Dependencies**
|
||||
- **SQL Database**: `Storage.DbOperations.GetSQLCommand()` queries `[TestSetups]` table.
|
||||
- **Prism Event Aggregator**: Relies on `ProgressBarEvent` being registered and subscribed to.
|
||||
|
||||
---
|
||||
|
||||
### **Gotchas**
|
||||
|
||||
1. **`TestSetupList` behavior is context-dependent**:
|
||||
- When accessed *after* a full `UpdateTestSetupList()` call, it returns *all* test names (including incomplete ones).
|
||||
- When accessed *initially* (empty cache), it filters to *only complete tests* (`if (!t.IsComplete) { continue; }`).
|
||||
→ This inconsistency may cause unexpected omissions or inclusions depending on call order.
|
||||
|
||||
2. **`UpdateTestSetupList(TestTemplate)` silently fails** if `ContainerLocator.Container` or `IEventAggregator` is unavailable (e.g., during cmdline import), returning early without updating the list.
|
||||
|
||||
3. **`TestSetupIds` returns a `List<string>` but is documented as `List<string>` in source—however, `TestSetupList` returns `string[]`.** Ensure callers do not assume mutability or shared references.
|
||||
|
||||
4. **`SetStatus2` is a trivial wrapper**: It does *not* validate `idas`, `progressValue`, or `status`. Misuse (e.g., null delegate) will throw at runtime.
|
||||
|
||||
5. **`TDC_LEGACY_TOM_CUTOFF_SPS` is a legacy constant**: The comment explicitly states that channels ≤8000 SPS are *not handled* in this module. Do not assume support for lower sampling rates.
|
||||
|
||||
6. **`TestSetupList` getter may block indefinitely** if `ContainerLocator.Container.Resolve<IEventAggregator>()` fails (e.g., in headless/test environments), since it does not guard against null `eventAggregator` in the fallback path (unlike `UpdateTestSetupList()` methods).
|
||||
|
||||
7. **CRC computation is expensive**: `GetCRC()` performs a full table scan and byte marshaling. Avoid calling it frequently outside `UpdateTestSetupListIfStale()`.
|
||||
|
||||
8. **No validation of `progressValue` in `SetStatus2`**: The delegate may expect `double` in [0,100] range, but the method accepts any `int` (e.g., negative or >100).
|
||||
@@ -0,0 +1,123 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.DataModel/Common/DbWrappers/DASGet.cs
|
||||
- Common/DTS.Common.DataModel/Common/DbWrappers/TestSetupHardwareGet.cs
|
||||
generated_at: "2026-04-16T03:34:55.106379+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "65c9860ac4e82586"
|
||||
---
|
||||
|
||||
# DbWrappers
|
||||
|
||||
## Documentation: `DASGet` and `TestSetupHardwareGet` DbWrappers
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
|
||||
This module provides wrapper classes (`DASGet` and `TestSetupHardwareGet`) that encapsulate database retrieval logic for DAS (Data Acquisition System) hardware configuration and test setup hardware associations, respectively. Their primary role is to abstract raw database calls (`DbOperations.DASGet`, `DbOperations.TestSetupHardwareGet`) into strongly-typed, validated, and repaired domain objects—ensuring data integrity by correcting known bad or inconsistent database values (e.g., missing or zero `AntiAliasFilterRate`) in a centralized manner. These wrappers serve as the canonical data-access layer for DAS and test setup hardware metadata within the system.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `DASGet` class (`DTS.Common.DataModel.Common.DbWrappers`)
|
||||
|
||||
- **`DASGet()`**
|
||||
Default constructor.
|
||||
|
||||
- **`DASGet(IDASDBRecord record)`**
|
||||
Constructor that initializes the instance from an `IDASDBRecord`. Includes logic to repair `MaxAAFRate` if it is `NaN`: sets `MaxAAFRate = MaxSampleRate / 5`.
|
||||
|
||||
- **`int Type { get; set; }`**
|
||||
Gets/sets the `DASType` property (inherited from base `DASDBRecord`). Maps directly to the underlying `DASType` field.
|
||||
|
||||
- **`bool Reprogramable { get; set; }`**
|
||||
Gets/sets the `IsProgrammable` property (inherited from base `DASDBRecord`). Note: spelling is *Reprogramable* (missing 'm'), matching the source.
|
||||
|
||||
- **`bool Reconfigurable { get; set; }`**
|
||||
Gets/sets the `IsReconfigurable` property (inherited from base `DASDBRecord`).
|
||||
|
||||
- **`List<DASGet> DASGet_Wrapper(string serialNumber = null, string position = null)`**
|
||||
Static-like wrapper method (instance method) that calls `DbOperations.DASGet(serialNumber, position, out var dbDAS)`. Returns a list of `DASGet` instances constructed from the returned `dbDAS` array. If `DbOperations.DASGet` returns non-zero `hResult` or `dbDAS` is null, returns an empty list.
|
||||
|
||||
#### `TestSetupHardwareGet` class (`DTS.Common.DataModel.Common.DbWrappers`)
|
||||
|
||||
- **`TestSetupHardwareGet()`**
|
||||
Default constructor.
|
||||
|
||||
- **`TestSetupHardwareGet(ITestSetupHardwareRecord copy)`**
|
||||
Constructor that initializes the instance from an `ITestSetupHardwareRecord`.
|
||||
|
||||
- **`bool AddOrRemove { get; set; }`**
|
||||
Gets/sets the `AddDAS` property (inherited from base `TestSetupHardwareRecord`). On set, raises `OnPropertyChanged("AddOrRemove")`.
|
||||
|
||||
- **`List<TestSetupHardwareGet> TestSetupHardwareGet_Wrapper(int? testSetupId, Dictionary<int, IDASHardware> hardwareLookup)`**
|
||||
Instance method that retrieves test setup hardware records via `DbOperations.TestSetupHardwareGet(testSetupId, out var records)`. For each record:
|
||||
- If `AntiAliasFilterRate == 0` and `hardwareLookup` is non-null, repairs the rate using `RepairAntiAliasFilterRate` based on the DAS type from `hardwareLookup[record.DASId]`.
|
||||
- Then, *after* initial construction, performs a second pass over the list to repair any remaining `AntiAliasFilterRate == 0` entries by querying `DASGet_Wrapper()` internally to fetch the DAS type for that `DASId`.
|
||||
Returns a list of repaired `TestSetupHardwareGet` instances.
|
||||
|
||||
- **`private HardwareTypes GetDASTypeEnumFromId(int dasId)`**
|
||||
Helper method: calls `DASGet_Wrapper()` to fetch all DAS records, then matches on `DASId` to retrieve the `Type` (int), wraps it in a `DTS.Common.ISO.Hardware` instance, and returns its `DASTypeEnum`.
|
||||
|
||||
- **`private int RepairAntiAliasFilterRate(HardwareTypes dasTypeEnum, int samplesPerSecond)`**
|
||||
Helper method: returns a non-zero `AntiAliasFilterRate` based on `dasTypeEnum` and `samplesPerSecond`:
|
||||
- For `HardwareTypes.DIM`, `G5INDUMMY`, `G5VDS`, `SIM`, `TDAS_Pro_Rack`, `TDAS_LabRack`, `TOM`: returns `0` (no repair—these types allow 0).
|
||||
- For all other types: returns `SerializedSettings.GetAAFException(SerializableAAF.DAS_TYPE.SLICE, samplesPerSecond)` cast to `int`.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
|
||||
- **`DASGet`**
|
||||
- After construction via `DASGet(IDASDBRecord)`, if `MaxAAFRate` is `NaN`, it is guaranteed to be set to `MaxSampleRate / 5`.
|
||||
- `Type`, `Reprogramable`, and `Reconfigurable` are direct aliases to underlying base properties (`DASType`, `IsProgrammable`, `IsReconfigurable`), so their values reflect the underlying record.
|
||||
|
||||
- **`TestSetupHardwareGet`**
|
||||
- After calling `TestSetupHardwareGet_Wrapper`, **no element in the returned list will have `AntiAliasFilterRate == 0`**, unless `GetDASTypeEnumFromId` returns `HardwareTypes.UNDEFINED` (in which case `RepairAntiAliasFilterRate` falls through to `default`, i.e., `0`).
|
||||
- `AddOrRemove` is a computed alias for `AddDAS`, with change notification.
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
#### `DASGet`
|
||||
- **Imports/Uses**:
|
||||
- `DTS.Common.Interface.DataRecorders.IDASDBRecord`
|
||||
- `DTS.Common.Storage.DbOperations.DASGet(...)`
|
||||
- `DTS.Common.Classes.Hardware` (namespace, used for base class `DASDBRecord`)
|
||||
- **Depended on by**:
|
||||
- `TestSetupHardwareGet.GetDASTypeEnumFromId(...)` calls `DASGet_Wrapper()` to resolve DAS types.
|
||||
|
||||
#### `TestSetupHardwareGet`
|
||||
- **Imports/Uses**:
|
||||
- `DTS.Common.Interface.DataRecorders.ITestSetupHardwareRecord`
|
||||
- `DTS.Common.Storage.DbOperations.TestSetupHardwareGet(...)`
|
||||
- `DTS.Common.Enums.Hardware.HardwareTypes`
|
||||
- `DTS.Common.Classes.Hardware` (base class `TestSetupHardwareRecord`)
|
||||
- `DTS.Common.Classes.TestSetups`, `DTS.Common.Interface.TestSetups`, `DataPROWin7.Common` (for `SerializedSettings`)
|
||||
- `DASGet.DASGet_Wrapper(...)` (indirectly via `GetDASTypeEnumFromId`)
|
||||
- **Depended on by**:
|
||||
- Likely used by test setup configuration UI or business logic layers (not evident from source).
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
|
||||
- **Spelling**: `Reprogramable` (missing 'm') is used in property names—this is intentional per source.
|
||||
- **Double repair logic in `TestSetupHardwareGet_Wrapper`**:
|
||||
- First repair uses `hardwareLookup` if provided.
|
||||
- Second repair (post-construction loop) *ignores* `hardwareLookup` and instead queries `DASGet_Wrapper()` to resolve DAS type.
|
||||
→ This may cause inconsistent behavior if `hardwareLookup` is stale/out-of-sync with DB.
|
||||
- **Fallback to `HardwareTypes.UNDEFINED`**:
|
||||
If `GetDASTypeEnumFromId` fails to find a matching `DASId`, it returns `HardwareTypes.UNDEFINED`, and `RepairAntiAliasFilterRate` returns `0`. This means `AntiAliasFilterRate` can still be `0` in the final list if the DAS record is missing.
|
||||
- **Hardcoded DAS type groups**:
|
||||
The `RepairAntiAliasFilterRate` switch statement assumes specific DAS types allow `0` AAF rate (e.g., TDAS family). Any new DAS type added must be explicitly added to avoid unintended repair.
|
||||
- **`DASGet_Wrapper()` is an instance method**:
|
||||
Despite being named like a static utility, it is an instance method on `DASGet` and `TestSetupHardwareGet`. Calling `new DASGet().DASGet_Wrapper()` is required.
|
||||
- **No null-safety on `hardwareLookup` in first repair pass**:
|
||||
If `hardwareLookup == null`, the first repair branch is skipped, but the second pass (which queries DB) still runs—so behavior is safe but potentially slower.
|
||||
|
||||
None identified beyond the above.
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.DataModel/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T03:32:08.688522+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "35833e634d97c22d"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## 1. Purpose
|
||||
This module (`DTS.Common.DataModel`) is an assembly containing shared data model definitions for the DTS (presumably *Data Transfer System* or domain-specific equivalent) platform. Its role is to centralize core data contracts (e.g., classes, structs, enums) used across other components in the system—ensuring consistency, reducing duplication, and enabling decoupled consumption of data structures. As indicated by its name and structure, it is a foundational library intended for reuse across multiple projects or services.
|
||||
|
||||
## 2. Public Interface
|
||||
**No public types are defined in this file.**
|
||||
The file `AssemblyInfo.cs` contains only assembly-level metadata attributes (e.g., title, version, COM visibility). It does not declare any public classes, interfaces, structs, enums, or methods. Therefore, there is **no public API surface** exposed by this file.
|
||||
|
||||
## 3. Invariants
|
||||
- The assembly identity is fixed at version `1.0.0.0` (both `AssemblyVersion` and `AssemblyFileVersion`).
|
||||
- The assembly is **not visible to COM** (`ComVisible(false)`), meaning it is not intended for interop with legacy COM clients.
|
||||
- The GUID `2a2f03a9-bf85-4360-a06a-cf3016d2633b` uniquely identifies the typelib for COM exposure *if* `ComVisible` were enabled (which it is not).
|
||||
- No runtime behavior or state is managed by this file; it is purely declarative metadata.
|
||||
|
||||
## 4. Dependencies
|
||||
- **Dependencies**: None (this file only references standard .NET attributes from `System.Reflection`, `System.Runtime.CompilerServices`, and `System.Runtime.InteropServices`).
|
||||
- **Dependents**: This assembly (`DTS.Common.DataModel`) is almost certainly referenced by other projects in the codebase (e.g., `DTS.Server`, `DTS.Client`, or similar), but such references are not visible in this file alone.
|
||||
|
||||
## 5. Gotchas
|
||||
- **Misleading filename**: Despite the name `DTS.Common.DataModel`, this file does *not* contain any data model types. Actual data model definitions (classes, structs, enums) are expected to reside in other files within the same project (e.g., `Models/`, `Entities/`, or similar subdirectories).
|
||||
- **Versioning rigidity**: The version is hardcoded to `1.0.0.0` with no build/revision auto-increment (`1.0.*` is commented out). This may complicate deployment or traceability if not managed externally (e.g., via CI/CD tooling).
|
||||
- **COM compatibility**: While `ComVisible(false)` is appropriate for modern .NET, teams integrating with legacy COM systems must be aware that this assembly *cannot* be consumed directly without additional interop layers.
|
||||
- **None identified from source alone.**
|
||||
@@ -0,0 +1,121 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.DataModel/StateMachines/OverallArmStatusStateMachine.cs
|
||||
generated_at: "2026-04-16T03:32:13.517351+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "8fbd8ac85721cb74"
|
||||
---
|
||||
|
||||
# StateMachines
|
||||
|
||||
## Documentation: `OverallArmStatusStateMachine`
|
||||
|
||||
---
|
||||
|
||||
### **1. Purpose**
|
||||
|
||||
The `OverallArmStatusStateMachine` class implements a state machine that tracks and manages the high-level operational status of an arm subsystem (likely related to data acquisition or recording hardware) within the DTS system. It uses the `Stateless` library to define transitions between states such as `Recording`, `IDLE`, `WaitingForTrigger`, `Downloading`, and `Disarmed`, based on triggers like `Recording`, `DoneRecording`, `Disarm`, and `DASNotFound`. Its primary role is to maintain a canonical "overall arm status" state, emit notifications on state changes via the `OverallStatusStateChange` event, and serve as a central coordination point for status reporting across the application (e.g., updating a global status UI field). It does *not* manage low-level arm logic but aggregates and reflects higher-level transitions.
|
||||
|
||||
---
|
||||
|
||||
### **2. Public Interface**
|
||||
|
||||
#### **Constructor**
|
||||
```csharp
|
||||
public OverallArmStatusStateMachine()
|
||||
```
|
||||
- Initializes the `IEventAggregator` via `ContainerLocator.Container.Resolve<IEventAggregator>()`.
|
||||
- Calls `Initialize()` to configure the underlying `Stateless.StateMachine`.
|
||||
|
||||
#### **Events**
|
||||
```csharp
|
||||
public event OverallStatusStateChangeDelegate OverallStatusStateChange;
|
||||
```
|
||||
- **Delegate**: `public delegate void OverallStatusStateChangeDelegate(ArmStateMachineStates.States previousState, ArmStateMachineStates.States nextState);`
|
||||
- Fired whenever the overall status transitions to a new state (i.e., `CurrentOverallStatusState` changes). The event includes the previous and next state.
|
||||
|
||||
#### **Methods**
|
||||
```csharp
|
||||
public ArmStateMachineStates.States GetDASStatus()
|
||||
```
|
||||
- Returns the current overall status state (`CurrentOverallStatusState`).
|
||||
|
||||
```csharp
|
||||
public void FireTrigger(Triggers trigger, ArmStateMachineStates.States state)
|
||||
```
|
||||
- Fires a named trigger with an associated *target state parameter* (note: this is unusual—see *Gotchas*).
|
||||
- Internally maps each `Triggers` enum value to a pre-configured `TriggerWithParameters<ArmStateMachineStates.States>` and invokes `StateMachine.Fire(trigger, state)`.
|
||||
- Logs exceptions via `APILogger.Log(ex.Message)`; does *not* rethrow.
|
||||
- **Special case**: `Triggers.PostTestProcessing` incorrectly fires `DoneRecordingTrigger` instead of a dedicated `PostTestProcessingTrigger`.
|
||||
|
||||
#### **Nested Types**
|
||||
- `public enum Triggers`: Defines 37+ named triggers (e.g., `Recording`, `Disarm`, `DASNotFound`, `Downloading`, `WaitingForTrigger`, `WaitingForSchedule`, `WaitingForInterval`, `ReadyForDownload`, `DoneRecording`, `NoDataToDownload`, `DataNeverDownloaded`, `Streaming`, `FlashClear`, `Error`, `GettingEventInfo`, `CheckingForData`, `Rearming`, `IDLE`, `IntervalRecording`, `NonIntervalRecording`, `RunButton`, `a`, `c`, `d`, `e`, `h`, `n`, `rr`, `tt`, `uu`, `yy`).
|
||||
- *Note*: Several triggers (`a`, `c`, `d`, `e`, `h`, `n`, `rr`, `tt`, `uu`, `yy`) appear to be placeholder or legacy names with no documented purpose.
|
||||
|
||||
---
|
||||
|
||||
### **3. Invariants**
|
||||
|
||||
- **Initial State**: The state machine always starts in `ArmStateMachineStates.States.CheckingForDAS`.
|
||||
- **Current State Tracking**: `CurrentOverallStatusState` is updated *only* via `SetOverallStatus()`, which:
|
||||
- Compares `newState` to `CurrentOverallStatusState`.
|
||||
- Logs transitions via `APILogger.Log(...)`.
|
||||
- Invokes `OverallStatusStateChange` *only if* the state changes.
|
||||
- **State Machine Library**: Uses `Stateless.StateMachine<ArmStateMachineStates.States, Triggers>`.
|
||||
- **Parameterized Triggers**: All transitions that accept a state parameter use `SetTriggerParameters<ArmStateMachineStates.States>()`, meaning every trigger expects a *target state* as an argument when fired (e.g., `Fire(trigger, targetState)`).
|
||||
- **No Explicit Error Handling in Transitions**: Transitions do not define custom `OnEntryFrom`/`OnExit` logic beyond calling `SetOverallStatus()`; no fallback or recovery behavior is defined in the state configuration.
|
||||
|
||||
---
|
||||
|
||||
### **4. Dependencies**
|
||||
|
||||
#### **Imports/Usings**
|
||||
- `Stateless` – Core state machine library.
|
||||
- `Prism.Ioc.ContainerLocator` – For resolving `IEventAggregator`.
|
||||
- `DTS.Common.Enums.TSRAIRGo` – Provides `ArmStateMachineStates.States` (not shown in this file).
|
||||
- `DTS.Common.Utilities.Logging` – Provides `APILogger`.
|
||||
- `System` and `Prism.Events` – For `IEventAggregator`.
|
||||
|
||||
#### **External Dependencies**
|
||||
- **`ArmStateMachineStates.States`**: An external enum defining the valid states (e.g., `CheckingForDAS`, `IDLE`, `Recording`, `Disarmed`, `Downloading`, `ClearingFlash`, `WaitingForTrigger`, `WaitingForSchedule`, `WaitingForInterval`, `PostTestProcessing`, `GettingEventInfo`, `ReadyForDownload`, `Streaming`). Its definition is not included here.
|
||||
- **`APILogger`**: Static logging utility.
|
||||
- **`ContainerLocator`**: Prism DI container accessor (assumes `IEventAggregator` is registered).
|
||||
|
||||
#### **Consumers**
|
||||
- Any component needing to update or query the overall arm status (e.g., UI, telemetry, control logic) must:
|
||||
- Subscribe to `OverallStatusStateChange` to react to state changes.
|
||||
- Call `FireTrigger()` to signal events.
|
||||
- Call `GetDASStatus()` to poll the current state.
|
||||
|
||||
---
|
||||
|
||||
### **5. Gotchas**
|
||||
|
||||
- **Unusual Trigger Signature**: All triggers are defined as `TriggerWithParameters<ArmStateMachineStates.States>`, meaning every `Fire()` call *must* supply a target state (e.g., `Fire(RecordingTrigger, ArmStateMachineStates.States.Recording)`). This is atypical—most state machines infer the next state from the transition configuration. The comment in `FireTrigger()` ("why specify state here? shouldn't that be done based on current state/trigger?") confirms this design is questionable and likely error-prone.
|
||||
|
||||
- **Incorrect Trigger Mapping**: In `FireTrigger()`, `Triggers.PostTestProcessing` incorrectly fires `DoneRecordingTrigger` instead of a dedicated `PostTestProcessingTrigger`. This may cause unintended state transitions (e.g., skipping `PostTestProcessing` state entirely).
|
||||
|
||||
- **Unused Triggers**: The `Triggers` enum includes 10 cryptic triggers (`a`, `c`, `d`, `e`, `h`, `n`, `rr`, `tt`, `uu`, `yy`) with no corresponding configuration in `Initialize()`. These are likely legacy or placeholders and should be removed or documented.
|
||||
|
||||
- **No Handling for `ErrorTrigger`**: While `ErrorTrigger` is declared, it is *not* used in any state configuration (no `.Permit()` or `.OnEntryFrom()` references it). Attempting to fire it will throw a `Stateless` exception (trigger not defined for current state).
|
||||
|
||||
- **Ignored Triggers May Cause Silent Failures**: Several states use `.Ignore()` for specific triggers (e.g., `ClearingFlash` ignores `ReadyForDownload`, `NoDataToDownload`, `DataNeverDownloaded`). Firing these triggers in those states will throw an exception (not silently ignored), contradicting the intent of `.Ignore()` in `Stateless` (which *does* allow the trigger but prevents transition). Verify `Stateless` behavior—this may be a source of runtime exceptions.
|
||||
|
||||
- **No Public Setter for State**: The current state is read-only via `GetDASStatus()`. There is no way to manually override or reset the state machine (e.g., for testing or recovery), which may complicate error recovery.
|
||||
|
||||
- **Logging Side Effect**: `SetOverallStatus()` logs *every* transition, which may be excessive in high-frequency scenarios. No filtering or throttling is applied.
|
||||
|
||||
- **Missing State Definitions**: The states used (e.g., `ArmStateMachineStates.States.CheckingForDAS`) are referenced but not defined in this file. Their semantics and relationships depend on the external `ArmStateMachineStates.States` enum.
|
||||
|
||||
- **No Validation on State Parameter**: `FireTrigger()` accepts any `ArmStateMachineStates.States` as the second parameter. Passing an invalid or inconsistent state (e.g., `Fire(RecordingTrigger, ArmStateMachineStates.States.Disarmed)`) may result in runtime exceptions or undefined behavior.
|
||||
|
||||
- **Exception Swallowing**: `FireTrigger()` catches and logs *all* exceptions (including `Stateless` exceptions like `InvalidOperationException` for invalid transitions), but does not propagate them. This can mask critical failures.
|
||||
|
||||
- **No Thread Safety**: The class does not indicate thread-safety. Concurrent calls to `FireTrigger()` or state queries may cause race conditions.
|
||||
|
||||
- **Graph Generation Side Effect**: `Stateless.Graph.UMLDotGraph.Format(...)` is called but the result is discarded (`string graph = ...; graph = ...;`). This suggests debugging code was left in place.
|
||||
|
||||
---
|
||||
|
||||
*Documentation generated from source file `Common/DTS.Common.DataModel/StateMachines/OverallArmStatusStateMachine.cs`.*
|
||||
248
enriched-qwen3-coder-next/Common/DTS.Common.ICommunication.md
Normal file
248
enriched-qwen3-coder-next/Common/DTS.Common.ICommunication.md
Normal file
@@ -0,0 +1,248 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.ICommunication/IDASConnectedDevice.cs
|
||||
- Common/DTS.Common.ICommunication/ICommunication.cs
|
||||
- Common/DTS.Common.ICommunication/Communication.cs
|
||||
generated_at: "2026-04-16T14:07:22.447976+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "b573bb7d2f5d27d0"
|
||||
---
|
||||
|
||||
# Documentation: DTS.Common.ICommunication
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides the core communication infrastructure for interacting with DAS (Data Acquisition System) hardware devices. It defines the contract for connected devices via `IDASConnectedDevice`, encapsulates device metadata through `Communication_DASInfo`, and implements an asynchronous, callback-driven communication layer via the abstract `Communication<T>` class. The module handles connection lifecycle management, command execution with timeout handling, cancellation support, and protocol version negotiation for hardware commands.
|
||||
|
||||
---
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### IDASConnectedDevice (Interface)
|
||||
**Namespace:** `DTS.DASLib.Communication`
|
||||
|
||||
Describes a device connected to a DAS (e.g., S6 connected to S6DB).
|
||||
|
||||
| Property | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `DeviceType` | `HardwareTypes` | The device type of the connected device |
|
||||
| `Port` | `int` | The port on the DAS which the device is on (0-based) |
|
||||
| `SpotOnPort` | `int` | The spot on the chain or port the device is on (0-based) |
|
||||
| `PhysicalAddress` | `PhysicalAddress` | MAC Address or physical address |
|
||||
| `IPAddress` | `string` | The IP address of the device |
|
||||
| `SerialNumber` | `string` | The serial number of the device |
|
||||
| `Location` | `string` | The location of the device |
|
||||
| `Version` | `string` | The version of the device |
|
||||
|
||||
---
|
||||
|
||||
### CanceledException (Class)
|
||||
**Namespace:** `DTS.Common.ICommunication`
|
||||
|
||||
A marker exception class extending `ApplicationException` to signal operation cancellation.
|
||||
|
||||
---
|
||||
|
||||
### Communication_DASInfo (Class)
|
||||
**Namespace:** `DTS.Common.ICommunication`
|
||||
**Implements:** `ICommunication_DASInfo`
|
||||
|
||||
Encapsulates metadata about a DAS device.
|
||||
|
||||
**Properties:**
|
||||
| Property | Type | Default | Description |
|
||||
|----------|------|---------|-------------|
|
||||
| `FirstUseDate` | `DateTime?` | `null` | Date of first use; `null` indicates hardware not used since calibration. Only valid when `IsFirstUseDateSupported` is `true` |
|
||||
| `IsFirstUseDateSupported` | `bool` | `false` | Indicates hardware supports first use dates |
|
||||
| `IsStreamingSupported` | `bool` | `false` | Indicates whether streaming is supported |
|
||||
| `ConnectedDevices` | `IDASConnectedDevice[]` | empty array | Devices connected to the DAS (currently only used by SLICE6DB) |
|
||||
| `SerialNumbers` | `string[]` | - | Array of serial numbers |
|
||||
| `FirmwareVersions` | `string[]` | - | Array of firmware versions |
|
||||
|
||||
**Methods:**
|
||||
- `void SetConnectedDevices(IDASConnectedDevice[] devices)` — Sets the `ConnectedDevices` array
|
||||
- `string StackSerialNumber(int devid)` — Returns a stacked serial number string. Returns "N/A" if `SerialNumbers` is null/empty; returns `SerialNumbers[0]::SerialNumbers[devid]` if `devid` is non-zero and valid; otherwise returns `SerialNumbers[0]`
|
||||
|
||||
**Constructors:**
|
||||
- `Communication_DASInfo()` — Default constructor
|
||||
- `Communication_DASInfo(string[] serials, string[] fwnums)` — Constructs with cloned copies of serial and firmware arrays
|
||||
|
||||
---
|
||||
|
||||
### Communication\<T\> (Abstract Class)
|
||||
**Namespace:** `DTS.Common.ICommunication`
|
||||
**Implements:** `Interface.DASFactory.ICommunication`, `IDisposable`
|
||||
**Constraint:** `where T : IConnection, new()`
|
||||
|
||||
Abstract base class for hardware communication, providing connection management, command execution, and cancellation support.
|
||||
|
||||
**Properties:**
|
||||
| Property | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `ErrorInSetup` | `bool` | Indicates an error occurred during setup |
|
||||
| `ConnectString` | `string` | Connection string from underlying socket |
|
||||
| `Connected` | `bool` | Whether the socket is connected |
|
||||
| `DASInfo` | `ICommunication_DASInfo` | DAS device information |
|
||||
| `Transport` | `IConnection` | Underlying connection transport (setter throws `NotSupportedException`) |
|
||||
| `ReceiveBufferSize` | `int` | Receive buffer size; default is 65536 (2^16) |
|
||||
| `SerialNumber` | `string` | Device serial number |
|
||||
| `FirmwareVersion` | `string` | Device firmware version; setter triggers `FirmwareVersionUpdated()` |
|
||||
| `ProtocolVersion` | `byte` | Protocol version for command support checks |
|
||||
| `MinimumProtocols` | `Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte>` | Maps commands to minimum required protocol versions |
|
||||
| `FlushTimeoutMilliSec` | `int` | Timeout for flush operations; default is 5ms |
|
||||
| `ExecuteIsBusy` | `bool` | Thread-safe flag indicating execution lock state |
|
||||
| `CancelEvent` | `ManualResetEvent` | Event signaling cancellation has occurred |
|
||||
|
||||
**Events:**
|
||||
- `EventHandler OnDisconnected` — Raised when the underlying socket disconnects
|
||||
|
||||
**Public Methods:**
|
||||
- `int CompareTo(Interface.DASFactory.ICommunication dev)` — Compares connection strings (case-insensitive, ordinal)
|
||||
- `int CompareTo(string conStr)` — Compares connection string to provided string
|
||||
- `abstract void InitMinProto()` — Must be implemented to populate `MinimumProtocols`
|
||||
- `bool IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands command)` — Returns `true` if `ProtocolVersion >= GetMinProto(command)`
|
||||
- `byte GetMinProto(DFConstantsAndEnums.ProtocolLimitedCommands command)` — Returns minimum protocol version for command; returns `0xFF` if not found; throws `NotSupportedException` if `MinimumProtocols` is null
|
||||
- `void Flush(int timeoutMs)` — Flushes the socket data buffer until empty or timeout
|
||||
- `byte[] SyncExecute(byte[] byteData, int cbTimeout)` — **Throws `NotSupportedException`** (not implemented)
|
||||
- `void Connect(string connectString, CommunicationCallback callback, object callbackObject, int callbackTimeout, string hostIPAddress)` — Initiates asynchronous connection
|
||||
- `void Disconnect(bool reuseSocket, CommunicationCallback callback, object callbackObject, int callbackTimeout)` — Initiates asynchronous disconnect
|
||||
- `void Cancel()` — Sets cancel state with 500ms sleep delay on clear
|
||||
- `void ForceCancel()` — Sets cancel state with 250ms sleep delay on clear
|
||||
- `bool IsCanceled()` — Returns current cancel state
|
||||
- `void ClearCancel()` — Clears cancel state after sleeping
|
||||
- `void Execute(byte[] byteData, CommunicationCallback cb, object cbObject, int cbTimeout)` — Sends data and processes responses asynchronously
|
||||
- `void PseudoExecute(byte[] byteData, CommunicationCallback cb, object cbObject, int cbTimeout)` — For commands that only receive data (no send); does not clear buffer
|
||||
- `void SetupReader()` — Initializes the asynchronous receive loop
|
||||
- `void Close(int timeout)` — Empty implementation (no-op)
|
||||
- `void Dispose()` — Implements `IDisposable`
|
||||
|
||||
**Protected Methods:**
|
||||
- `void Lock()` — Empty implementation
|
||||
- `void Release()` — Empty implementation
|
||||
- `virtual void FirmwareVersionUpdated()` — Called when `FirmwareVersion` is set
|
||||
|
||||
---
|
||||
|
||||
### CommunicationReport (Class)
|
||||
**Namespace:** `DTS.Common.ICommunication`
|
||||
**Implements:** `ICommunicationReport`
|
||||
|
||||
Carries the result of an asynchronous communication operation.
|
||||
|
||||
| Property | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `UserState` | `object` | User-provided state object |
|
||||
| `Result` | `CommunicationResult` | Result enum value |
|
||||
| `Data` | `byte[]` | Received data (for read operations) |
|
||||
|
||||
**Constructor:** `CommunicationReport(object state, CommunicationResult res)`
|
||||
|
||||
---
|
||||
|
||||
### Communication\<T\>.ActionData (Abstract Nested Class)
|
||||
Base class for tracking asynchronous operations with timeout handling.
|
||||
|
||||
| Property | Description |
|
||||
|----------|-------------|
|
||||
| `UserCallback` | `CommunicationCallback` delegate |
|
||||
| `UserCallbackObject` | User-provided state object |
|
||||
| `UserTimeout` | Timeout in milliseconds |
|
||||
| `TimerExpired` | Whether the timeout timer fired |
|
||||
|
||||
**Methods:**
|
||||
- `void StartTimer()` — Starts the timeout timer
|
||||
- `void KillTimer()` — Stops and disposes the timer
|
||||
- `bool ReportCanceled()` — Invokes callback with `CommunicationResult.Canceled`
|
||||
- `abstract bool ReportFailure()` — Must implement failure reporting
|
||||
- `abstract bool ReportSuccess()` — Must implement success reporting
|
||||
- `abstract CommunicationResult GetTimeoutResult()` — Must return the timeout-specific result
|
||||
|
||||
---
|
||||
|
||||
### Communication\<T\>.ExecuteActionData (Nested Class)
|
||||
Extends `ActionData` for execute operations.
|
||||
|
||||
**Additional Methods:**
|
||||
- `bool ReportReadSuccess(byte[] data)` — Reports successful read with data
|
||||
- `bool ReportReadTimeout()` — Reports read timeout
|
||||
- `bool ReportReadDisconnected()` — Reports disconnection during read
|
||||
|
||||
---
|
||||
|
||||
### Communication\<T\>.PseudoAsyncResult (Nested Class)
|
||||
Implements `IAsyncResult` for `PseudoExecute` operations.
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| `IsCompleted` | Always `true` |
|
||||
| `AsyncState` | The `ExecuteActionData` instance |
|
||||
| `CompletedSynchronously` | Always `true` |
|
||||
| `AsyncWaitHandle` | Throws `NotImplementedException` |
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
1. **Connection State Consistency**: `sock` is instantiated in the constructor and cannot be replaced via `Transport` setter (throws `NotSupportedException`).
|
||||
|
||||
2. **Execute Locking**: `ExecuteIsBusy` must be `false` before setting to `true`, and `true` before setting to `false`. Debug assertions enforce this—violations indicate re-entry or extra unlock bugs.
|
||||
|
||||
3. **Port/Spot Indexing**: `Port` and `SpotOnPort` on `IDASConnectedDevice` are 0-based indices.
|
||||
|
||||
4. **FirstUseDate Validity**: `FirstUseDate` is only meaningful when `IsFirstUseDateSupported` is `true`.
|
||||
|
||||
5. **MinimumProtocols Initialization**: `MinimumProtocols` must be populated by `InitMinProto()` before calling `GetMinProto()` or `IsCommandSupported()`, otherwise `NotSupportedException` is thrown.
|
||||
|
||||
6. **Callback Non-Null Assertion**: `ActionData` constructor asserts that the callback parameter is non-null.
|
||||
|
||||
7. **Thread ID Consistency**: In `ProcessReceivedData` and `SRRecvCallback`, if the thread ID changes during `WaitWithCondition.Wait`, the method exits early without processing.
|
||||
|
||||
---
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### This module depends on:
|
||||
- `DTS.Common.Enums.Hardware` — `HardwareTypes` enum
|
||||
- `DTS.Common.Enums.Communication` — `CommunicationResult`, `CommunicationConstantsAndEnums`
|
||||
- `DTS.Common.Enums.DASFactory` — `DFConstantsAndEnums`
|
||||
- `DTS.Common.Interface.Communication` — `ICommunication_DASInfo`, `CommunicationCallback` delegate
|
||||
- `DTS.Common.Interface.Connection` — `IConnection`
|
||||
- `DTS.Common.Classes.Connection` — (referenced but contents not in source)
|
||||
- `DTS.Common.Utilities.Logging` — `APILogger`
|
||||
- `DTS.Common.Utilities` — `SecureQueue<T>`
|
||||
- `DTS.Common.Utils` — `WaitWithCondition`
|
||||
- `System.Net.NetworkInformation` — `PhysicalAddress`
|
||||
- `System.Net.Sockets` — `SocketException`
|
||||
- `System.Threading` — `ManualResetEvent`, `Timer`, `Timeout`
|
||||
- `System.Threading.Tasks` — `Task`
|
||||
|
||||
### What depends on this module:
|
||||
- Implementations of `IConnection` (generic constraint `T`)
|
||||
- Concrete DAS communication implementations that extend `Communication<T>`
|
||||
- Consumers of `IDASConnectedDevice` for device enumeration
|
||||
- Consumers of `ICommunication_DASInfo` for device metadata
|
||||
|
||||
---
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
1. **SyncExecute Not Implemented**: Calling `SyncExecute()` throws `NotSupportedException`. Use `Execute()` with callbacks instead.
|
||||
|
||||
2. **Lock/Release Are No-ops**: `Lock()` and `Release()` methods have empty implementations. Any synchronization relying on these is not actually protected.
|
||||
|
||||
3. **Close() Does Nothing**: `Close(int timeout)` has an empty body and performs no cleanup.
|
||||
|
||||
4. **Cancel Sleep Delays**: `ClearCancel()` sleeps for either 500ms (after `Cancel()`) or 250ms (after `ForceCancel()`) before clearing the cancel state. This can introduce unexpected latency.
|
||||
|
||||
5. **Transport Setter Always Throws**: Setting `Transport` throws `NotSupportedException`—the socket cannot be replaced after construction.
|
||||
|
||||
6. **PseudoExecute Buffer Behavior**: Unlike `Execute()`, `PseudoExecute()` does not flush the buffer before operation and picks up from wherever the previous `PseudoExecute` left off.
|
||||
|
||||
7. **StackSerialNumber Edge Cases**: Returns "N/A" for empty/null `SerialNumbers`, but returns `SerialNumbers[0]` for `devid` values outside valid range (except 0). This may mask indexing errors.
|
||||
|
||||
8. **ActionData Timer Race**: The timer callback and `KillTimer()` both check `_timerFired` under a lock, but if the timer fires just before disposal, the callback will still execute.
|
||||
|
||||
9. **ReceiveCallback Disconnection Handling**: When `sock.EndReceive` returns 0 bytes, `_receiveCallbackRunning` is set to `false` and `OnDisconnected` is invoked, but the socket state is not explicitly cleaned up.
|
||||
|
||||
10. **Extra Communication Logging**: Conditional logging via `DFConstantsAndEnums.ExtraCommunicationLogging` may impact performance if enabled in production.
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.ICommunication/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T02:05:22.047619+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "f8d21de2dda7b77f"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
### 1. **Purpose**
|
||||
This module (`DTS.Common.ICommunication`) is an assembly containing shared interfaces and contracts for communication functionality within the DTS (likely *Data Transfer System* or similar domain-specific system) codebase. Based on the assembly name and versioning, it serves as a foundational abstraction layer—defining contracts (e.g., `ICommunication`-related interfaces) that concrete implementations must adhere to, enabling decoupling between communication logic and its consumers. It does not contain implementation logic itself but acts as a contract library for inter-module communication.
|
||||
|
||||
### 2. **Public Interface**
|
||||
**No public types are defined in this file.**
|
||||
The file `AssemblyInfo.cs` contains only assembly-level metadata attributes (e.g., title, version, COM visibility). It declares no classes, interfaces, methods, or properties. Therefore, there are *no* public functions, classes, or methods documented here. Actual interface definitions (e.g., `ICommunication`, `IChannel`, etc.)—if any—reside in other source files *outside* this assembly metadata file.
|
||||
|
||||
### 3. **Invariants**
|
||||
- The assembly is **non-`ComVisible`** (`[assembly: ComVisible(false)]`), meaning its types are not exposed to COM by default.
|
||||
- The assembly version is fixed at `1.06.0081` (both `AssemblyVersion` and `AssemblyFileVersion`).
|
||||
- The GUID `11eb7c8b-d4b6-4121-8dcb-1b6ddfe1136f` uniquely identifies the typelib for COM interop *if* `ComVisible` were enabled for specific types (currently disabled at assembly level).
|
||||
- No runtime behavior or state is managed here; this is purely declarative metadata.
|
||||
|
||||
### 4. **Dependencies**
|
||||
- **Dependencies**: This file depends solely on the .NET Framework assemblies `System.Reflection`, `System.Runtime.CompilerServices`, and `System.Runtime.InteropServices` (standard runtime namespaces).
|
||||
- **Dependents**: This assembly is likely referenced by other modules in the `DTS.Common.*` family (e.g., `DTS.Common.Communication`, `DTS.Client`, etc.), which would consume its *interface definitions* (not present in this file).
|
||||
- **Note**: Since this file contains no types, it has no *type-level* dependencies beyond the core runtime.
|
||||
|
||||
### 5. **Gotchas**
|
||||
- **Misleading file name**: The assembly is named `ICommunication`, but this file (`AssemblyInfo.cs`) contains no interface definitions—only metadata. Developers may incorrectly assume this file defines `ICommunication` or related interfaces.
|
||||
- **Versioning**: The version `1.06.0081` (interpreted as `1.6.81`) suggests legacy status (copyright date is 2008). Caution is warranted when updating or refactoring—backward compatibility may be critical.
|
||||
- **COM interop**: Though `ComVisible` is `false` at the assembly level, if types in *other* files in this assembly are marked `[ComVisible(true)]`, they will be exposed to COM using the specified GUID. This could cause versioning conflicts if the GUID changes.
|
||||
- **No documentation in source**: The `AssemblyDescription` and `AssemblyConfiguration` attributes are empty, indicating minimal tooling or build-time documentation support.
|
||||
|
||||
**None identified from source alone** beyond the above—no behavioral quirks, side effects, or hidden contracts exist in this file.
|
||||
27
enriched-qwen3-coder-next/Common/DTS.Common.IConnection.md
Normal file
27
enriched-qwen3-coder-next/Common/DTS.Common.IConnection.md
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.IConnection/IConnection.cs
|
||||
generated_at: "2026-04-16T14:08:16.882363+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "3e284d4b0962cb4a"
|
||||
---
|
||||
|
||||
# Documentation for `IConnection.cs`
|
||||
|
||||
## Purpose
|
||||
This source file establishes the namespace `DTS.Common.IConnection` but currently contains no types, interfaces, or implementation logic. Based on the namespace naming convention, it appears intended to define contracts or abstractions related to connections (likely database or network), but the file currently serves as a placeholder or stub.
|
||||
|
||||
## Public Interface
|
||||
None. The namespace `DTS.Common.IConnection` is empty in the provided source code. There are no public classes, interfaces, methods, or constants defined.
|
||||
|
||||
## Invariants
|
||||
None identified from source alone.
|
||||
|
||||
## Dependencies
|
||||
* **References:** `System` (imported via `using System;`, though currently unused).
|
||||
* **Dependents:** Unknown. Without seeing other project files, consumers of this namespace cannot be determined.
|
||||
|
||||
## Gotchas
|
||||
* **Empty Implementation:** The file is effectively empty. The project name `DTS.Common.IConnection` strongly implies the existence of an `IConnection` interface, but no such type is defined in this file.
|
||||
* **Unused Import:** The `using System;` directive is present but serves no purpose as the namespace block is empty.
|
||||
@@ -0,0 +1,224 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.IConnection/EthernetConnection/RESTConnection.cs
|
||||
- Common/DTS.Common.IConnection/EthernetConnection/EthernetConnection.cs
|
||||
generated_at: "2026-04-16T02:09:04.702798+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "21dfcca726b35e5d"
|
||||
---
|
||||
|
||||
# Documentation: `RESTConnection` and `EthernetConnection` Classes
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides two concrete implementations of the `IConnection` interface for network communication: `RESTConnection`, a stub implementation that simulates connection operations without actual network activity (intended for REST-based or mock scenarios), and `EthernetConnection`, a full-featured implementation using `System.Net.Sockets.Socket` for real-time Ethernet communication with hardware devices. `RESTConnection` exists to satisfy interface contracts in environments where actual socket communication is unnecessary or undesirable (e.g., testing, REST API interactions), while `EthernetConnection` handles real socket operations including connection establishment, data transfer, keep-alive configuration, and soft disconnect/reconnect workflows for embedded hardware.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `RESTConnection` (namespace `DTS.DASLib.Connection`)
|
||||
|
||||
- **`bool IConnection.IsSoftDisconnected => false`**
|
||||
Always returns `false`; does not support soft disconnect semantics.
|
||||
|
||||
- **`SocketFlags IConnection.Flags { get; set; }`**
|
||||
Gets/sets socket flags (unused; always `SocketFlags.None`).
|
||||
|
||||
- **`string IConnection.ConnectString => _ConnectString`**
|
||||
Returns the stored connection string (e.g., `"host:port"`), set via `Create`.
|
||||
|
||||
- **`bool IConnection.Connected => _bConnected`**
|
||||
Returns internal `_bConnected` state (set to `true` on `BeginConnect`, `false` on `BeginDisconnect`).
|
||||
|
||||
- **`event EventHandler OnDisconnected`**
|
||||
Declared but never raised (no invocation in source).
|
||||
|
||||
- **`void IConnection.Create(string connectString)`**
|
||||
Stores `connectString` in `_ConnectString`.
|
||||
|
||||
- **`void IConnection.Create(string connectString, string hostIPAddress)`**
|
||||
Stores `connectString` and `hostIPAddress` in respective fields.
|
||||
|
||||
- **`IAsyncResult IConnection.BeginConnect(AsyncCallback callback, object callbackObject)`**
|
||||
Sets `_bConnected = true` and returns a *synchronously completed* `IAsyncResult` via `GetAlreadyCompleted`.
|
||||
|
||||
- **`IAsyncResult IConnection.BeginDisconnect(bool reuseSocket, AsyncCallback callback, object state)`**
|
||||
Sets `_bConnected = false` and returns a *synchronously completed* `IAsyncResult`.
|
||||
|
||||
- **`IAsyncResult IConnection.BeginSend(...)` / `BeginReceive(...)` / `BeginAccept(...)`**
|
||||
All return *synchronously completed* `IAsyncResult` instances; no actual I/O.
|
||||
|
||||
- **`void IConnection.EndConnect(...)` / `EndDisconnect(...)` / `EndSend(...)` / `EndReceive(...)` / `EndAccept(...)`**
|
||||
No-op implementations. `EndSend`/`EndReceive` return `0`. `EndAccept` returns `this`.
|
||||
|
||||
- **`void IConnection.Bind(int port)`**
|
||||
Stub; no-op.
|
||||
|
||||
- **`void IConnection.Listen(int backlog)`**
|
||||
Stub; no-op.
|
||||
|
||||
- **`void IConnection.KeepAliveErrorReceived()`**
|
||||
Stub; no-op.
|
||||
|
||||
- **`string IConnection.GetConnectionData()`**
|
||||
Returns `"{_ConnectString} - {_hostIPAddress}"`.
|
||||
|
||||
- **`Task<int> IConnection.SendAsync(...)`**
|
||||
Wraps `BeginSend`/`EndSend` using `Task.Factory.FromAsync`; returns a completed task with result `0`.
|
||||
|
||||
- **`void IConnection.SoftConnect()` / `SoftDisconnect()`**
|
||||
Stubs; no-op.
|
||||
|
||||
- **`void Dispose()` / `~RESTConnection()`**
|
||||
Implements `IDisposable`; marks `_disposed = true` but performs no socket cleanup.
|
||||
|
||||
### `EthernetConnection` (namespace `DTS.Common`)
|
||||
|
||||
- **`bool IsSoftDisconnected { get; private set; }`**
|
||||
Tracks soft-disconnect state; `true` after successful `SoftDisconnect()`.
|
||||
|
||||
- **`bool Connected => Sock != null && Sock.Connected`**
|
||||
Reflects underlying socket state.
|
||||
|
||||
- **`string ConnectString => Connect_String`**
|
||||
Returns stored connection string.
|
||||
|
||||
- **`SocketFlags Flags { get; set; }`**
|
||||
Gets/sets socket flags used in `BeginSend`/`BeginReceive`.
|
||||
|
||||
- **`Socket Sock`**
|
||||
Public field holding the underlying `Socket` instance.
|
||||
|
||||
- **`event EventHandler OnDisconnected`**
|
||||
Raised in `KeepAliveErrorReceived()`.
|
||||
|
||||
- **`void Create(string connectString, string hostIPAddress)`**
|
||||
Stores `connectString` and `hostIPAddress`, then calls `CreateSock` to initialize `Sock`.
|
||||
|
||||
- **`Socket CreateSock(string connectString, string hostIPAddress)`**
|
||||
Creates and configures a `Socket` with:
|
||||
- `NoDelay = true` (Nagle disabled)
|
||||
- `KeepAlive = true`
|
||||
- Buffer sizes from `DFConstantsAndEnums.SendBufferSizeBytes` / `ReceiveBufferSizeBytes`
|
||||
- Custom keep-alive parameters from `DFConstantsAndEnums.LocalKeepAliveTimeOutMS` / `LocalKeepAliveRetryIntervalMS`
|
||||
- Optional binding to `hostIPAddress` if provided.
|
||||
|
||||
- **`void SoftDisconnect()`**
|
||||
If `HardwareConstants.AllowSoftDisconnects` is `true` and socket is connected:
|
||||
- Disconnects and disposes `Sock`
|
||||
- Sets `IsSoftDisconnected = true`
|
||||
- Logs action.
|
||||
|
||||
- **`void SoftConnect()`**
|
||||
If `AllowSoftDisconnects` is `true` and socket is not connected:
|
||||
- Parses `Connect_String` as `"host:port"`.
|
||||
- If `RequiresKeepAliveReset` is `true`, connects to port `8200`, sends `<60,5,4>`, receives response, then disconnects.
|
||||
- Retries up to 3 times to connect to `host:port` (1s delay between attempts).
|
||||
- Sets `IsSoftDisconnected = false`, logs success.
|
||||
|
||||
- **`void KeepAliveErrorReceived()`**
|
||||
Shuts down, closes, and disposes `Sock`, sets `Sock = null`, and raises `OnDisconnected`.
|
||||
|
||||
- **`string GetConnectionData()`**
|
||||
Returns `"local: {LocalEndPoint}, Remote: {RemoteEndPoint}"` or `""` on error.
|
||||
|
||||
- **`IAsyncResult BeginConnect(AsyncCallback, object)`**
|
||||
Validates `Sock`, `Connect_String`, and port format; delegates to `Sock.BeginConnect`.
|
||||
|
||||
- **`void EndConnect(IAsyncResult)`**
|
||||
Calls `Sock.EndConnect`, logs connection details.
|
||||
|
||||
- **`IAsyncResult BeginDisconnect(bool, AsyncCallback, object)`**
|
||||
Validates `Sock`; throws if socket is `null` or *not* connected (`SocketException WSAEISCONN`); delegates to `Sock.BeginDisconnect`.
|
||||
|
||||
- **`void EndDisconnect(IAsyncResult)`**
|
||||
Calls `Sock.EndDisconnect`.
|
||||
|
||||
- **`IAsyncResult BeginAccept(AsyncCallback, object)`**
|
||||
Validates `Sock`; delegates to `Sock.BeginAccept`.
|
||||
|
||||
- **`IConnection EndAccept(IAsyncResult)`**
|
||||
Calls `Sock.EndAccept`, wraps result in a *new* `EthernetConnection` instance.
|
||||
|
||||
- **`void Bind(int port)`**
|
||||
Validates `Sock`; binds to first DNS-resolved IP address on `port`.
|
||||
|
||||
- **`void Listen(int backlog)`**
|
||||
Validates `Sock`; calls `Sock.Listen`.
|
||||
|
||||
- **`IAsyncResult BeginSend(byte[], int, int, AsyncCallback, object)`**
|
||||
Validates `Sock`, callback, and connection state; throws if not connected; delegates to `Sock.BeginSend`.
|
||||
|
||||
- **`int EndSend(IAsyncResult)`**
|
||||
Calls `Sock.EndSend`; sets `Sock = null` on exception.
|
||||
|
||||
- **`Task<int> SendAsync(...)`**
|
||||
Wraps `BeginSend`/`EndSend` via `Task.Factory.FromAsync`.
|
||||
|
||||
- **`IAsyncResult BeginReceive(byte[], int, int, AsyncCallback, object)`**
|
||||
Validates `Sock` and callback; delegates to `Sock.BeginReceive`.
|
||||
|
||||
- **`int EndReceive(IAsyncResult)`**
|
||||
Calls `Sock.EndReceive`.
|
||||
|
||||
- **`void Dispose()` / `~EthernetConnection()`**
|
||||
Implements `IDisposable`; safely shuts down/disposes `Sock` in `Dispose(bool)`.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **`RESTConnection`**:
|
||||
- `_bConnected` is the sole source of truth for connection state; never updated by external I/O.
|
||||
- All `Begin*`/`End*` operations are synchronous and return immediately; no async state is maintained.
|
||||
- `IsSoftDisconnected` is always `false`; soft disconnect logic is absent.
|
||||
- `Connected` reflects `_bConnected`, which is manually toggled by `BeginConnect`/`BeginDisconnect`.
|
||||
|
||||
- **`EthernetConnection`**:
|
||||
- `Connected` depends on `Sock != null && Sock.Connected`; `Sock` may be `null` after errors or disposal.
|
||||
- `SoftDisconnect()` and `SoftConnect()` only execute if `HardwareConstants.AllowSoftDisconnects` is `true`.
|
||||
- `SoftConnect()` requires `Connect_String` to be in `"host:port"` format; port must be parseable as `int`.
|
||||
- `BeginDisconnect` throws `SocketException` if socket is not connected (per `WSAEISCONN`).
|
||||
- `BeginSend`/`BeginReceive` throw if socket is not connected or callback is `null`.
|
||||
- `KeepAliveErrorReceived()` guarantees `Sock` is `null` after execution (disposal path).
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### `RESTConnection`:
|
||||
- **Imports**:
|
||||
- `DTS.Common.Interface.Connection` (for `IConnection`)
|
||||
- `DTS.Common.Utilities.Logging` (for `APILogger`, but *not used* in this file)
|
||||
- Standard .NET libraries (`System.Net.Sockets`, `System.Threading`, etc.)
|
||||
- **Depended on by**: Any code requiring an `IConnection` instance where network activity is unnecessary (e.g., unit tests, REST-based workflows).
|
||||
|
||||
### `EthernetConnection`:
|
||||
- **Imports**:
|
||||
- `DTS.Common.Interface.Connection` (`IConnection`)
|
||||
- `DTS.Common.DASResource` (for `Strings.EthernetConnection_*_Err*` exception messages)
|
||||
- `DTS.Common.Enums.DASFactory` (for `HardwareConstants.AllowSoftDisconnects`)
|
||||
- `DTS.Common.Utilities.Logging` (for `APILogger`)
|
||||
- `DFConstantsAndEnums` (for buffer sizes, keep-alive timeouts, `WSAEISCONN`)
|
||||
- **Depended on by**: Higher-level connection management logic (e.g., device initialization, data acquisition pipelines) requiring real Ethernet communication.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **`RESTConnection`**:
|
||||
- `IsSoftDisconnected` is hardcoded to `false`; callers expecting soft-disconnect behavior will be misled.
|
||||
- `OnDisconnected` is declared but never raised; event subscriptions have no effect.
|
||||
- `Begin*`/`End*` methods are *synchronous stubs*; using them in async contexts may cause deadlocks or incorrect assumptions about I/O latency.
|
||||
- `EndSend`/`EndReceive` always return `0`—no actual bytes sent/received.
|
||||
- `SoftConnect`/`SoftDisconnect` are no-ops despite being part of `IConnection`.
|
||||
|
||||
- **`EthernetConnection`**:
|
||||
- `SoftConnect()` uses `Thread.Sleep` (50ms/100ms/1000ms) for timing; this is blocking and may cause issues in high-throughput or UI contexts.
|
||||
- `SoftConnect()` sends `<60,5,4>` to port `8200` for keep-alive setup; this is a hardcoded protocol-specific command (device-dependent).
|
||||
- `BeginDisconnect` throws `SocketException` if socket is not connected—*not* an error condition per se, but callers must handle this exception to avoid crashes.
|
||||
- `EndSend` sets `Sock = null` on exception; this may cause subsequent operations to fail unexpectedly.
|
||||
- `Bind` uses the *first* DNS-resolved IP address (`AddressList[0]`), which may be non-deterministic or IPv6 in some environments.
|
||||
- `CreateSock` uses `IOControlCode.KeepAliveValues` with hardcoded `KeepAliveOn = 1`; this may conflict with system-wide settings.
|
||||
- `IsSoftDisconnected` is not reset to `false` in `SoftConnect` if `AllowSoftDisconnects` is `false`—only if soft disconnect logic runs.
|
||||
|
||||
- **Both**:
|
||||
- Neither class validates `connectString` format in `Create(string)` alone (only in `Create(string, string)` or `BeginConnect`).
|
||||
- `RESTConnection` and `EthernetConnection` share the same `IConnection` interface but have wildly different semantics; callers must know which implementation they hold.
|
||||
- `RESTConnection`’s `GetConnectionData()` returns a string with `_hostIPAddress`, but `_hostIPAddress` is never used in `RESTConnection` beyond storage—no binding or resolution occurs.
|
||||
|
||||
None identified beyond those above.
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.IConnection/EthernetConnection/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T02:07:20.010068+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "21f98ce79850642b"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
### 1. **Purpose**
|
||||
This module is an assembly metadata configuration file (`AssemblyInfo.cs`) for the `EthernetConnection` .NET assembly, part of the `DTS.Common.IConnection` namespace. Its purpose is to define assembly-level attributes—such as title, version, and COM visibility—used for identification, versioning, and interoperability. It does not contain executable logic or types; rather, it provides metadata consumed by the .NET runtime and tools (e.g., reflection, deployment, COM interop).
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
**No public types, functions, or classes are defined in this file.**
|
||||
This file exclusively contains assembly-level attributes via `Assembly*` attributes (e.g., `AssemblyTitle`, `AssemblyVersion`). It does not declare any public APIs.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
- The assembly is **not visible to COM** by default (`ComVisible(false)`).
|
||||
- The assembly version is strictly `1.06.0081` (both `AssemblyVersion` and `AssemblyFileVersion` match).
|
||||
- The `Guid` attribute is set to `"355ff6bb-d823-4853-93aa-4c12fd8c350e"` for COM type library identification.
|
||||
- No culture-specific attributes are set (`AssemblyCulture("")` indicates a neutral/culture-agnostic assembly).
|
||||
- Copyright notice is fixed to "Copyright © 2008".
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
- **Dependencies**:
|
||||
- `System.Reflection`
|
||||
- `System.Runtime.CompilerServices`
|
||||
- `System.Runtime.InteropServices`
|
||||
These are standard .NET namespaces, so the only external dependency is the .NET Framework (or compatible runtime).
|
||||
- **Depended on by**:
|
||||
- Other modules in the `DTS.Common.IConnection` project (or solution) that reference this `EthernetConnection` assembly.
|
||||
- Tools or components that rely on assembly metadata (e.g., COM interop consumers, build/deployment scripts, reflection-based diagnostics).
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
- **Versioning**: The `AssemblyVersion` (`1.06.0081`) uses a non-standard format (likely `Major.Minor.Build` where `06` = minor, `0081` = build). This may cause confusion if consumers expect semantic versioning (e.g., `1.6.81`).
|
||||
- **COM Interop**: Though `ComVisible(false)` is set, the explicit `Guid` suggests this assembly *may* have been designed for COM exposure at some point. If COM interop is needed, `ComVisible(true)` must be enabled on specific types—not the assembly—and the GUID must be preserved.
|
||||
- **No functional logic**: This file has no runtime behavior; errors here (e.g., malformed GUID) only surface during build/compile time or COM registration.
|
||||
- **Copyright year**: The hardcoded `2008` copyright may be outdated and could mislead auditors or legal reviews.
|
||||
- **Empty fields**: `AssemblyDescription`, `AssemblyCompany`, and `AssemblyTrademark` are empty strings—no documentation or branding metadata is embedded.
|
||||
- **None identified from source alone.** *(Note: While the above points are reasonable inferences, they are not explicit in the source and thus should be verified in context.)*
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.IConnection/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T02:09:10.860889+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "344d5d1b6c8a507c"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
### **1. Purpose**
|
||||
This module defines the `IConnection` assembly, a foundational .NET component intended to encapsulate connection-related abstractions for the broader system. Based on the assembly title and GUID, it serves as a shared contract layer—likely providing interfaces and possibly base types—for database, network, or service connections used across dependent modules. Its existence suggests a design goal of decoupling connection logic from implementation details, enabling testability and interchangeability of connection providers.
|
||||
|
||||
---
|
||||
|
||||
### **2. Public Interface**
|
||||
**No public types (classes, interfaces, structs, or enums) are defined in this file.**
|
||||
The file `AssemblyInfo.cs` contains only assembly-level metadata attributes (e.g., version, GUID, COM visibility). It does not declare any public APIs, interfaces, or types. The actual `IConnection` interface (implied by the assembly name) must reside in other source files not provided here.
|
||||
|
||||
---
|
||||
|
||||
### **3. Invariants**
|
||||
- **Assembly Identity**: The assembly is uniquely identified by GUID `c8394d57-92d3-4ee1-b2f3-f8fabce0d487`.
|
||||
- **Versioning**: Version is strictly `1.06.0081` (both `AssemblyVersion` and `AssemblyFileVersion`).
|
||||
- **COM Visibility**: Types in this assembly are **not** visible to COM (`ComVisible(false)`), unless explicitly overridden on individual types.
|
||||
- **No Runtime Behavior**: This file contributes no executable logic or state; it only defines metadata.
|
||||
|
||||
---
|
||||
|
||||
### **4. Dependencies**
|
||||
- **Dependencies**:
|
||||
- `System.Reflection`
|
||||
- `System.Runtime.CompilerServices`
|
||||
- `System.Runtime.InteropServices`
|
||||
These are standard .NET Framework namespaces; no external or proprietary dependencies are declared.
|
||||
|
||||
- **Dependents**:
|
||||
- Any assembly referencing `IConnection` (e.g., database clients, service adapters) depends on this assembly for its contract types (e.g., `IConnection` interface), though those types are not defined here.
|
||||
- The assembly’s GUID and version suggest it may be consumed by COM-aware components or build systems expecting strong-named or versioned contracts, but no explicit references are visible in this file.
|
||||
|
||||
---
|
||||
|
||||
### **5. Gotchas**
|
||||
- **Misleading Name**: The assembly is named `IConnection`, but this file contains no `IConnection` interface—developers may incorrectly assume the interface is defined here.
|
||||
- **Version Format**: The version `1.06.0081` uses a non-standard format (likely `Major.Minor.BuildRevision`), which may cause confusion during version comparison or binding.
|
||||
- **COM Interop**: While `ComVisible(false)` is set, if this assembly is referenced by COM clients, *any* types defined elsewhere in the assembly must explicitly opt in to COM visibility (e.g., via `[ComVisible(true)]`), or they will remain inaccessible.
|
||||
- **No Public API Surface**: This file alone provides no actionable API documentation; developers must inspect other files in the `DTS.Common.IConnection` project to understand the actual contract.
|
||||
|
||||
None identified beyond the above.
|
||||
@@ -0,0 +1,136 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.IConnection/SerialConnection/SerialConnection.cs
|
||||
generated_at: "2026-04-16T02:09:02.781823+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "4992256eaf51da73"
|
||||
---
|
||||
|
||||
# SerialConnection
|
||||
|
||||
## Documentation: `SerialConnection` Class
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
|
||||
The `SerialConnection` class provides a serial port–based implementation of the `IConnection` interface, enabling asynchronous I/O operations over a system serial port (`System.IO.Ports.SerialPort`). It wraps the .NET `SerialPort` class to expose standard connection semantics (connect, disconnect, send, receive) using the asynchronous programming model (APM) and Task-based wrappers. Despite implementing methods like `SoftConnect`, `SoftDisconnect`, `Bind`, `Listen`, and `Accept`, the class does **not** support soft disconnection or server-side listening—those methods are stubs or throw exceptions when misused. Its primary role is to allow serial communication to be used interchangeably with other connection types (e.g., TCP) via the `IConnection` abstraction.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
All methods and properties are part of the public API unless explicitly marked `protected`.
|
||||
|
||||
| Member | Signature | Description |
|
||||
|--------|-----------|-------------|
|
||||
| **`IsSoftDisconnected`** | `public bool IsSoftDisconnected { get; private set; }` | Always `false`. Not used for serial connections. |
|
||||
| **`SoftConnect()`** | `public void SoftConnect()` | No-op. Comment notes: *"does nothing for serial as we don't have a soft disconnect option yet."* |
|
||||
| **`SoftDisconnect()`** | `public void SoftDisconnect()` | No-op. Comment notes: *"does nothing for serial as we don't have a soft disconnect option yet."* |
|
||||
| **`KeepAliveErrorReceived()`** | `void IConnection.KeepAliveErrorReceived()` | Explicit interface implementation; no-op. |
|
||||
| **`Create(string connectString, string hostIPAddress)`** | `public void Create(string connectString, string hostIPAddress)` | No-op. Does not assign `connectString`. |
|
||||
| **`GetConnectionData()`** | `public string GetConnectionData()` | Returns `""`. |
|
||||
| **`GetCurrentDownloadRate()`** | `public double GetCurrentDownloadRate()` | Returns `0D`. |
|
||||
| **`GetCurrentUploadRate()`** | `public double GetCurrentUploadRate()` | Returns `0D`. |
|
||||
| **`OnDisconnected`** | `public event EventHandler OnDisconnected` | Event declared but never raised. |
|
||||
| **`Connected`** | `public bool Connected { get; }` | Always `false`. Not updated on connect. |
|
||||
| **`ConnectString`** | `public string ConnectString => _PortName` | Returns the last-assigned port name (e.g., `"COM3"`). |
|
||||
| **`Flags`** | `public System.Net.Sockets.SocketFlags Flags { get; set; }` | Property inherited from `IConnection`; unused (no socket semantics). |
|
||||
| **`Create(string PortName)`** | `public void Create(string PortName)` | Initializes `Port` with `_PortName` (note: bug—see *Gotchas*). Sets `_PortName = PortName`. |
|
||||
| **`BeginConnect(...)`** | `public IAsyncResult BeginConnect(AsyncCallback cb, object state)` | Opens the `SerialPort`. Throws if `Port == null` or `_PortName` is null/empty. Returns `null`. |
|
||||
| **`EndConnect(...)`** | `public void EndConnect(IAsyncResult ar)` | No-op. Throws if `Port == null`. |
|
||||
| **`BeginDisconnect(...)`** | `public IAsyncResult BeginDisconnect(bool reuseSocket, AsyncCallback cb, object state)` | No-op. Throws if `Port == null`. Returns `null`. |
|
||||
| **`EndDisconnect(...)`** | `public void EndDisconnect(IAsyncResult asyncResult)` | No-op. Throws if `Port == null`. |
|
||||
| **`BeginAccept(...)`** | `public IAsyncResult BeginAccept(AsyncCallback callback, Object state)` | Throws if `Port == null`. Returns `null`. |
|
||||
| **`EndAccept(...)`** | `public IConnection EndAccept(IAsyncResult asyncResult)` | Returns a **new** `SerialConnection` instance (uninitialized—no `Port` created). Throws if `Port == null`. |
|
||||
| **`Bind(int port)`** | `public void Bind(int port)` | No-op. Throws if `Port == null`. |
|
||||
| **`Listen(int backlog)`** | `public void Listen(int backlog)` | No-op. Throws if `Port == null`. |
|
||||
| **`BeginSend(...)`** | `public IAsyncResult BeginSend(byte[] buffer, int offset, int size, AsyncCallback cb, object state)` | Delegates to `SerialPort.BaseStream.BeginWrite(...)`. Throws if `Port == null` or `cb == null`. |
|
||||
| **`EndSend(...)`** | `public int EndSend(IAsyncResult ar)` | Calls `SerialPort.BaseStream.EndWrite(ar)`. Returns `Port.BytesToWrite`. Throws if `Port == null`. |
|
||||
| **`SendAsync(...)`** | `public Task<int> SendAsync(byte[] sendBuffer, int bufferStartOffset, int bufferSizeToSend)` | Wraps `BeginSend`/`EndSend` using `Task.Factory.FromAsync`. |
|
||||
| **`BeginReceive(...)`** | `public IAsyncResult BeginReceive(byte[] buffer, int offset, int size, AsyncCallback cb, object state)` | Delegates to `SerialPort.BaseStream.BeginRead(...)`. Throws if `Port == null` or `cb == null`. |
|
||||
| **`EndReceive(...)`** | `public int EndReceive(IAsyncResult ar)` | Calls `SerialPort.BaseStream.EndRead(ar)`. Throws if `Port == null`. |
|
||||
| **`Dispose()`** | `public void Dispose()` | Calls `Dispose(true)` and suppresses finalization. |
|
||||
| **`~SerialConnection()`** | `~SerialConnection()` | Finalizer calls `Dispose(false)`. |
|
||||
| **`Dispose(bool)`** | `protected virtual void Dispose(bool disposing)` | Closes and nulls `Port` if `disposing` is `true`. Sets `disposed = true`. |
|
||||
|
||||
> **Note**: The class implements `IDisposable`. `Connected` is never set to `true`, and `OnDisconnected` is never invoked.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
|
||||
- `Connected` is **always** `false`. It is a read-only property initialized to `false` and never modified.
|
||||
- `_PortName` is set only via `Create(string PortName)`. `ConnectString` returns `_PortName`.
|
||||
- `Port` is only initialized in `Create(string PortName)` and `EndAccept(...)`. In the latter case, the new `SerialConnection` instance has `Port == null`.
|
||||
- `BeginConnect` is the only method that actually opens the serial port (`Port.Open()`). No other method affects port state.
|
||||
- `EndSend` returns `Port.BytesToWrite`, which reflects the number of bytes *still pending in the transmit buffer*—not bytes sent.
|
||||
- `SoftConnect`, `SoftDisconnect`, `Bind`, `Listen`, and `BeginAccept`/`EndAccept` are **not functional** for serial connections and may throw if `Port == null`.
|
||||
- `IsSoftDisconnected` is always `false` and unused.
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
- **Depends on**:
|
||||
- `DTS.Common.Interface.Connection` (via `IConnection` interface).
|
||||
- `System.IO.Ports` (for `SerialPort`).
|
||||
- `System.Threading.Tasks` (for `Task<int>`).
|
||||
- `System` (for `EventHandler`, `AsyncCallback`, `IAsyncResult`, `Exception`).
|
||||
|
||||
- **Depended on by**:
|
||||
- Unknown from source alone. Presumably used by higher-level connection-handling logic that consumes `IConnection`.
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
|
||||
- **Critical Bug in `Create(string PortName)`**:
|
||||
```csharp
|
||||
Port = new SerialPort(_PortName); // ❌ Uses uninitialized _PortName
|
||||
_PortName = PortName; // ✅ Sets _PortName *after* use
|
||||
```
|
||||
The `SerialPort` constructor is called with `_PortName`, which is `null` at that point. Should be `new SerialPort(PortName)`.
|
||||
|
||||
- **`Connected` is never updated**:
|
||||
Even after `BeginConnect` succeeds, `Connected` remains `false`. Consumers cannot rely on this property.
|
||||
|
||||
- **`OnDisconnected` is never raised**:
|
||||
The event is declared but never invoked—even during `Dispose` or `Port.Close()`.
|
||||
|
||||
- **`EndAccept` returns an uninitialized `SerialConnection`**:
|
||||
The new instance has `Port == null`, so calling `BeginConnect`/`Send`/`Receive` on it will throw.
|
||||
|
||||
- **`SoftConnect`/`SoftDisconnect` are no-ops**:
|
||||
Despite being part of `IConnection`, they do nothing. Do not expect disconnection behavior from them.
|
||||
|
||||
- **`BeginDisconnect`/`EndDisconnect` do not close the port**:
|
||||
Only `Dispose` closes the `SerialPort`. `EndDisconnect` is a no-op.
|
||||
|
||||
- **`GetCurrentDownloadRate()` / `GetCurrentUploadRate()` always return `0D`**:
|
||||
No actual rate tracking is implemented.
|
||||
|
||||
- **`Flags` property is unused**:
|
||||
It is a `SocketFlags` property (from `IConnection`) but serial ports do not use socket flags.
|
||||
|
||||
- **`BeginSend`/`BeginReceive` use `SerialPort.BaseStream`**:
|
||||
This is correct for async I/O, but note that `SerialPort.BaseStream` is synchronous under the hood—performance may be suboptimal for high-throughput scenarios.
|
||||
|
||||
- **No validation of `PortName` in `Create`**:
|
||||
Invalid port names (e.g., `"COM999"`) will only fail at `Port.Open()` in `BeginConnect`.
|
||||
|
||||
- **`ConnectString` is misleading**:
|
||||
It holds only the port name (e.g., `"COM3"`), not a full connection string. Also, the overload `Create(string connectString, string hostIPAddress)` ignores `connectString`.
|
||||
|
||||
- **`disposed` flag prevents double-dispose**:
|
||||
Safe, but `Port` may be `null` after first dispose—subsequent `Dispose` calls are no-ops.
|
||||
|
||||
- **No exception handling in `BeginConnect`/`EndConnect`**:
|
||||
Exceptions from `Port.Open()` (e.g., `UnauthorizedAccessException`, `IOException`) propagate directly.
|
||||
|
||||
- **No cancellation support**:
|
||||
All async methods lack `CancellationToken` support.
|
||||
|
||||
- **`EndSend` returns `BytesToWrite`**:
|
||||
This is the number of bytes *remaining* in the output buffer—not bytes sent. Likely a mistake; should be bytes *written* (which is implicit in `EndWrite`’s return value, but `EndSend` discards it and returns `BytesToWrite` instead).
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.IConnection/SerialConnection/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T02:09:13.932338+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "387f9fdb03f26ec5"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## Documentation: DTS.Common.IConnection.SerialConnection Assembly
|
||||
|
||||
### 1. Purpose
|
||||
This assembly (`DTS.Common.IConnection.SerialConnection`) defines metadata and versioning information for a .NET assembly containing serial connection functionality. Based solely on the provided source file, the assembly itself does not contain implementation logic—it is an *assembly-level metadata file* (`AssemblyInfo.cs`) used to configure assembly attributes such as title, version, and COM visibility. Its role is to identify and version the `SerialConnection.cs` component within the broader `DTS.Common.IConnection` module, enabling proper deployment, referencing, and version management in the system.
|
||||
|
||||
### 2. Public Interface
|
||||
**No public types (classes, interfaces, structs, enums, or delegates) are defined in this file.**
|
||||
The file contains only assembly-level attributes (via `Assembly*` attributes). No executable code, types, or public APIs are declared here.
|
||||
|
||||
### 3. Invariants
|
||||
- The assembly version is fixed at `1.06.0081` (both `AssemblyVersion` and `AssemblyFileVersion`).
|
||||
- The assembly is **not** COM-visible (`ComVisible(false)`), meaning its types cannot be consumed by COM clients unless explicitly exposed via other mechanisms (e.g., `ComVisible(true)` on individual types).
|
||||
- The `Guid` attribute (`8d3a85de-321a-48fb-8f9e-f1d9594ee423`) uniquely identifies the typelib for COM interop scenarios (though COM visibility is disabled, this GUID is still present for potential future use or legacy compatibility).
|
||||
- The assembly title is `"SerialConnection.cs"` (note: likely a misnomer, as this is an assembly title, not a file title).
|
||||
|
||||
### 4. Dependencies
|
||||
- **No runtime dependencies** are declared in this file.
|
||||
- The file uses standard .NET namespaces: `System.Reflection`, `System.Runtime.CompilerServices`, and `System.Runtime.InteropServices`.
|
||||
- This assembly is part of the `DTS.Common.IConnection` module (inferred from the assembly title and directory path), implying it is consumed by other modules in the `DTS.Common` hierarchy. However, no direct references or dependents are specified in this file.
|
||||
|
||||
### 5. Gotchas
|
||||
- **Misleading assembly title**: The `AssemblyTitle` is set to `"SerialConnection.cs"`, which suggests a single file, but assembly titles conventionally describe the *assembly* (e.g., `"DTS Serial Connection Library"`), not a source file. This may cause confusion during debugging or deployment.
|
||||
- **COM interop ambiguity**: While `ComVisible(false)` is set, the presence of a `Guid` attribute implies potential COM exposure intent. If COM interop is required, this setting may need revisiting (e.g., enabling `ComVisible(true)` on specific types).
|
||||
- **No public surface area**: Developers expecting to find serial connection logic (e.g., `Open()`, `Write()`, `Read()`) in this file will be misled—this file is purely metadata. Actual implementation resides in other files (e.g., `SerialConnection.cs` in the same directory, not provided here).
|
||||
- **Versioning**: The version `1.06.0081` uses a non-standard format (likely `major.minor.build` where `06` = minor version 6, `0081` = build 81). Ensure build/deployment tooling interprets this correctly.
|
||||
|
||||
None identified beyond the above.
|
||||
@@ -0,0 +1,147 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.IConnection/USBConnection/HIDUSBConnection/HIDUSBConnection.cs
|
||||
generated_at: "2026-04-16T02:10:22.619594+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "4a9eeb7b8043999a"
|
||||
---
|
||||
|
||||
# Documentation: `HIDUSBConnection` Class
|
||||
|
||||
## 1. Purpose
|
||||
`HIDUSBConnection` is a concrete implementation of the `IConnection` interface that enables communication with a specific HID-class USB device (identified by Vendor ID `0x1CB9` and Product ID `0x0003`, named *HIDSLICE*) using Windows file I/O APIs (`CreateFile`, `ReadFile`, `WriteFile` via overlapped I/O). It abstracts low-level HID report handling (input/output reports) over USB, providing asynchronous send/receive semantics consistent with .NET’s `IAsyncResult` pattern. This module exists to support direct, low-latency data transfer to/from embedded hardware (e.g., a data acquisition recorder) where standard socket-based communication is not applicable.
|
||||
|
||||
---
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Constructors & Finalizer
|
||||
- **`HIDUSBConnection()`**
|
||||
Initializes the instance, sets up `SECURITY_ATTRIBUTES` for `CreateFile`, and initializes `_Connected = false`.
|
||||
|
||||
- **`~HIDUSBConnection()`**
|
||||
Finalizer that invokes `Dispose(false)` to release unmanaged resources.
|
||||
|
||||
### Disposal
|
||||
- **`void Dispose()`**
|
||||
Performs deterministic cleanup: calls `Dispose(true)` and suppresses finalization.
|
||||
|
||||
- **`protected virtual void Dispose(bool disposing)`**
|
||||
Releases all handles (`_HIDHandle`, `_ReadHandle`, `_WriteHandle`) via `FileIODeclarations.CloseHandle`, disposes `_MyHID`, and sets `_Connected = false`. Idempotent (`disposed` flag prevents double-disposal).
|
||||
|
||||
### Connection Management
|
||||
- **`void Create(string ConnectString)`**
|
||||
Stores the device path (`ConnectString`) for later use in `EndConnect`. Does *not* open the device.
|
||||
|
||||
- **`IAsyncResult BeginConnect(AsyncCallback cb, object state)`**
|
||||
Initiates asynchronous connection. Enqueues a work item to invoke `NetCallbackFix`, which in turn invokes the callback on the thread pool. *Actual device opening occurs in `EndConnect`*.
|
||||
|
||||
- **`void EndConnect(IAsyncResult ar)`**
|
||||
Opens the device using `ConnectString` (set via `Create`) via three `CreateFile` calls:
|
||||
- `_HIDHandle`: for attribute queries (no access rights)
|
||||
- `_ReadHandle`: for reading input reports (`GENERIC_READ`)
|
||||
- `_WriteHandle`: for writing output reports (`GENERIC_WRITE`)
|
||||
Retrieves device attributes (`HidD_GetAttributes`), capabilities (`GetDeviceCapabilities`), and input report buffer size (`GetInputReportBufferSize`). Flushes the input queue. Sets `_Connected = true`. Throws on handle failure or attribute retrieval failure.
|
||||
|
||||
- **`IAsyncResult BeginDisconnect(bool reuseSocket, AsyncCallback cb, object state)`**
|
||||
Asynchronous disconnect. Enqueues a work item to invoke the callback. *Actual cleanup is deferred to `EndDisconnect`*.
|
||||
|
||||
- **`void EndDisconnect(IAsyncResult asyncResult)`**
|
||||
Closes all three handles (`_HIDHandle`, `_ReadHandle`, `_WriteHandle`) and sets `_Connected = false`.
|
||||
|
||||
### Properties
|
||||
- **`bool Connected { get; }`**
|
||||
Returns `_Connected`.
|
||||
|
||||
- **`string ConnectString { get; }`**
|
||||
Returns `Device_Name` (set via `Create`).
|
||||
|
||||
- **`System.Net.Sockets.SocketFlags Flags { get; set; }`**
|
||||
Property required by `IConnection` interface; unused in this implementation.
|
||||
|
||||
- **`string GetConnectionData()`**
|
||||
Returns `""` (empty string). No meaningful data exposed.
|
||||
|
||||
- **`double GetCurrentDownloadRate()`**
|
||||
Returns `0D`. Rate tracking not implemented.
|
||||
|
||||
- **`double GetCurrentUploadRate()`**
|
||||
Returns `0D`. Rate tracking not implemented.
|
||||
|
||||
### Static Utility
|
||||
- **`static string GetFirstConnectString()`**
|
||||
Scans all HID devices on the system to find the first device matching `DTS_VID` (`0x1CB9`) and `HIDSLICE_PID` (`0x0003`). Returns the device’s path string (e.g., `\\?\hid#vid_1cb9&pid_0003#...`) or `string.Empty` if not found. Uses `HIDDeclarations.HidD_GetHidGuid`, `DeviceManagement.FindDeviceFromGuid`, and `HIDDeclarations.HidD_GetAttributes`.
|
||||
|
||||
### I/O Operations
|
||||
- **`IAsyncResult BeginSend(byte[] buffer, int offset, int size, AsyncCallback cb, object state)`**
|
||||
Initiates asynchronous send. Validates `_ReadHandle` and `_WriteHandle` are valid. Enqueues callback via `ThreadPool.QueueUserWorkItem`. *Actual transmission occurs in `EndSend`*.
|
||||
|
||||
- **`int EndSend(IAsyncResult ar)`**
|
||||
Writes `buffer[offset..offset+size)` to the device in chunks, respecting `OutputReportByteLength`.
|
||||
- Prepends each chunk with report ID `0x00` at index `0`.
|
||||
- Uses `HIDevice.OutputReport.Write` for each chunk.
|
||||
Returns `size` (number of bytes sent). Throws on invalid handles or write failure.
|
||||
|
||||
- **`IAsyncResult BeginReceive(byte[] buffer, int offset, int size, AsyncCallback cb, object state)`**
|
||||
Initiates asynchronous receive. Validates handles. Enqueues callback. *Actual read occurs in `EndReceive`*.
|
||||
|
||||
- **`int EndReceive(IAsyncResult ar)`**
|
||||
Reads one input report into `InputReportBuffer` via `HIDevice.InputReport.Read`. Copies data (skipping report ID at index `0`) into `buffer[offset..]`. Returns `size` if successful, `0` otherwise. Sets `IsCompleted = true` and signals `AsyncWaitHandle`.
|
||||
|
||||
### Unsupported Operations (Throw `NotSupportedException`)
|
||||
- `BeginAccept`, `EndAccept`, `Bind(int)`, `Listen(int)`
|
||||
These methods are implemented only to satisfy `IConnection` but are not applicable to HID device communication.
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Device Identity**: Only devices with `VendorID == 0x1CB9` and `ProductID == 0x0003` are accepted.
|
||||
- **Handle State**: `_HIDHandle`, `_ReadHandle`, and `_WriteHandle` must be valid (non-`INVALID_HANDLE_VALUE`) before `BeginSend`/`BeginReceive` succeeds.
|
||||
- **Connection State**: `_Connected` is `true` only after successful completion of `EndConnect`, and `false` otherwise (including after `EndDisconnect` or disposal).
|
||||
- **Report Structure**:
|
||||
- Input reports: Data starts at index `1`; index `0` is the report ID (ignored).
|
||||
- Output reports: Data starts at index `1`; index `0` is report ID (set to `0`).
|
||||
- **Buffer Size**: `InputReportBuffer` is sized to `_MyHID.Capabilities.InputReportByteLength` during `EndConnect`.
|
||||
- **Disposal Safety**: `Dispose` is idempotent (`disposed` flag prevents re-entry).
|
||||
- **Asynchronous Pattern**: All async operations (`BeginConnect`, `BeginSend`, etc.) use `HIDUSBRecAsyncResult` and delegate callback invocation to `NetCallbackFix`, which runs on a thread pool thread.
|
||||
|
||||
---
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### External Dependencies
|
||||
- **Windows API (via interop)**:
|
||||
- `FileIODeclarations.CreateFile`, `CloseHandle`, `FILE_SHARE_*`, `GENERIC_*`, `INVALID_HANDLE_VALUE`, `OPEN_EXISTING`
|
||||
- `HIDDeclarations.HidD_GetHidGuid`, `HidD_GetAttributes`
|
||||
- **`DTS.DASLib.Connection.USBFramework`**:
|
||||
- `HIDevice` class (used for device attributes, capabilities, input/output report handling)
|
||||
- `DeviceManagement` class (used in `GetFirstConnectString`)
|
||||
- **`DTS.DASLib.DASResource`**:
|
||||
- `Strings` resource class (for localized error messages, e.g., `Strings.HIDUSBConnection_EndConnect_Err1`)
|
||||
- **.NET Framework Core**:
|
||||
- `System.Runtime.InteropServices` (for `Marshal.SizeOf`, `SECURITY_ATTRIBUTES`)
|
||||
- `System.Threading` (for `ThreadPool`, `ManualResetEvent`)
|
||||
- `System.Windows.Forms.MessageBox` (used in `NetCallbackFix` for exception reporting—*potential runtime dependency on WinForms*).
|
||||
|
||||
### Implemented Interfaces
|
||||
- `IConnection` (interface defining the contract; not shown in source but referenced).
|
||||
|
||||
### Inferred Consumers
|
||||
- Any code requiring `IConnection` to communicate with the *HIDSLICE* device (e.g., data acquisition logic, device enumeration UI).
|
||||
- `GetFirstConnectString` is likely called by device discovery components.
|
||||
|
||||
---
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Misleading Async Pattern**: `BeginConnect`/`BeginSend`/`BeginReceive` do *not* perform actual I/O; they only enqueue a callback. All work happens in `End*` methods. This deviates from typical .NET async patterns where `Begin*` initiates the operation.
|
||||
- **No Overlapped I/O**: Despite using `CreateFile` with overlapped semantics (implied by `_ReadHandle`/`_WriteHandle`), the code does *not* use `OVERLAPPED` structures or `ReadFile`/`WriteFile` with completion callbacks. Instead, it relies on synchronous `HIDevice.InputReport.Read`/`Write`, which may block the thread pool thread.
|
||||
- **Hardcoded Report ID**: Output reports always use `0x00` as the report ID. This assumes the device expects report ID `0`; mismatched IDs will cause silent failures or device errors.
|
||||
- **WinForms Dependency in Error Handling**: `NetCallbackFix` shows a `MessageBox` on exceptions—a severe anti-pattern for non-UI threads or server environments.
|
||||
- **`GetFirstConnectString` Hack**: The method scans *all* HID devices and stops at the first match. If multiple *HIDSLICE* devices are connected, behavior is undefined (first found wins).
|
||||
- **Buffer Size Mismatch in `EndReceive`**: `EndReceive` copies `InputReportBuffer.Length - 1` bytes into the user buffer, but returns `rar.size` regardless. If `rar.size < InputReportBuffer.Length - 1`, the caller may read uninitialized buffer data beyond the actual received payload.
|
||||
- **No Timeout Handling**: No mechanism for read/write timeouts; operations may block indefinitely.
|
||||
- **`Flags` Property Unused**: The `SocketFlags` property is implemented but never used.
|
||||
- **`BeginAccept`/`EndAccept` Misuse**: Throwing `NotSupportedException` for connection-oriented methods suggests this class was adapted from a socket-based `IConnection` implementation without full refactoring.
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.IConnection/USBConnection/HIDUSBConnection/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T02:10:22.587640+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "1fcf58774b015c19"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## 1. Purpose
|
||||
This file is an assembly-level metadata configuration file (`AssemblyInfo.cs`) for the `DTS.Common.IConnection.USBConnection.HIDUSBConnection` .NET assembly. Its purpose is to define assembly-wide attributes such as title, version, COM visibility, and GUID—used for identification, versioning, and interoperability—but it does *not* contain any executable logic, interfaces, or types. It serves as infrastructure metadata required by the .NET build system and COM interop layer, with no runtime behavior or public API surface.
|
||||
|
||||
## 2. Public Interface
|
||||
**None.**
|
||||
This file contains only assembly-level attributes and no public types (classes, structs, interfaces, enums), methods, properties, or fields. All content is metadata declarations via `Assembly*` attributes.
|
||||
|
||||
## 3. Invariants
|
||||
- The assembly is **not visible to COM** (`ComVisible(false)`), meaning its types cannot be accessed via COM unless explicitly exposed elsewhere.
|
||||
- The assembly’s version is fixed at **1.06.0081** for both `AssemblyVersion` and `AssemblyFileVersion`.
|
||||
- The assembly’s GUID is **`9127ae79-928b-4187-a425-97f49034c5ad`**, used for COM type library identification (though irrelevant here due to `ComVisible(false)`).
|
||||
- No runtime invariants apply, as this file contributes no executable code.
|
||||
|
||||
## 4. Dependencies
|
||||
- **Dependencies**: None (this file has no external dependencies beyond the .NET Framework’s `System.Reflection`, `System.Runtime.CompilerServices`, and `System.Runtime.InteropServices` namespaces, which are implicitly available).
|
||||
- **Depended upon**: None directly—this file is consumed by the build system and runtime metadata infrastructure, not by application code. Other modules in the `DTS.Common.IConnection` hierarchy may reference this assembly, but they do not depend on its metadata content.
|
||||
|
||||
## 5. Gotchas
|
||||
- **Versioning nuance**: `AssemblyVersion` (`1.06.0081`) controls binding redirects and assembly identity at runtime, while `AssemblyFileVersion` is informational (used for file properties in Windows). Changing only `AssemblyFileVersion` does *not* affect runtime binding.
|
||||
- **COM irrelevance**: Despite the explicit `Guid` attribute, `ComVisible(false)` renders the GUID unused for COM registration. If COM interop is needed, `ComVisible(true)` must be set *and* types must be explicitly marked with `ComVisible(true)`.
|
||||
- **No functional impact**: Modifying or deleting this file will not break runtime logic but may cause build warnings or break COM registration tooling (e.g., `regasm`) if used.
|
||||
- **Historical date**: Copyright year is set to 2008; verify if this reflects current ownership or is legacy.
|
||||
@@ -0,0 +1,158 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.IConnection/USBConnection/USBFramework/FileIODeclarations.cs
|
||||
- Common/DTS.Common.IConnection/USBConnection/USBFramework/HIDDeclarations.cs
|
||||
- Common/DTS.Common.IConnection/USBConnection/USBFramework/DeviceManagementDeclarations.cs
|
||||
- Common/DTS.Common.IConnection/USBConnection/USBFramework/DeviceManagement.cs
|
||||
generated_at: "2026-04-16T02:09:55.521694+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "8939bee008e13a9a"
|
||||
---
|
||||
|
||||
# Documentation: USBFramework Module
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides low-level Windows API interop declarations and high-level device management utilities for USB device communication, specifically targeting HID-class devices and generic file I/O operations. It serves as the foundational layer for USB device enumeration, notification handling, and raw communication in the DTS system. The module exposes P/Invoke signatures for Windows kernel32.dll, hid.dll, setupapi.dll, and advapi32.dll functions, alongside managed wrappers (e.g., `DeviceManagement`) that abstract device discovery, registration for plug-and-play events, and property retrieval. Its role is to enable reliable detection, connection, and interaction with USB devices without relying on higher-level .NET USB libraries.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `FileIODeclarations` class (namespace `DTS.Common.USBFramework`)
|
||||
- **`const uint GENERIC_READ = 0x80000000`**
|
||||
Access mask for read operations in `CreateFile`.
|
||||
- **`const uint GENERIC_WRITE = 0x40000000`**
|
||||
Access mask for write operations in `CreateFile`.
|
||||
- **`const uint FILE_SHARE_READ = 0x00000001`**
|
||||
Share mode flag for read sharing.
|
||||
- **`const uint FILE_SHARE_WRITE = 0x00000002`**
|
||||
Share mode flag for write sharing.
|
||||
- **`const uint FILE_FLAG_OVERLAPPED = 0x40000000`**
|
||||
Flag for asynchronous I/O in `CreateFile`.
|
||||
- **`const int INVALID_HANDLE_VALUE = -1`**
|
||||
Sentinel value for invalid handle.
|
||||
- **`const short OPEN_EXISTING = 3`**
|
||||
Creation disposition for opening existing files/devices.
|
||||
- **`const int WAIT_TIMEOUT = 0x102`**, **`WAIT_OBJECT_0 = 0`**, **`WAIT_FAILED = 0xFFFFFFFF`**, **`WAIT_ABANDONED = 0x00000080`**
|
||||
Return codes for `WaitForSingleObject`.
|
||||
- **`const int FSCTL_SET_COMPRESSION = 0x9C040`**
|
||||
I/O control code for compression (unused in current context).
|
||||
- **`struct OVERLAPPED`**
|
||||
Unmanaged structure for asynchronous I/O (note: `hEvent` is `int`, not `IntPtr`).
|
||||
- **`struct SECURITY_ATTRIBUTES`**
|
||||
Unmanaged structure for security descriptor handling (note: `lpSecurityDescriptor` is `int`, not `IntPtr`).
|
||||
- **`int CancelIo(int hFile)`**
|
||||
Cancels pending I/O operations on the specified file handle.
|
||||
- **`int CloseHandle(int hObject)`**
|
||||
Closes an open object handle.
|
||||
- **`int CreateEvent(ref SECURITY_ATTRIBUTES SecurityAttributes, int bManualReset, int bInitialState, string lpName)`**
|
||||
Creates or opens a named or unnamed event object.
|
||||
- **`int CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, ref SECURITY_ATTRIBUTES lpSecurityAttributes, int dwCreationDisposition, uint dwFlagsAndAttributes, int hTemplateFile)`**
|
||||
Creates or opens a file or I/O device (e.g., USB device).
|
||||
- **`int GetLastError()`**
|
||||
Retrieves the calling thread’s last-error code.
|
||||
- **`int ReadFile(int hFile, ref byte lpBuffer, int nNumberOfBytesToRead, ref int lpNumberOfBytesRead, int lpOverlapped)`**
|
||||
Reads from a file or device (note: `lpOverlapped` is `int`, not `ref OVERLAPPED`).
|
||||
- **`uint WaitForSingleObject(int hHandle, int dwMilliseconds)`**
|
||||
Waits until the specified object is in the signaled state or the time-out interval elapses.
|
||||
- **`int WriteFile(int hFile, ref byte lpBuffer, int nNumberOfBytesToWrite, ref int lpNumberOfBytesWritten, int lpOverlapped)`**
|
||||
Writes to a file or device.
|
||||
- **`int DeviceIoControl(IntPtr hDevice, int dwIoControlCode, ref short lpInBuffer, int nInBufferSize, IntPtr lpOutBuffer, int nOutBufferSize, ref int lpBytesReturned, IntPtr lpOverlapped)`**
|
||||
Sends a control code directly to a device driver.
|
||||
|
||||
### `FileIO` class (namespace `DTS.Common.USBFramework`)
|
||||
- **`const short FILE_ATTRIBUTE_NORMAL = 0x80`**, **`FILE_FLAG_OVERLAPPED = 0x40000000`**, etc.
|
||||
Duplicate constants (with different types) from `FileIODeclarations`.
|
||||
- **`struct SECURITY_ATTRIBUTES`**
|
||||
Alternate definition with `lpSecurityDescriptor` as `IntPtr` (inconsistent with `FileIODeclarations`).
|
||||
- **`bool CloseHandle(SafeFileHandle hObject)`**
|
||||
Managed wrapper for closing a `SafeFileHandle`.
|
||||
- **`SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess, int dwShareMode, ref SECURITY_ATTRIBUTES lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, int hTemplateFile)`**
|
||||
Managed wrapper returning `SafeFileHandle`.
|
||||
|
||||
### `HIDDeclarations` class (namespace `DTS.DASLib.Connection.USBFramework`)
|
||||
- **`const short HidP_Input = 0`, `HidP_Output = 1`, `HidP_Feature = 2`**
|
||||
Report types for HID operations.
|
||||
- **`struct HIDD_ATTRIBUTES`**
|
||||
Contains vendor ID, product ID, and version number.
|
||||
- **`struct HIDP_CAPS`**
|
||||
Contains HID device capabilities (report sizes, usage pages, etc.).
|
||||
- **`struct HidP_Value_Caps`**
|
||||
Describes value capabilities (e.g., range, usage, min/max).
|
||||
- **`bool HidD_FlushQueue(int HidDeviceObject)`**
|
||||
Flushes the input buffer of an HID device.
|
||||
- **`bool HidD_FreePreparsedData(ref IntPtr PreparsedData)`**
|
||||
Frees preparsed data allocated by `HidD_GetPreparsedData`.
|
||||
- **`int HidD_GetAttributes(int HidDeviceObject, ref HIDD_ATTRIBUTES Attributes)`**
|
||||
Retrieves device attributes (VID, PID, version).
|
||||
- **`bool HidD_GetFeature(int HidDeviceObject, ref byte lpReportBuffer, int ReportBufferLength)`**
|
||||
Retrieves a feature report from the device.
|
||||
- **`bool HidD_GetInputReport(int HidDeviceObject, ref byte lpReportBuffer, int ReportBufferLength)`**
|
||||
Retrieves an input report from the device.
|
||||
- **`void HidD_GetHidGuid(ref Guid HidGuid)`**
|
||||
Retrieves the system-defined GUID for HID devices.
|
||||
- **`bool HidD_GetNumInputBuffers(int HidDeviceObject, ref int NumberBuffers)`**
|
||||
Gets the number of input buffers allocated for the device.
|
||||
- **`bool HidD_GetPreparsedData(int HidDeviceObject, ref IntPtr PreparsedData)`**
|
||||
Retrieves preparsed data for HID device.
|
||||
- **`bool HidD_SetFeature(int HidDeviceObject, ref byte lpReportBuffer, int ReportBufferLength)`**
|
||||
Sends a feature report to the device.
|
||||
- **`bool HidD_SetNumInputBuffers(int HidDeviceObject, int NumberBuffers)`**
|
||||
Sets the number of input buffers.
|
||||
- **`bool HidD_SetOutputReport(int HidDeviceObject, ref byte lpReportBuffer, int ReportBufferLength)`**
|
||||
Sends an output report to the device.
|
||||
- **`int HidP_GetCaps(IntPtr PreparsedData, ref HIDP_CAPS Capabilities)`**
|
||||
Retrieves HID capabilities from preparsed data.
|
||||
- **`int HidP_GetValueCaps(short ReportType, ref byte ValueCaps, ref short ValueCapsLength, IntPtr PreparsedData)`**
|
||||
Retrieves value capability information.
|
||||
|
||||
### `DeviceManagement` class (namespace `DTS.Common.USBFramework`)
|
||||
- **`bool DeviceNameMatch(Message m, string mydevicePathName)`**
|
||||
Compares the device path in a `WM_DEVICECHANGE` message with `mydevicePathName`. Returns `true` if they match (case-insensitive). Uses `DEV_BROADCAST_DEVICEINTERFACE_1` to extract the device name from the message’s `LParam`.
|
||||
- **`bool FindDeviceFromGuid(Guid myGuid, ref string[] devicePathName)`**
|
||||
Enumerates devices in the interface class specified by `myGuid` and populates `devicePathName` with their device paths. Returns `true` if at least one device is found. Uses `SetupDiGetClassDevs`, `SetupDiEnumDeviceInterfaces`, and `SetupDiGetDeviceInterfaceDetail`.
|
||||
- **`bool RegisterForDeviceNotifications(IntPtr formHandle, Guid classGuid, ref IntPtr deviceNotificationHandle)`**
|
||||
Registers a window (`formHandle`) to receive `WM_DEVICECHANGE` notifications for devices in `classGuid`. Returns `true` on success. Allocates unmanaged memory for `DEV_BROADCAST_DEVICEINTERFACE` and calls `RegisterDeviceNotification`.
|
||||
- **`void StopReceivingDeviceNotifications(IntPtr deviceNotificationHandle)`**
|
||||
Unregisters device notifications using `UnregisterDeviceNotification`. Ignores failures.
|
||||
- **`bool GetDeviceRegistryProperty(Guid myGuid)`**
|
||||
Enumerates devices in `myGuid`’s class and retrieves the `SPDRP_DRIVER` registry property for each device. Logs results via `APILogger`. Returns `true` on success (even if no devices found).
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Handle Validity**: All handle-based APIs (`CreateFile`, `RegisterDeviceNotification`) return `INVALID_HANDLE_VALUE` (-1) or `IntPtr.Zero` on failure. Callers must check return values before use.
|
||||
- **Memory Management**: Unmanaged memory allocated via `Marshal.AllocHGlobal` (e.g., in `FindDeviceFromGuid`, `RegisterForDeviceNotifications`) must be freed with `Marshal.FreeHGlobal`. The `DeviceManagement` class handles this in `try/finally` blocks.
|
||||
- **Structure Size Consistency**: The `cbSize` field of `SP_DEVICE_INTERFACE_DETAIL_DATA` must be set to `Marshal.SizeOf()` *before* calling `SetupDiGetDeviceInterfaceDetail`. The implementation writes `cbSize` manually to the unmanaged buffer, with logic to handle 32/64-bit alignment.
|
||||
- **64-bit Compatibility**: `IS64_BIT_PROCESS` (set via `IntPtr.Size == 8`) is used to adjust pointer arithmetic (e.g., `cbSize` offset, handle comparison). This is critical for `FindDeviceFromGuid` and `RegisterForDeviceNotifications`.
|
||||
- **HID Report Buffer Size**: `HidD_GetFeature`, `HidD_SetFeature`, etc., require the report buffer to be exactly `InputReportByteLength`/`OutputReportByteLength`/`FeatureReportByteLength` bytes (from `HIDP_CAPS`), including the report ID byte.
|
||||
- **GUID Consistency**: The `HidD_GetHidGuid` function populates a `Guid` by reference; callers must pass a valid `Guid` instance (not `Guid.Empty`).
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Imports/References:
|
||||
- **System.Runtime.InteropServices**: Required for P/Invoke, `Marshal`, `StructLayout`.
|
||||
- **Microsoft.Win32.SafeHandles**: Used in `FileIO.CloseHandle` (via `SafeFileHandle`).
|
||||
- **System.Windows.Forms**: Required for `Message` type in `DeviceNameMatch`.
|
||||
- **DTS.Common.Utilities.Logging**: Used for `APILogger.Log` in `GetDeviceRegistryProperty`.
|
||||
- **hid.dll**, **setupapi.dll**, **kernel32.dll**, **advapi32.dll**: Native libraries for HID, device setup, and registry operations.
|
||||
|
||||
### Dependencies on Other Modules:
|
||||
- **`DeviceManagement`** depends on `DeviceManagementDeclarations` for unmanaged API declarations.
|
||||
- **`FileIO`** and **`FileIODeclarations`** provide overlapping declarations (likely legacy duplication).
|
||||
- **`HIDDeclarations`** is in a different namespace (`DTS.DASLib.Connection.USBFramework`) and is used by HID-specific communication logic (not shown here).
|
||||
|
||||
### Used By:
|
||||
- Higher-level USB connection classes (e.g., `USBConnection`, `HIDConnection`) that consume `DeviceManagement` for device discovery and `HIDDeclarations` for HID I/O.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Duplicate Constants**: `FileIO` and `FileIODeclarations` define identical constants (e.g., `GENERIC_READ`, `FILE_FLAG_OVERLAPPED`) with inconsistent types (`uint` vs `short`/`int`). This may cause confusion or errors if mixed.
|
||||
- **Inconsistent Structure Definitions**: `SECURITY_ATTRIBUTES` is defined twice in `FileIODeclarations` and `FileIO` with different field types (`int` vs `IntPtr`). This is unsafe and may cause crashes on 64-bit systems.
|
||||
- **`OVERLAPPED` Structure**: The `OVERLAPPED` struct uses `int` for `hEvent` instead of `IntPtr`, which is incorrect for 64-bit compatibility. This will fail on 64-bit processes.
|
||||
- **`CreateFile` Overloads**: `FileIODeclarations.CreateFile` returns `int` (unmanaged handle), while `FileIO.CreateFile` returns `SafeFileHandle`. Using the wrong overload may lead to resource leaks or handle misuse.
|
||||
- **`RegisterForDeviceNotifications` Memory Leak Risk**: The `buffer` allocated via `Marshal.AllocHGlobal` is freed *after* `RegisterDeviceNotification`, but if `RegisterDeviceNotification` fails, the handle is `IntPtr.Zero`, and the buffer is still freed. This is safe, but the comment `// Set fDeleteOld True to prevent memory leaks` is misleading—the `true` flag in `StructureToPtr` overwrites the old pointer, but `AllocHGlobal`/`FreeHGlobal` is still required.
|
||||
- **`FindDeviceFromGuid` Buffer Size Calculation**: The `cbSize` offset calculation `(IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8` assumes `cbSize` is 4 bytes on 32-bit and 8 on 64-bit, but `SP_DEVICE_INTERFACE_DETAIL_DATA.cbSize` is `int` (4 bytes) regardless of platform. This may cause misalignment on 64-bit.
|
||||
- **`DeviceNameMatch` String Size Calculation**: Assumes `dbcc_name` is Unicode (2 bytes/char) and subtracts 28 bytes for fixed fields. This is correct for `DEV_BROADCAST_DEVICEINTERFACE_1` but may break if structure layout changes.
|
||||
- **`GetDeviceRegistryProperty` Registry Key Access**: Uses `SetupDiOpenDevRegKey` but does not show its usage; the implementation only retrieves `SPDRP_DRIVER` via `SetupDiGetDeviceRegistryPropertyA`. Registry access may fail without elevated privileges.
|
||||
- **`HIDP_*` Functions**: Return codes (e.g., `HidP_GetCaps`) are `int` but not documented. Callers must check for success (typically `0` for success, non-zero for error codes like `HIDP_STATUS_BUFFER_TOO_SMALL`).
|
||||
- **No Async Support**: Despite `FILE_FLAG_OVERLAPPED` being defined, the `ReadFile`/`WriteFile` declarations use synchronous signatures (no `OVERLAPPED` pointer). Asynchronous I/O is not implemented.
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.IConnection/USBConnection/USBFramework/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T02:10:14.603636+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "f8e1fde835545ec4"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## 1. Purpose
|
||||
This module is the `DTS.Common.IConnection.USBConnection.USBFramework` assembly (internally titled *HIDFramework*), a .NET class library component responsible for providing USB communication capabilities—specifically targeting Human Interface Device (HID) protocols—within the DTS (presumably *Digital Training Systems* or similar domain) ecosystem. It serves as a foundational layer for establishing and managing connections to USB HID devices, likely abstracting low-level OS interactions (e.g., Windows HID API) into higher-level .NET interfaces used by other connection-handling modules (e.g., `IConnection` implementations). Its existence enables standardized, reusable USB device integration across the codebase.
|
||||
|
||||
## 2. Public Interface
|
||||
**No public types (classes, interfaces, structs, or methods) are declared in this file.**
|
||||
This file (`AssemblyInfo.cs`) contains only assembly-level metadata attributes (e.g., title, version, COM visibility) and does not define any executable code or public API surface. Therefore, there are **no public functions, classes, or methods** documented here. Public interfaces would reside in other source files within the `USBFramework` project (e.g., `HIDDevice.cs`, `USBConnection.cs`), which are not provided.
|
||||
|
||||
## 3. Invariants
|
||||
- The assembly is **not COM-visible** (`ComVisible(false)`), meaning its types cannot be directly consumed by COM clients without explicit interop wrappers.
|
||||
- The assembly version is fixed at `1.06.0081` (both `AssemblyVersion` and `AssemblyFileVersion`).
|
||||
- The assembly GUID (`c655f31f-ca6c-4e9b-9480-934762d20a8c`) uniquely identifies the typelib for COM interop *if* `ComVisible` were enabled (though it is not).
|
||||
- No runtime invariants (e.g., state constraints, validation rules) are expressible in this file, as it contains no logic.
|
||||
|
||||
## 4. Dependencies
|
||||
- **Framework Dependencies**: Requires core .NET Framework assemblies (implicitly via `System.Reflection`, `System.Runtime.CompilerServices`, `System.Runtime.InteropServices`).
|
||||
- **No explicit external dependencies** are declared in this file.
|
||||
- **Inferred consumers**: Other modules in the `DTS.Common.IConnection` hierarchy (e.g., `USBConnection` implementations) likely depend on types defined in this assembly, but those types are not visible here.
|
||||
- **Inferred producers**: This assembly is likely built as part of a larger solution where `USBFramework` is a referenced library for USB-specific connection logic.
|
||||
|
||||
## 5. Gotchas
|
||||
- **Misleading assembly title**: The `AssemblyTitle` is `"HIDFramework"`, but the namespace/path is `USBFramework`. This may cause confusion during debugging, logging, or reflection-based discovery (e.g., `Assembly.GetExecutingAssembly().Title` returns `"HIDFramework"`).
|
||||
- **No versioning strategy in source**: The version `1.06.0081` is hardcoded; no build-time auto-increment or CI integration is evident.
|
||||
- **COM interop disabled**: While `ComVisible(false)` is appropriate for pure .NET usage, it precludes direct COM consumption without additional interop layers (e.g., `RegAsm` with `/tlb` and `/codebase`).
|
||||
- **No documentation comments**: The file lacks XML documentation (`<summary>`, etc.), consistent with typical `AssemblyInfo.cs` but contributing to low discoverability of assembly-level intent.
|
||||
- **None identified from source alone** regarding runtime behavior, logic, or usage patterns—these would require inspecting the actual implementation files (not provided).
|
||||
@@ -0,0 +1,284 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.IConnection/USBConnection/WINUSBConnection/WINUSBDeviceApi.cs
|
||||
- Common/DTS.Common.IConnection/USBConnection/WINUSBConnection/CDCUSBConnection.cs
|
||||
- Common/DTS.Common.IConnection/USBConnection/WINUSBConnection/WINUSBConnection.cs
|
||||
generated_at: "2026-04-16T02:09:52.794052+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "2043cd8e3c0f04ef"
|
||||
---
|
||||
|
||||
# Documentation: USB Connection Modules
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides two distinct USB-based connection implementations (`CDCUSBConnection` and `WINUSBConnection`) that implement the `IConnection` interface for communicating with DTS hardware devices. `CDCUSBConnection` emulates a serial port over USB using the Windows `SerialPort` class (CDC–Communication Device Class), while `WINUSBConnection` uses the native Windows WinUSB API (`winusb.dll`) for direct USB communication. Both modules support asynchronous I/O operations (`BeginConnect`, `EndConnect`, `BeginSend`, `EndSend`, etc.), resource disposal, and registry-based device enumeration for the DTS vendor ID `0x1CB9` and specific product IDs.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `CDCUSBConnection`
|
||||
|
||||
- **`public bool IsSoftDisconnected { get; }`**
|
||||
Always returns `false`. Soft disconnect is not supported for CDCUSB.
|
||||
|
||||
- **`public void SoftConnect()`**
|
||||
No-op. Soft connect is not supported.
|
||||
|
||||
- **`public void SoftDisconnect()`**
|
||||
No-op. Soft disconnect is not supported.
|
||||
|
||||
- **`public double GetCurrentUploadRate()`**
|
||||
Returns `0.0`. Upload rate is not tracked.
|
||||
|
||||
- **`public double GetCurrentDownloadRate()`**
|
||||
Returns `0.0`. Download rate is not tracked.
|
||||
|
||||
- **`public string PortName { get; set; }`**
|
||||
Gets or sets the COM port name (e.g., `"COM3"`) used for serial communication.
|
||||
|
||||
- **`public string ConnectString { get; }`**
|
||||
Returns the `_devicePathname` passed to `Create`. Used as a device identifier.
|
||||
|
||||
- **`public bool Connected { get; }`**
|
||||
Returns `_Connected`, indicating whether the underlying `SerialPort` is open.
|
||||
|
||||
- **`public event EventHandler OnDisconnected`**
|
||||
Event raised on disconnection (currently unused in this implementation).
|
||||
|
||||
- **`public static IList<string> RegKeys { get; }`**
|
||||
Lazily-initialized list of registry subkey names under the DTS CDCUSB device path (`USB\VID_1CB9&PID_001A`). Used to locate device-specific COM port names.
|
||||
|
||||
- **`public CDCUSBConnection()`**
|
||||
Constructor initializing internal state (`_Connected = false`, `Disposed = false`, `Disposing = false`).
|
||||
|
||||
- **`public void Create(string connectString, string hostIPAddress)`**
|
||||
Parses `connectString` to match a registry key in `RegKeys`, then reads the `"PortName"` value from the device’s registry `"Device Parameters"` subkey and assigns it to `PortName`. Sets `_devicePathname = connectString`.
|
||||
|
||||
- **`public IAsyncResult BeginConnect(AsyncCallback cb, object state)`**
|
||||
Returns an `IAsyncResult` (`UsbRecAsyncResult`) and queues a callback via `ThreadPool.QueueUserWorkItem`. Does *not* perform the actual connection.
|
||||
|
||||
- **`public void EndConnect(IAsyncResult ar)`**
|
||||
Opens the `SerialPort` using configured `_baudRate`, `_parity`, `_stopBits`, `DATA_BITS`, and `PortName`. Sets `_Connected = true` on success.
|
||||
|
||||
- **`public IAsyncResult BeginSend(byte[] buffer, int offset, int size, AsyncCallback cb, object state)`**
|
||||
Returns `UsbRecAsyncResult` with buffer metadata. Actual write occurs in `EndSend`.
|
||||
|
||||
- **`public int EndSend(IAsyncResult ar)`**
|
||||
Writes `buffer` (using `size` and `offset` from `UsbRecAsyncResult`) to `_comPort.Write(...)`. Returns `size`.
|
||||
|
||||
- **`public Task<int> SendAsync(...)`**
|
||||
Wraps `BeginSend`/`EndSend` in a `Task<int>`.
|
||||
|
||||
- **`public IAsyncResult BeginReceive(byte[] buffer, int offset, int size, AsyncCallback cb, object state)`**
|
||||
Returns `UsbRecAsyncResult` with buffer metadata.
|
||||
|
||||
- **`public int EndReceive(IAsyncResult ar)`**
|
||||
Reads from `_comPort.Read(...)` in a loop until at least one byte is read (sleeps 1 ms between retries). Returns number of bytes read.
|
||||
|
||||
- **`public IAsyncResult BeginDisconnect(...)`**
|
||||
Returns `UsbRecAsyncResult`. Actual disconnect occurs in `EndDisconnect`.
|
||||
|
||||
- **`public void EndDisconnect(IAsyncResult ar)`**
|
||||
Closes and disposes `_comPort`, sets `_Connected = false`.
|
||||
|
||||
- **`public void Dispose()` / `protected virtual void Dispose(bool)`**
|
||||
Implements `IDisposable`. Closes `_comPort` if open, sets `Disposed = true`.
|
||||
|
||||
- **`public void Bind(int port)` / `public void Listen(int backlog)` / `public IAsyncResult BeginAccept(...)` / `public IConnection EndAccept(...)`**
|
||||
All throw `NotSupportedException`.
|
||||
|
||||
### `WINUSBConnection`
|
||||
|
||||
- **`public bool IsSoftDisconnected { get; }`**
|
||||
Always returns `false`. Soft disconnect is not supported.
|
||||
|
||||
- **`public void SoftConnect()` / `public void SoftDisconnect()`**
|
||||
No-op.
|
||||
|
||||
- **`public double GetCurrentUploadRate()` / `public double GetCurrentDownloadRate()`**
|
||||
Return `0.0`.
|
||||
|
||||
- **`public bool Connected { get; private set; }`**
|
||||
Indicates whether the device is connected via WinUSB.
|
||||
|
||||
- **`public string ConnectString { get; private set; }`**
|
||||
Stores the device path passed to `Create`.
|
||||
|
||||
- **`public event EventHandler OnDisconnected`**
|
||||
Event for disconnection notifications (currently unused).
|
||||
|
||||
- **`public void Create(string connectString, string hostIPAddress)`**
|
||||
Stores `connectString` in `ConnectString`.
|
||||
|
||||
- **`public IAsyncResult BeginConnect(AsyncCallback cb, object state)`**
|
||||
Validates `_sliceDev == null && !Connected`. Returns `WinUSBRecAsyncResult`, waits synchronously on `AsyncWaitHandle` before returning.
|
||||
|
||||
- **`public void EndConnect(IAsyncResult ar)`**
|
||||
Instantiates `_sliceDev = new WinUsbDevice()`, calls `_sliceDev.GetDeviceHandle(ConnectString)` and `_sliceDev.InitializeDevice()`. Sets `Connected = true` on success. Logs and throws `NotConnectedException` on failure.
|
||||
|
||||
- **`public IAsyncResult BeginSend(byte[] buffer, int offset, int size, AsyncCallback cb, object state)`**
|
||||
Validates connection and buffer parameters. Returns `WinUSBRecAsyncResult`.
|
||||
|
||||
- **`public int EndSend(IAsyncResult ar)`**
|
||||
Copies buffer data, then calls `_sliceDev.SendViaInterruptTransfer(...)` or `_sliceDev.SendViaBulkTransfer(...)` depending on `MyDevInfo.UseHybridBulkIntMode`. Throws on failure.
|
||||
|
||||
- **`public Task<int> SendAsync(...)`**
|
||||
Wraps `BeginSend`/`EndSend`.
|
||||
|
||||
- **`public IAsyncResult BeginReceive(byte[] buffer, int offset, int size, AsyncCallback cb, object state)`**
|
||||
Validates connection and buffer parameters. Returns `WinUSBRecAsyncResult`.
|
||||
|
||||
- **`public int EndReceive(IAsyncResult ar)`**
|
||||
Calls `_sliceDev.ReadViaBulkTransfer(...)` in a loop until `bytesRead > 0` or failure. Copies data into `rar.Buffer`. Returns bytes read.
|
||||
|
||||
- **`public IAsyncResult BeginDisconnect(...)`**
|
||||
Validates `_sliceDev != null`. Sets `Connected = false`, returns `WinUSBRecAsyncResult`.
|
||||
|
||||
- **`public void EndDisconnect(IAsyncResult ar)`**
|
||||
Calls `DisposeSliceDev()` to release WinUSB handle.
|
||||
|
||||
- **`public void Dispose()` / `protected virtual void Dispose(bool)`**
|
||||
Implements `IDisposable`. Disposes `_wusbDeviceManagement` and calls `DisposeSliceDev()`. Uses `Mutex _usbConnectionMutex` for thread safety.
|
||||
|
||||
- **`public void Bind(int port)` / `public void Listen(int backlog)` / `public IAsyncResult BeginAccept(...)` / `public IConnection EndAccept(...)`**
|
||||
All throw `NotSupportedException`.
|
||||
|
||||
### `WinUsbDevice` (internal)
|
||||
|
||||
- **`internal const uint DEVICE_SPEED = 1`**
|
||||
Used with `WinUsb_QueryDeviceInformation`.
|
||||
|
||||
- **`internal const byte USB_ENDPOINT_DIRECTION_MASK = 0x80`**
|
||||
Mask to determine endpoint direction (IN/OUT).
|
||||
|
||||
- **`internal enum PolicyType`**
|
||||
Defines WinUSB pipe policies: `ShortPacketTerminate`, `AutoClearStall`, `PipeTransferTimeout`, etc.
|
||||
|
||||
- **`internal enum USBDPipeTypes`**
|
||||
Pipe types: `UsbdPipeTypeControl`, `UsbdPipeTypeIsochronous`, `UsbdPipeTypeBulk`, `UsbdPipeTypeInterrupt`.
|
||||
|
||||
- **`internal enum USBDeviceSpeeds`**
|
||||
Device speeds: `UsbLowSpeed`, `UsbFullSpeed`, `UsbHighSpeed`.
|
||||
|
||||
- **`internal struct USBConfigurationDescriptor`**
|
||||
P/Invoke struct for USB configuration descriptor.
|
||||
|
||||
- **`internal struct USBInterfaceDescriptor`**
|
||||
P/Invoke struct for USB interface descriptor.
|
||||
|
||||
- **`internal struct WinUSBPipeInformation`**
|
||||
P/Invoke struct for pipe info: `PipeTypes`, `PipeId`, `MaximumPacketSize`, `Interval`.
|
||||
|
||||
- **`internal struct WinUSBSetupPacket`**
|
||||
P/Invoke struct for control transfer setup packet.
|
||||
|
||||
- **`internal static extern bool WinUsb_ControlTransfer(...)`**
|
||||
Sends control transfers.
|
||||
|
||||
- **`internal static extern bool WinUsb_Initialize(...)`**
|
||||
Initializes WinUSB interface handle.
|
||||
|
||||
- **`internal static extern bool WinUsb_Free(...)`**
|
||||
Frees WinUSB interface handle.
|
||||
|
||||
- **`internal static extern bool WinUsb_QueryDeviceInformation(...)`**
|
||||
Retrieves device info (e.g., speed) using `DEVICE_SPEED`.
|
||||
|
||||
- **`internal static extern bool WinUsb_QueryInterfaceSettings(...)`**
|
||||
Queries interface settings.
|
||||
|
||||
- **`internal static extern bool WinUsb_QueryPipe(...)`**
|
||||
Queries pipe info.
|
||||
|
||||
- **`internal static extern bool WinUsb_ReadPipe(...)`**
|
||||
Reads from a pipe.
|
||||
|
||||
- **`internal static extern bool WinUsb_WritePipe(...)`**
|
||||
Writes to a pipe.
|
||||
|
||||
- **`internal static extern bool WinUsb_SetPipePolicy(...)`**
|
||||
Sets pipe policy (byte value).
|
||||
**Alias**: `WinUsb_SetPipePolicy1` for `PIPE_TRANSFER_TIMEOUT` (uses `uint` value).
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **`Connected` state**
|
||||
- `CDCUSBConnection`: `_Connected` is `true` only when `_comPort.IsOpen == true`.
|
||||
- `WINUSBConnection`: `Connected` is `true` only after `_sliceDev.GetDeviceHandle(...)` and `_sliceDev.InitializeDevice()` both succeed.
|
||||
|
||||
- **`ConnectString` usage**
|
||||
- `CDCUSBConnection`: Used to match registry keys for COM port lookup.
|
||||
- `WINUSBConnection`: Passed to `_sliceDev.GetDeviceHandle(...)` to locate device.
|
||||
|
||||
- **Thread safety**
|
||||
- `WINUSBConnection` uses `_usbConnectionMutex` around `WinUsbDevice` disposal.
|
||||
- `CDCUSBConnection.RegKeys` uses `KEY_LOCK` for lazy initialization.
|
||||
|
||||
- **Asynchronous pattern**
|
||||
- `Begin*` methods queue work to `ThreadPool` via `NetCallbackFix`, which invokes the callback.
|
||||
- `End*` methods perform actual I/O and signal `AsyncWaitHandle.Set()`.
|
||||
|
||||
- **No soft disconnect**
|
||||
Both `CDCUSBConnection` and `WINUSBConnection` have no-op `SoftConnect`/`SoftDisconnect`.
|
||||
|
||||
- **No socket operations**
|
||||
`Bind`, `Listen`, `BeginAccept`, `EndAccept` throw `NotSupportedException` in both classes.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Imports / External Dependencies
|
||||
- **Windows API**: `winusb.dll` (for `WINUSBConnection` via P/Invoke in `WinUsbDevice`).
|
||||
- **.NET Framework**:
|
||||
- `System.IO.Ports.SerialPort` (for `CDCUSBConnection`).
|
||||
- `System.Threading`, `System.Threading.Tasks`, `System.Runtime.InteropServices`.
|
||||
- `Microsoft.Win32.Registry` (for registry enumeration).
|
||||
- **Internal DTS modules** (from namespace imports):
|
||||
- `DTS.Common.DASResource` (string resources, e.g., `DASResource.Strings.*`).
|
||||
- `DTS.Common.Interface.Connection` (`IConnection` interface).
|
||||
- `DTS.Common.Utilities.Logging` (`APILogger`).
|
||||
- `DTS.Common.USBFramework` (likely contains `DeviceManagement`).
|
||||
- `DTS.Common.Classes.Connection` (likely contains `NotConnectedException`).
|
||||
|
||||
### Dependencies on Other Modules
|
||||
- `WINUSBConnection` depends on `DeviceManagement` and `WinUsbDevice` (defined in same namespace).
|
||||
- `CDCUSBConnection` depends on `DASResource.Strings` for exception messages.
|
||||
|
||||
### Dependencies *by* This Module
|
||||
- `IConnection` interface (consumed by higher layers).
|
||||
- `DeviceManagement` (used by `WINUSBConnection` for device lifecycle management).
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **`Create` recursion**
|
||||
Both `CDCUSBConnection.Create(string)` and `WINUSBConnection.Create(string)` contain commented-out recursive calls (`//Create(connectString); - this is recursive!`). This suggests a historical bug or incomplete refactoring.
|
||||
|
||||
- **`BeginConnect` blocking in `WINUSBConnection`**
|
||||
`WINUSBConnection.BeginConnect` calls `rar.AsyncWaitHandle.WaitOne()` *before returning*, making it effectively synchronous despite being an "Async" pattern. This violates the expected non-blocking behavior of `Begin*` methods.
|
||||
|
||||
- **`EndConnect` in `WINUSBConnection` throws if already connected**
|
||||
`EndConnect` checks `if (_sliceDev != null || Connected)` and throws `NotConnectedException`, but `BeginConnect` already sets `Connected = false` *before* the async work. This is inconsistent and may cause confusion.
|
||||
|
||||
- **`EndReceive` busy-waits**
|
||||
`CDCUSBConnection.EndReceive` and `WINUSBConnection.EndReceive` both use tight loops with `Thread.Sleep(1)` when no data is available. This can cause high CPU usage.
|
||||
|
||||
- **`WinUSB_SetPipePolicy` vs `WinUsb_SetPipePolicy1`**
|
||||
Two separate P/Invoke declarations exist for `WinUsb_SetPipePolicy`, with `WinUsb_SetPipePolicy1` used *only* for `PIPE_TRANSFER_TIMEOUT` (which requires a `uint` instead of `byte`). This is error-prone and not enforced by the API.
|
||||
|
||||
- **`RegKeys` is static and lazily initialized**
|
||||
`CDCUSBConnection.RegKeys` is a static property. If the registry changes after first access, the list will be stale until app restart.
|
||||
|
||||
- **No error propagation in `NetCallbackFix`**
|
||||
Exceptions in `NetCallbackFix` are caught and logged, but the callback is still invoked. This may leave callers expecting an exception to be thrown in `End*`.
|
||||
|
||||
- **`IsSoftDisconnected` always false**
|
||||
Both classes report `IsSoftDisconnected = false`, but the interface contract may expect it to reflect a real state. This could mislead callers.
|
||||
|
||||
- **`GetConnectionData()` returns `""`**
|
||||
Both classes return empty strings. This may indicate incomplete implementation.
|
||||
|
||||
- **`Flags` property unused**
|
||||
`System.Net.Sockets.SocketFlags Flags { get; set; }` is exposed but never used in either class.
|
||||
|
||||
- **`USB_ENDPOINT_DIRECTION_MASK` is internal**
|
||||
While defined, it is not used in the provided source. May be used elsewhere in the codebase.
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.IConnection/USBConnection/WINUSBConnection/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T02:10:04.213580+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "8875c5ea92f3aea7"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## 1. Purpose
|
||||
This module is an assembly metadata definition for the `WINUSBConnection` component, part of the `DTS.Common.IConnection` namespace. It does not contain executable logic or implementation code; its sole purpose is to declare assembly-level attributes—such as title, version, and COM visibility settings—that identify and configure the compiled .NET assembly for deployment and interoperation. It serves as a static configuration layer for the WINUSB-based USB communication module within the larger device connectivity framework.
|
||||
|
||||
## 2. Public Interface
|
||||
**No public types, functions, classes, or methods are defined in this file.**
|
||||
This file (`AssemblyInfo.cs`) contains only assembly-level attributes and does not declare any runtime-visible members. All public APIs (e.g., connection handling, USB I/O) reside in other source files (e.g., `WINUSBConnection.cs`, `IConnection.cs`) not included here.
|
||||
|
||||
## 3. Invariants
|
||||
- The assembly is **not visible to COM** (`ComVisible(false)`), meaning external COM clients cannot directly instantiate types from this assembly unless explicitly exposed via other mechanisms (e.g., COM-visible wrapper assemblies).
|
||||
- The assembly version is strictly `1.06.0081` (both `AssemblyVersion` and `AssemblyFileVersion`), enforcing version consistency for binding and deployment.
|
||||
- The GUID `F3C369E6-BFFB-41bc-B8E8-A31094CED447` is reserved for the type library ID (if exposed to COM in the future), and must remain unchanged to preserve type identity across builds.
|
||||
|
||||
## 4. Dependencies
|
||||
- **No runtime dependencies** are declared in this file.
|
||||
- **Build-time dependency**: Requires the .NET Framework (or .NET Standard/Core with compatible attributes) to process `System.Reflection`, `System.Runtime.CompilerServices`, and `System.Runtime.InteropServices`.
|
||||
- **Logical dependency**: This assembly (`WINUSBConnection`) is part of the `DTS.Common.IConnection` hierarchy, implying it implements or references interfaces defined in `DTS.Common.IConnection` (e.g., `IConnection`), though those interfaces are not defined here.
|
||||
|
||||
## 5. Gotchas
|
||||
- **Misleading file location**: The path `Common/DTS.Common.IConnection/USBConnection/WINUSBConnection/Properties/AssemblyInfo.cs` suggests this assembly contains WINUSB-specific logic, but this file *only* defines metadata—no actual USB communication code resides here. Developers must look elsewhere (e.g., `WINUSBConnection.cs`) for implementation.
|
||||
- **Hardcoded version**: Version `1.06.0081` is fixed in source; automated versioning (e.g., via CI) would require modifying this file or overriding via build scripts.
|
||||
- **COM visibility**: `ComVisible(false)` prevents accidental COM exposure, but if COM interop is needed, additional attributes (e.g., `[ComVisible(true)]` on specific types) must be added in *other* files—this file alone does not enable COM support.
|
||||
- **No functional behavior**: This file cannot be tested for correctness beyond verifying attribute values; runtime behavior is entirely absent here.
|
||||
|
||||
None identified beyond the above.
|
||||
119
enriched-qwen3-coder-next/Common/DTS.Common.ISO.md
Normal file
119
enriched-qwen3-coder-next/Common/DTS.Common.ISO.md
Normal file
@@ -0,0 +1,119 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.ISO/IsoMDBFile.cs
|
||||
- Common/DTS.Common.ISO/ISerializableFile.cs
|
||||
- Common/DTS.Common.ISO/AbstractOLEDbWrapper.cs
|
||||
- Common/DTS.Common.ISO/HardwareChannel.cs
|
||||
- Common/DTS.Common.ISO/IsoCode.cs
|
||||
- Common/DTS.Common.ISO/TestObjectChannel.cs
|
||||
- Common/DTS.Common.ISO/CalculatedValueClass.cs
|
||||
- Common/DTS.Common.ISO/LevelTriggerChannel.cs
|
||||
- Common/DTS.Common.ISO/TestSetting.cs
|
||||
- Common/DTS.Common.ISO/TestObjectTemplate.cs
|
||||
- Common/DTS.Common.ISO/MMEFilterClasses.cs
|
||||
- Common/DTS.Common.ISO/MMEPositions.cs
|
||||
- Common/DTS.Common.ISO/MMEFineLocations2.cs
|
||||
generated_at: "2026-04-16T14:13:51.176520+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "8371f072462a5521"
|
||||
---
|
||||
|
||||
# Documentation: DTS.Common.ISO
|
||||
|
||||
## 1. Purpose
|
||||
The `DTS.Common.ISO` namespace provides a domain model and data access layer for a Data Acquisition System (DAS), with specific support for ISO 13499 (MME) standards. It defines core entities representing hardware channels, test object templates, calculated channels, and trigger logic. The module bridges raw database records (via OLE DB) and XML serialization with higher-level application logic, facilitating the configuration and execution of crash test simulations or data recording scenarios.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Classes
|
||||
|
||||
#### `AbstractOLEDbWrapper`
|
||||
An abstract base class providing utility methods for safe data reading.
|
||||
* `protected static long GetLong(IDataReader reader, string field)`: Returns `long.MinValue` if the database field is `DBNull`, otherwise converts the value to `long`.
|
||||
* `protected static DateTime GetDate(IDataReader reader, string field)`: Returns `DateTime.MinValue` if the database field is `DBNull`, otherwise casts to `DateTime`.
|
||||
|
||||
#### `HardwareChannel`
|
||||
Represents a physical hardware channel, inheriting from `DASChannelDBRecord`.
|
||||
* `Hardware ParentDAS`: Gets or sets the parent hardware device.
|
||||
* `HardwareChannel()`: Default constructor.
|
||||
* `HardwareChannel(IDASChannelDBRecord record, Hardware h)`: Constructs a channel from a record and parent hardware.
|
||||
* `HardwareChannel(HardwareChannel copy, Hardware h)`: Copy constructor.
|
||||
* `static int PhysicalCompare(HardwareChannel left, HardwareChannel right)`: Compares two channels by `ChannelIdx`. Handles nulls.
|
||||
* `void Insert()`: Inserts the channel into the database via `DbOperations.DASChannelsInsert`.
|
||||
* `bool IsSupported(SensorConstants.BridgeType bridge)`: Checks if a specific bridge type is supported using bitwise comparison.
|
||||
|
||||
#### `IsoCodeStatics`
|
||||
Static helper class for generating ISO code strings.
|
||||
* `static string GetString(MMEPossibleChannels channel, MMETestObjects container, MMEPositions position, MMEFilterClasses fc)`: Constructs an ISO code string from channel metadata.
|
||||
* `static string GetString(MMEPossibleChannels channel, bool careAboutTestTimeFields)`: Overload that optionally masks test time fields (TestObject, FilterClass) with placeholders ("??", "?").
|
||||
* `static string GetString(string testObject, ..., string fc)`: Constructs the string via concatenation of parameters.
|
||||
|
||||
#### `TestObjectChannel`
|
||||
Represents a channel within a test object, implementing `IComparable<TestObjectChannel>` and `IGroupChannel`.
|
||||
* `bool Disabled`: Determines if the channel is used in data collection.
|
||||
* `int ChannelIdx`: Index of the channel, defaults to `CHANNEL_IDX_UNKNOWN` (-1).
|
||||
* `string SensorSerialNumber`: Serial number of the associated sensor.
|
||||
* `string HardwareId`: Physical hardware channel ID. The setter parses and reformats the string if it contains underscores.
|
||||
* `SquibChannelTypes SquibChannelType`: Enum (`None`, `Voltage`, `Current`).
|
||||
* `TestObject TestObject`: The parent test object.
|
||||
* `int CompareTo(TestObjectChannel right)`: Sorts by `DisplayOrder`, then `Name`, then `TestObject.SerialNumber`.
|
||||
* `string GetGraphId()`: Returns the ID, appending `Constants.CURRENT_SUFFIX` if `SquibChannelType` is `Current`.
|
||||
* `string GetId()`: Returns a composite ID string (`SerialNumber_MMEChannelType_Id`).
|
||||
* `string GetDASId()`: Extracts the DAS ID from the `HardwareId` string.
|
||||
|
||||
#### `CalculatedValueClass`
|
||||
Represents a calculated/derived channel (e.g., sum, HIC), inheriting from `CalculatedChannelRecord`.
|
||||
* `bool SupportsRealtime`: Returns true if `ViewInRealtime` is true.
|
||||
* `bool IsValid(Dictionary<string, bool> channelIdLookup)`: Validates that the channel has a name and all input channel IDs exist in the lookup.
|
||||
* `Operations Operation`: Setter triggers property change events for `ViewInRealtime` and `CanChangeViewInRealtime`.
|
||||
* `bool ViewInRealtime`: Returns false for specific operations (`IRTRACC3D`, `HIC`, etc.) regardless of the base value.
|
||||
* `string[] InputChannelIds`: Getter reconstructs the array from the `_channels` list if populated.
|
||||
* `byte[] InputChannelIdsBlob`: Serializes/deserializes input channel IDs to/from UTF-8 bytes.
|
||||
* `void ReplaceInputChannelIdAtIndex(int index, string newId)`: Replaces a specific ID in the input array.
|
||||
|
||||
#### `CCAttributeBase`
|
||||
Abstract base class for attributes attached to calculated channels.
|
||||
* `int AttributeId`: Read-only ID.
|
||||
* `abstract string GetSerializedValue()`: Must be implemented to return the string value.
|
||||
* `abstract string GetDefaultValue()`: Must be implemented to return the default value.
|
||||
* `abstract CCAttributeBase Copy()`: Must be implemented for deep copying.
|
||||
|
||||
#### `LevelTriggerChannel`
|
||||
Defines trigger conditions based on signal levels.
|
||||
* `LevelTriggerChannel(DataRow dr)`: Constructs the object from a database row.
|
||||
* `string LevelTriggerText`: Generates a human-readable description of the trigger logic (e.g., "Less than 5.00(V)").
|
||||
* Properties include thresholds: `GreaterThanThresholdEU`, `LessThanThresholdEU`, `InsideUpperLevelEU`, etc.
|
||||
|
||||
#### `TestSetting` & `TestSettingDictionary`
|
||||
Manage configuration settings for a test.
|
||||
* `TestSetting(int id, string value, string defaultValue)`: Constructor.
|
||||
* `static bool TryParse(string s, out TestSetting ts)`: Parses a string format "id=value".
|
||||
* `TestSettingDictionary.GetValue(int id, string defaultValue)`: Retrieves a value or returns the default.
|
||||
* `TestSettingDictionary.SetValue(TestSetting setting)`: Sets or updates a setting in the internal dictionary.
|
||||
* `string ToSerializeString()`: Serializes the dictionary to a string using culture-invariant separators.
|
||||
|
||||
#### `TestObjectTemplate`
|
||||
A lightweight wrapper for group templates (ISO metadata).
|
||||
* `string TemplateNameOrOriginalTemplateName`: Returns the original name if embedded (GUID name), otherwise `TemplateName`.
|
||||
* `TestObjectTemplateChannel[] Channels`: Array of channels belonging to the template.
|
||||
* `bool IsISOMode()`: Checks if `TestObjectType` contains specific non-ISO markers.
|
||||
|
||||
#### ISO Metadata Classes (`MMEFilterClasses`, `MMEPositions`, `MMEFineLocations2`)
|
||||
Data mappers for ISO 13499 reference tables.
|
||||
* `static [Type][] Get[Types]()`: Static method that queries the database (via `DbOperations.GetISOCommand()`) and returns an array of objects.
|
||||
* `static [Type] ReadXML(XmlElement node)`: Factory method to instantiate from XML attributes.
|
||||
* Properties map directly to DB columns: `S_GUID`, `Text_L1`, `Version`, `Expired`, `History`, etc.
|
||||
|
||||
### Interfaces
|
||||
|
||||
#### `ISerializableFile`
|
||||
* `string GetDirectory()`
|
||||
* `string GetExtension()`
|
||||
* `string GetFilter()`
|
||||
* `string GetFileLocation()`
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
* **HardwareChannel Insertion**: Calling `HardwareChannel.Insert()` requires `ParentDAS` to be non-null, as it calls `ParentDAS.GetId()`.
|
||||
* **TestObjectChannel ID Parsing**: The `HardwareId` setter expects a specific format (tokens separated by `_`). If it does not match the expected
|
||||
@@ -0,0 +1,71 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.ISO/Properties/AssemblyInfo.cs
|
||||
- Common/DTS.Common.ISO/Properties/Resources.Designer.cs
|
||||
generated_at: "2026-04-16T03:29:22.576207+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "67d8506a4452cfae"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## Documentation Page: `DTS.Common.ISO` Assembly (ISO Module)
|
||||
|
||||
---
|
||||
|
||||
### 1. **Purpose**
|
||||
|
||||
This module (`DTS.Common.ISO`) is a .NET class library assembly that provides shared infrastructure and resources for ISO-related functionality within the DTS (presumably *Data Transfer System* or domain-specific acronym) codebase. Based on the source files, its primary role is to define assembly metadata (e.g., versioning, COM visibility) and expose strongly-typed access to embedded UI resources—specifically, two bitmap images (`DTS_2C_Logo` and `DTS_2C_web_small`). It does not contain business logic or core functionality beyond resource management, suggesting it serves as a lightweight dependency for UI or presentation layers that require consistent branding or iconography.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
|
||||
The assembly exposes **no public types or methods** beyond the auto-generated `Resources` class. All public surface area is contained in the `DTS.Common.ISO.Properties.Resources` class:
|
||||
|
||||
- **`internal static class Resources`**
|
||||
A strongly-typed resource class for accessing embedded resources (bitmaps).
|
||||
- **`ResourceManager ResourceManager { get; }`**
|
||||
Returns a cached `System.Resources.ResourceManager` instance used to look up resources by name. Initialized lazily on first access.
|
||||
- **`CultureInfo Culture { get; set; }`**
|
||||
Gets or sets the UI culture used for resource lookups. Allows overriding the current thread’s `CurrentUICulture` for resource resolution.
|
||||
- **`Bitmap DTS_2C_Logo { get; }`**
|
||||
Returns the embedded bitmap resource named `"DTS_2C_Logo"`. Throws `MissingManifestResourceException` if the resource is not found.
|
||||
- **`Bitmap DTS_2C_web_small { get; }`**
|
||||
Returns the embedded bitmap resource named `"DTS_2C_web_small"`. Throws `MissingManifestResourceException` if the resource is not found.
|
||||
|
||||
> **Note**: All members of `Resources` are `internal`, meaning they are only accessible within the same assembly (`DTS.Common.ISO`). No public types or methods are exposed to external consumers.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
|
||||
- **Resource names are fixed and case-sensitive**: Resource lookups rely on exact string keys (`"DTS_2C_Logo"`, `"DTS_2C_web_small"`). Mismatches in casing or spelling will cause `ResourceManager.GetObject()` to return `null`, which is then cast to `Bitmap`, potentially causing `InvalidCastException` or `NullReferenceException` at runtime.
|
||||
- **`ResourceManager` is lazily initialized and thread-safe for read access**: The `ResourceManager` property uses a null-check-and-assign pattern. While not explicitly synchronized, the .NET `ResourceManager` class is thread-safe for concurrent reads.
|
||||
- **Assembly identity is static**: Version is fixed at `1.0.0.0` (both `AssemblyVersion` and `AssemblyFileVersion`). The `AssemblyCulture` is empty (indicating a neutral/satellite assembly not tied to a specific culture).
|
||||
- **COM visibility is disabled**: `ComVisible(false)` ensures types in this assembly are not exposed to COM by default.
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
|
||||
- **Dependencies *of* this assembly**:
|
||||
- `System.Drawing` (for `System.Drawing.Bitmap`)
|
||||
- `System.Resources` (for `ResourceManager`, `CultureInfo`)
|
||||
- Core .NET runtime (`mscorlib`, `System`)
|
||||
|
||||
- **Dependencies *on* this assembly**:
|
||||
- Not inferable from source alone. However, given the embedded resources (`DTS_2C_Logo`, `DTS_2C_web_small`), it is likely referenced by UI projects (e.g., WinForms, WPF, or reporting modules) that require consistent DTS branding assets.
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
|
||||
- **No public API surface**: External consumers cannot directly use this assembly for functionality beyond resource access, and even resource access is limited to internal use (since `Resources` is `internal`). If external access is needed, the class must be made `public`.
|
||||
- **Resource file mismatch risk**: The `Resources.Designer.cs` file references `"ISO.Properties.Resources"` as the base name for the `ResourceManager`. This assumes a corresponding `Resources.resx` file exists in the `Properties/` folder with matching embedded resources. If the `.resx` file is missing, renamed, or misconfigured, resource lookups will fail.
|
||||
- **No localization logic**: While `Culture` can be set, the assembly itself does not define any localized strings or fallback logic. Only bitmaps are exposed, so culture changes affect only resource *lookup* (e.g., for satellite assemblies), not behavior.
|
||||
- **Auto-generated code warning**: The `Resources.Designer.cs` header explicitly warns that manual edits will be lost on regeneration. Changes to resources must be made via `.resx` files and rebuilt.
|
||||
- **No versioning strategy**: Fixed version `1.0.0.0` may cause issues if this assembly evolves independently. Consider aligning with semantic versioning or build-time version injection.
|
||||
|
||||
> **None identified from source alone** beyond the above—no complex logic, edge cases, or deprecated patterns are evident.
|
||||
131
enriched-qwen3-coder-next/Common/DTS.Common.ISO/Strings.md
Normal file
131
enriched-qwen3-coder-next/Common/DTS.Common.ISO/Strings.md
Normal file
@@ -0,0 +1,131 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.ISO/Strings/StringResources.Designer.cs
|
||||
generated_at: "2026-04-16T03:29:29.164879+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "f14833e08b2b143d"
|
||||
---
|
||||
|
||||
# Documentation: `ISO.Strings.StringResources`
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides a strongly-typed, auto-generated resource class (`StringResources`) for centralized retrieval of localized UI strings used throughout the ISO (likely *SLICE* or *DAS* — Device Access System) application suite. Its primary role is to decouple user-facing messages—particularly validation and device-detection error messages—from business logic—by storing them externally in `.resx` files and exposing them via compile-time-safe properties. This enables localization (e.g., multi-language support) and improves maintainability by avoiding hardcoded string literals.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
The class is `internal`, but its members are used internally by the assembly. All members are static and accessed via property getters.
|
||||
|
||||
### `StringResources.ResourceManager` (property)
|
||||
- **Type**: `System.Resources.ResourceManager`
|
||||
- **Behavior**: Returns a cached `ResourceManager` instance initialized for the `"ISO.Strings.StringResources"` base name in the current assembly. Lazily initializes on first access.
|
||||
|
||||
### `StringResources.Culture` (property)
|
||||
- **Type**: `System.Globalization.CultureInfo`
|
||||
- **Behavior**: Gets or sets the UI culture override for all resource lookups via this class. Allows runtime switching of language (e.g., for testing or user preference).
|
||||
|
||||
### Device Serial Number Validation & Detection Messages
|
||||
The following properties return localized strings used during device auto-detection (e.g., validating serial number prefixes). Each corresponds to a specific device type or validation rule:
|
||||
|
||||
| Property Name | Example Message Content | Purpose |
|
||||
|---------------|-------------------------|---------|
|
||||
| `AutoDetectDas_DIMShouldStartWithSPD` | `"SLICE PRO DIM serial numbers should start with 'SPD'."` | Validation error for DIM devices |
|
||||
| `AutoDetectDas_DIRShouldStartWithDI` | `"DIR serial numbers should start with 'DI'."` | DIR device validation |
|
||||
| `AutoDetectDas_DKRShouldStartWithDK` | `"DKR serial numbers should start with 'DK'."` | DKR device validation |
|
||||
| `AutoDetectDas_G5ShouldStartWith5M` | `"TDAS G5 serial numbers should start with '5M'."` | TDAS G5 validation |
|
||||
| `AutoDetectDAS_MICROBasePlusShouldStartWithBA0` | `"SLICE MICRO Base+ serial numbers should start with 'BA0'."` | MICRO Base+ validation |
|
||||
| `AutoDetectDas_MicroSerialNumberShouldStartWithBA0` | `"SLICE MICRO serial numbers should start with 'BA0'."` | Standard MICRO validation |
|
||||
| `AutoDetectDAS_NANOBasePlusShouldStartWithBA5` | `"SLICE NANO Base+ serial numbers should start with 'BA5'."` | NANO Base+ validation |
|
||||
| `AutoDetectDas_PowerProShouldStartWithPPRO` | `"PowerPRO serial numbers should start with 'PPRO'."` | PowerPRO validation |
|
||||
| `AutoDetectDas_SIMShouldStartWithSPS` | `"SLICE PRO SIM serial numbers should start with 'SPS'."` | SIM device validation |
|
||||
| `AutoDetectDAS_SLDShouldStartWithSLD` | `"SLICE PRO Lab DIM serial numbers should start with 'SLD'."` | Lab DIM validation |
|
||||
| `AutoDetectDAS_SliceECM` | `"SLICE PRO Ethernet Control Module serial numbers should start with 'SPE'."` | ECM validation |
|
||||
| `AutoDetectDas_SliceG5ShouldStartWithSG5` | `"SLICE G5 serial numbers should start with 'SG5'."` | SLICE G5 validation |
|
||||
| `AutoDetectDAS_SliceLabEthernetShouldStartWithSLE` | `"SLICE Lab Ethernet serial numbers should start with 'SLE'."` | Lab Ethernet validation |
|
||||
| `AutoDetectDas_SLICENanoShouldStartWithBA5` | `"SLICE NANO serial numbers should start with 'BA5'."` | Standard NANO validation |
|
||||
| `AutoDetectDAS_SLICEPRODBShouldStartWithSPDB` | `"SLICE PRO Distributor serial numbers should start with 'SPDB'."` | PRO Distributor validation |
|
||||
| `AutoDetectDas_SliceSPM` | `"SLICE Mini Distributor serial numbers should start with 'SPM'."` | Mini Distributor validation |
|
||||
| `AutoDetectDAS_SLSShouldStartWithSLS` | `"SLICE PRO Lab SIM serial numbers should start with 'SLS'."` | Lab SIM validation |
|
||||
| `AutoDetectDAS_SLTShouldStartWithSLT` | `"SLICE PRO Lab TOM serial numbers should start with 'SLT'."` | Lab TOM validation |
|
||||
| `AutoDetectDAS_TDASLabRackShouldStartWith` | `"TDAS PRO lab rack serial numbers should start with 'LR'."` | Lab rack validation |
|
||||
| `AutoDetectDas_TDASRackShouldStartWith` | `"TDAS PRO rack serial numbers should start with 'DR'."` | Rack validation |
|
||||
| `AutoDetectDas_TOMShouldStartWithSPT` | `"SLICE PRO TOM serial numbers should start with 'SPT'."` | TOM validation |
|
||||
| `AutoDetectDas_TSRAIRShouldStartWithTA` | `"TSR AIR serial numbers should start with 'TA'."` | TSR AIR validation |
|
||||
| `AutoDetectDas_SLICE6AIRBRShouldStartWith` | `"SLICE 6 AIR-BR serial numbers should start with 'S6BR'."` | SLICE 6 AIR-BR validation |
|
||||
| `AutoDetectDas_SLICE6AIRShouldStartWith` | `"SLICE 6 AIR serial numbers should start with 'S6A'."` | SLICE 6 AIR validation |
|
||||
| `AutoDetectDas_SLICE6DB3ShouldStartWith` | `"SLICE 6 distributor 3 serial numbers should start with S6DB3."` | SLICE 6 DB3 validation |
|
||||
| `AutoDetectDas_Slice6DBShouldStartWithS6DB` | `"SLICE 6 distributor serial numbers should start with 'S6DB'."` | SLICE 6 Distributor validation |
|
||||
| `AutoDetectDas_SLICE6ShouldStartWith` | `"SLICE 6 serial numbers should start with 'SL6'."` | SLICE 6 validation |
|
||||
| `AutoDetectDas_SliceDBShouldStartWithSDB` | `"SLICE distributor serial numbers should start with 'SD'."` | Distributor validation |
|
||||
| `AutoDetectDas_TypeShouldStartWithPrepend` | `"{0} serial numbers should start with '{1}'."` | Generic template for prefix validation messages (e.g., `string.Format(..., "SLICE PRO", "SPD")`) |
|
||||
|
||||
### Device Type Identification Messages
|
||||
These properties return messages indicating which device type a given serial number was detected as:
|
||||
|
||||
| Property Name | Example Message Content | Purpose |
|
||||
|---------------|-------------------------|---------|
|
||||
| `AutoDetectDAS_SerialNumberBelongsToAG5` | `"Serial number belongs to a TDAS G5."` | TDAS G5 detection |
|
||||
| `AutoDetectDAS_SerialNumberBelongsToAMicro` | `"Serial number belongs to a SLICE MICRO."` | SLICE MICRO detection |
|
||||
| `AutoDetectDas_SerialNumberBelongsToANano` | `"Serial number belongs to a SLICE NANO."` | SLICE NANO detection |
|
||||
| `AutoDetectDAS_SerialNumberBelongsToAPowerPRO` | `"Serial number belongs to a PowerPRO Battery."` | PowerPRO detection |
|
||||
| `AutoDetectDas_SerialNumberBelongsToASLICEG5` | `"Serial number belongs to a SLICE G5."` | SLICE G5 detection |
|
||||
| `AutoDetectDAS_SerialNumberBelongsToASLICEPROLabSIM` | `"Serial number belongs to a SLICE PRO Lab SIM."` | Lab SIM detection |
|
||||
| `AutoDetectDAS_SerialNumberBelongsToASlicePROLabSLE` | `"Serial number belongs to a SLICE Lab Ethernet."` | Lab Ethernet detection |
|
||||
| `AutoDetectDas_SerialNumberBelongsToASLICEProSim` | `"Serial number belongs to a SLICE PRO SIM."` | PRO SIM detection |
|
||||
| `AutoDetectDAS_SerialNumberBelongsToATDASLabRack` | `"Serial number belongs to a TDAS PRO Lab rack."` | Lab rack detection |
|
||||
| `AutoDetectDas_SerialNumberBelongsToATDASRack` | `"Serial number belongs to a TDAS PRO rack."` | Rack detection |
|
||||
| `AutoDetectDAS_SLICE_SerialNumberBelongsToASLICELABDIM` | `"Serial number belongs to a SLICE PRO Lab DIM."` | Lab DIM detection |
|
||||
| `AutoDetectDAS_SLICE_SerialNumberBelongsToASLICELABTOM` | `"Serial number belongs to a SLICE PRO Lab TOM."` | Lab TOM detection |
|
||||
| `AutoDetectDas_SLICE_SerialNumberBelongsToASLICEProDIM` | `"Serial number belongs to a SLICE PRO DIM."` | PRO DIM detection |
|
||||
|
||||
### Required Field Validation Messages
|
||||
|
||||
| Property Name | Example Message Content | Purpose |
|
||||
|---------------|-------------------------|---------|
|
||||
| `AutoDetectDAS_IPAddressRequired` | `"IP address required."` | IP address field validation |
|
||||
| `AutoDetectDAS_SerialNumberRequired` | `"Serial number required."` | Serial number field validation |
|
||||
|
||||
### Commit/Validation Failure Messages for Metadata Entities
|
||||
|
||||
| Property Name | Example Message Content | Purpose |
|
||||
|---------------|-------------------------|---------|
|
||||
| `CustomerDetails_FailedToCommit` | `"Failed to commit CustomerDetails."` | Error for saving customer metadata |
|
||||
| `CustomerDetails_NullReferenceName` | `"CustomerDetail: Required name is null."` | Null-name validation for customer |
|
||||
| `LabDetails_FailedToCommit` | `"Failed to commit LabDetails."` | Error for saving lab metadata |
|
||||
| `LabDetails_NullReferenceName` | `"LabDetail: Required name is null."` | Null-name validation for lab |
|
||||
| `TestEngineerDetails_FailedToCommit` | `"Failed to commit TestEngineerDetails."` | Error for saving test engineer metadata |
|
||||
| `TestEngineerDetails_NullReferenceName` | `"TestEngineerDetail: Required name is null."` | Null-name validation for test engineer |
|
||||
|
||||
> **Note**: All message properties are read-only; they only expose string values via `ResourceManager.GetString(...)`. No methods or constructors are public.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Thread-safety**: The `ResourceManager` instance is lazily initialized and stored in a static field. While the getter checks for `null`, there is no explicit locking—reliance is on .NET’s `ResourceManager` thread-safety guarantees (which are documented as safe for concurrent reads, but not guaranteed for concurrent *initialization* in older frameworks; however, the code uses `object.ReferenceEquals` and does not reassign after initialization, so it is effectively safe for read-only use).
|
||||
- **Localization scope**: All strings are retrieved using the current `Culture` (if set) or the current UI culture. No fallback logic is implemented in this class—it delegates entirely to `ResourceManager`.
|
||||
- **No mutation**: The class itself is immutable at runtime. String values are retrieved on-demand from the underlying resource store and not cached per-property (only the `ResourceManager` is cached).
|
||||
- **Auto-generation constraint**: As indicated by the `<auto-generated>` header, manual edits to this file will be overwritten. All string keys and properties are derived from the corresponding `.resx` file.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### This module depends on:
|
||||
- `System.Resources.ResourceManager` (mscorlib)
|
||||
- `System.Globalization.CultureInfo` (mscorlib)
|
||||
- `System.CodeDom.Compiler`, `System.Diagnostics`, `System.Runtime.CompilerServices`, `System.ComponentModel` (various core assemblies)
|
||||
|
||||
### This module is depended upon by:
|
||||
- Any code in the `ISO` namespace (or referencing this assembly) that needs localized strings—especially UI layers (e.g., WPF/WinForms), validation logic, or device detection routines.
|
||||
- Likely consumers include:
|
||||
- Device auto-detection modules (e.g., `AutoDetectDAS` logic)
|
||||
- Forms or view models that display error messages (e.g., `CustomerDetails`, `LabDetails`, `TestEngineerDetails` classes)
|
||||
- Validation utilities that check serial number prefixes or required fields
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **No runtime error handling**: If a resource key is missing from the `.resx` file, `ResourceManager.GetString(...)` returns `null`. Callers must handle or guard against null returns (not visible in this file).
|
||||
- **Culture override is global**: Setting `StringResources.Culture` affects *all* subsequent lookups in the AppDomain via this class—potentially causing race conditions in multi-threaded UI scenarios if not synchronized.
|
||||
- **Hardcoded key names**: The property names (e.g., `AutoDetectDas_DIMShouldStartWithSPD`) are tightly coupled to the `.resx` key names. Renaming keys in the `.resx` without regenerating this file will break consumers.
|
||||
- **No localization for generic template**: While `AutoDetectDas_TypeShouldStartWithPrepend` is a format string (`"{0} serial numbers should start with '{1}'."`), callers must manually apply `string.Format`—the class does not provide a helper method for this.
|
||||
- **No documentation of `.resx` file location or build process**: The source `.resx` file(s) are not included here, so the full set of keys and their current values (beyond what’s exposed in properties) cannot be verified from this file alone.
|
||||
|
||||
None identified beyond the above.
|
||||
141
enriched-qwen3-coder-next/Common/DTS.Common.Import.md
Normal file
141
enriched-qwen3-coder-next/Common/DTS.Common.Import.md
Normal file
@@ -0,0 +1,141 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Import/ImportError.cs
|
||||
- Common/DTS.Common.Import/ParseProcessor.cs
|
||||
- Common/DTS.Common.Import/TsetSetupImportSensorInfo.cs
|
||||
- Common/DTS.Common.Import/CsvUtil.cs
|
||||
- Common/DTS.Common.Import/ImportNotification.cs
|
||||
- Common/DTS.Common.Import/XMLParseProcessor.cs
|
||||
- Common/DTS.Common.Import/CalibrationImport.cs
|
||||
- Common/DTS.Common.Import/GroupHelper.cs
|
||||
- Common/DTS.Common.Import/ImportObject.cs
|
||||
generated_at: "2026-04-16T14:08:49.625344+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "e94d77a26e8f0798"
|
||||
---
|
||||
|
||||
# Module Documentation: DTS.Common.Import
|
||||
|
||||
## 1. Purpose
|
||||
The `DTS.Common.Import` namespace provides the infrastructure for parsing and importing test configuration data (sensors, calibrations, test setups, hardware) from external files (CSV, XML) into the application's internal object model. It defines a centralized data container (`ImportObject`), processors for handling file parsing workflows (`ParseProcessor`, `XMLParseProcessor`), and various utility classes for data transformation and error reporting during the import process.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Classes
|
||||
|
||||
#### `ImportObject`
|
||||
The central state container for an import operation. It holds all imported entities and lookup mappings.
|
||||
* **Properties**:
|
||||
* `ImportFormats SourceFormat`: Gets or sets the format of the source file.
|
||||
* `ImportFileFormat TestSetupImportFileFormat`: Gets or sets the file format type (Single, Multiple, No Test Setup).
|
||||
* **Methods**:
|
||||
* `IEnumerable<ImportError> Errors()`: Returns the list of import errors.
|
||||
* `void AddError(ImportError d)`, `void AddErrors(IEnumerable<ImportError> d)`: Appends errors to the collection.
|
||||
* `void ClearErrors()`: Clears the error list.
|
||||
* `void ClearSensors()`: Clears the sensor list.
|
||||
* `void ClearTestSetups()`: Clears the test setup list.
|
||||
* `ImportFileFormat GetImportFileFormat()`: Determines the file format based on the count of test setups.
|
||||
* **Add/Get methods for collections**: `Sensors`, `Calibrations`, `TestSetups`, `Groups`, `GroupTemplates`, `Hardware`, `Users`, `CustomerDetails`, `LabDetails`, `TestEngineerDetails`, `CustomChannels`, `PhysicalDimensions`, `Positions`, `Directions`, `FilterClasses`, `MainLocations`, `FineLoc1s/2s/3s`, `TestObjects`, `SensorModels`, `StaticGroups`.
|
||||
* Pattern: `void Add[Entity](T item)`, `void Add[Entity]List(IEnumerable list)`, `IEnumerable Get[Entity]()`.
|
||||
* **Lookup Management**:
|
||||
* `void AssignSensorLookup(Dictionary<string, SensorData> sensorLookup)`
|
||||
* `void AssignCalibrationLookup(Dictionary<string, List<SensorCalibration>> calibrationLookup)`
|
||||
* `void AssignSensorGroupNameLookup(Dictionary<string, string> sensorGroupNameLookup)`
|
||||
* `void AssignOldSensorDatabaseIdToNew(Dictionary<int, int> oldSensorDatabaseIdToNew)`
|
||||
* Corresponding `Add...` and `Get...` methods for these lookups.
|
||||
* `IReadOnlyDictionary<int, ISensorData> GetSensorLookup()`: Constructs a lookup dictionary keyed by `DatabaseId` from the current sensors list.
|
||||
|
||||
#### `ParseProcessor`
|
||||
Orchestrates parsing using a list of file names and `IParseVariant` implementations.
|
||||
* **Constructor**: `ParseProcessor(ImportObject importObject, IEnumerable<string> fileNames, IEnumerable<IParseVariant> parseVariants)`
|
||||
* **Methods**:
|
||||
* `ImportObject Process()`: Iterates through `_fileNames` and `_parseVariants`, executing `variant.Parse(ref _importObject)` for each.
|
||||
|
||||
#### `XMLParseProcessor`
|
||||
Orchestrates XML parsing with progress notification and cancellation support.
|
||||
* **Constructor**: `XMLParseProcessor(ImportObject importObject, IImportNotification importNotification, IEnumerable<string> fileNames, Func<bool> isCancelled, bool skipNormalizing)`
|
||||
* **Properties**:
|
||||
* `List<IUIItems> UIItems`: Gets or sets UI items used by the parser factory.
|
||||
* **Methods**:
|
||||
* `ImportObject Process()`: Iterates files, sets status, creates parsers via `XmlParserFactory`, executes parsing, and notifies progress.
|
||||
|
||||
#### `ImportNotification` & `IImportNotification`
|
||||
Provides callback delegates for reporting import status and progress.
|
||||
* **Interface `IImportNotification`**:
|
||||
* `Action ImportDone`
|
||||
* `Action<List<string>> ReportErrors`
|
||||
* `Action<double> SetProgress`
|
||||
* `Action<ImportStatus> SetStatus`
|
||||
* **Class `ImportNotification`**:
|
||||
* **Constructors**: Default (no-op delegates), Parameterized (accepts specific `Action` delegates).
|
||||
|
||||
#### `CalibrationImport`
|
||||
Implements `ICalibrationImport` to manipulate sensor calibration data.
|
||||
* **Methods**:
|
||||
* `SensorCalibration CheckForExcitationCalibration(SensorCalibration sc, double sensitivity, ExcitationVoltageOptions.ExcitationVoltageOption excitation, string EU)`: Adds a calibration record if the excitation differs from the first record.
|
||||
* `SensorCalibration AddLinearCalRecordIfNeeded(SensorCalibration sc, bool savedIsProportional, bool savedRemoveOffset)`: Adds a linear calibration record if only one record exists.
|
||||
* `SensorCalibration AddLinearZeroMethodIfNeeded(SensorCalibration sc, ZeroMethodType zeroMethodType, double zeroMethodStart, double zeroMethodEnd)`: Adds a zero method if only one exists.
|
||||
|
||||
#### `CsvUtil`
|
||||
Static utility for CSV file handling.
|
||||
* **Methods**:
|
||||
* `static CsvReader CreateCsvReader(string filename)`: Creates a `CsvReader` using `CultureInfo.InvariantCulture`.
|
||||
* `static List<string> ReadFields(CsvReader csvReader, bool readNextLine = true)`: Reads fields from the current/next line into a trimmed string list.
|
||||
|
||||
#### `GroupHelper`
|
||||
Static utility methods for group and sensor data manipulation during import.
|
||||
* **Methods**:
|
||||
* `static IGroup CreateEmptyGroup()`: Returns a new `GroupList.Model.Group`.
|
||||
* `static void GetTestSensorParameters(...)`: Resolves sensor parameters (ISO code, channel names, etc.) using `ParseParameters` overrides.
|
||||
* `static IReadOnlyDictionary<string, int> GetDAS(...)`: Maps DAS serial numbers to DAS IDs.
|
||||
* `static List<SensorData> CleanUneededSensorDataPlaceHolder(...)`: Removes sensors with specific prefixes or invalid calibrations.
|
||||
* `static List<SensorData> NormalizeSensorIds(List<SensorData> sensorList)`: Assigns temporary negative IDs to new sensors or existing DB IDs.
|
||||
|
||||
#### `ImportError`
|
||||
Represents a single error or warning during import.
|
||||
* **Properties**:
|
||||
* `string Message`
|
||||
* `ImportSeverityError Severity`
|
||||
* `bool ContinueImportOnError` (default: `true`)
|
||||
|
||||
#### `ImportStatus`
|
||||
Represents the current status of the import operation.
|
||||
* **Properties**: `string Status`, `PossibleStatus PossibleStatus`, `ImportExtraStatus ExtraStatus`.
|
||||
|
||||
#### `TsetSetupImportSensorInfo`
|
||||
Sealed class holding sensor mapping details for test setup imports.
|
||||
* **Constructors**: Accepts full details or partial (serial number, ISO code).
|
||||
* **Properties**: `SerialNumber`, `IsoCode`, `IsoChannelName`, `UserCode`, `UserChannelName`, `DASSerialNumber`, `DASChannelIndex`, `GroupType`.
|
||||
|
||||
### Enums
|
||||
* `ImportSeverityError`: `Critical`, `Error`, `Warning`, `Info`.
|
||||
|
||||
## 3. Invariants
|
||||
* **ImportError Defaults**: By default, `ImportError.ContinueImportOnError` is `true`.
|
||||
* **ID Normalization**: In `GroupHelper.NormalizeSensorIds`, new sensors (not found in `SensorsCollection`) are assigned temporary negative IDs starting at -2 (-1 is reserved for "no sensor").
|
||||
* **Progress Calculation**: In `XMLParseProcessor`, progress is calculated as a ratio of total imported items (Calibrations + Sensors + Groups, etc.) to `itemsToComplete`. Progress is capped at 1.0.
|
||||
* **CSV Reading**: `CsvUtil.ReadFields` always trims whitespace from retrieved fields.
|
||||
* **ImportObject References**: `ParseProcessor` and `XMLParseProcessor` pass `ImportObject` by reference (`ref`) to `IParseVariant.Parse`, suggesting the object instance itself might be swapped or modified in place by parsers.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Internal Dependencies
|
||||
* `DTS.Common.Import.Interfaces`: Used by `ParseProcessor` and `GroupHelper` (`IParseVariant`, `ParseParameters`).
|
||||
* `DTS.Common.Import.Enums`: Used by `ImportNotification` and `XMLParseProcessor` (`PossibleStatus`, `ImportExtraStatus`).
|
||||
* `DTS.Common.Utils`: Used by `XMLParseProcessor` (specifically `XmlParserFactory` and `XMLUtils`).
|
||||
* `DTS.Common.Classes.Sensors`: Used for `SensorCalibration`, `CalibrationRecord`, `ZeroMethod`.
|
||||
* `DTS.Common.Enums`: Used for `ExcitationVoltageOptions`, `ZeroMethodType`.
|
||||
* `DTS.Common.Interface.Sensors`: Used for `ISensorData`, `ICalibrationRecord`.
|
||||
* `DTS.SensorDB`: Used for `SensorData`, `DASHardware`, `SensorsCollection`, `SensorCalibrationList`.
|
||||
* `DataPROWin7.DataModel`: Used for `TestTemplate`, `TestObject`, `TestObjectTemplate`.
|
||||
* `DTS.Slice.Users`: Used for `User` class.
|
||||
* `DTS.Common.ISO`: Used for `CustomerDetails`, `TestEngineerDetails`, `LabratoryDetails`.
|
||||
|
||||
### External Dependencies
|
||||
* `CsvHelper`: Used in `CsvUtil` for CSV parsing.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
* **Potential Bug in `ImportObject.AssignSensorModelLookup`**: The method accepts a `Dictionary<string, List<SensorCalibration>>` argument named `calibrationLookup` but ignores it completely, initializing `_sensorModelLookup` to an empty dictionary instead. This appears to be a copy-paste error.
|
||||
* **Silent Failures in `ImportObject.GetSensorLookup`**: If duplicate sensors (same `DatabaseId`) are found, the method writes to `System.Diagnostics.Trace.WriteLine` rather than throwing an
|
||||
@@ -0,0 +1,156 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Import/DatabaseLocks/LockImportGroups.cs
|
||||
- Common/DTS.Common.Import/DatabaseLocks/LockImportTestSetups.cs
|
||||
- Common/DTS.Common.Import/DatabaseLocks/LockImportSensors.cs
|
||||
generated_at: "2026-04-16T02:06:50.106613+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "95ed39e21f5416a3"
|
||||
---
|
||||
|
||||
# Documentation: Database Locking for Import Operations
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides database-level locking for import operations on three distinct entity types—**Groups**, **Test Setups**, and **Sensors**—to prevent concurrent modifications during data import workflows. Each class (`LockImportGroups`, `LockImportTestSetups`, `LockImportSensors`) implements the `ILockImport` interface and encapsulates logic to acquire, release, and (if authorized) steal locks on the respective entities. Locks are managed via the shared `LockManager` utility, with support for detecting and reclaiming *stranded locks* (i.e., locks held longer than a configurable timeout) and handling contention by requiring explicit admin consent. These classes exist to ensure data integrity and consistency during import processes that modify critical system resources.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
All three classes implement the same interface `ILockImport`, with identical method signatures and semantics. Below are the concrete implementations per class.
|
||||
|
||||
### `LockImportGroups`
|
||||
|
||||
- **Constructor**:
|
||||
`LockImportGroups(User currentUser, double strandedLockTimeoutMinutes)`
|
||||
Initializes the instance with the current user and timeout (in minutes) after which a lock is considered stranded.
|
||||
|
||||
- **`bool Contended { get; }`**
|
||||
Returns `true` if any group lock acquisition failed due to contention (i.e., another user holds the lock and it is not expired or owned by the current user).
|
||||
|
||||
- **`void FreeLock(ref ImportObject importObject)`**
|
||||
Releases all locks currently held by this instance (stored in `_lockedGroups`). Iterates over `_lockedGroups` and calls `LockManager.FreeLock(...)` for each. No-op if `_lockedGroups` is empty.
|
||||
|
||||
- **`void SetLock(ref ImportObject importObject, ref StringBuilder message)`**
|
||||
Attempts to acquire locks for all groups returned by `importObject.StaticGroups()`.
|
||||
- Clears `_lockedGroups` and `_contendedGroups` first.
|
||||
- For each group:
|
||||
- Calls `LockManager.LockItem(...)` with category `LockManager.ItemCategories.Group`.
|
||||
- On failure:
|
||||
- Skips if `lockError.ErrorCode == LockError.ITEM_NOT_FOUND`.
|
||||
- Otherwise, checks if lock is expired (`LastUpdated + timeout < Now`) or owned by current user/machine. If so, frees and re-acquires the lock, adding to `_lockedGroups`.
|
||||
- Else, adds the existing lock record to `_contendedGroups`.
|
||||
- On success, adds lock record to `_lockedGroups`.
|
||||
- If any locks are contended, appends a user-facing message listing each contended group (key, owner, machine) using `StringResources.ImportTestSetup_GroupsLocked`.
|
||||
|
||||
- **`bool StealLock(bool proceed)`**
|
||||
Attempts to steal contended locks (only if `proceed == true` and `_currentUser.IsAdmin == true`).
|
||||
- Returns `true` if no contention or if stealing succeeded.
|
||||
- Returns `false` if user is not admin or `proceed` is `false`.
|
||||
- For each contended group:
|
||||
- Calls `LockManager.FreeLock(...)` to release the existing lock.
|
||||
- Calls `LockManager.LockItem(...)` again (note: category incorrectly set to `LockManager.ItemCategories.Sensor`—see *Gotchas*).
|
||||
- Adds the new lock record to `_lockedGroups`.
|
||||
|
||||
### `LockImportTestSetups`
|
||||
|
||||
- **Constructor**:
|
||||
`LockImportTestSetups(User currentUser, double strandedLockTimeoutMinutes)`
|
||||
Same semantics as `LockImportGroups`.
|
||||
|
||||
- **`bool Contended { get; }`**
|
||||
Same semantics.
|
||||
|
||||
- **`void FreeLock(ref ImportObject importObject)`**
|
||||
Releases locks in `_lockedTests` via `LockManager.FreeLock(...)`.
|
||||
|
||||
- **`void SetLock(ref ImportObject importObject, ref StringBuilder message)`**
|
||||
Attempts to lock all test setups returned by `importObject.TestSetups()`, using category `LockManager.ItemCategories.TestSetup`.
|
||||
- On contention, appends message using `StringResources.ImportTestSetup_TestsLocked`.
|
||||
|
||||
- **`bool StealLock(bool proceed)`**
|
||||
Same logic as `LockImportGroups.StealLock(...)`, but operates on `_contendedTests` and `_lockedTests`.
|
||||
|
||||
### `LockImportSensors`
|
||||
|
||||
- **Constructor**:
|
||||
`LockImportSensors(User currentUser, double strandedLockTimeoutMinutes)`
|
||||
Same semantics.
|
||||
|
||||
- **`bool Contended { get; }`**
|
||||
Same semantics.
|
||||
|
||||
- **`void FreeLock(ref ImportObject importObject)`**
|
||||
Releases locks in `_lockedSensors` via `LockManager.FreeLock(...)`.
|
||||
|
||||
- **`void SetLock(ref ImportObject importObject, ref StringBuilder message)`**
|
||||
Attempts to lock all sensors referenced in `importObject.Sensors()`.
|
||||
- Pre-builds a `sensorLookup` from `SensorsCollection.SensorsList.GetAllSensors(true)` keyed by `SerialNumber`.
|
||||
- Skips sensors not in the lookup.
|
||||
- Uses category `LockManager.ItemCategories.Sensor`.
|
||||
- On contention, appends message using `StringResources.ImportTestSetup_TestsLocked` *(note: same string as test setups—see *Gotchas*)*.
|
||||
|
||||
- **`bool StealLock(bool proceed)`**
|
||||
Same logic as others, but operates on `_contendedSensors` and `_lockedSensors`.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Lock ownership and expiration**:
|
||||
A lock is considered reclaimable if either:
|
||||
- `existingLock.LastUpdated.AddMinutes(_strandedLockTimeoutMinutes) < DateTime.Now`, *or*
|
||||
- `existingLock.LockingUserName == _currentUser.UserName && existingLock.LockingMachineName == Environment.MachineName`.
|
||||
|
||||
- **Lock state separation**:
|
||||
After `SetLock(...)` completes, `_lockedGroups`/`_lockedTests`/`_lockedSensors` contains *only* locks successfully acquired (including re-claimed ones), and `_contendedGroups`/`_contendedTests`/`_contendedSensors` contains *only* locks that could not be acquired due to active contention.
|
||||
|
||||
- **`Contended` property**:
|
||||
Always reflects whether `_contended*` list is non-empty *after* the last `SetLock(...)` call.
|
||||
|
||||
- **Admin requirement for stealing**:
|
||||
`StealLock(...)` returns `false` unless `_currentUser.IsAdmin == true` *and* `proceed == true`.
|
||||
|
||||
- **No double-locking**:
|
||||
`SetLock(...)` clears the internal lists before processing, ensuring no stale lock records persist across calls.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### External Dependencies
|
||||
- **`DTS.Common.Classes.Locking.LockManager`**: Central lock manager used for `LockItem`, `FreeLock`. Defines `LockError`, `LockRecord`, and `ItemCategories`.
|
||||
- **`DTS.Slice.Users.User`**: Represents the current user; accessed for `UserName`, `Id`, and `IsAdmin`.
|
||||
- **`DTS.Common.Storage.LockManager`**: Used in `LockImportSensors` to access `SensorsCollection.SensorsList.GetAllSensors(...)`.
|
||||
- **`DTS.Common.SharedResource.Strings.StringResources`**: Provides localized messages (e.g., `ImportTestSetup_GroupsLocked`, `ImportTestSetup_TestsLocked`).
|
||||
- **`DTS.Common.Utilities.Logging.APILogger`**: Used to log exceptions during lock operations.
|
||||
|
||||
### Interface Dependencies
|
||||
- **`ILockImport`**: All three classes implement this interface (not shown in source, but implied by usage and naming). Signature must include `SetLock`, `FreeLock`, `StealLock`, and `Contended`.
|
||||
|
||||
### Depended Upon
|
||||
- These classes are likely used by higher-level import orchestrators (e.g., `ImportService`, `ImportWizard`) that coordinate import workflows and handle user prompts for lock stealing.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Incorrect category in `StealLock` for Groups**:
|
||||
In `LockImportGroups.StealLock(...)`, the re-lock call uses `LockManager.ItemCategories.Sensor` instead of `LockManager.ItemCategories.Group`. This is inconsistent with the initial lock and may cause lock metadata corruption or misattribution.
|
||||
|
||||
- **Incorrect resource string for sensor contention messages**:
|
||||
In `LockImportSensors.SetLock(...)`, the message appended on contention uses `StringResources.ImportTestSetup_TestsLocked` (same as test setups), not a sensor-specific string. This may mislead users.
|
||||
|
||||
- **No validation of `ImportObject` contents**:
|
||||
The classes assume `importObject.StaticGroups()`, `TestSetups()`, and `Sensors()` return valid collections. No null/empty checks are performed on the collections themselves.
|
||||
|
||||
- **Exception swallowing in `SetLock`**:
|
||||
All exceptions during lock acquisition are caught and logged via `APILogger.Log(ex)`, but the method continues silently. This may hide critical failures (e.g., database connectivity issues) and leave the system in an inconsistent state (e.g., partial locking).
|
||||
|
||||
- **Race condition in lock stealing**:
|
||||
Between `FreeLock` and `LockItem` in `StealLock(...)`, another user could acquire the lock. The code does not re-check lock ownership before re-locking.
|
||||
|
||||
- **Ambiguity in `ImportObject` interface**:
|
||||
The source does not define `ImportObject` or its methods (`StaticGroups`, `TestSetups`, `Sensors`). Their behavior (e.g., ordering, nullability) is unknown.
|
||||
|
||||
- **No rollback on partial failure**:
|
||||
If `SetLock(...)` fails partway through (e.g., due to an exception), already-locked items are *not* released. Only `FreeLock(...)` (called later) cleans up.
|
||||
|
||||
- **Machine name dependency**:
|
||||
Lock ownership check uses `Environment.MachineName`, which may be unreliable in containerized/distributed environments or if machine names change.
|
||||
|
||||
None identified beyond the above.
|
||||
110
enriched-qwen3-coder-next/Common/DTS.Common.Import/Factories.md
Normal file
110
enriched-qwen3-coder-next/Common/DTS.Common.Import/Factories.md
Normal file
@@ -0,0 +1,110 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Import/Factories/CSVTestParserFactory.cs
|
||||
- Common/DTS.Common.Import/Factories/DatabaseLocksFactory.cs
|
||||
- Common/DTS.Common.Import/Factories/CSVSensorParserFactory.cs
|
||||
- Common/DTS.Common.Import/Factories/SaveVariantFactory.cs
|
||||
- Common/DTS.Common.Import/Factories/XmlParserFactory.cs
|
||||
generated_at: "2026-04-16T02:07:25.656251+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "23d838f43f91b04f"
|
||||
---
|
||||
|
||||
# Import Factories Module Documentation
|
||||
|
||||
## 1. Purpose
|
||||
This module provides factory classes responsible for constructing and configuring domain-specific parsers and persistence handlers used during data import operations. It centralizes the logic for instantiating versioned CSV and XML parsers (for tests, sensors), database lock objects, and save handlers for various import entities (e.g., sensors, groups, test setups). Its role is to decouple object creation from consumption, enabling version-aware and context-aware instantiation of import components based on input data format, version, and configuration options.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `CSVTestParserFactory.CreateCSVParsers()`
|
||||
**Signature:** `public static IParseCSVTest[] CreateCSVParsers()`
|
||||
**Behavior:** Returns an array of versioned CSV test parsers (`Version0CSVTestParser`, `Version5CSVTestParser`, `Version6CSVTestParser`) implementing `IParseCSVTest`. Parsers are returned in version order (v0, v5, v6). No initialization parameters are required.
|
||||
|
||||
### `DatabaseLocksFactory.Create(ImportObject, User, double)`
|
||||
**Signature:** `public static List<ILockImport> Create(ImportObject importObject, User user, double strandedLockTimeoutMinutes)`
|
||||
**Behavior:** Returns a list of database lock objects implementing `ILockImport`, conditionally instantiated based on the presence of data in the `ImportObject`. Lock types created include:
|
||||
- `LockImportTestSetups` (if `importObject.TestSetups()` is non-empty)
|
||||
- `LockImportSensors` (if `importObject.Sensors()` is non-empty)
|
||||
- `LockImportGroups` (if `importObject.StaticGroups()` is non-empty)
|
||||
Each lock is initialized with the provided `user` and `strandedLockTimeoutMinutes`.
|
||||
|
||||
### `CSVSensorParserFactory.CreateCSVParsers(...)`
|
||||
**Signature:**
|
||||
```csharp
|
||||
public static IReadOnlyDictionary<int, IParseCSVSensor> CreateCSVParsers(
|
||||
ICalibrationImport import,
|
||||
ZeroMethodOptions zmOptions,
|
||||
IImportNotification importNotification,
|
||||
bool importCreateDynamicGroups,
|
||||
bool useISOCodeFilterMapping,
|
||||
bool useZeroForUnfiltered)
|
||||
```
|
||||
**Behavior:** Returns a dictionary mapping parser version numbers (int) to initialized `IParseCSVSensor` implementations (`Version0CSVSensorParser`, `Version2CSVSensorParser`, `Version3CSVSensorParser`, `Version4CSVSensorParser`). Each parser is initialized via its `Initialize(...)` method with the provided parameters. Keys are the parsers’ `Version` property values.
|
||||
|
||||
### `SaveVariantFactory.CreateVariants(...)`
|
||||
**Signature:**
|
||||
```csharp
|
||||
public static List<IPersistImport> CreateVariants(
|
||||
ImportObject importObject,
|
||||
ImportNotification importNotification,
|
||||
User user,
|
||||
Func<bool> isCanceled,
|
||||
bool showCheckoutButton)
|
||||
```
|
||||
**Behavior:** Returns a list of `IPersistImport` implementations (save handlers) for various import entities, conditionally instantiated based on content in `importObject`. Includes:
|
||||
- `SaveCustomerDetails`, `SaveTestEngineerDetails`, `SaveLabDetails`, `SaveSensorModels`, `SaveUsers`, `SaveGlobalSettings`
|
||||
- `SaveCsvSourceSensor` or `SaveNonCsvSourceSensor` (based on `importObject.SourceFormat == ImportFormats.DTS_CSV`)
|
||||
- `SaveHardware`, `SaveGroupTemplates`, `SaveGroups`, `SaveCustomChannels`
|
||||
- `SaveTestSetup` and optionally `SaveCheckoutTestSetup` (if `importObject.TestSetups()` is non-empty and `showCheckoutButton` is true)
|
||||
The `SaveTestSetup` name is modified by appending `Serialization.RDF.File.SUFFIX_RUNTEST`. If `showCheckoutButton` is true, a second `SaveCheckoutTestSetup` is created with `SUFFIX_CHECKOUT`. All handlers receive `isCanceled` and `importNotification`, and some receive `user` or other dependencies (e.g., `saveHardware`, `saveGroups`). A shared `PersistCalculator` instance is used to track progress totals.
|
||||
|
||||
### `XmlParserFactory.CreateXMLParsers(...)`
|
||||
**Signature:**
|
||||
```csharp
|
||||
public static IEnumerable<IParseVariant> CreateXMLParsers(
|
||||
string fileName,
|
||||
IImportNotification importNotification,
|
||||
Func<bool> isCanceled,
|
||||
bool skipNormalizing)
|
||||
```
|
||||
**Behavior:** Returns an enumeration of `IParseVariant` implementations based on the XML file version (determined via `FileUtils.GetImportXmlNode(...)`).
|
||||
- For versions **< `FileUtils.DataPRO20XmlVersion`**: Calls `LessThan20XMLVersion(...)`, wrapping parsers in pre-20-specific adapters (e.g., `XMLPre20ParseSensors`, `XMLPre20ParseCalibrations`).
|
||||
- For versions **≥ `FileUtils.DataPRO20XmlVersion`**: Calls `GreaterOrEqual20XMLVersion(...)`, using direct parsers (e.g., `XMLParseSensors`, `XMLParseCalibrations`).
|
||||
Supported `TopLevelFields` include: `CustomChannels`, `CustomMainLocs`, `DASList`, `Sensors`, `Calibrations`, `GroupTemplates`, `Groups`, `TestSetups`, `LabDetails`, `CustomerDetails`, `TestEngineerDetails`, `Users`.
|
||||
Parsers are initialized with `importNotification`, `isCanceled`, and version-specific parameters. Static properties `UIItems` and `ImportNotification` are set before parsing.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Parser versioning**: CSV parsers are versioned and returned in ascending order (e.g., v0, v5, v6 for tests; v0, v2, v3, v4 for sensors). XML parsers are selected based on a hard-coded version threshold (`FileUtils.DataPRO20XmlVersion`).
|
||||
- **Conditional instantiation**: All factories instantiate components only when corresponding data exists in `ImportObject` (e.g., `TestSetups().Any()`, `Sensors().Any()`), avoiding unnecessary object creation.
|
||||
- **Initialization consistency**: For `CSVSensorParserFactory`, all parsers are initialized with identical parameters and must be fully initialized before use (via `Initialize(...)`).
|
||||
- **Progress tracking**: `SaveVariantFactory` uses a shared `PersistCalculator` instance to accumulate total item counts across all save handlers.
|
||||
- **Checkout behavior**: `SaveCheckoutTestSetup` is created *only* if `showCheckoutButton` is true and `TestSetups()` is non-empty. The test setup name is modified using `Serialization.RDF.File.SUFFIX_RUNTEST`/`SUFFIX_CHECKOUT`.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### This module depends on:
|
||||
- `DTS.Common.Import.Interfaces` (`IParseCSVTest`, `IParseCSVSensor`, `ILockImport`, `IPersistImport`, `IParseVariant`, `IImportNotification`, `ICalibrationImport`)
|
||||
- `DTS.Slice.Users` (`User`)
|
||||
- `DTS.Common.Import.DatabaseLocks` (`LockImportTestSetups`, `LockImportSensors`, `LockImportGroups`)
|
||||
- `DTS.Common.Import.Parsers.CSV` (`Version0CSVTestParser`, `Version5CSVTestParser`, `Version6CSVTestParser`, `Version0CSVSensorParser`, `Version2CSVSensorParser`, `Version3CSVSensorParser`, `Version4CSVSensorParser`)
|
||||
- `DTS.Common.Import.Persist` (`SaveCustomerDetails`, `SaveTestEngineerDetails`, `SaveLabDetails`, `SaveSensorModels`, `SaveCsvSourceSensor`, `SaveNonCsvSourceSensor`, `SaveUsers`, `SaveGlobalSettings`, `SaveHardware`, `SaveGroupTemplates`, `SaveGroups`, `SaveCustomChannels`, `SaveTestSetup`, `SaveCheckoutTestSetup`, `PersistCalculator`)
|
||||
- `DTS.Common.Import.XML` (XML parser types, e.g., `XMLParseSensors`, `XMLPre20ParseSensors`)
|
||||
- `DTS.Common.Enums.DBExport` (`TopLevelFields`)
|
||||
- `DTS.Common.Utils` (`FileUtils`, `Serialization.RDF.File`)
|
||||
- `System.Xml` (`XmlElement`, `XmlDocument`)
|
||||
|
||||
### This module is depended upon by:
|
||||
- Import orchestration logic (e.g., `ImportService`, `ImportProcessor`) that consumes these factories to build import pipelines.
|
||||
*(Exact callers are not visible in the provided source but are implied by the factory pattern usage.)*
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Static state in `XmlParserFactory`**: The factory uses static properties (`UIItems`, `ImportNotification`) and a static field (`_isCancelled`) to pass context into parsers. This introduces thread-safety concerns if `CreateXMLParsers` is called concurrently.
|
||||
- **`SaveVariantFactory` mutates `SaveCsvSourceSensor`/`SaveNonCsvSourceSensor`**: The `CurrentUser` property is assigned *after* construction, not via constructor. Callers must ensure this is set before use.
|
||||
- **`SaveTestSetup.TestSetupName` modification**: The test setup name is modified *only* when `showCheckoutButton` is true, appending `SUFFIX_RUNTEST`. This behavior is tied to GM parse mode (per comment `//FB 38039`), but the condition is `showCheckoutButton`, not a dedicated flag.
|
||||
- **XML version threshold**: The version split (`< 20` vs `>= 20`) is based on `FileUtils.DataPRO20XmlVersion`, but the constant itself is not defined in the provided source—its value must be verified externally.
|
||||
- **`LessThan20XMLVersion` early exit**: Returns an empty list if `node == null || node.ChildNodes == null`, but does not log or signal an error. Callers must handle empty results gracefully.
|
||||
- **`SaveGroups` and `SaveTestSetup` dependencies**: `SaveGroups` and `SaveTestSetup` constructors require `saveHardware` and `saveGroups` (respectively) as parameters, but these are instantiated *after* their dependencies in the factory method. This implies the factory method must construct them in dependency order (e.g., `saveHardware` before `saveGroups`, `saveGroups` before `saveTestSetup`).
|
||||
@@ -0,0 +1,69 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Import/ImportOptions/EqxImportOptions.cs
|
||||
- Common/DTS.Common.Import/ImportOptions/CsvImportOptions.cs
|
||||
generated_at: "2026-04-16T02:06:34.717084+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "c231715b4e36a96d"
|
||||
---
|
||||
|
||||
# ImportOptions
|
||||
|
||||
## Documentation: Import Options Module
|
||||
|
||||
### 1. Purpose
|
||||
This module defines data structures for configuring import behavior in the DTS system, specifically for equipment (Eqx) and CSV-based sensor data ingestion. It centralizes user-controllable settings that dictate how imported data interacts with existing system state (e.g., overwriting sensors, importing sensor models) and how raw data files are interpreted (e.g., encoding, separators, cultural formatting, zeroing logic). The classes reside in the `DTS.Common.Import.ImportOptions` namespace and serve as configuration payloads passed to import pipelines.
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `EqxImportOptions`
|
||||
- **Namespace**: `DTS.Common.Import.ImportOptions`
|
||||
- **Properties**:
|
||||
- `bool OverwriteExistingSensors { get; set; } = true`
|
||||
Controls whether imported equipment sensor definitions should replace existing sensors with matching identifiers. Defaults to `true`.
|
||||
- `bool ImportSensorModels { get; set; } = true`
|
||||
Determines whether sensor model metadata (e.g., calibration curves, physical specs) should be imported alongside sensor instances. Defaults to `true`.
|
||||
|
||||
#### `CsvImportOptions`
|
||||
- **Namespace**: `DTS.Common.Import.ImportOptions`
|
||||
- **Properties**:
|
||||
- `string Encoding { get; set; }`
|
||||
Specifies the text encoding used in the CSV file (e.g., `"utf-8"`, `"iso-8859-1"`). No default is set; must be provided by caller if non-default encoding is required.
|
||||
- `string FieldSeparator { get; set; }`
|
||||
Defines the character(s) used to delimit fields in the CSV (e.g., `","`, `";"`, `"\t"`). No default is set; must be provided by caller.
|
||||
- `CultureInfo ImportCulture { get; set; }`
|
||||
Specifies the culture used to parse numeric values (e.g., decimal separators, date formats). No default is set; must be provided by caller.
|
||||
- `bool StripBackSlash { get; set; }`
|
||||
Indicates whether leading/trailing backslashes (`\`) should be removed from field values during parsing. No default is set; defaults to `false` (C# default for `bool`).
|
||||
|
||||
#### `ZeroMethodOptions`
|
||||
- **Namespace**: `DTS.Common.Import.ImportOptions`
|
||||
- **Properties**:
|
||||
- `ZeroMethodType ZeroMethodType { get; set; }`
|
||||
Specifies the algorithm used to compute a zero offset (e.g., `Average`, `Median`, `Manual`). Type is defined in `DTS.Common.Enums.Sensors`.
|
||||
- `double ZeroMethodStart { get; set; }`
|
||||
Start index or time offset (in seconds or samples, depending on context) for the region used to calculate the zero offset.
|
||||
- `double ZeroMethodEnd { get; set; }`
|
||||
End index or time offset for the zero-calculation region. Must be ≥ `ZeroMethodStart`.
|
||||
|
||||
### 3. Invariants
|
||||
- For `ZeroMethodOptions`: `ZeroMethodEnd ≥ ZeroMethodStart` must hold. Violation implies invalid configuration, though no runtime enforcement is visible in this file.
|
||||
- `CsvImportOptions` properties (`Encoding`, `FieldSeparator`, `ImportCulture`) are nullable reference types (no `= null!` or default initialization), implying they are *optional* but may be required by consumers.
|
||||
- `OverwriteExistingSensors` and `ImportSensorModels` in `EqxImportOptions` default to `true`; callers relying on default behavior will overwrite and import models unless explicitly disabled.
|
||||
- `StripBackSlash` defaults to `false` (C# default for `bool`), meaning backslash stripping is opt-in.
|
||||
|
||||
### 4. Dependencies
|
||||
- **Imports/References**:
|
||||
- `System` (core types, LINQ, `CultureInfo`)
|
||||
- `DTS.Common.Enums.Sensors` (for `ZeroMethodType` enum used in `ZeroMethodOptions`)
|
||||
- **Consumers**:
|
||||
- Import pipeline classes (e.g., `EqxImporter`, `CsvImporter`) in the `DTS.Common.Import` hierarchy are implied consumers, though not visible here.
|
||||
- UI or configuration layers that serialize/deserialize these options for user input.
|
||||
|
||||
### 5. Gotchas
|
||||
- **Missing validation**: No validation is performed in these classes (e.g., `ZeroMethodEnd ≥ ZeroMethodStart`, non-empty `FieldSeparator`). Consumers must enforce constraints.
|
||||
- **Ambiguous defaults**: `Encoding`, `FieldSeparator`, and `ImportCulture` in `CsvImportOptions` have no defaults. If left `null`, behavior depends on downstream parsing logic (e.g., `Encoding` may default to UTF-8 via `StreamReader`, but this is not guaranteed here).
|
||||
- **`ZeroMethodOptions` semantics**: The unit of `ZeroMethodStart`/`ZeroMethodEnd` (samples vs. seconds) is context-dependent and not encoded in the type. Consumers must interpret consistently.
|
||||
- **No inheritance or interfaces**: These are plain POCOs; no polymorphic behavior or shared base is defined.
|
||||
- **No XML comments**: Source lacks documentation comments; all descriptions are inferred from property names and types.
|
||||
@@ -0,0 +1,92 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Import/Interfaces/IPersistImport.cs
|
||||
- Common/DTS.Common.Import/Interfaces/IParseImport.cs
|
||||
- Common/DTS.Common.Import/Interfaces/IParseVariant.cs
|
||||
- Common/DTS.Common.Import/Interfaces/IParseCSVTest.cs
|
||||
- Common/DTS.Common.Import/Interfaces/IParseCSVSensor.cs
|
||||
- Common/DTS.Common.Import/Interfaces/ICalibrationImport.cs
|
||||
- Common/DTS.Common.Import/Interfaces/ILockImport.cs
|
||||
- Common/DTS.Common.Import/Interfaces/IGroupImport.cs
|
||||
generated_at: "2026-04-16T02:07:53.745184+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "4d7a3572ba82cd30"
|
||||
---
|
||||
|
||||
# Interfaces
|
||||
|
||||
## Documentation: `DTS.Common.Import` Module
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
This module provides a structured, interface-driven abstraction layer for importing and persisting test and sensor configuration data—specifically supporting CSV-based import workflows. It defines contracts for parsing raw import files into a canonical `ImportObject`, handling variant-specific parsing logic, managing calibration and group creation, and enforcing database-level locking during import operations. Its role is to decouple import *logic* (e.g., CSV parsing, calibration application, group assignment) from *implementation* (e.g., concrete CSV readers, database access), enabling versioned, testable, and maintainable import pipelines.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
| Interface | Method/Property | Signature | Behavior |
|
||||
|-----------|-----------------|-----------|----------|
|
||||
| **`IPersistImport`** | `Save` | `void Save();` | Persists the current state of the `ImportObject` (or associated data) to persistent storage (e.g., database). No parameters; no return value. |
|
||||
| **`IParseImport`** | `Parse` | `ImportObject Parse(IEnumerable<string> importFiles);` | Parses one or more import files (e.g., CSVs) and returns a fully populated `ImportObject`. Input is a collection of file paths/URIs. |
|
||||
| **`IParseVariant`** | `FileName` | `string FileName { get; set; }` | Gets or sets the name of the file this variant parser is responsible for. |
|
||||
| | `Parse` | `void Parse(ref ImportObject importObject);` | Modifies the provided `ImportObject` in-place using data specific to this variant (e.g., test setup, sensor metadata). |
|
||||
| **`IParseCSVTest`** | `Version` | `int Version { get; }` | Gets the version number this parser supports (e.g., for versioned CSV formats). |
|
||||
| | `ParseVersion` | `void ParseVersion(CsvReader csvReader, TestSetupImportData tsid);` | Parses version-specific test setup data from a `CsvReader` into the provided `TestSetupImportData` instance. |
|
||||
| **`IParseCSVSensor`** | `Version` | `int Version { get; }` | Gets the version number this sensor parser supports. |
|
||||
| | `Initialize` | `void Initialize(ICalibrationImport import, ZeroMethodOptions zmOptions, IImportNotification importNotification, bool importCreateDynamicGroups, bool useIsoCodeFilterMapping, bool useZeroForUnfiltered);` | Configures the parser with dependencies and options required for sensor parsing (e.g., calibration, zero method, group creation behavior). |
|
||||
| | `ParseVersion` | `void ParseVersion(CSVImportTags.Tags field, string val, ParseParameters pp);` | Parses a single field (`field`) and its value (`val`) into the `ParseParameters` context. Used for incremental sensor data parsing. |
|
||||
| **`ICalibrationImport`** | `AddLinearCalRecordIfNeeded` | `SensorCalibration AddLinearCalRecordIfNeeded(SensorCalibration sc, bool savedIsProportional, bool savedRemoveOffset);` | Conditionally adds a linear calibration record to `sc` based on `savedIsProportional` and `savedRemoveOffset`. Returns the (possibly modified) `SensorCalibration`. |
|
||||
| | `AddLinearZeroMethodIfNeeded` | `SensorCalibration AddLinearZeroMethodIfNeeded(SensorCalibration sc, ZeroMethodType zeroMethodType, double zeroMethodStart, double zeroMethodEnd);` | Conditionally adds a linear zero method (e.g., offset, span) to `sc`. Returns the (possibly modified) `SensorCalibration`. |
|
||||
| | `CheckForExcitationCalibration` | `SensorCalibration CheckForExcitationCalibration(SensorCalibration sc, double sensitivity, ExcitationVoltageOptions.ExcitationVoltageOption excitation, string EU);` | Applies excitation-specific calibration adjustments to `sc` if applicable. Returns the (possibly modified) `SensorCalibration`. |
|
||||
| **`ILockImport`** | `Contended` | `bool Contended { get; }` | Indicates whether the lock collection contains any items (i.e., whether contention exists). |
|
||||
| | `SetLock` | `void SetLock(ref ImportObject importObject, ref StringBuilder message);` | Attempts to acquire a database lock for the given `importObject`. Errors (if any) are appended to `message`. |
|
||||
| | `FreeLock` | `void FreeLock(ref ImportObject importObject);` | Releases the database lock previously acquired for `importObject`. |
|
||||
| | `StealLock` | `bool StealLock(bool proceed);` | Attempts to forcibly acquire (steal) the lock. Returns `true` on success. `proceed` likely controls whether to proceed despite warnings. |
|
||||
| **`IGroupImport`** | `ParseParameters` | `ParseParameters ParseParameters { get; set; }` | Gets or sets the shared parsing context used during group creation. |
|
||||
| | `CreateGroups` | `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 (static and/or dynamic) from sensor data. Returns a tuple of the updated `TestTemplate` and list of created `IGroup` instances. `setProgress` enables progress reporting. |
|
||||
| | `GetGroupSensorLookup` | `Dictionary<string, List<TsetSetupImportSensorInfo>> GetGroupSensorLookup(List<SensorData> sensors, Dictionary<string, string> sensorGroupNameLookup, Dictionary<string, List<string>> groupNameSensorListLookup);` | Builds a mapping from group names to their associated sensor info (`TsetSetupImportSensorInfo`) using precomputed lookup dictionaries. |
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
|
||||
- **`ImportObject` is the canonical data carrier**: All parsing interfaces (`IParseImport`, `IParseVariant`, `IParseCSVTest`, `IParseCSVSensor`) operate on or modify an `ImportObject` (or its subcomponents like `TestSetupImportData`). This object must be fully initialized before `IPersistImport.Save()` is called.
|
||||
- **Versioned parsing is mandatory**: All CSV-specific parsers (`IParseCSVTest`, `IParseCSVSensor`) expose a `Version` property, implying that parsing logic must be version-aware and only process data matching its declared version.
|
||||
- **`ParseParameters` is shared context**: `IGroupImport.ParseParameters` must be set consistently across all parsing steps that influence group creation (e.g., by `IParseCSVSensor.Initialize` or prior parsing steps).
|
||||
- **Locking is explicit and paired**: `ILockImport.SetLock` and `ILockImport.FreeLock` must be called in matched pairs (or `StealLock` used appropriately) to avoid deadlocks or orphaned locks. The `message` parameter in `SetLock` is *mutated* and must be checked after each call.
|
||||
- **Calibration is applied incrementally**: `ICalibrationImport` methods modify `SensorCalibration` in-place and return the same instance (or a new one), but callers must ensure methods are invoked in the correct order (e.g., zero method before excitation calibration if dependencies exist).
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
**Imports/uses from this module:**
|
||||
- `DTS.Common.Import` namespace (obvious).
|
||||
- `DTS.Common.Classes` (e.g., `TestSetupImportData`, `ParseParameters`).
|
||||
- `DTS.Common.Enums`, `DTS.Common.Enums.Sensors` (e.g., `ZeroMethodType`, `ExcitationVoltageOption`).
|
||||
- `DTS.SensorDB` (e.g., `SensorCalibration`, `SensorData`).
|
||||
- `CsvHelper` (for `CsvReader` in `IParseCSVTest`).
|
||||
- `DataPROWin7.DataModel` (e.g., `TestTemplate` in `IGroupImport`).
|
||||
- `DTS.Common.Interface.Groups.GroupList` (e.g., `IGroup` in `IGroupImport`).
|
||||
|
||||
**Depended upon by (inferred):**
|
||||
- Any concrete import pipeline (e.g., a `CsvImportService` or `ImportController`) that implements `IParseImport` and orchestrates `IParseVariant`, `IParseCSVSensor`, `ICalibrationImport`, `IGroupImport`, and `ILockImport`.
|
||||
- Database persistence layers (implementing `IPersistImport`).
|
||||
- Test setup or sensor configuration UIs that validate or preview imports (using `IParseCSVTest`, `IParseCSVSensor`).
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
|
||||
- **`ref` parameters in `ILockImport` and `IParseVariant.Parse`**: Both `SetLock(ref ImportObject, ref StringBuilder)` and `Parse(ref ImportObject)` use `ref`, meaning the callee may reassign the object reference. Callers must ensure variables are not boxed or copied before passing.
|
||||
- **`FileName` in `IParseVariant` is mutable but not validated**: The setter allows arbitrary strings; no validation or normalization is guaranteed. Callers must ensure filenames match expected patterns (e.g., case, extensions).
|
||||
- **`IParseCSVSensor.Initialize` has many flags**: The `Initialize` method accepts 6 parameters, including boolean toggles (`importCreateDynamicGroups`, `useIsoCodeFilterMapping`, `useZeroForUnfiltered`). Misconfiguring these may lead to silent misbehavior (e.g., groups not created, filters ignored).
|
||||
- **`IGroupImport.CreateGroups` progress reporting is optional**: The `setProgress` parameter is an `Action<double>`—callers may pass `null`, but implementations may assume it’s non-null and throw `NullReferenceException` if not handled.
|
||||
- **No explicit error handling in interfaces**: None of the interfaces declare exceptions. Implementations may throw (e.g., `CsvHelper` parsing errors), but callers must rely on outer try/catch blocks.
|
||||
- **`ILockImport.StealLock` behavior is underspecified**: The `proceed` parameter’s semantics (e.g., user prompt, forced override) are not documented in the interface. Implementation-specific behavior may vary.
|
||||
- **`TsetSetupImportSensorInfo` typo in `IGroupImport`**: The parameter name `groupSensorLookup` and return type use `TsetSetupImportSensorInfo` (likely a typo for `TestSetupImportSensorInfo`). Verify actual type name in implementation.
|
||||
|
||||
> **Note**: Several types referenced (e.g., `ImportObject`, `ParseParameters`, `SensorData`, `TsetSetupImportSensorInfo`, `CSVImportTags.Tags`) are not defined in the provided source files. Their structure and behavior must be inferred from usage or consulted in other modules.
|
||||
@@ -0,0 +1,69 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Import/Parsers/ParseVariantBase.cs
|
||||
- Common/DTS.Common.Import/Parsers/DefaultParseImport.cs
|
||||
- Common/DTS.Common.Import/Parsers/DTSXMLParseImport.cs
|
||||
generated_at: "2026-04-16T02:06:24.270866+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "6317dc1ace913c30"
|
||||
---
|
||||
|
||||
# Parsers
|
||||
|
||||
## Documentation: Import Parsing Module
|
||||
|
||||
### 1. Purpose
|
||||
This module provides foundational infrastructure and concrete implementations for parsing import files into a structured `ImportObject`. It defines an extensible parsing pipeline via the `IParseImport` interface, with base abstractions (`ParseVariantBase`) for variant-specific parsing logic and two concrete import processors: `DefaultParseImport` (generic, variant-driven parsing) and `DTSXMLParseImport` (XML-specific parsing with UI integration, cancellation support, and post-processing for DAS-linked hardware). The module serves as the core engine for transforming raw file inputs into domain objects used throughout the DTS import workflow.
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `ParseVariantBase` (abstract class)
|
||||
- **`string FileName { get; set; }`**
|
||||
Gets or sets the name of the file being parsed by this variant. Set by the caller before `Parse` is invoked.
|
||||
- **`abstract void Parse(ref ImportObject importObject)`**
|
||||
Parses the file (identified by `FileName`) and mutates the provided `ImportObject` by adding or updating its contents. Must be implemented by derived classes.
|
||||
|
||||
#### `DefaultParseImport` (concrete class)
|
||||
- **`DefaultParseImport(ImportObject importObject, IEnumerable<IParseVariant> parseVariants)`**
|
||||
Constructor. Initializes the parser with a target `ImportObject` and a sequence of `IParseVariant` implementations to apply.
|
||||
- **`ImportObject Parse(IEnumerable<string> importFiles)`**
|
||||
Processes each file in `importFiles` using the configured `IParseVariant`s via a `ParseProcessor`. Returns the mutated `_importObject`.
|
||||
*Note:* The same `ImportObject` instance passed to the constructor is returned (though mutated internally).
|
||||
|
||||
#### `DTSXMLParseImport` (concrete class)
|
||||
- **`DTSXMLParseImport(ImportObject importObject, IImportNotification importNotification, Func<bool> isCancelled = null, bool skipNormalizing = false)`**
|
||||
Constructor. Initializes the XML parser with a target `ImportObject`, notification sink, optional cancellation delegate, and flag to skip normalization.
|
||||
- **`List<IUIItems> UIItems { get; set; }`**
|
||||
Gets or sets UI-related items (e.g., progress indicators, messages) to be used by the underlying processor.
|
||||
- **`ImportObject Parse(IEnumerable<string> importFiles)`**
|
||||
Processes XML files via `XMLParseProcessor`, applies post-processing (`AssignLinkedDASSerials`), and returns the mutated `_importObject`.
|
||||
*Note:* `UIItems` is assigned to the processor before processing.
|
||||
|
||||
#### `AssignLinkedDASSerials` (private method in `DTSXMLParseImport`)
|
||||
- **`void AssignLinkedDASSerials(ref ImportObject importObject)`**
|
||||
Post-processes `importObject.Hardware()` to populate `LinkedDASSerials` for pseudo-rack hardware: for each pseudo-rack (`IsPseudoRack() == true`), collects all hardware items whose `ParentDAS` matches the rack’s `SerialNumber`, and stores their serials in `LinkedDASSerials`.
|
||||
|
||||
### 3. Invariants
|
||||
- **`ParseVariantBase.Parse` must mutate `importObject` in-place** (via `ref`), not replace it.
|
||||
- **`FileName` must be set on each `IParseVariant` instance before calling `Parse(ref ImportObject)`** (enforced by caller, not by class).
|
||||
- **`DTSXMLParseImport.Parse` always calls `AssignLinkedDASSerials` after processing**, ensuring `LinkedDASSerials` is populated for pseudo-rack hardware.
|
||||
- **`DefaultParseImport` does not modify the `importFiles` sequence**; it only iterates over it.
|
||||
- **`DTSXMLParseImport` supports cancellation** via the `_isCancelled` delegate (behavior depends on `XMLParseProcessor` implementation, not visible here).
|
||||
|
||||
### 4. Dependencies
|
||||
- **Depends on:**
|
||||
- `DTS.Common.Import.Interfaces` namespace (`IParseImport`, `IParseVariant`, `IImportNotification`, `IUIItems`).
|
||||
- `DTS.Slice.Users` namespace (for `IImportNotification`, `IUIItems`).
|
||||
- `ImportObject` type (used throughout; definition not provided here).
|
||||
- Internal types: `ParseProcessor`, `XMLParseProcessor` (referenced but not documented here).
|
||||
- **Depended on by:**
|
||||
- Unknown from source alone. Likely consumed by higher-level import orchestration (e.g., UI layers, batch import services).
|
||||
|
||||
### 5. Gotchas
|
||||
- **`DefaultParseImport` reuses the same `ImportObject` instance** passed to its constructor; callers must be aware that the returned object is the *same reference*, not a copy.
|
||||
- **`DTSXMLParseImport.AssignLinkedDASSerials` only processes hardware where `IsPseudoRack()` returns `true`**; non-rack hardware is skipped.
|
||||
- **`DTSXMLParseImport` does not validate `importFiles` for XML format**—assumes correctness (handled by `XMLParseProcessor`).
|
||||
- **`UIItems` must be set on `DTSXMLParseImport` *before* calling `Parse`** to be effective (assigned to processor inside `Parse`).
|
||||
- **`skipNormalizing` flag behavior is not visible in this module**—depends on `XMLParseProcessor` implementation.
|
||||
- **`AssignLinkedDASSerials` uses LINQ query materialization (`as string[] ?? matches.ToArray()`) but does not guard against null `Hardware()`**—potential `NullReferenceException` if `importObject.Hardware()` returns `null`.
|
||||
@@ -0,0 +1,143 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Import/Parsers/CSV/AbstractCSVParser.cs
|
||||
- Common/DTS.Common.Import/Parsers/CSV/Version0CSVTestParser.cs
|
||||
- Common/DTS.Common.Import/Parsers/CSV/CSVFile.cs
|
||||
- Common/DTS.Common.Import/Parsers/CSV/Version6CSVTestParser.cs
|
||||
- Common/DTS.Common.Import/Parsers/CSV/Version3CSVSensorParser.cs
|
||||
- Common/DTS.Common.Import/Parsers/CSV/Version5CSVTestParser.cs
|
||||
- Common/DTS.Common.Import/Parsers/CSV/Version4CSVSensorParser.cs
|
||||
- Common/DTS.Common.Import/Parsers/CSV/CSVGroupImport.cs
|
||||
- Common/DTS.Common.Import/Parsers/CSV/DTSCSVTestSetupParser.cs
|
||||
- Common/DTS.Common.Import/Parsers/CSV/DTSCSVSensorsParser.cs
|
||||
generated_at: "2026-04-16T02:08:24.981291+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "2bff5b23b8f73415"
|
||||
---
|
||||
|
||||
# CSV Import Module Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides a versioned CSV parsing infrastructure for importing sensor and test setup data into the DTS system. It supports two distinct import workflows: **sensor data import** (handled by `DTSCSVSensorsParser`) and **test setup data import** (handled by `DTSCSVTestSetupParser`). The module uses an abstract base class (`AbstractCSVParser`) and concrete version-specific parsers to handle evolving CSV formats across versions 0 through 6. It decouples parsing logic from business logic, delegates group creation to `CSVGroupImport`, and integrates with calibration, sensor, and hardware data models to construct `TestTemplate` and `ImportObject` instances for downstream processing.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `AbstractCSVParser` (abstract base class)
|
||||
- **`int Version { get; }`**
|
||||
Returns the CSV format version supported by this parser (e.g., 3, 4).
|
||||
- **`void Initialize(ICalibrationImport import, ZeroMethodOptions zmOptions, IImportNotification importNotification, bool importCreateDynamicGroups, bool useISOCodeFilterMapping, bool useZeroForUnfiltered)`**
|
||||
Injects dependencies and configuration flags required for parsing. Must be called before `ParseVersion`.
|
||||
- **`abstract void ParseVersion(CSVImportTags.Tags field, string val, ParseParameters pp)`**
|
||||
Parses a single field (`field`) from a sensor CSV row, using value `val`. Errors are appended to `pp.Errors`. Behavior is version-specific.
|
||||
|
||||
### `Version0CSVTestParser`
|
||||
- **`int Version => 0`**
|
||||
- **`void ParseVersion(CsvReader csvReader, TestSetupImportData tsid)`**
|
||||
Parses test setup metadata (e.g., `PostTriggerSec`, `SampleRate`, `RecordingMode`) from a CSV with a simple header-value pair format. Reads two rows: header names and values.
|
||||
|
||||
### `Version3CSVSensorParser`
|
||||
- **`int Version => 3`**
|
||||
- **`void ParseVersion(CSVImportTags.Tags field, string sVal, ParseParameters pp)`**
|
||||
Handles `GroupName` and `GroupType` fields. Enforces non-empty values, uniqueness of sensor serial numbers in group lookups, and consistency of `TestObject` per group (throws `Exception("Parse error")` on conflict if `ImportCreateDynamicGroups` is false).
|
||||
|
||||
### `Version4CSVSensorParser`
|
||||
- **`int Version => 4`**
|
||||
- **`void ParseVersion(CSVImportTags.Tags field, string sVal, ParseParameters pp)`**
|
||||
Parses DAS-related (`DASSerialNumber`, `DASChannelIndex`), streaming (`StreamProfile`, `UDPAddress`, `TimeChannelId`, `DataChannelId`, `TmNSConfig`, `IRIGTimeDataPacketIntervalMS`, `TMATSIntervalMS`), UART (`BaudRate`, `DataBits`, `StopBits`, `Parity`, `DataFormat`), and user-defined fields (`TestUserCode`, `TestUserChannelName`, `TestIsoCode`, `TestIsoChannelName`). Updates `pp.SensorData` and lookup dictionaries.
|
||||
|
||||
### `Version5CSVTestParser`
|
||||
- **`int Version => 5`**
|
||||
- **`void ParseVersion(CsvReader csvReader, TestSetupImportData tsid)`**
|
||||
Parses clock synchronization settings (e.g., `ClockMasterInputType`, `ClockMasterOutputType`, `ManageClocksOutsideDPMaster`) from a header-value row format.
|
||||
|
||||
### `Version6CSVTestParser`
|
||||
- **`int Version => 6`**
|
||||
- **`void ParseVersion(CsvReader csvReader, TestSetupImportData tsid)`**
|
||||
Parses per-DAS hardware configuration (e.g., `DASSerial`, `DASSampleRate`, `PTPDomainId`, `ClockMaster`) in a table format. Reads header row, then iterates rows until an empty line or non-matching field is encountered.
|
||||
|
||||
### `CSVFile`
|
||||
- **`static bool IsInUse(string filename)`**
|
||||
Returns `true` if the file is locked (IOException on `File.ReadAllLines`), else `false`.
|
||||
- **`static bool IsCSVFileForTestSetupImport(string filename, CsvImportOptions csvImportOptions)`**
|
||||
Returns `true` if the first field of the first row is `"Version"`.
|
||||
- **`static int GetCsvVersion(string filename)`**
|
||||
Returns the integer value in the first column of the second row if the first row starts with `"Version"`, else `0`.
|
||||
- **`int LineCount { get; }`**
|
||||
Returns the number of lines in the file (0 on error or null filename).
|
||||
|
||||
### `CSVGroupImport`
|
||||
- **`ParseParameters ParseParameters { get; set; }`**
|
||||
- **`Tuple<TestTemplate, List<IGroup>> CreateGroups(List<SensorData> sensors, Dictionary<string, List<TsetSetupImportSensorInfo>> groupSensorLookup, TestTemplate testTemplate, bool createDynamicGroups, List<IGroup> staticGroups, Action<double> setProgress)`**
|
||||
Creates `IGroup` instances from `groupSensorLookup`, assigns sensor/channel properties (ISO/user codes, DAS mapping, calibration defaults), and adds groups to `testTemplate`. Updates `setProgress`.
|
||||
- **`Dictionary<string, List<TsetSetupImportSensorInfo>> GetGroupSensorLookup(List<SensorData> sensors, Dictionary<string, string> sensorGroupNameLookup, Dictionary<string, List<string>> groupNameSensorListLookup)`**
|
||||
Builds a mapping from group name to list of `TsetSetupImportSensorInfo` (containing sensor/DAS parameters) using either `sensorGroupNameLookup` or `groupNameSensorListLookup`.
|
||||
|
||||
### `DTSCSVTestSetupParser`
|
||||
- **`void Parse(ref ImportObject importObject)`**
|
||||
Orchestrates test setup import: validates CSV format, parses test setup data via `ParseTestSetup`, creates `TestTemplate`, assigns hardware, clock sync, and tags, then delegates group creation to `AssignGroupsToTestSetup`. Adds result to `importObject`.
|
||||
|
||||
### `DTSCSVSensorsParser`
|
||||
- **`void Parse(ref ImportObject importObject)`**
|
||||
Orchestrates sensor import: reads CSV, populates `SensorData` and `SensorCalibration` objects via `PopulateSensor`, handles sensitivity unit corrections, and adds sensors/calibrations to `importObject`. Reports errors and warnings.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **CSV Format Validation**:
|
||||
- A CSV is recognized as a test setup file if its first field is `"Version"`.
|
||||
- Sensor CSVs must have recognizable column headers (else `ImportSensorsPreviewControl_NoColumnsInTDCCSV` error).
|
||||
- **Version Consistency**:
|
||||
- `Version0CSVTestParser` and `Version5CSVTestParser` expect header-value pairs.
|
||||
- `Version6CSVTestParser` expects a table format with header row followed by data rows until an empty line.
|
||||
- `DTSCSVTestSetupParser.ParseTestSetup` uses `CSVFile.GetCsvVersion` to determine which parsers to invoke; version 6 triggers all parsers (0 + 5 + 6).
|
||||
- **Sensor Grouping**:
|
||||
- `Version3CSVSensorParser` enforces that a group name maps to a single `SensorTestObject` unless `ImportCreateDynamicGroups` is true.
|
||||
- Duplicate sensor serial numbers in `sensorGroupNameLookup` or `sensorGroupTypeLookup` are rejected with errors.
|
||||
- **Calibration & Defaults**:
|
||||
- `DTSCSVSensorsParser` applies user-specific defaults for squib/digital output settings.
|
||||
- Sensitivity units are corrected from `mVperVperEU` to `mVperEU` for non-proportional calibrations.
|
||||
- Zero method is initialized from `pp.SensorCal.ZeroMethods.Methods[0]` during `PostParse`.
|
||||
- **Hardware Mapping**:
|
||||
- DAS hardware is added to `TestTemplate` only if version ≥ 6 (per `DTSCSVTestSetupParser` comment FB 43815).
|
||||
- DAS sample rates are set in both `t.SetSampleRateForHardware` and `t.DASSampleRateList`.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Imports/References:
|
||||
- **Core Types**: `DTS.Common.Classes`, `DTS.Common.Enums`, `DTS.Common.Import.Interfaces`, `CsvHelper`, `System.IO`, `System.Collections.Generic`.
|
||||
- **Hardware/Storage**: `DataPROWin7.DataModel`, `DTS.SensorDB`, `DTS.Common.Storage`.
|
||||
- **Import Infrastructure**: `ParseVariantBase`, `ParseParameters`, `ImportObject`, `TestSetupImportData`, `SensorData`, `SensorCalibration`, `IGroup`, `IGroupImport`, `ICalibrationImport`, `IImportNotification`.
|
||||
- **CSV Tags**: `CSVImportTags` (static class providing `GetTagForString`, `GetVersionForTag`).
|
||||
- **Factories**: `CSVTestParserFactory`, `CSVSensorParserFactory`.
|
||||
|
||||
### Used By:
|
||||
- `DTSCSVTestSetupParser` is invoked by the test setup import pipeline.
|
||||
- `DTSCSVSensorsParser` is invoked by the sensor import pipeline.
|
||||
- `CSVGroupImport` is used by `DTSCSVTestSetupParser` to create groups.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Version 6 CSV Parsing Quirk**:
|
||||
In `DTSCSVSensorsParser.ParseSensor`, if version is 6, the parser skips rows until it finds a tag with version ≤ 4 (to avoid parsing test setup-specific rows as sensor data). This assumes sensor and test setup data are in the same file but separated by an empty line.
|
||||
|
||||
- **Exception Thrown in Group Parsing**:
|
||||
`Version3CSVSensorParser.ParseVersion` throws `new Exception("Parse error")` on group/test object conflict (if `ImportCreateDynamicGroups` is false). This is caught by `DTSCSVSensorsParser` and reported as a sensor error, but the exception itself is non-descriptive.
|
||||
|
||||
- **Sensitivity Unit Correction**:
|
||||
`DTSCSVSensorsParser` silently changes `SensitivityUnits` from `mVperVperEU` to `mVperEU` for non-proportional calibrations. This is logged as a warning but may cause unexpected calibration behavior.
|
||||
|
||||
- **DAS Hardware Lookup**:
|
||||
`CSVGroupImport.CreateGroups` uses `DbOperations.GetChannelSettingDefaults()` and `GroupHelper.GetDAS` to map DAS serial numbers to IDs. If DAS is not in `DASHardwareList.GetAllHardware()`, channel DAS ID remains unset.
|
||||
|
||||
- **Zero Method Initialization**:
|
||||
`PostParse` in `DTSCSVSensorsParser` initializes `pp.ZeroType`, `pp.ZeroStart`, `pp.ZeroEnd` from `pp.SensorCal.ZeroMethods.Methods[0]`. If `ZeroMethods` is uninitialized or empty, this may cause `IndexOutOfRangeException`.
|
||||
|
||||
- **No Validation of Sensor Serial Number Format**:
|
||||
Sensors with serial numbers starting with `Constants.ISO_CH_ONLY_PREFIX` bypass some validation (e.g., sensitivity/capacity checks), but the prefix is not defined in the provided source.
|
||||
|
||||
- **Error Reporting Inconsistency**:
|
||||
`DTSCSVSensorsParser` aggregates errors per line and reports them as a single error string, while `DTSCSVTestSetupParser` reports errors via `IImportNotification.ReportErrors`. Error severity and continuation behavior differ between parsers.
|
||||
|
||||
- **File Lock Detection Limitation**:
|
||||
`CSVFile.IsInUse` uses `File.ReadAllLines`, which may not reliably detect all lock states (e.g., file opened for append-only).
|
||||
@@ -0,0 +1,115 @@
|
||||
---
|
||||
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).
|
||||
338
enriched-qwen3-coder-next/Common/DTS.Common.Import/Persist.md
Normal file
338
enriched-qwen3-coder-next/Common/DTS.Common.Import/Persist.md
Normal file
@@ -0,0 +1,338 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Import/Persist/SaveServer.cs
|
||||
- Common/DTS.Common.Import/Persist/SaveGroupTemplates.cs
|
||||
- Common/DTS.Common.Import/Persist/SaveVariantBase.cs
|
||||
- Common/DTS.Common.Import/Persist/SaveGlobalSettings.cs
|
||||
- Common/DTS.Common.Import/Persist/PersistCalculator.cs
|
||||
- Common/DTS.Common.Import/Persist/SaveSensorModels.cs
|
||||
- Common/DTS.Common.Import/Persist/SaveTestEngineerDetails.cs
|
||||
- Common/DTS.Common.Import/Persist/SaveLabDetails.cs
|
||||
- Common/DTS.Common.Import/Persist/SaveUsers.cs
|
||||
- Common/DTS.Common.Import/Persist/SaveCustomerDetails.cs
|
||||
- Common/DTS.Common.Import/Persist/SaveHardware.cs
|
||||
- Common/DTS.Common.Import/Persist/SaveTestSetupHelper.cs
|
||||
- Common/DTS.Common.Import/Persist/SaveGroups.cs
|
||||
- Common/DTS.Common.Import/Persist/SaveCustomChannels.cs
|
||||
- Common/DTS.Common.Import/Persist/SaveTestSetup.cs
|
||||
- Common/DTS.Common.Import/Persist/SaveCheckoutTestSetup.cs
|
||||
generated_at: "2026-04-16T02:08:08.051368+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "695fcda61b684601"
|
||||
---
|
||||
|
||||
# Documentation: `DTS.Common.Import.Persist` Module
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides a family of concrete implementations for persisting various types of imported data during a data import workflow. Each class (`Save*`) corresponds to a distinct category of data (e.g., hardware, groups, test setups, users, custom channels) and encapsulates the logic required to commit that data to the target database or system. All implementations inherit from the abstract base class `SaveVariantBase`, which provides shared infrastructure for progress tracking, cancellation support, and dependency injection of core services (`IPersistCalculator`, `IImportNotification`). The module serves as the persistence layer of the import pipeline, transforming in-memory `ImportObject` data into persistent system state.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
All classes listed below are `public` (except `SaveServer`, which is `internal`) and inherit from `SaveVariantBase`. Each implements the `Save()` method.
|
||||
|
||||
### `SaveVariantBase` (abstract base class)
|
||||
|
||||
- **Namespace**: `DTS.Common.Import.Persist`
|
||||
- **Signature**: `public abstract class SaveVariantBase : IPersistImport`
|
||||
- **Constructor**:
|
||||
```csharp
|
||||
protected SaveVariantBase(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, Func<bool> isCancelled = null)
|
||||
```
|
||||
- **Properties**:
|
||||
- `protected ImportObject _importObject`
|
||||
- `protected readonly IPersistCalculator _persistCalculator`
|
||||
- `protected readonly IImportNotification _importNotification`
|
||||
- `protected readonly Func<bool> IsCancelled`
|
||||
- **Methods**:
|
||||
- `public abstract void Save()`
|
||||
|
||||
### `SaveServer` (internal)
|
||||
|
||||
- **Namespace**: `DTS.Common.Import.Persist`
|
||||
- **Signature**: `class SaveServer : SaveVariantBase`
|
||||
- **Constructor**:
|
||||
```csharp
|
||||
public SaveServer(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, Func<bool> isCancelled = null)
|
||||
```
|
||||
- **Methods**:
|
||||
- `public override void Save()` → **Throws `NotImplementedException`**. This class is a placeholder and not functional.
|
||||
|
||||
### `SaveGroupTemplates`
|
||||
|
||||
- **Namespace**: `DTS.Common.Import.Persist`
|
||||
- **Signature**: `public class SaveGroupTemplates : SaveVariantBase`
|
||||
- **Constructor**:
|
||||
```csharp
|
||||
public SaveGroupTemplates(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, Func<bool> isCancelled = null)
|
||||
```
|
||||
- **Methods**:
|
||||
- `public override void Save()`
|
||||
Iterates over `_importObject.GroupTemplates()`. For each template:
|
||||
- Checks cancellation (`IsCancelled()`), returns early if true.
|
||||
- Calls `_persistCalculator.AddDone()` (increments by 1).
|
||||
- Calls `_importNotification.SetProgress(_persistCalculator.ProgressValue)`.
|
||||
**Note**: Does *not* actually commit group templates to storage; only updates progress.
|
||||
|
||||
### `SaveGlobalSettings`
|
||||
|
||||
- **Namespace**: `DTS.Common.Import.Persist`
|
||||
- **Signature**: `public class SaveGlobalSettings : SaveVariantBase`
|
||||
- **Constructor**:
|
||||
```csharp
|
||||
public SaveGlobalSettings(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, Func<bool> isCancelled = null)
|
||||
```
|
||||
- **Methods**:
|
||||
- `public override void Save()`
|
||||
Iterates over `_importObject.GlobalSettings()`. For each setting `g`:
|
||||
- Checks cancellation, returns early if true.
|
||||
- Calls `SettingsDB.SetGlobalValue(g.Key, g.Value)`.
|
||||
- Calls `_persistCalculator.AddDone()` (increments by 1).
|
||||
- Calls `_importNotification.SetProgress(...)`.
|
||||
|
||||
### `SaveSensorModels`
|
||||
|
||||
- **Namespace**: `DTS.Common.Import.Persist`
|
||||
- **Signature**: `public class SaveSensorModels : SaveVariantBase`
|
||||
- **Properties**:
|
||||
- `public User CurrentUser { get; set; }`
|
||||
- **Constructor**:
|
||||
```csharp
|
||||
public SaveSensorModels(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, Func<bool> isCancelled = null)
|
||||
```
|
||||
- **Methods**:
|
||||
- `public override void Save()`
|
||||
Iterates over `_importObject.SensorModels()`. For each model `st`:
|
||||
- Checks cancellation, returns early if true.
|
||||
- Calls `SensorModelCollection.SensorModelList.Commit(st, CurrentUser.UserName)`.
|
||||
- Calls `_persistCalculator.AddDone()` (increments by 1).
|
||||
- Calls `_importNotification.SetProgress(...)`.
|
||||
|
||||
### `SaveTestEngineerDetails`
|
||||
|
||||
- **Namespace**: `DTS.Common.Import.Persist`
|
||||
- **Signature**: `public class SaveTestEngineerDetails : SaveVariantBase`
|
||||
- **Constructor**:
|
||||
```csharp
|
||||
public SaveTestEngineerDetails(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, Func<bool> isCancelled = null)
|
||||
```
|
||||
- **Methods**:
|
||||
- `public override void Save()`
|
||||
- First, calls `_importNotification.SetStatus.Invoke(...)` with `ExtraStatus = ImportExtraStatus.ReadingEngineerDetails`.
|
||||
- Iterates over `_importObject.TestEngineerDetails()`. For each detail `t`:
|
||||
- Checks cancellation, returns early if true.
|
||||
- Calls `TestEngineerDetailsList.TestEngineerList.AddTestEngineer(new TestEngineerDetails(t))`.
|
||||
- Calls `_persistCalculator.AddDone()` (increments by 1).
|
||||
- Calls `_importNotification.SetProgress(...)`.
|
||||
|
||||
### `SaveLabDetails`
|
||||
|
||||
- **Namespace**: `DTS.Common.Import.Persist`
|
||||
- **Signature**: `public class SaveLabDetails : SaveVariantBase`
|
||||
- **Constructor**:
|
||||
```csharp
|
||||
public SaveLabDetails(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, Func<bool> isCancelled = null)
|
||||
```
|
||||
- **Methods**:
|
||||
- `public override void Save()`
|
||||
- First, calls `_importNotification.SetStatus.Invoke(...)` with `ExtraStatus = ImportExtraStatus.ReadingLabDetails`.
|
||||
- Declares `bool invalidLabDetails = false;` (but does *not* use it further).
|
||||
- Iterates over `_importObject.LabDetails()`. For each detail `l`:
|
||||
- Checks cancellation, returns early if true.
|
||||
- If `l.IsInvalidBlank()` is true, sets `invalidLabDetails = true`.
|
||||
- Otherwise, calls `LabratoryDetailsList.AddLab(new LabratoryDetails(l))`.
|
||||
- Calls `_persistCalculator.AddDone()` (increments by 1).
|
||||
- Calls `_importNotification.SetProgress(...)`.
|
||||
|
||||
### `SaveCustomerDetails`
|
||||
|
||||
- **Namespace**: `DTS.Common.Import.Persist`
|
||||
- **Signature**: `public class SaveCustomerDetails : SaveVariantBase`
|
||||
- **Properties**:
|
||||
- `bool invalidCustomerDetails = false;` (instance field, not used beyond assignment)
|
||||
- **Constructor**:
|
||||
```csharp
|
||||
public SaveCustomerDetails(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, Func<bool> isCancelled = null)
|
||||
```
|
||||
- **Methods**:
|
||||
- `public override void Save()`
|
||||
- First, calls `_importNotification.SetStatus.Invoke(...)` with `ExtraStatus = ImportExtraStatus.ReadingLabDetails` *(note: likely a copy-paste error; should be `ReadingCustomerDetails`)*.
|
||||
- Iterates over `_importObject.CustomerDetails()`. For each detail `c`:
|
||||
- Checks cancellation, returns early if true.
|
||||
- If `c.IsInvalidBlank()` is true, sets `invalidCustomerDetails = true`.
|
||||
- Otherwise, calls `CustomerDetailsList.AddCustomer(new CustomerDetails(c))`.
|
||||
- Calls `_persistCalculator.AddDone()` (increments by 1).
|
||||
- Calls `_importNotification.SetProgress(...)`.
|
||||
|
||||
### `SaveUsers`
|
||||
|
||||
- **Namespace**: `DTS.Common.Import.Persist`
|
||||
- **Signature**: `public class SaveUsers : SaveVariantBase`
|
||||
- **Properties**:
|
||||
- `public IUIItems[] UIItems { get; set; }`
|
||||
- `public User CurrentUser { get; set; }`
|
||||
- **Constructor**:
|
||||
```csharp
|
||||
public SaveUsers(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, Func<bool> isCancelled = null)
|
||||
```
|
||||
- **Methods**:
|
||||
- `public override void Save()`
|
||||
- First, calls `_importNotification.SetStatus.Invoke(...)` with `ExtraStatus = ImportExtraStatus.ReadingUsers`.
|
||||
- Iterates over `_importObject.Users()`. For each `user`:
|
||||
- Checks cancellation, returns early if true.
|
||||
- Asserts `CurrentUser.IsAdmin` via `System.Diagnostics.Trace.Assert(...)` (throws in debug if false).
|
||||
- Calls `UserCollection.UsersList.Commit(user, CurrentUser.UserName, UIItems)`.
|
||||
- Calls `_persistCalculator.AddDone()` (increments by 1).
|
||||
- Calls `_importNotification.SetProgress(...)`.
|
||||
|
||||
### `SaveHardware`
|
||||
|
||||
- **Namespace**: `DTS.Common.Import.Persist`
|
||||
- **Signature**: `public class SaveHardware : SaveVariantBase`
|
||||
- **Properties**:
|
||||
- `public Dictionary<int, int> OldDASIdToNewDASId { get; set; }`
|
||||
- `public Dictionary<int, List<IISOHardware>> TestIdToHardware { get; set; }`
|
||||
- **Constructor**:
|
||||
```csharp
|
||||
public SaveHardware(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, Func<bool> isCancelled = null)
|
||||
```
|
||||
- **Methods**:
|
||||
- `public override void Save()`
|
||||
- First, calls `_importNotification.SetStatus.Invoke(...)` with `ExtraStatus = ImportExtraStatus.ReadingHardware`.
|
||||
- Calls `_importObject.Hardware().ToList().Sort()` (sorts hardware list in-place).
|
||||
- Iterates over `_importObject.Hardware()`. For each hardware `h`:
|
||||
- Checks cancellation, returns early if true.
|
||||
- Stores `oldId = h.DASId`.
|
||||
- Calls `DASHardwareList.GetList().Commit(h, false, true)`.
|
||||
- If `h.DASId != oldId`, adds mapping `OldDASIdToNewDASId[oldId] = h.DASId`.
|
||||
- Gets `iso = h.GetHardware()`. If `iso.TestId != null`, adds `iso` to `TestIdToHardware[(int)iso.TestId]`.
|
||||
- Calls `_persistCalculator.AddDone()` (increments by 1).
|
||||
- Calls `_persistCalculator.AddDone(h.Channels?.Length ?? 0)` (adds number of channels).
|
||||
- Calls `_importNotification.SetProgress(...)`.
|
||||
|
||||
### `SaveGroups`
|
||||
|
||||
- **Namespace**: `DTS.Common.Import.Persist`
|
||||
- **Signature**: `public class SaveGroups : SaveVariantBase`
|
||||
- **Properties**:
|
||||
- `public bool CanCurrentUserCommitChannelCodes { get; set; } = true`
|
||||
- `public IChannelSetting DefaultZeroMethod { get; set; }`
|
||||
- `public IChannelSetting DefaultZeroStart { get; set; }`
|
||||
- `public IChannelSetting DefaultZeroEnd { get; set; }`
|
||||
- `public IChannelSetting DefaultInitialOffset { get; set; }`
|
||||
- `public Dictionary<int?, int> OldGroupIdToNewGroupId { get; set; }`
|
||||
- `private readonly SaveHardware _saveHardware`
|
||||
- **Constructor**:
|
||||
```csharp
|
||||
public SaveGroups(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, SaveHardware saveHardware, Func<bool> isCancelled = null)
|
||||
```
|
||||
- **Methods**:
|
||||
- `public override void Save()`
|
||||
- First, calls `_importNotification.SetStatus.Invoke(...)` with `ExtraStatus = ImportExtraStatus.ReadingGroups`.
|
||||
- Builds `idToDASId` lookup from `DASHardwareList.GetAllHardware()`.
|
||||
- Retrieves channel defaults from `DbOperations.GetChannelSettingDefaults()` and assigns to `Default*` properties.
|
||||
- Iterates over `_importObject.StaticGroups()`. For each group `g`:
|
||||
- Checks cancellation, returns early if true.
|
||||
- If `!g.Embedded`:
|
||||
- For each channel `ch` in `g.GroupChannelList`:
|
||||
- Updates `ch.SensorId` using `_importObject.OldSensorDatabaseIdsToNew()`.
|
||||
- Updates `ch.DASId` using `_saveHardware.OldDASIdToNewDASId`; if missing, sets `ch.DASId = -1` and tracks group name in `missingDASGroupList`.
|
||||
- Calls `SaveSensor.FixMissingZeroMethodParameter(...)` and `SaveSensor.FixMissingInitialOffset(...)` (methods not defined in source).
|
||||
- Calls `SetGroupId(g)` (static helper) to resolve group ID from DB.
|
||||
- Calls `FixGroupHardware(g, idToDASId)` (static helper) to resolve hardware IDs.
|
||||
- Calls `g.Save(g.GroupChannelList.ToArray(), CanCurrentUserCommitChannelCodes)`.
|
||||
- Maps `OldGroupIdToNewGroupId[normalizedStaticGroupId] = g.Id`.
|
||||
- Calls `_persistCalculator.AddDone()` (increments by 1).
|
||||
- Calls `_importNotification.SetProgress(...)`.
|
||||
- If `missingDASGroupList.Any()`, reports a warning via `_importObject.AddError(...)`.
|
||||
|
||||
### `SaveCustomChannels`
|
||||
|
||||
- **Namespace**: `DTS.Common.Import.Persist`
|
||||
- **Signature**: `public class SaveCustomChannels : SaveVariantBase`
|
||||
- **Properties**:
|
||||
- `public ISO13499FileDb IsoDb { get; set; }`
|
||||
- `public Dictionary<string, string> CustomChannelTextIdToOldChannelId { get; set; }`
|
||||
- `public Dictionary<string, TestObjectChannel> CustomChannelOldChannelIdToChannel { get; set; }`
|
||||
- **Constructor**:
|
||||
```csharp
|
||||
public SaveCustomChannels(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, Func<bool> isCancelled = null)
|
||||
```
|
||||
- **Methods**:
|
||||
- `public override void Save()`
|
||||
- Early return if `_importObject.CustomChannels()` is null or empty.
|
||||
- Iterates over custom channels in reverse order. For each `cc`:
|
||||
- Checks cancellation, returns early if true.
|
||||
- Stores `oldid = cc.Id`.
|
||||
- Tries to find existing channel by ISO code (`CustomChannelList.List.GetChannelByISOCode(...)`). If found, uses its ID; otherwise, clears `cc.Id` and inserts.
|
||||
- Commits `new CustomChannel(cc)`.
|
||||
- For each group template in `_importObject.GroupTemplates()`:
|
||||
- If channel matches, updates its ID to `newid`.
|
||||
- Updates group templates and associated groups, preserving sensor/hardware IDs.
|
||||
- Populates `CustomChannelTextIdToOldChannelId` and `CustomChannelOldChannelIdToChannel` for later remapping.
|
||||
- Calls `_persistCalculator.AddDone()` (increments by 1).
|
||||
- Calls `_importNotification.SetProgress(...)`.
|
||||
- **Commented-out GC.Collect** indicates memory pressure concerns.
|
||||
- Calls `CustomChannelList.List.UpdateAll()`.
|
||||
|
||||
### `SaveTestSetup`
|
||||
|
||||
- **Namespace**: `DTS.Common.Import.Persist`
|
||||
- **Signature**: `public class SaveTestSetup : SaveVariantBase`
|
||||
- **Properties**:
|
||||
- `private readonly SaveCustomChannels _saveCustomChannels`
|
||||
- `private readonly SaveHardware _saveHardware`
|
||||
- `private readonly SaveGroups _saveGroups`
|
||||
- `public User CurrentUser { get; set; }`
|
||||
- `public string TestSetupName { get; set; }`
|
||||
- **Constructor**:
|
||||
```csharp
|
||||
public SaveTestSetup(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification,
|
||||
SaveCustomChannels saveCustomChannels, SaveHardware saveHardware, SaveGroups saveGroups, Func<bool> isCancelled = null)
|
||||
```
|
||||
- **Methods**:
|
||||
- `private void ConfigureDefaultRunTestTestSetup(TestTemplate testSetup)`
|
||||
Sets many boolean/numeric properties (e.g., `DoROIDownload = true`, `ExportFormats = rdfadc`, etc.) for run-test mode.
|
||||
- `public override void Save()`
|
||||
- If `ImportFileFormat == SingleTestSetup` and `TestSetupName` is set, overrides `Name`, `TestId`, and calls `ConfigureDefaultRunTestTestSetup(...)`.
|
||||
- Calls `SaveTestSetupHelper.UpdateLevelTriggers(...)` to remap level trigger channel IDs.
|
||||
- Calls `SaveTestSetupHelper.DeleteExistingTestSetups(...)` to delete existing test setups.
|
||||
- Calls `SaveTestSetupHelper.PopulateHarwareLookup()` to build `hardwareLookup`.
|
||||
- Iterates over `_importObject.TestSetups()`. For each `t`:
|
||||
- Calls `SaveTestSetupHelper.FixDasAff(...)` to fix DAS AAF rates.
|
||||
- Stores `idPriorToCommit = t.Id`, then sets `t.Id = 0`.
|
||||
- For each channel in `t.ChannelsForGroup`:
|
||||
- Updates `SensorId` and `DASId` using mappings from `_importObject` and `_saveHardware`.
|
||||
- Calls `SaveSensor.FixMissingZeroMethodParameter(...)` and `SaveSensor.FixMissingInitialOffset(...)`.
|
||||
- Updates `hardwareIncluded`/`hardwareRemoved` lists using `OldDASIdToNewDASId`.
|
||||
- Calls `SaveTestSetupHelper.AddHardwareFromEmbeddedGroups(...)`.
|
||||
- Calls `t.ReplaceCalculatedChannel(oldIdToNewIdLookup)`.
|
||||
- Checks cancellation, returns early if true.
|
||||
- Ensures `t.TestSetupUniqueId` is set (generates GUID if null).
|
||||
- Commits `t` via `TestTemplateList.TestTemplatesList.Commit(t, false)`.
|
||||
- If `idPriorToCommit > 0`, updates `TestId` on associated hardware in `_saveHardware.TestIdToHardware`.
|
||||
- Calls `_persistCalculator.AddDone()` (increments by 1).
|
||||
- Calls `_importNotification.SetProgress(...)`.
|
||||
- Clears `oldIdToNewIdLookup`.
|
||||
- Sets status to `ImportExtraStatus.None`/`PossibleStatus.Working`.
|
||||
|
||||
### `SaveCheckoutTestSetup`
|
||||
|
||||
- **Namespace**: `DTS.Common.Import.Persist`
|
||||
- **Signature**: `public class SaveCheckoutTestSetup : SaveVariantBase`
|
||||
- **Properties**:
|
||||
- `private readonly SaveCustomChannels _saveCustomChannels`
|
||||
- `private readonly SaveHardware _saveHardware`
|
||||
- `private readonly SaveGroups _saveGroups`
|
||||
- `private readonly string _setupName`
|
||||
- `public User CurrentUser { get; set; }`
|
||||
- **Constructor**:
|
||||
```csharp
|
||||
public SaveCheckoutTestSetup(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification,
|
||||
SaveCustomChannels saveCustomChannels, SaveHardware saveHardware, SaveGroups saveGroups, Func<bool> isCancelled = null, string setupName = null)
|
||||
```
|
||||
- **Methods**:
|
||||
- `private void ConfigureCheckoutTestSetup(TestTemplate TestSetupCheckout)`
|
||||
Sets many boolean properties for checkout mode (e.g., `CheckoutMode = true`, `AllowMissingSensors = true`, `ExportFormats = none`, etc.).
|
||||
-
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Import/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T02:06:58.956349+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "528b9a9492c4b445"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## Documentation Page: `DTS.Common.Import` Assembly
|
||||
|
||||
### 1. Purpose
|
||||
This module is the `DTS.Common.Import` .NET assembly, a foundational component in the DTS (Data Transfer System) codebase. Its primary purpose is to serve as a shared library for import-related functionality—though the provided source file itself contains only assembly metadata and no implementation code. It acts as a container for types related to data import operations (e.g., parsing, validation, transformation), likely referenced by other modules in the system (e.g., `DTS.Common`, `DTS.ImportService`). The assembly is not executable on its own; it is intended to be consumed as a dependency.
|
||||
|
||||
### 2. Public Interface
|
||||
**No public types or members are defined in this file.**
|
||||
The file `AssemblyInfo.cs` contains only assembly-level attributes (e.g., version, title, COM visibility). It does not declare any classes, interfaces, methods, properties, or fields. Therefore, there is no public interface to document here.
|
||||
|
||||
### 3. Invariants
|
||||
- **Assembly identity is fixed at build time**: The assembly version is explicitly set to `1.0.0.0` via `[assembly: AssemblyVersion("1.0.0.0")]` and `[assembly: AssemblyFileVersion("1.0.0.0")]`.
|
||||
- **COM visibility is disabled**: `[assembly: ComVisible(false)]` ensures types in this assembly are not exposed to COM by default.
|
||||
- **GUID is stable**: The typelib GUID `c1bc06f4-8657-4892-bc4d-1064da01c4c7` uniquely identifies this assembly for COM interop (though COM exposure is disabled).
|
||||
- **No runtime behavior**: This file contributes no executable logic; invariants apply only to metadata and build-time configuration.
|
||||
|
||||
### 4. Dependencies
|
||||
- **Dependencies on .NET Framework**: This assembly depends on core .NET types via `System.Reflection`, `System.Runtime.CompilerServices`, and `System.Runtime.InteropServices`.
|
||||
- **Consumed by**: Other modules in the DTS ecosystem (e.g., `DTS.ImportService`, `DTS.Common`) are expected to reference this assembly to access import-related types (not visible in this file).
|
||||
- **No internal dependencies**: Since this file contains only attributes, it has no internal dependencies on other types or modules within the `DTS.Common.Import` assembly.
|
||||
|
||||
### 5. Gotchas
|
||||
- **Misleading file name**: The file `AssemblyInfo.cs` is standard for assembly metadata but contains no business logic. Developers should not expect to find import-related functionality here.
|
||||
- **Versioning convention**: The use of `[assembly: AssemblyVersion("1.0.0.0")]` with no wildcard (`*`) means build/revision numbers are static unless manually updated. This may conflict with CI/CD practices that auto-increment versions.
|
||||
- **COM interop is disabled**: If this assembly is intended for COM consumption (e.g., legacy integration), the `ComVisible(false)` setting must be overridden per-type (not shown here), or `ComVisible(true)` must be enabled at the assembly level.
|
||||
- **No documentation on public types**: The absence of public members in this file implies that all meaningful types reside in other source files (not provided), which may require separate documentation.
|
||||
|
||||
None identified from source alone beyond the above.
|
||||
183
enriched-qwen3-coder-next/Common/DTS.Common.Import/XML.md
Normal file
183
enriched-qwen3-coder-next/Common/DTS.Common.Import/XML.md
Normal file
@@ -0,0 +1,183 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Import/XML/XMLPre20ParseGroupTemplates.cs
|
||||
- Common/DTS.Common.Import/XML/XMLParseMMECustomDirections.cs
|
||||
- Common/DTS.Common.Import/XML/XMLParseMMECustomTestObjects.cs
|
||||
- Common/DTS.Common.Import/XML/XMLParseMMECustomPositions.cs
|
||||
- Common/DTS.Common.Import/XML/XMLParseMMECustomFineLoc3s.cs
|
||||
- Common/DTS.Common.Import/XML/XMLParseMMECustomFineLoc2s.cs
|
||||
- Common/DTS.Common.Import/XML/XMLParseMMECustomFineLoc1s.cs
|
||||
- Common/DTS.Common.Import/XML/XMLParseSensorModels.cs
|
||||
- Common/DTS.Common.Import/XML/XMLParseMMECustomFilterClasses.cs
|
||||
- Common/DTS.Common.Import/XML/XMLParseMMECustomChannels.cs
|
||||
- Common/DTS.Common.Import/XML/XMLParseMMECustomMainLocations.cs
|
||||
- Common/DTS.Common.Import/XML/XMLParseMMECustomPhysicalDimensions.cs
|
||||
- Common/DTS.Common.Import/XML/XMLPre20ParseSensors.cs
|
||||
- Common/DTS.Common.Import/XML/XMLParseUsers.cs
|
||||
- Common/DTS.Common.Import/XML/XMLParseBase.cs
|
||||
- Common/DTS.Common.Import/XML/XMLParseTestEngineerDetails.cs
|
||||
- Common/DTS.Common.Import/XML/XMLParseLabDetails.cs
|
||||
- Common/DTS.Common.Import/XML/XMLParseGlobalSettings.cs
|
||||
- Common/DTS.Common.Import/XML/XMLPre20ParseDASList.cs
|
||||
- Common/DTS.Common.Import/XML/XMLParseCustomerDetails.cs
|
||||
- Common/DTS.Common.Import/XML/XMLParseSensors.cs
|
||||
- Common/DTS.Common.Import/XML/XMLParseDASList.cs
|
||||
- Common/DTS.Common.Import/XML/XMLParseGroupTemplates.cs
|
||||
- Common/DTS.Common.Import/XML/XMLParseCalibrations.cs
|
||||
- Common/DTS.Common.Import/XML/XMLPre20ParseCalibrations.cs
|
||||
- Common/DTS.Common.Import/XML/XMLParseGroups.cs
|
||||
- Common/DTS.Common.Import/XML/XMLParseTestSetups.cs
|
||||
generated_at: "2026-04-16T02:07:16.226597+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "87dec39982bd8179"
|
||||
---
|
||||
|
||||
# XML Import Parsers Module Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides a family of XML parsing classes responsible for deserializing versioned XML export files into the system’s in-memory `ImportObject` representation during data import operations. Each concrete parser targets a specific data domain (e.g., sensors, groups, channels, test setups, calibration data, MME custom objects) and handles both direct parsing and migration logic for pre-2.0 XML formats. These parsers implement the `IParseVariant` interface, inherit from `XMLParseBase`, and coordinate with other parsers (e.g., via constructor injection) to resolve cross-references and normalize identifiers across related entities. The module serves as the core deserialization layer for backward-compatible XML imports, ensuring robust handling of schema evolution and data integrity constraints.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
All classes inherit from `XMLParseBase` and implement the abstract method `Parse(ref ImportObject importObject)`. Below are the public classes and their key behaviors.
|
||||
|
||||
### `XMLParseBase`
|
||||
- **Constructor**: `XMLParseBase(XmlElement root, double importedVersion, Func<bool> isCancelled = null, bool skipNormalizing = false)`
|
||||
- Stores the XML root node, imported file version, cancellation token, and normalization flag.
|
||||
- Initializes internal XML writer and mapping dictionaries (`_dasIdMapping`, `_groupIdMapping`, `_sensorIdMapping`, `_channelIdMapping`) for cross-entity ID normalization.
|
||||
- **Protected Methods**:
|
||||
- `XmlElement GetXmlElement()` – Finalizes XML writing and returns the constructed `XmlElement`.
|
||||
- `bool IsCancelled()` – Invokes the cancellation token (defaults to `() => false`).
|
||||
|
||||
### `XMLParseSensors`
|
||||
- **Constructor**: `XMLParseSensors(XmlElement root, double importedVersion, Func<bool> isCancelled = null, bool skipNormalizing = false)`
|
||||
- **Public Methods**:
|
||||
- `XmlElement ConvertSensors(IEnumerable<SensorData> sensors)` – Normalizes sensor `DatabaseId`s (assigns negative IDs starting at -2), updates `_sensorIdMapping`, and writes normalized XML.
|
||||
- `IEnumerable<SensorData> ParseSensors(XmlElement root)` – Parses `SensorData` objects from XML nodes; skips non-`XmlElement` nodes.
|
||||
|
||||
### `XMLPre20ParseSensors`
|
||||
- **Constructor**: `XMLPre20ParseSensors(XmlElement root, double importedVersion, XMLParseSensors xmlParseSensors, Func<bool> isCancelled = null)`
|
||||
- **Public Methods**:
|
||||
- `XmlElement MigrateSensors(IEnumerable<SensorData> sensors)` – Migrates pre-2.0 sensor data by assigning negative `DatabaseId`s (starting at -1) and writing to XML.
|
||||
- **Behavior**: Parses sensors, migrates them to the new schema, then delegates to `_xmlParseSensors.ParseSensors()` for final parsing.
|
||||
|
||||
### `XMLParseDASList`
|
||||
- **Constructor**: `XMLParseDASList(XmlElement root, double importedVersion, Func<bool> isCancelled = null, bool skipNormalizing = false)`
|
||||
- **Public Methods**:
|
||||
- `List<DASHardware> ParseDASList(XmlElement root)` – Parses `DASHardware` objects; filters out entries with invalid `DASType` (logs serial numbers to `invalidDAS` list, but does not report errors).
|
||||
- `XmlElement ConvertDASList(List<DASHardware> dasList)` – Normalizes `DASId`s (starting at -2) and updates `_dasIdMapping`.
|
||||
- **Behavior**: On import, validates `DASType` enum values; skips invalid entries silently.
|
||||
|
||||
### `XMLPre20ParseDASList`
|
||||
- **Constructor**: `XMLPre20ParseDASList(XmlElement root, double importedVersion, XMLParseDASList xmlParseDASList, Func<bool> isCancelled = null)`
|
||||
- **Public Methods**:
|
||||
- `List<DASHardware> ParsePre20DASList(XmlElement root)` – Parses pre-2.0 `DASHardware` objects.
|
||||
- `XmlElement MigratePre20DASList(List<DASHardware> dasList)` – Assigns negative `DASId`s (starting at -1) and writes to XML.
|
||||
- **Behavior**: Migrates pre-2.0 DAS list, then delegates to `_xmlParseDASList.ParseDASList()`.
|
||||
|
||||
### `XMLParseGroups`
|
||||
- **Constructor**: `XMLParseGroups(XmlElement root, double importedVersion, Func<bool> isCancelled = null)`
|
||||
- **Public Methods**:
|
||||
- `List<IGroup> ParseGroups(XmlElement root, ref ImportObject importObject)` – Parses groups, resolving channel references to imported sensors/DAS via lookup dictionaries. Handles both pre-2.0 (name-based) and post-2.0 (ID-based) group IDs in `_groupIdMapping`.
|
||||
- `XmlElement ConvertGroups(List<IGroup> staticGroups)` – Normalizes group `Id`s (starting at -2), DAS/sensor IDs in channels (using `_dasIdMapping`/`_sensorIdMapping`), and writes to XML. Silently sets `SensorId = 0` for deleted sensors (FB 14308).
|
||||
- **Behavior**: Normalizes group and channel IDs; handles sensor deletion gracefully.
|
||||
|
||||
### `XMLParseGroupTemplates`
|
||||
- **Constructor**: `XMLParseGroupTemplates(XmlElement root, double importedVersion, ISO.ISO13499FileDb iSO13499FileDb, Func<bool> isCancelled = null)`
|
||||
- **Public Methods**:
|
||||
- `IEnumerable<DataPROWin7.DataModel.TestObjectTemplate> ParseGroupTemplates(ref ImportObject importObject, XmlElement root)` – Parses group templates, resolving channels from `importObject.CustomChannels()`. Enforces that referenced ISO test objects exist in `importObject.TestObjects()` (throws `NotSupportedException` if missing, FB 8790).
|
||||
- **Behavior**: Requires pre-parsed custom channels and test objects; validates test object existence.
|
||||
|
||||
### `XMLParseTestSetups`
|
||||
- **Constructor**: `XMLParseTestSetups(XmlElement root, double importedVersion, Func<bool> isCancelled = null, bool skipNormalizing = false)`
|
||||
- **Public Methods**:
|
||||
- `XmlElement ConvertTestTemplates(IEnumerable<TestTemplate> testTemplates, ImportObject importObject)` – Normalizes group IDs, channel IDs (using `_groupIdMapping`, `_channelIdMapping`), and DAS/sensor IDs in channels. Handles missing static group IDs (sets to `null`) and deleted sensors (sets `SensorId = 0`, FB 14308).
|
||||
- `IEnumerable<TestTemplate> ParseTestTemplate(ImportObject importObject, XmlElement root)` – Parses test setups using lookup dictionaries for test objects, groups, customer/lab details, sensors, etc. Catches and logs parsing errors as warnings (FB 36879).
|
||||
- **Behavior**: Requires pre-parsed entities (groups, sensors, etc.) to resolve references; handles missing/invalid references gracefully.
|
||||
|
||||
### `XMLParseCalibrations`
|
||||
- **Constructor**: `XMLParseCalibrations(XmlElement root, double importedVersion, Func<bool> isCancelled = null)`
|
||||
- **Public Methods**:
|
||||
- `XmlElement ConvertCalibrations(IEnumerable<SensorCalibration> calibrations)` – Writes normalized calibration XML.
|
||||
- `IEnumerable<SensorCalibration> ParseCalibrations(XmlElement root)` – Parses calibrations with version-specific logic:
|
||||
- For `importedVersion >= DataPROPre20XmlVersion`: Direct parsing.
|
||||
- For `importedVersion == 1.0`: Sets `AtCapacity = false` and infers `SensitivityUnits` (mV/EU, mV/V/EU, or NONE) based on calibration type.
|
||||
|
||||
### `XMLPre20ParseCalibrations`
|
||||
- **Constructor**: `XMLPre20ParseCalibrations(XmlElement root, double importedVersion, XMLParseCalibrations xmlParseCalibrations, Func<bool> isCancelled = null)`
|
||||
- **Behavior**: Parses pre-2.0 calibrations, adds them to sensors via `AddToSensor()`, then delegates normalization and re-parsing to `_xmlParseCalibrations`.
|
||||
|
||||
### `XMLParseMMECustom*` Parsers (e.g., `XMLParseMMECustomChannels`, `XMLParseMMECustomPositions`, etc.)
|
||||
- **Common Pattern**:
|
||||
- **Constructor**: `XMLParseMMECustom* (XmlElement root, double importedVersion, Func<bool> isCancelled = null)`
|
||||
- **Public/Protected Methods**:
|
||||
- `ParseCustom* (XmlElement root)` – Parses a list of MME objects (e.g., `ISO.MMEPossibleChannels`, `ISO.MMEPositions`) from XML child nodes.
|
||||
- `Parse(ref ImportObject importObject)` – Adds parsed list to `importObject` via `AddCustom*()` methods.
|
||||
- **Behavior**: Iterates child `XmlElement`s, calls `ReadXML()` on each, and respects cancellation. No normalization or migration logic (assumes current-version format).
|
||||
|
||||
### `XMLPre20ParseGroupTemplates`
|
||||
- **Constructor**: `XMLPre20ParseGroupTemplates(XmlElement root, double importedVersion, XMLParseGroupTemplates xmlParseGroupTemplates, Func<bool> isCancelled = null)`
|
||||
- **Behavior**: Delegates parsing to `_xmlParseGroupTemplates.ParseGroupTemplates()`; no migration logic visible.
|
||||
|
||||
### `XMLParseUsers`
|
||||
- **Constructor**: `XMLParseUsers(XmlElement root, double importedVersion, IEnumerable<IUIItems> uiItems, Func<bool> isCancelled = null)`
|
||||
- **Behavior**: Parses `User` objects using `User.ReadXML()`, passing `uiItems` for UI context.
|
||||
|
||||
### `XMLParseTestEngineerDetails`, `XMLParseLabDetails`, `XMLParseCustomerDetails`
|
||||
- **Pattern**: Parse → Convert → Re-parse → Add to `importObject`.
|
||||
- `Parse*()` – Initial parse.
|
||||
- `Convert*()` – Writes parsed objects to XML.
|
||||
- Re-parse normalized XML to ensure consistency.
|
||||
- **Behavior**: All use `Convert*()` to normalize and re-parse; no ID mapping beyond XML structure.
|
||||
|
||||
### `XMLParseGlobalSettings`
|
||||
- **Constructor**: `XMLParseGlobalSettings(XmlElement root, double importedVersion, Func<bool> isCancelled = null)`
|
||||
- **Behavior**: Parses `<SettingName>` and `<SettingValue>` child elements into a `Dictionary<string, string>`.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **ID Normalization**: All parsers that normalize IDs (e.g., `XMLParseSensors`, `XMLParseDASList`, `XMLParseGroups`, `XMLParseTestSetups`) assign negative integer IDs starting at -1 or -2 (to avoid conflicts with database IDs). Mappings are stored in static dictionaries (`_sensorIdMapping`, `_dasIdMapping`, `_groupIdMapping`, `_channelIdMapping`) and used during cross-entity resolution.
|
||||
- **Cancellation Handling**: All parsers check `IsCancelled()` before processing each node and return partial results if cancelled.
|
||||
- **XML Node Validation**: All parsers skip non-`XmlElement` nodes (e.g., whitespace, comments) during iteration.
|
||||
- **Version-Specific Parsing**: Calibrations and sensors have distinct parsing logic for `importedVersion == 1.0` vs. newer versions.
|
||||
- **Group Template Validation**: `XMLParseGroupTemplates` enforces that referenced ISO test objects exist in `importObject.TestObjects()`; throws `NotSupportedException` if missing.
|
||||
- **DAS Type Validation**: `XMLParseDASList` filters out `DASHardware` with invalid `DASType` enums but does not report errors (silently drops entries).
|
||||
- **Sensor Deletion Handling**: Group and Test Setup parsers set `SensorId = 0` for deleted sensors (FB 14308) to avoid import failures.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Internal Dependencies
|
||||
- **Imports**:
|
||||
- `DTS.Common.Import.Interfaces` (`ImportObject`, `IParseVariant`, `IImportNotification`, `ImportStatus`, `ImportError`, `ImportSeverityError`)
|
||||
- `DTS.Common.Interface.*` (e.g., `GroupTemplate`, `Groups.GroupList`, `Sensors`, `Channels`)
|
||||
- `DTS.SensorDB` (`SensorModel`, `SensorData`, `SensorCalibration`)
|
||||
- `DataPROWin7.DataModel` (`DASHardware`, `TestObjectTemplate`)
|
||||
- `ISO.*` (e.g., `MMEPossibleChannels`, `MMETestObjects`, `MMEPositions`, `TestEngineerDetails`, `CustomerDetails`, `LabratoryDetails`)
|
||||
- `System.Xml` (`XmlElement`, `XmlDocument`, `XmlWriter`)
|
||||
- **Shared State**:
|
||||
- Static dictionaries in `XMLParseBase` (`_dasIdMapping`, `_groupIdMapping`, `_sensorIdMapping`, `_channelIdMapping`) are shared across parsers in the same import session.
|
||||
- `ImportNotification` property used for status updates (settable via property).
|
||||
- **Constructor Injection**:
|
||||
- Pre-2.0 parsers (`XMLPre20ParseSensors`, `XMLPre20ParseDASList`, `XMLPre20ParseCalibrations`, `XMLPre20ParseGroupTemplates`) depend on their post-2.0 counterparts to perform normalization and final parsing.
|
||||
|
||||
### External Dependencies
|
||||
- `DataPROWin7.DataModel.DASHardware.ReadXML()` – Static method for pre-2.0 DAS parsing.
|
||||
- `ISO.*.ReadXML()` – Static methods for MME object parsing (e.g., `ISO.MMEPossibleChannels.ReadXML()`).
|
||||
- `User.ReadXML()` – Static method for user parsing.
|
||||
- `SensorData.ReadXML()`, `SensorCalibration.ReadXML()` – Static methods for sensor/calibration parsing.
|
||||
- `DataPROWin7.DataModel.TestObjectTemplate.ReadXML()` – Static method for group template parsing.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Silent DAS Filtering**: `XMLParseDASList.ParseDASList()` silently drops DAS entries with invalid `DASType` enums (no error logged or reported).
|
||||
- **ID Mapping Side Effects**: Static ID mappings in `XMLParseBase` are shared across parsers; clearing them (e.g., in `XMLParseDASList` constructor) may affect other parsers if not coordinated.
|
||||
- **Version-Specific Calibration Logic**: For `importedVersion == 1.0`, `XMLParseCalibrations` mutates calibration records (e.g., sets `AtCapacity = false`, infers `SensitivityUnits`). This logic is duplicated in `XMLPre20ParseCalibrations`.
|
||||
- **FB References**: Several parsers reference internal bug IDs (e.g., FB 8790, FB 14308, FB 36879) in comments or exceptions; these are internal tracking references.
|
||||
- **Test Setup Reference Resolution**: `XMLParseTestSetups.ParseTestTemplate()` uses lookup dictionaries built from `importObject` entities; if entities are not parsed in the correct order, lookups may fail (e.g., missing groups/sensors).
|
||||
- **Group Template Test Object Validation**: `XMLParseGroupTemplates` throws `NotSupportedException` if a referenced ISO test object is missing; this is a hard failure.
|
||||
- **XML Writer State**: `XMLParseBase` uses a shared `XmlWriter` instance per parser; reusing the same writer across multiple `Convert*()` calls without reinitialization may cause issues (though current code creates a new `_doc` per instance).
|
||||
- **Pre-2.0 Migration Assumptions**: `XMLPre20Parse*` parsers assume the target parser (`_xmlParse*`) handles normalization; no validation that the target parser is compatible with the migrated XML structure.
|
||||
- **Group ID Mapping Ambiguity**: `XMLParseGroups` uses `_groupIdMapping` with keys as `g.Id.ToString()` (post-2.0) or `g.Name` (pre-2.0); this dual-key approach may cause issues if group names collide with numeric IDs.
|
||||
- **Channel ID Normalization**: `XMLParseTestSetups` normalizes channel IDs *after* normalizing group IDs; order of normalization matters for cross-references.
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Licensing/Enums/DataProLicensingEnums.cs
|
||||
generated_at: "2026-04-16T03:29:49.432908+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "94783647b326bc4a"
|
||||
---
|
||||
|
||||
# Enums
|
||||
|
||||
## 1. Purpose
|
||||
This module defines core licensing-related enumerations used throughout the DataPro system. Specifically, it declares the `LicenseType` enum, which categorizes different software license tiers available in the product. Its role is to provide a standardized, type-safe representation of license types across licensing validation, feature gating, and configuration logic in the broader codebase.
|
||||
|
||||
## 2. Public Interface
|
||||
The only public type exposed is the `LicenseType` enum, nested inside the `DataProLicensingEnums` class.
|
||||
|
||||
- **`DataProLicensingEnums.LicenseType`**
|
||||
- **Definition**: `public enum LicenseType`
|
||||
- **Values**:
|
||||
- `Standard = 0`
|
||||
- `Enterprise = 1`
|
||||
- `EnterpriseSite = 2`
|
||||
- `TSRAir = 3`
|
||||
- `StandardSite = 4`
|
||||
- **Behavior**: Represents discrete license tiers. Values are explicitly assigned integer constants (0–4). The `StandardSite` value was added in response to feature request FB 30628.
|
||||
|
||||
## 3. Invariants
|
||||
- The `LicenseType` enum contains exactly five defined values; no others are declared in this file.
|
||||
- Each enum value maps to a unique underlying integer (0 through 4), with no duplicates.
|
||||
- The enum is *not* marked with `[Flags]`, implying values are mutually exclusive and not combinable via bitwise operations.
|
||||
- The enum is declared as `public`, but the containing class `DataProLicensingEnums` is also `public` and non-static—however, it serves only as a namespace-like container for the enum (a common C# pattern for grouping related enums).
|
||||
|
||||
## 4. Dependencies
|
||||
- **Dependencies *of* this module**:
|
||||
- `System`, `System.Collections.Generic`, `System.Linq`, `System.Text`, `System.Threading.Tasks` (standard .NET namespaces).
|
||||
- **Dependencies *on* this module**:
|
||||
- Not inferable from this file alone. However, given the namespace `DTS.Common.Licensing`, it is highly likely that other modules in the `DTS.Common.*` assembly (e.g., licensing validation, feature management, or UI components) depend on this enum.
|
||||
|
||||
## 5. Gotchas
|
||||
- The class `DataProLicensingEnums` is non-static and contains only an enum—this is unusual and may cause confusion (e.g., developers might instantiate it unnecessarily). It likely exists for historical or organizational reasons.
|
||||
- The comment `//FB 30628 Added StandardSite license type` indicates a feature request reference; developers should consult external tracking (e.g., Jira, Azure DevOps) for full context if needed.
|
||||
- No validation or conversion helpers (e.g., `TryParse`, `IsValid`) are defined in this file—consumers must implement their own validation if required.
|
||||
- No documentation comments (XML doc comments) are present on the enum or its members; developers must infer semantics from names and comments alone.
|
||||
- None identified from source alone.
|
||||
@@ -0,0 +1,84 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Licensing/Messages/ValidationFailure.cs
|
||||
- Common/DTS.Common.Licensing/Messages/LicenseKey.cs
|
||||
- Common/DTS.Common.Licensing/Messages/ValidationResult.cs
|
||||
generated_at: "2026-04-16T03:29:48.963073+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "52e7e10ea2ae6d13"
|
||||
---
|
||||
|
||||
# Messages
|
||||
|
||||
## Documentation: Licensing Validation Messages
|
||||
|
||||
### 1. Purpose
|
||||
This module defines core data structures used for representing license validation outcomes and license metadata within the DTS licensing system. It provides strongly-typed message contracts (`ValidationResult`, `ValidationFailure`, `LicenseKey`) that enable consistent communication of license status—such as validity, expiration, version compatibility, and ownership—between licensing validation components and downstream consumers (e.g., UI, service layers, or license enforcement logic). These types serve as the canonical output of license validation operations and are intended to decouple validation logic from business logic by standardizing the shape of validation results.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `ValidationFailure`
|
||||
- **Namespace**: `DTS.Common.Licensing.Messages`
|
||||
- **Properties**:
|
||||
- `string Message { get; set; }` – A human-readable description of the validation issue (e.g., `"License has expired"`).
|
||||
- `string HowToResolve { get; set; }` – Guidance on how to remediate the failure (e.g., `"Renew your license at https://example.com/renew"`).
|
||||
- **Behavior**: A simple DTO for encapsulating a single validation failure; no validation or side effects occur upon construction or property assignment.
|
||||
|
||||
#### `LicenseKey`
|
||||
- **Namespace**: `DTS.Common.Licensing`
|
||||
- **Properties**:
|
||||
- `string KeyGuid { get; set; }` – A string representation of the license’s unique identifier (likely a GUID).
|
||||
- `string PublicKey { get; set; }` – The public key associated with the license (e.g., used for signature verification).
|
||||
- **Behavior**: A lightweight DTO for conveying core license identification and cryptographic material; no validation or processing is performed.
|
||||
|
||||
#### `ValidationResult`
|
||||
- **Namespace**: `DTS.Common.Licensing.Messages`
|
||||
- **Properties**:
|
||||
- `IEnumerable<ValidationFailure> ValidationFailures { get; set; }` – Collection of all validation failures encountered; may be `null` or empty if no failures occurred.
|
||||
- `bool IsLicenseExpired { get; set; }` – `true` if the license has expired (based on `LicenseExpiration`); `false` otherwise.
|
||||
- `bool IsLicenseVersionValid { get; set; }` – `true` if the license version is compatible with the current product version; `false` otherwise.
|
||||
- `Version ProductVersion { get; set; }` – The version of the product being licensed (e.g., `1.2.3.0`).
|
||||
- `string LicenseVersion { get; set; }` – The version string declared in the license (e.g., `"1.2"`).
|
||||
- `DateTime? LicenseExpiration { get; set; }` – The expiration date/time of the license; `null` if the license does not expire.
|
||||
- `bool IsValid { get; set; }` – `true` if *all* validation checks passed (i.e., `ValidationFailures` is empty, `IsLicenseExpired` is `false`, and `IsLicenseVersionValid` is `true`); `false` otherwise.
|
||||
- `bool IsLicensed { get; set; } = true` – Indicates whether a license file was present and loaded (`true`) or absent (`false`). Default value is `true`.
|
||||
- `string LicensedTo { get; set; }` – The entity (e.g., company or user name) to whom the license was issued.
|
||||
- `DataProLicensingEnums.LicenseType LicenseType { get; set; }` – The type of license (e.g., Trial, Standard, Enterprise); defined in `DataProLicensingEnums`.
|
||||
- `Guid LicenseId { get; set; }` – The unique identifier of the license.
|
||||
- **Behavior**: Encapsulates the complete result of a license validation operation. The `IsValid` property is derived from the combination of other fields (see *Invariants*), not computed independently.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
- **`IsValid` is logically dependent**: `IsValid` must be `true` if and only if:
|
||||
- `ValidationFailures` is `null` or empty,
|
||||
- `IsLicenseExpired` is `false`, and
|
||||
- `IsLicenseVersionValid` is `true`.
|
||||
*(Note: The source does not enforce this via code—e.g., no setter logic—but it is the intended semantic contract implied by the property name and comments.)*
|
||||
- **`IsLicensed` default**: `IsLicensed` defaults to `true`; a value of `false` explicitly indicates the license file was not found or could not be loaded.
|
||||
- **`LicenseExpiration` may be null**: A `null` value for `LicenseExpiration` signifies a perpetual (non-expiring) license.
|
||||
- **`ValidationFailures` may be null**: The property is not initialized to an empty collection by default, so consumers must handle `null` explicitly.
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
- **Internal dependencies**:
|
||||
- `System` (via `System.Collections.Generic`, `System.Linq`, `System.Text`, `System.Threading.Tasks`, `System` implicitly for `Version`, `DateTime`, `Guid`).
|
||||
- `DataProLicensingEnums.LicenseType` (referenced in `ValidationResult.LicenseType`); defined in an external assembly (`DTS.Common.Licensing` namespace implies a dependency on `DTS.Common.Licensing.dll`, but the enum itself is not defined in the provided sources).
|
||||
- **Consumers**:
|
||||
- Licensing validation services (e.g., a `LicenseValidator` class not shown here) are expected to produce `ValidationResult` instances.
|
||||
- UI or middleware layers that consume validation results to make decisions (e.g., enabling/disabling features, prompting renewal).
|
||||
- **No external library dependencies** beyond core .NET types (e.g., no third-party packages referenced in the provided files).
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
- **`ValidationFailures` is not initialized**: The property `ValidationFailures` is not auto-initialized to an empty collection (e.g., via `= new List<ValidationFailure>()`), so consumers must check for `null` before enumeration.
|
||||
- **`IsValid` is not computed automatically**: Though logically defined by other properties, `IsValid` is a simple `bool` with no setter logic or computed backing; callers must ensure it is set consistently by the producer (e.g., validation service).
|
||||
- **`IsLicensed` default may be misleading**: Its default value of `true` could cause confusion if a `ValidationResult` is constructed without explicitly setting `IsLicensed = false` when no license file exists.
|
||||
- **`LicenseKey.KeyGuid` is a string, not a `Guid`**: Despite the name suggesting a GUID, it is stored as a `string`, which may include formatting (e.g., with/without dashes) or non-GUID values. Consumers should not assume parseability without validation.
|
||||
- **No version comparison logic in `ValidationResult`**: While `ProductVersion` and `LicenseVersion` are present, the class itself provides no helper for comparing them (e.g., `IsLicenseVersionValid` is set externally).
|
||||
- **Missing `LicenseKey` usage context**: The `LicenseKey` class is defined but no usage or relationship to `ValidationResult`/`ValidationFailure` is evident from these files alone (e.g., whether `LicenseKey` is used as input to validation).
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Licensing/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T03:29:56.774702+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "b8a216f95467a02c"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## 1. Purpose
|
||||
This module (`DTS.Common.Licensing`) is an assembly containing licensing-related functionality for the DTS (presumably *Document Tracking System* or domain-specific) platform. Based solely on the provided file, it serves as a foundational .NET assembly with no visible licensing logic exposed in the snippet—its purpose is likely to encapsulate licensing infrastructure (e.g., license validation, feature flags, or activation logic), but the actual implementation resides in other source files not included here. The assembly is configured as a non-`ComVisible` library with version `1.0.0.0`, indicating it is an initial stable release intended for internal use within the .NET ecosystem.
|
||||
|
||||
## 2. Public Interface
|
||||
**No public types, functions, classes, or methods are defined in this file.**
|
||||
The file `AssemblyInfo.cs` contains only assembly-level metadata attributes (e.g., title, version, GUID) and does not declare any executable code, interfaces, or public APIs. Therefore, there are *no* public functions, classes, or methods documented here.
|
||||
|
||||
## 3. Invariants
|
||||
- The assembly is **not visible to COM** (`ComVisible(false)`), meaning external COM clients cannot directly instantiate or reference its types.
|
||||
- The assembly version is fixed at `1.0.0.0` for both `AssemblyVersion` and `AssemblyFileVersion`.
|
||||
- The `Guid` attribute (`8b169b1c-37cb-4b7c-8071-385036b96faa`) uniquely identifies the typelib for COM interop *if* `ComVisible` were enabled (though it is not).
|
||||
- All assembly attributes are statically defined and immutable at compile time.
|
||||
|
||||
## 4. Dependencies
|
||||
- **Dependencies**: None declared in this file. It only references standard .NET attributes (`System.Reflection`, `System.Runtime.CompilerServices`, `System.Runtime.InteropServices`).
|
||||
- **Dependents**: Unknown from this file alone. As a shared library (`DTS.Common.*`), it is likely referenced by other modules in the DTS platform (e.g., `DTS.Server`, `DTS.Client`), but no explicit references are visible here.
|
||||
|
||||
## 5. Gotchas
|
||||
- **No licensing logic is present in this file**—this is purely assembly metadata. Developers should not expect to find licensing functionality here; implementation resides in other source files (e.g., `LicenseManager.cs`, `LicenseValidator.cs`).
|
||||
- The `AssemblyVersion` and `AssemblyFileVersion` are both hardcoded to `1.0.0.0`. If versioning is managed elsewhere (e.g., via CI/CD or `Directory.Build.props`), this may be redundant or overridden.
|
||||
- The `AssemblyConfiguration` and `AssemblyCompany` attributes are empty strings, which may cause issues in environments expecting non-empty metadata (e.g., installer tools or telemetry).
|
||||
- None identified from source alone.
|
||||
@@ -0,0 +1,91 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Licensing/SystemInformation/MachineInfo.cs
|
||||
- Common/DTS.Common.Licensing/SystemInformation/ComputerSystemInfo.cs
|
||||
- Common/DTS.Common.Licensing/SystemInformation/MainBoardInfo.cs
|
||||
- Common/DTS.Common.Licensing/SystemInformation/ProcessorInfo.cs
|
||||
- Common/DTS.Common.Licensing/SystemInformation/SystemInformationXSD.cs
|
||||
generated_at: "2026-04-16T03:29:41.596274+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "3f95f5cfcf14dbc2"
|
||||
---
|
||||
|
||||
# SystemInformation
|
||||
|
||||
## Documentation: System Information Module (`DTS.Common.Licensing.SystemInformation`)
|
||||
|
||||
---
|
||||
|
||||
### 1. **Purpose**
|
||||
|
||||
This module provides static accessors to retrieve hardware-identifying information from the local Windows machine using WMI (Windows Management Instrumentation) and .NET environment APIs. It is part of the licensing subsystem and is intended to supply stable, hardware-based identifiers (e.g., motherboard serial, CPU ID, system UUID) for machine fingerprinting or license validation. The module is read-only and defensive: all property getters return empty strings on failure instead of throwing exceptions, ensuring robustness in constrained or non-standard environments.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
|
||||
All types are `static` classes; no instantiation is required.
|
||||
|
||||
| Type | Member | Signature | Behavior |
|
||||
|------|--------|-----------|----------|
|
||||
| `MachineInfo` | `MachineName` | `public static string MachineName { get; }` | Returns the network name of the machine via `Environment.MachineName`. Returns `""` on any exception. |
|
||||
| `ComputerSystemInfo` | `SystemID` | `public static string SystemID { get; }` | Returns the UUID of the computer system product (from `Win32_ComputerSystemProduct.UUID`). Returns `""` on any exception. |
|
||||
| `MainBoardInfo` | `SerialNumber` | `public static string SerialNumber { get; }` | Returns the serial number of the baseboard (motherboard) (from `Win32_BaseBoard.SerialNumber`). Returns `""` on any exception. |
|
||||
| `ProcessorInfo` | `ProcessorID` | `public static string ProcessorID { get; }` | Returns the `ProcessorID` field of the first processor (from `Win32_Processor.ProcessorID`). Returns `""` on any exception. |
|
||||
| `SystemInformationXSD` | `XSD` | `public static string XSD { get; }` | Returns a hardcoded XML Schema Definition (XSD) string for validating a `SysInfo` XML document containing the above fields. |
|
||||
|
||||
> **Note**: All getters are *eagerly evaluated* on first access and cached internally (via static field initialization or static property getter logic). Subsequent accesses reuse the result unless the underlying WMI query is re-executed (see *Gotchas*).
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
|
||||
- **Non-null return values**: All public properties return either a non-empty string (if WMI/Environment data is successfully retrieved) or `""` (empty string) on failure. **No property ever returns `null`.**
|
||||
- **No side effects**: Property getters are idempotent *per call*, but due to static `ManagementObjectSearcher` fields, repeated access may reuse cached WMI results (see *Gotchas*).
|
||||
- **Windows-only dependency**: All WMI-based properties (`SystemID`, `SerialNumber`, `ProcessorID`) assume Windows and rely on `System.Management`. Behavior on non-Windows platforms is undefined (but likely to return `""` due to exception handling).
|
||||
- **Schema consistency**: The `XSD` string defines a fixed schema for a `SysInfo` XML element containing exactly four child elements (`MainBoardSerialNumber`, `ProcessorID`, `SystemID`, `MachineName`) and two attributes (`Version`, `SystemInformationGuid`). The order of child elements is fixed.
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
|
||||
| Dependency | Usage |
|
||||
|------------|-------|
|
||||
| `System.Environment` (mscorlib) | Used by `MachineInfo.MachineName` to fetch machine name. |
|
||||
| `System.Management` (System.Management.dll) | Required for all WMI-based properties (`ComputerSystemInfo.SystemID`, `MainBoardInfo.SerialNumber`, `ProcessorInfo.ProcessorID`). |
|
||||
| `System.Linq` (System.Core.dll) | Used via LINQ extension methods (`OfType<T>()`, `FirstOrDefault()`) to safely extract WMI results. |
|
||||
| `System.Collections.Generic` (System.Core.dll) | Used for `ManagementObjectSearcher.Get()` result enumeration. |
|
||||
|
||||
**Depended on by**:
|
||||
This module is part of `DTS.Common.Licensing`, implying it is consumed by licensing validation logic (e.g., to generate or verify machine fingerprints). No direct reverse dependencies are visible in the provided source.
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
|
||||
- **WMI query execution is not lazy per access**:
|
||||
`ManagementObjectSearcher` instances are *static fields*, initialized once at type initialization. Each property getter calls `systemSearcher.Get()` (or equivalent) *on every access*, meaning repeated calls to `ProcessorInfo.ProcessorID` will re-execute the WMI query each time. This is inefficient and may cause performance issues if called frequently. Consider caching the first result (e.g., via `Lazy<T>` or a static field) if repeated access is expected.
|
||||
|
||||
- **`Win32_*` WMI classes are Windows-specific**:
|
||||
On non-Windows platforms (e.g., via .NET Core on Linux/macOS), `System.Management` may not be available or may throw exceptions. All properties will return `""`, but this behavior is not guaranteed across all environments.
|
||||
|
||||
- **`ProcessorID` may be empty or non-unique**:
|
||||
The `Win32_Processor.ProcessorID` field is *not guaranteed* to be populated on all systems (e.g., virtual machines, some OEM hardware). It may be empty or fall back to a placeholder value. The code does not validate uniqueness or consistency across processors.
|
||||
|
||||
- **`SystemID` vs. `UUID` ambiguity**:
|
||||
The WMI class `Win32_ComputerSystemProduct.UUID` is used for `SystemID`. While commonly stable, UUIDs can be reset (e.g., BIOS reset, VM cloning) or duplicated in some virtualized environments.
|
||||
|
||||
- **No validation of WMI field presence**:
|
||||
The code assumes the WMI properties (`UUID`, `SerialNumber`, `ProcessorID`) exist and are non-null. If a property is missing from the WMI result (e.g., due to driver issues), `["FieldName"]` may throw a `NullReferenceException`, which is caught and returns `""`. This is safe but obscures the root cause.
|
||||
|
||||
- **`SystemInformationXSD.XSD` is hardcoded and immutable**:
|
||||
The schema string is constant at compile time. There is no mechanism to update or version the schema dynamically. The `Version` and `SystemInformationGuid` attributes are defined in the schema but not used by any code in this module.
|
||||
|
||||
- **No thread-safety guarantees**:
|
||||
While `ManagementObjectSearcher` is generally thread-safe for concurrent reads, the module does not document or enforce thread-safety. Concurrent access to these properties is *likely* safe but not guaranteed by design.
|
||||
|
||||
- **No cleanup of WMI resources**:
|
||||
`ManagementObjectSearcher` implements `IDisposable`, but none of the searchers are disposed. This may lead to resource leaks in long-running processes (e.g., services), though `ManagementObjectSearcher` internally manages native handles and may mitigate this.
|
||||
|
||||
> **Recommendation for future refactoring**: Cache results on first access using `Lazy<string>` and ensure proper disposal of WMI resources if repeated access is common.
|
||||
109
enriched-qwen3-coder-next/Common/DTS.Common.Property.md
Normal file
109
enriched-qwen3-coder-next/Common/DTS.Common.Property.md
Normal file
@@ -0,0 +1,109 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Property/PropertyModule.cs
|
||||
generated_at: "2026-04-16T14:12:34.427071+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "5ade2343bf1c7a50"
|
||||
---
|
||||
|
||||
# Documentation: DTS.Common.Property.PropertyModule
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module serves as the Prism module initializer for the Property component within the DTS application. It registers the Property view and view-model with the Unity dependency injection container, enabling the Property UI component to be dynamically loaded and displayed in the application's modular architecture. The module also defines assembly-level metadata attributes (`PropertiesNameAttribute` and `PropertiesImageAttribute`) that provide display information (name, image, region, group) used by the main shell to present this module as an available component to users.
|
||||
|
||||
---
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `PropertyModule` Class
|
||||
|
||||
**Signature:**
|
||||
```csharp
|
||||
[Export(typeof(IModule))]
|
||||
[Module(ModuleName = "Property")]
|
||||
public class PropertyModule : IModule
|
||||
```
|
||||
|
||||
| Member | Signature | Description |
|
||||
|--------|-----------|-------------|
|
||||
| Constructor | `public PropertyModule(IUnityContainer unityContainer)` | Accepts an injected Unity container reference for DI registration. |
|
||||
| `Initialize()` | `public void Initialize()` | Registers `IPropertyView` → `PropertyView` and `IPropertyViewModel` → `PropertyViewModel` with the Unity container (transient lifetime, not singleton despite the comment). |
|
||||
|
||||
### `PropertiesNameAttribute` Class
|
||||
|
||||
**Signature:**
|
||||
```csharp
|
||||
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
|
||||
public class PropertiesNameAttribute : TextAttribute
|
||||
```
|
||||
|
||||
| Member | Signature | Description |
|
||||
|--------|-----------|-------------|
|
||||
| Default Constructor | `public PropertiesNameAttribute()` | Initializes with no parameters. |
|
||||
| Parameterized Constructor | `public PropertiesNameAttribute(string s)` | Accepts a string parameter (which is ignored). |
|
||||
| `AssemblyName` | `public override string AssemblyName { get; }` | Returns hardcoded value `"PropertiesAsssembly"`. |
|
||||
| `GetAttributeType()` | `public override Type GetAttributeType()` | Returns `typeof(TextAttribute)`. |
|
||||
| `GetAssemblyName()` | `public override string GetAssemblyName()` | Returns the `AssemblyName` property value. |
|
||||
|
||||
### `PropertiesImageAttribute` Class
|
||||
|
||||
**Signature:**
|
||||
```csharp
|
||||
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
|
||||
public class PropertiesImageAttribute : ImageAttribute
|
||||
```
|
||||
|
||||
| Member | Signature | Description |
|
||||
|--------|-----------|-------------|
|
||||
| Default Constructor | `public PropertiesImageAttribute()` | Initializes with no parameters. |
|
||||
| Parameterized Constructor | `public PropertiesImageAttribute(string s)` | Accepts a string parameter (which is ignored). |
|
||||
| `AssemblyImage` | `public override BitmapImage AssemblyImage { get; }` | Retrieves image via `AssemblyInfo.GetImage(AssemblyNames.Property.ToString())`. |
|
||||
| `AssemblyName` | `public override string AssemblyName { get; }` | Returns `AssemblyNames.Property.ToString()`. |
|
||||
| `AssemblyGroup` | `public override string AssemblyGroup { get; }` | Returns `eAssemblyGroups.Viewer.ToString()`. |
|
||||
| `AssemblyRegion` | `public override eAssemblyRegion AssemblyRegion { get; }` | Returns `eAssemblyRegion.PropertyRegion`. |
|
||||
| `GetAttributeType()` | `public override Type GetAttributeType()` | Returns `typeof(ImageAttribute)`. |
|
||||
| `GetAssemblyImage()` | `public override BitmapImage GetAssemblyImage()` | Returns the `AssemblyImage` property. |
|
||||
| `GetAssemblyName()` | `public override string GetAssemblyName()` | Returns the `AssemblyName` property. |
|
||||
| `GetAssemblyRegion()` | `public override eAssemblyRegion GetAssemblyRegion()` | Returns the `AssemblyRegion` property. |
|
||||
| `GetAssemblyGroup()` | `public override string GetAssemblyGroup()` | Returns the `AssemblyGroup` property. |
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Single Instance per Assembly**: Both `PropertiesNameAttribute` and `PropertiesImageAttribute` are applied at assembly level with `AllowMultiple = false`, ensuring only one instance of each exists per assembly.
|
||||
- **Module Name**: The module is registered with the fixed name `"Property"` via the `[Module]` attribute.
|
||||
- **Registration Lifetime**: The `RegisterType` calls in `Initialize()` register types with transient (not singleton) lifetime. The code comment claims singleton registration, but `RegisterType` without a `ContainerControlledLifetimeManager` creates new instances per resolve.
|
||||
- **Attribute Parameter Ignored**: Both attribute classes accept a `string s` parameter in their constructors, but this value is never used.
|
||||
|
||||
---
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### This Module Depends On:
|
||||
- `System` - Core .NET framework
|
||||
- `System.ComponentModel.Composition` - MEF for module export
|
||||
- `System.Windows.Media.Imaging` - `BitmapImage` for assembly image
|
||||
- `Microsoft.Practices.Prism.Modularity` - `IModule` interface and `[Module]` attribute
|
||||
- `Microsoft.Practices.Unity` - `IUnityContainer` for DI
|
||||
- `DTS.Common.Interface` - Defines `IPropertyView`, `IPropertyViewModel`, `TextAttribute`, `ImageAttribute`, `AssemblyNames`, `eAssemblyGroups`, `eAssemblyRegion`, `AssemblyInfo` (inferred from usage)
|
||||
|
||||
### What Depends On This Module:
|
||||
- The main application shell (loads this module via Prism's module catalog)
|
||||
- The main UI (uses assembly attributes to display module metadata)
|
||||
|
||||
---
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
1. **Typo in Assembly Name**: `PropertiesNameAttribute._assemblyName` is hardcoded to `"PropertiesAsssembly"` (note the triple 's': "Asss" instead of "Asse"). This may cause display or lookup issues.
|
||||
|
||||
2. **Misleading XML Comment**: The constructor's XML documentation references `<see cref="PropertiesModule"/>`, but the actual class name is `PropertyModule` (singular "Property", not "Properties").
|
||||
|
||||
3. **Misleading Registration Comment**: The comment in `Initialize()` states "Register View & View-Model... as a singleton", but `RegisterType<TFrom, TTo>()` without a lifetime manager registers types as transient, not singleton. To achieve singleton behavior, `RegisterType<TFrom, TTo>(new ContainerControlledLifetimeManager())` would be required.
|
||||
|
||||
4. **Property Getters with Side Effects**: The `AssemblyImage` property getter in `PropertiesImageAttribute` has a side effect—it assigns to the private `_img` field. This violates typical property getter conventions and could cause unexpected behavior if the property is accessed multiple times.
|
||||
|
||||
5. **Ignored Constructor Parameters**: Both attribute classes have constructors accepting a `string s` parameter that is completely ignored. This is confusing and potentially dead code.
|
||||
@@ -0,0 +1,62 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Property/Model/GraphPropertyObject.cs
|
||||
generated_at: "2026-04-16T03:28:40.550784+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "9e6ad0b9e1f98318"
|
||||
---
|
||||
|
||||
# Model
|
||||
|
||||
### **Purpose**
|
||||
`GraphPropertyObject` is a data model class designed to expose a standardized set of graph-related metadata properties for display and editing in a WPF PropertyGrid control (specifically, the Xceed WPF Toolkit PropertyGrid). It serves as a base or shared model for objects whose properties need to be presented in a structured, categorized UI—typically for configuration, debugging, or visualization of graph elements (e.g., nodes, edges, or signal traces in a DTS system). The class encapsulates user-facing metadata such as description, filtering criteria, data flags, and engineering unit (EU) conversion parameters, enabling consistent property browsing without requiring custom UI logic.
|
||||
|
||||
---
|
||||
|
||||
### **Public Interface**
|
||||
|
||||
All members are instance properties; no methods or nested types are defined.
|
||||
|
||||
| Property | Type | Attributes | Description |
|
||||
|----------|------|------------|-------------|
|
||||
| `Description` | `string` | `[Category("Action")]`, `[DisplayName("Description")]`, `[Description("This property uses a TextBox as the default editor.")]` | Free-text description of the graph element. |
|
||||
| `Filter` | `string` | `[Category("Action")]`, `[DisplayName("Filter")]`, `[Description("This property uses a TextBox as the default editor.")]`, `[ItemsSource(typeof(CFCFilterItemSource))]` | Filter string (likely for narrowing displayed data). Uses `CFCFilterItemSource` as a source for dropdown suggestions (though the actual `CFCFilterItemSource` type is not defined in this file). |
|
||||
| `DataFlag` | `string` | `[Category("Information")]`, `[DisplayName("Data Flag")]`, `[Description("This property uses a TextBox as the default editor.")]` | A flag indicating data status or type (e.g., "Valid", "Stale"). |
|
||||
| `ShiftT0` | `double` | `[Category("Information")]`, `[DisplayName("Shift T0 (ms)")]`, `[Description("This property uses a TextBox as the default editor.")]` | Time shift offset applied to the signal’s time base, in milliseconds. |
|
||||
| `EuMultiplier` | `double` | `[Category("Information")]`, `[DisplayName("EU Multiplier")]`, `[Description("This property uses a TextBox as the default editor.")]` | Multiplicative factor for converting raw values to engineering units. |
|
||||
| `EuOffset` | `double` | `[Category("Information")]`, `[DisplayName("EU Offset")]`, `[Description("This property uses a TextBox as the default editor.")]` | Additive offset for converting raw values to engineering units. |
|
||||
|
||||
> **Note**: All properties use `TextBox` editors by default in the PropertyGrid. The `ItemsSource` attribute on `Filter` implies integration with `CFCFilterItemSource`, but its implementation is not included here.
|
||||
|
||||
---
|
||||
|
||||
### **Invariants**
|
||||
- No explicit validation or invariants are enforced in the class itself (e.g., no null checks, range validation, or required fields).
|
||||
- All properties are publicly gettable/settable; no immutability guarantees.
|
||||
- The `ShiftT0`, `EuMultiplier`, and `EuOffset` properties are of type `double`, but no constraints (e.g., non-negative, finite) are specified in metadata or code.
|
||||
- The `Filter` property’s valid values are *intended* to be constrained by `CFCFilterItemSource`, but the class does not enforce this at runtime.
|
||||
|
||||
---
|
||||
|
||||
### **Dependencies**
|
||||
|
||||
**External Dependencies (via imports):**
|
||||
- `System.ComponentModel` – Used for `CategoryAttribute`, `DisplayNameAttribute`, and `DescriptionAttribute`.
|
||||
- `Xceed.Wpf.Toolkit.PropertyGrid.Attributes` – Provides `ItemsSourceAttribute`, used on the `Filter` property.
|
||||
|
||||
**Type References (not defined here):**
|
||||
- `CFCFilterItemSource` – Referenced as a type argument for `ItemsSourceAttribute` on `Filter`. Its definition is not included in the provided source; likely a custom `IItemSource` implementation for the PropertyGrid.
|
||||
|
||||
**Depended Upon By:**
|
||||
- Inferred to be used by UI components (e.g., PropertyGrid instances) in WPF applications, likely within the `DTS` system (e.g., for configuring graph elements in a test or visualization tool).
|
||||
- No other code in this file references it, so dependencies must be inferred from usage elsewhere in the codebase.
|
||||
|
||||
---
|
||||
|
||||
### **Gotchas**
|
||||
- **Missing `CFCFilterItemSource` definition**: The `ItemsSource` attribute on `Filter` references `CFCFilterItemSource`, but this type is not declared or imported in the provided source. Its behavior (e.g., item format, filtering logic) is unknown without additional context.
|
||||
- **No validation on numeric properties**: `ShiftT0`, `EuMultiplier`, and `EuOffset` accept any `double` value (including `NaN`, `Infinity`, or negative values), which may lead to runtime errors if consumed by downstream logic expecting valid EU conversion parameters.
|
||||
- **No inheritance or interface implementation**: The class is a plain POCO. If intended for data binding or serialization, consumers must ensure compatibility (e.g., via `INotifyPropertyChanged`, though none is implemented here).
|
||||
- **Hard-coded categories**: Categories ("Action", "Information") are fixed; renaming or reorganizing them requires code changes.
|
||||
- **No documentation on EU conversion formula**: While `EuMultiplier` and `EuOffset` suggest linear conversion (`EU = raw * EuMultiplier + EuOffset`), this is not stated explicitly in the source.
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Property/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T03:28:27.855508+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "fde27770883326da"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## Documentation: DTS.Common.Property Assembly (DTS.Viewer.GraphProperties)
|
||||
|
||||
### 1. Purpose
|
||||
This module is an assembly containing shared property-related types for the `DTS.Viewer.GraphProperties` component. It serves as a foundational library for property management within the DTS (Data Tracking System) viewer, likely providing data structures, interfaces, or utilities used by UI or core graph visualization modules to represent and manipulate property metadata. The assembly itself contains no application logic—its purpose is purely to package and version shared property abstractions.
|
||||
|
||||
### 2. Public Interface
|
||||
**No public types are defined in this file.**
|
||||
The file `AssemblyInfo.cs` contains only assembly-level metadata attributes (e.g., `AssemblyTitle`, `AssemblyVersion`). It does not declare any classes, interfaces, structs, enums, or methods. Therefore, there are **no public functions, classes, or methods** documented here. Public APIs must reside in other source files within the `DTS.Common.Property` project.
|
||||
|
||||
### 3. Invariants
|
||||
- The assembly identity is fixed at version `1.0.0.0` (both `AssemblyVersion` and `AssemblyFileVersion`).
|
||||
- The assembly is **not COM-visible** (`ComVisible(false)`), meaning its types cannot be consumed by COM clients unless explicitly exposed via other means (e.g., `ComVisible(true)` on individual types).
|
||||
- The GUID `d076086a-82c6-4c14-a8d6-ce0eea28e3cb` uniquely identifies the typelib for COM interop (though irrelevant given `ComVisible(false)`).
|
||||
- The assembly title and product are consistently named `"DTS.Viewer.GraphProperties"`.
|
||||
- Copyright is attributed to Microsoft (2017), indicating legacy or internal Microsoft ownership.
|
||||
|
||||
### 4. Dependencies
|
||||
- **Dependencies**: This file has no runtime dependencies beyond the .NET Framework base assemblies (`System`, `System.Runtime.InteropServices`, etc.) required for `System.Reflection` and `System.Runtime.CompilerServices`.
|
||||
- **Dependents**: This assembly (`DTS.Common.Property`) is presumably referenced by other modules in the `DTS.Viewer` suite (e.g., `DTS.Viewer.GraphProperties` UI layer, core graph engine), though the dependency direction cannot be inferred from this file alone.
|
||||
|
||||
### 5. Gotchas
|
||||
- **Misleading filename**: The assembly title and product name (`DTS.Viewer.GraphProperties`) do not match the folder path (`Common/DTS.Common.Property`), which may cause confusion about the assembly’s scope.
|
||||
- **No public surface area**: Developers should not expect to find APIs in this file; it is purely metadata. Actual property-related types are likely in other files (e.g., `Property.cs`, `IProperty.cs`).
|
||||
- **Versioning rigidity**: Both `AssemblyVersion` and `AssemblyFileVersion` are hardcoded to `1.0.0.0`. This may indicate legacy code or intentional immutability, but could complicate deployment if version-based binding is expected.
|
||||
- **COM compatibility**: While `ComVisible(false)` is set, the presence of a `Guid` attribute suggests historical COM exposure intent—verify if any types *within the same assembly* (not in this file) are marked `ComVisible(true)`.
|
||||
|
||||
None identified from source alone beyond the above.
|
||||
48
enriched-qwen3-coder-next/Common/DTS.Common.Property/View.md
Normal file
48
enriched-qwen3-coder-next/Common/DTS.Common.Property/View.md
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Property/View/PropertyView.xaml.cs
|
||||
generated_at: "2026-04-16T03:28:35.882669+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "3a321f21820c1d34"
|
||||
---
|
||||
|
||||
# View
|
||||
|
||||
### 1. **Purpose**
|
||||
This module defines the WPF UI view (`PropertyView`) for displaying and editing properties of a graph node or element within the DTS (Data Transformation Services) system. It serves as the concrete implementation of the `IPropertyView` interface, bridging the UI layer with the underlying property model via data binding. Its existence enables a standardized, reusable property editing surface in the application’s UI, likely used in conjunction with a graph editor or configuration panel.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
- **`PropertyView()`**
|
||||
*Signature:* `public PropertyView()`
|
||||
*Behavior:* Constructor that initializes the WPF component by calling `InitializeComponent()`, which wires up the XAML-defined UI elements (from `PropertyView.xaml`) to the code-behind. No additional initialization logic is present in the provided source.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
- The class implements the `IPropertyView` interface (from `DTS.Common.Interface`), implying it adheres to a contract defined elsewhere for property view behavior (e.g., exposing a `DataContext` of a property model, supporting refresh/update methods).
|
||||
- `InitializeComponent()` must be called exactly once during construction—standard WPF practice—ensuring the XAML UI is properly instantiated before use.
|
||||
- No explicit validation or state constraints are visible in this file alone; invariants are likely enforced by the `IPropertyView` interface or by consumers of this view.
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
- **Internal Dependencies:**
|
||||
- `DTS.Common.Interface` namespace (specifically the `IPropertyView` interface).
|
||||
- **External Dependencies (WPF):**
|
||||
- `System.Windows.Controls` (via `partial class PropertyView : Window/UserControl` implied by XAML).
|
||||
- `PropertyView.xaml` (must exist in the same project/folder; not shown but required for `InitializeComponent()`).
|
||||
- **Depended Upon By:**
|
||||
- Likely consumed by higher-level UI components (e.g., a graph editor or property pane) that depend on `IPropertyView` for polymorphic UI injection.
|
||||
- No direct consumers are visible in this file; dependency direction is inferred from interface usage.
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
- **No logic in constructor**: The constructor does not accept parameters or perform property initialization—consumers must set the `DataContext` (e.g., to a property model object) *after* instantiation to populate the view.
|
||||
- **Interface contract ambiguity**: While `IPropertyView` is referenced, its members (e.g., methods/properties like `Refresh()`, `ApplyChanges()`) are not visible here; behavior expectations rely on external documentation.
|
||||
- **XAML coupling**: The view’s behavior is partially defined in `PropertyView.xaml` (not provided), so runtime behavior (e.g., data binding paths, event handlers) cannot be fully inferred from this file.
|
||||
- **No error handling visible**: Absence of try/catch or validation logic in the constructor means exceptions during `InitializeComponent()` (e.g., XAML parsing errors) will propagate unhandled.
|
||||
- **None identified from source alone.**
|
||||
@@ -0,0 +1,102 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Property/ViewModel/PropertyViewModel.cs
|
||||
generated_at: "2026-04-16T03:28:26.668106+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "07b6bc1210aae7cd"
|
||||
---
|
||||
|
||||
# ViewModel
|
||||
|
||||
## Documentation: `PropertyViewModel` Module
|
||||
|
||||
---
|
||||
|
||||
### 1. **Purpose**
|
||||
|
||||
The `PropertyViewModel` class serves as the view model for a property editing UI in the DTS (Data Tracking System) application, implementing Prism’s MVVM pattern and integrating with Unity dependency injection and region management. It acts as a bridge between the `IPropertyView` UI layer and underlying domain data (`_properties`), while also exposing Prism `InteractionRequest`s for displaying notifications and confirmations. It inherits from `BaseViewModel<IGraphPropertyViewModel>`, suggesting it participates in a broader graph-based property editing context (e.g., for editing properties of nodes/edges in a graph model), though current implementation is largely skeletal.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
|
||||
#### `PropertyViewModel(IPropertyView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)`
|
||||
- **Behavior**: Constructor. Assigns the provided `view`, sets `view.DataContext = this`, initializes `NotificationRequest` and `ConfirmationRequest`, registers `OnRaiseNotification` as a handler for the `RaiseNotification` event via `EventAggregator`, and stores references to infrastructure services.
|
||||
|
||||
#### `InteractionRequest<Notification> NotificationRequest { get; }`
|
||||
- **Behavior**: Prism interaction request used to raise notification popups (e.g., informational messages). Triggered internally via `OnRaiseNotification` when a `RaiseNotification` event is published.
|
||||
|
||||
#### `InteractionRequest<Confirmation> ConfirmationRequest { get; }`
|
||||
- **Behavior**: Prism interaction request used to raise confirmation dialogs (e.g., yes/no prompts). *Currently unused in the provided source*.
|
||||
|
||||
#### `IPropertyView View { get; }`
|
||||
- **Behavior**: Read-only reference to the associated view instance. Set during construction and never modified.
|
||||
|
||||
#### `string HeaderInfo { get; }`
|
||||
- **Behavior**: Returns the static header string `"Graph Property"`.
|
||||
|
||||
#### `object Properties { get; set; }`
|
||||
- **Behavior**: Holds arbitrary property data (likely a domain object or DTO representing editable properties). Raises `PropertyChanged` when set.
|
||||
|
||||
#### `override void Initialize(object parameter)`
|
||||
- **Behavior**: Assigns `Parent` from the cast `parameter` to `IBaseWindowModel`. *Note: Does not call `base.Initialize(parameter)`.*
|
||||
|
||||
#### `void Initialize(object parameter, object properties)`
|
||||
- **Behavior**: Assigns `Parent` and `_properties` from the respective parameters. *Note: Does not raise `PropertyChanged` for `Properties` here — only the property setter does.*
|
||||
|
||||
#### `override event PropertyChangedEventHandler PropertyChanged`
|
||||
- **Behavior**: Overrides base `INotifyPropertyChanged` implementation. *Note: Uses `new` to hide base implementation.*
|
||||
|
||||
#### `override void Cleanup()`, `override Task CleanupAsync()`, `override void Activated()`, `override Task InitializeAsync()`, `override Task InitializeAsync(object parameter)`
|
||||
- **Behavior**: All currently throw `NotImplementedException`. *These lifecycle methods are declared but not implemented.*
|
||||
|
||||
#### `override void Initialize()`, `override Task InitializeAsync()`
|
||||
- **Behavior**: Empty overrides (no-op). *No base call or logic.*
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
|
||||
- `View.DataContext` is always set to `this` (`PropertyViewModel` instance) immediately after construction.
|
||||
- `NotificationRequest` and `ConfirmationRequest` are initialized once and never reassigned.
|
||||
- `EventAggregator.GetEvent<RaiseNotification>().Subscribe(OnRaiseNotification)` is called exactly once in the constructor — implying a single subscription for the lifetime of the instance (no unsubscription logic is present).
|
||||
- `Parent` is assigned only via `Initialize(object parameter)` or `Initialize(object parameter, object properties)` — not in the constructor.
|
||||
- `Properties` property setter triggers `OnPropertyChanged("Properties")`, ensuring UI binding updates.
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
|
||||
#### **External Dependencies (via imports):**
|
||||
- `DTS.Common.Base` → `BaseViewModel<IGraphPropertyViewModel>`
|
||||
- `DTS.Common.Events` → `RaiseNotification`, `NotificationContentEventArgs`
|
||||
- `DTS.Common.Interface` → `IPropertyView`, `IBaseWindowModel`, `IGraphPropertyViewModel`
|
||||
- `Microsoft.Practices.Prism.Events` → `IEventAggregator`, `EventAggregator`
|
||||
- `Microsoft.Practices.Prism.Interactivity.InteractionRequest` → `InteractionRequest<T>`, `Notification`, `Confirmation`
|
||||
- `Microsoft.Practices.Prism.Regions` → `IRegionManager`
|
||||
- `Microsoft.Practices.Unity` → `IUnityContainer`
|
||||
|
||||
#### **Internal Dependencies (inferred):**
|
||||
- `BaseViewModel<IGraphPropertyViewModel>` — base class providing region/event/container infrastructure.
|
||||
- `RaiseNotification` event (from `DTS.Common.Events`) — expected to be published elsewhere in the system to trigger notifications via this VM.
|
||||
- `IBaseWindowModel` — expected to be passed as `parameter` during initialization (likely represents a parent window or graph context).
|
||||
- `IPropertyView` — must be provided at construction; implies a corresponding view class implementing this interface.
|
||||
|
||||
#### **Depended upon by:**
|
||||
- Likely consumed by Prism region navigation (e.g., via `IRegionManager.RequestNavigate`) given `IRegionManager` usage.
|
||||
- `IUnityContainer` usage suggests it is registered and resolved via Unity DI.
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
|
||||
- **Critical Unimplemented Methods**: `Activated()`, `Cleanup()`, `CleanupAsync()`, `InitializeAsync()`, and `InitializeAsync(object)` all throw `NotImplementedException`. This may cause runtime failures if Prism’s lifecycle expects these to be called (e.g., during region navigation or view disposal).
|
||||
- **Missing `IsBusy`/`IsDirty` Implementation**: Properties `IsBusy` and `IsDirty` throw `NotImplementedException` in both getter and setter — likely placeholders.
|
||||
- **No Unsubscription from `RaiseNotification` Event**: The constructor subscribes to `RaiseNotification` but never unsubscribes. If `PropertyViewModel` instances are long-lived or reused, this could lead to memory leaks or duplicate notifications.
|
||||
- **`Properties` setter uses `"Properties"` string literal**: Prone to refactoring errors (e.g., renaming field/property without updating string). No `nameof()` usage.
|
||||
- **`new` keyword usage**: `new event PropertyChangedEventHandler`, `new IRegionManager`, `new bool IsBusy`, `new bool IsDirty` — suggests the base class (`BaseViewModel<...>`) declares members with the same names. This can cause confusion and subtle bugs if consumers expect base behavior.
|
||||
- **`NotificationRequest.Raise(...)` expects `NotificationContentEventArgsWithoutTitle`**: The comment states the `Notification` object expects a `NotificationContentEventArgsWithoutTitle`, but the code constructs a `NotificationContentEventArgs`. This mismatch may indicate a bug or undocumented type alias/conversion — unclear from source alone.
|
||||
- **No validation or null checks**: `parameter` is cast directly to `IBaseWindowModel` — will throw `InvalidCastException` if incorrect type is passed.
|
||||
|
||||
*None identified from source alone.* — *Correction*: The above gotchas are apparent from source analysis.
|
||||
64
enriched-qwen3-coder-next/Common/DTS.Common.Security.md
Normal file
64
enriched-qwen3-coder-next/Common/DTS.Common.Security.md
Normal file
@@ -0,0 +1,64 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Security/Encryption.cs
|
||||
generated_at: "2026-04-16T14:14:38.025149+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "2d41661347ec3dbc"
|
||||
---
|
||||
|
||||
# Documentation: DTS.Common.Security.Encryption
|
||||
|
||||
## 1. Purpose
|
||||
This module provides symmetric encryption and decryption utilities for string data within the `DTS.Common.Security` namespace. It exists to securely transform plaintext strings into byte arrays and vice versa using the Advanced Encryption Standard (AES) algorithm. It serves as a stateless wrapper around `AesCryptoServiceProvider` to facilitate data confidentiality.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Class: `Encryption`
|
||||
**Type:** `static`
|
||||
|
||||
### Method: `EncryptStringToBytes`
|
||||
**Signature:** `public static byte[] EncryptStringToBytes(string plainText, byte[] key, byte[] iv)`
|
||||
|
||||
Encrypts a given string into an array of bytes using AES.
|
||||
* **Parameters:**
|
||||
* `plainText` (`string`): The data to encrypt.
|
||||
* `key` (`byte[]`): The secret key for symmetric encryption.
|
||||
* `iv` (`byte[]`): The initialization vector.
|
||||
* **Returns:** `byte[]` containing the encrypted data.
|
||||
* **Behavior:** Validates inputs, initializes an `AesCryptoServiceProvider`, and writes the encrypted data to a `MemoryStream` using a `CryptoStream`.
|
||||
|
||||
### Method: `DecryptStringFromBytes`
|
||||
**Signature:** `public static string DecryptStringFromBytes(byte[] cipherText, byte[] key, byte[] iv)`
|
||||
|
||||
Decrypts a byte array back into a string using AES.
|
||||
* **Parameters:**
|
||||
* `cipherText` (`byte[]`): The encrypted data.
|
||||
* `key` (`byte[]`): The secret key used for encryption.
|
||||
* `iv` (`byte[]`): The initialization vector used for encryption.
|
||||
* **Returns:** `string` containing the decrypted plaintext.
|
||||
* **Behavior:** Validates inputs, initializes an `AesCryptoServiceProvider`, and reads the decrypted data from a `MemoryStream` using a `CryptoStream`.
|
||||
|
||||
## 3. Invariants
|
||||
* **Null/Empty Checks:** All parameters (`plainText`, `key`, `iv`, `cipherText`) must be non-null and have a length greater than 0. If these conditions are not met, an `ArgumentNullException` is thrown.
|
||||
* **Symmetric Keys:** The `key` and `iv` provided to `DecryptStringFromBytes` must be identical to those used in `EncryptStringToBytes` to produce the original plaintext.
|
||||
* **Encoding:** Text encoding relies on the default behavior of `StreamWriter` and `StreamReader` (typically UTF-8) wrapping the crypto streams.
|
||||
* **Algorithm:** The encryption algorithm is implicitly set to the default mode and padding of `AesCryptoServiceProvider` (typically CBC mode with PKCS7 padding), as these properties are not explicitly set in the source.
|
||||
|
||||
## 4. Dependencies
|
||||
* **Internal Dependencies:** None.
|
||||
* **External Dependencies:**
|
||||
* `System`
|
||||
* `System.IO` (for `MemoryStream`, `StreamReader`, `StreamWriter`)
|
||||
* `System.Security.Cryptography` (for `AesCryptoServiceProvider`, `CryptoStream`)
|
||||
* `System.Text` (implicitly used by Stream readers/writers)
|
||||
|
||||
## 5. Gotchas
|
||||
* **Incorrect Exception Parameter Name:** In both `EncryptStringToBytes` and `DecryptStringFromBytes`, the validation logic for the `iv` parameter throws an exception naming `key` instead:
|
||||
```csharp
|
||||
if (iv == null || iv.Length <= 0) throw new ArgumentNullException(nameof(key));
|
||||
```
|
||||
This will mislead developers debugging null IV issues.
|
||||
* **Comment/Code Mismatch:** The XML comments and inline comments refer to `RijndaelManaged`, but the actual code instantiates `AesCryptoServiceProvider`. While AES is a subset of Rijndael, the types are different. The variable name `rijAlg` is also misleading given the type.
|
||||
* **Implicit Crypto Settings:** The code does not explicitly set the `Mode` (e.g., CBC, ECB) or `Padding` properties of the `AesCryptoServiceProvider`. It relies entirely on the framework's default values. This can be fragile if code is ported to environments with different defaults, though .NET defaults are consistent (CBC/PKCS7).
|
||||
* **Unused Imports:** The file imports `System.Collections.Generic`, `System.Linq`, and `System.Threading.Tasks`, none of which are used in the provided implementation.
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Security/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T03:35:00.869185+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "69b3a358d69de229"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
## 1. Purpose
|
||||
This module (`DTS.Common.Security`) is an assembly containing shared security-related functionality for the DTS (presumably *Data Tracking System* or domain-specific platform) codebase. As indicated by its name and location (`Common/DTS.Common.Security`), it serves as a centralized library for security primitives—though the provided `AssemblyInfo.cs` file itself contains only metadata (e.g., versioning, COM visibility, GUID) and no executable logic. Its role is to define the assembly boundary for security utilities, enabling versioning, strong naming (if signed elsewhere), and clear separation of security concerns from other components.
|
||||
|
||||
## 2. Public Interface
|
||||
**No public API surface is exposed in this file.**
|
||||
The `AssemblyInfo.cs` file contains only assembly-level attributes and does not declare any classes, interfaces, methods, properties, or other public members. Therefore, there are *no* public functions, classes, or methods documented here. Actual security logic (if any) resides in other source files not included in this submission.
|
||||
|
||||
## 3. Invariants
|
||||
- The assembly identity is fixed:
|
||||
- **Title**: `"DTS.Common.Security"`
|
||||
- **Version**: `1.0.0.0` (both `AssemblyVersion` and `AssemblyFileVersion`)
|
||||
- **COM visibility**: Disabled (`ComVisible(false)`)
|
||||
- **GUID**: `"8c99ed0f-c778-463d-bb0d-d72d1d791d47"`
|
||||
- The assembly is *not* marked for COM interop by default; explicit `ComVisible(true)` would be required to expose types to COM.
|
||||
- No runtime invariants or state constraints are defined in this file.
|
||||
|
||||
## 4. Dependencies
|
||||
- **Framework dependencies**:
|
||||
- `System.Reflection`
|
||||
- `System.Runtime.CompilerServices`
|
||||
- `System.Runtime.InteropServices`
|
||||
- **No external project/library dependencies** are declared in this file.
|
||||
- **Depended upon by**: Unknown from this file alone. Other projects or modules in the DTS ecosystem likely reference this assembly to consume its security functionality (e.g., authentication, authorization, encryption), but those consumers are not visible here.
|
||||
|
||||
## 5. Gotchas
|
||||
- **No executable code**: This file is purely metadata and does not implement any security logic. Developers should not expect to find security APIs here; they must look in other files (e.g., `SecurityManager.cs`, `TokenValidator.cs`, etc.).
|
||||
- **Versioning**: Both `AssemblyVersion` and `AssemblyFileVersion` are hardcoded to `1.0.0.0`. This may indicate initial release status or a placeholder—verify if versioning is managed elsewhere (e.g., via CI/CD build scripts or shared `Directory.Build.props`).
|
||||
- **COM interop**: While `ComVisible(false)` is set, if any types *within* this assembly are later marked `[ComVisible(true)]`, they will be exposed to COM. Ensure intentional exposure to avoid unintended surface area.
|
||||
- **Missing strong name**: No `AssemblyKeyFile` or `AssemblyKeyName` attributes are present. If strong naming is required (e.g., for GAC deployment or dependency chaining), this must be configured externally (e.g., via project build settings or signing key injection).
|
||||
- **None identified from source alone** regarding runtime behavior, as no logic is present.
|
||||
249
enriched-qwen3-coder-next/Common/DTS.Common.Serialization.md
Normal file
249
enriched-qwen3-coder-next/Common/DTS.Common.Serialization.md
Normal file
@@ -0,0 +1,249 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Serialization/StringWriterWithEncoding.cs
|
||||
- Common/DTS.Common.Serialization/TickEventHandler.cs
|
||||
- Common/DTS.Common.Serialization/InvariantStreamWriter.cs
|
||||
- Common/DTS.Common.Serialization/BadCRCBypass.cs
|
||||
- Common/DTS.Common.Serialization/IProgressAware.cs
|
||||
- Common/DTS.Common.Serialization/ToyotaCsv.File.cs
|
||||
- Common/DTS.Common.Serialization/EventHandlers.cs
|
||||
- Common/DTS.Common.Serialization/Test.IConvertable.cs
|
||||
- Common/DTS.Common.Serialization/TestSetup.TestObject.Channel.cs
|
||||
- Common/DTS.Common.Serialization/Test.Module.IConvertable.cs
|
||||
- Common/DTS.Common.Serialization/Test.Module.Channel.IConvertable.cs
|
||||
- Common/DTS.Common.Serialization/TestSetup.TestObject.DASHardware.cs
|
||||
- Common/DTS.Common.Serialization/TestSetup.Sensor.cs
|
||||
- Common/DTS.Common.Serialization/File.Writer.cs
|
||||
- Common/DTS.Common.Serialization/IReadable.cs
|
||||
- Common/DTS.Common.Serialization/TestSetup.Graph.cs
|
||||
- Common/DTS.Common.Serialization/FilteredData.cs
|
||||
- Common/DTS.Common.Serialization/File.Writer.CharacterCountingStreamWriter.cs
|
||||
- Common/DTS.Common.Serialization/Diadem.File.cs
|
||||
- Common/DTS.Common.Serialization/TestSetup.TestObject.DASHardware.DASChannel.cs
|
||||
- Common/DTS.Common.Serialization/File.cs
|
||||
- Common/DTS.Common.Serialization/File.Reader.cs
|
||||
- Common/DTS.Common.Serialization/TestSetup.Graph.Channel.cs
|
||||
- Common/DTS.Common.Serialization/EventInfoAggregate.cs
|
||||
- Common/DTS.Common.Serialization/IWriteable.cs
|
||||
generated_at: "2026-04-16T14:18:31.446837+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "2a2f1c17484ea7d0"
|
||||
---
|
||||
|
||||
# DTS.Serialization Module Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
The `DTS.Serialization` module provides a framework for serializing and deserializing test data to various file formats. It defines an abstract file hierarchy (`File`, `Reader<T>`, `Writer<T>`) with format-specific implementations (Toyota CSV, Diadem), a rich domain model for test data (`Test`, `Module`, `Channel`), and progress-aware serialization operations with event-based notification. The module supports extensibility through `IConvertable` interfaces that allow external objects to transform to/from the internal test representation.
|
||||
|
||||
---
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Core File Abstractions
|
||||
|
||||
#### `File` (abstract partial class)
|
||||
- **Signature**: `public abstract partial class File : Exceptional`
|
||||
- **Constructor**: `File(string formatName)`
|
||||
- **Properties**:
|
||||
- `string FormatName` (read-only, set via constructor)
|
||||
- `int DefaultEncoding` (defaults to `Encoding.UTF8.CodePage`)
|
||||
- `static string BaseExportDirectory` (static getter/setter)
|
||||
- `static bool UseLegacyTDCSoftwareFiltering` (static getter/setter)
|
||||
- `Common.Enums.IsoViewMode ISOViewMode` (getter/setter)
|
||||
- **Methods**:
|
||||
- `protected string EnsureTrailingBackslashOnPathString(string path)`
|
||||
- `virtual void SetEUData(string channelID, FilteredData fd)`
|
||||
- `virtual FilteredData GetEUData(string channelID)`
|
||||
- `virtual int GetChannelNumberFromChannelFileName(string channelFileName)` - returns -1 by default
|
||||
|
||||
#### `File.Reader<T>` (abstract nested class)
|
||||
- **Signature**: `public abstract class Reader<T> : Exceptional, IReader where T : File`
|
||||
- **Constructor**: `protected Reader(T fileType)`
|
||||
- **Properties**:
|
||||
- `protected T FileType` (read-only)
|
||||
- `protected ChannelFilenameComparer ChFileCompare` (read-only)
|
||||
- **Nested Class**: `ChannelFilenameComparer` (implements `IComparer<string>`)
|
||||
|
||||
#### `File.Writer<T>` (abstract partial nested class)
|
||||
- **Signature**: `public abstract partial class Writer<T> : Exceptional, IWriter where T : File`
|
||||
- **Constructor**: `public Writer(T fileType, int encoding)`
|
||||
- **Properties**:
|
||||
- `protected T FileType` (read-only)
|
||||
- `virtual int DefaultEncoding` (getter/setter, defaults to UTF8 codepage)
|
||||
- **Nested Class**: `CharacterCountingStreamWriter` (extends `StreamWriter`, counts characters via `WriteLine`)
|
||||
|
||||
### Interfaces
|
||||
|
||||
#### `IReadable` / `IReadable<T>`
|
||||
- **Signature**: `public interface IReadable` (marker interface)
|
||||
- **Signature**: `public interface IReadable<T> : IReadable`
|
||||
- **Property**: `IReader<T> Importer { get; }`
|
||||
|
||||
#### `IReader` / `IReader<T>`
|
||||
- **Signature**: `public interface IReader` (marker interface)
|
||||
- **Signature**: `public interface IReader<T> : IReader`
|
||||
- **Method**: `void Read(string pathname, out T target)`
|
||||
|
||||
#### `IWritable` / `IWritable<T>`
|
||||
- **Signature**: `public interface IWritable` (marker interface)
|
||||
- **Signature**: `public interface IWritable<T> : IWritable`
|
||||
- **Property**: `IWriter<T> Exporter { get; }`
|
||||
|
||||
#### `IWriter` / `IWriter<T>`
|
||||
- **Signature**: `public interface IWriter` (marker interface)
|
||||
- **Signature**: `public interface IWriter<T> : IWriter`
|
||||
- **Methods**:
|
||||
- `void Write(string pathname, string id, T target, bool bFiltering, bool includeGroupNameInISOExport, double minStartTime, int dataCollectionLength)`
|
||||
- `void Write(string pathname, string id, string dataFolder, T target, bool bFiltering, bool includeGroupNameInISOExport, FilteredData fd, Test.Module.Channel tmChannel, int channelNumber, BeginEventHandler onBeginEvent, CancelEventHandler onCancelEvent, EndEventHandler onEndEvent, TickEventHandler onTickEvent, ErrorEventHandler onErrorEvent, CancelRequested cancelRequested, double minStartTime, int dataCollectionLength)`
|
||||
- `void Initialize(string pathname, string id, string dataFolder, T target, bool bFiltering, bool includeGroupNameInISOExport, FilteredData fd, Test.Module.Channel tmChannel, int channelNumber, BeginEventHandler onBeginEvent, CancelEventHandler onCancelEvent, EndEventHandler onEndEvent, TickEventHandler onTickEvent, ErrorEventHandler onErrorEvent, CancelRequested cancelRequested)`
|
||||
|
||||
#### `IProgressAware`
|
||||
- **Signature**: `interface IProgressAware`
|
||||
- **Events**: `OnBegin` (BeginEventHandler), `OnEnd` (EndEventHandler), `OnTick` (TickEventHandler), `OnCancel` (CancelEventHandler), `OnError` (ErrorEventHandler)
|
||||
|
||||
### Event Delegates
|
||||
|
||||
- `delegate void TickEventHandler(object sender, double percentageComplete)`
|
||||
- `delegate void BeginEventHandler(object sender, uint numberOfTicks)`
|
||||
- `delegate void EndEventHandler(object sender)`
|
||||
- `delegate void CancelEventHandler(object sender)`
|
||||
- `delegate void ErrorEventHandler(object sender, Exception ex)`
|
||||
- `delegate bool CancelRequested()`
|
||||
|
||||
### Convertable Interfaces
|
||||
|
||||
#### `Test.IConvertable` (nested interface)
|
||||
- **Methods**:
|
||||
- `Test ToDtsSerializationTest()`
|
||||
- `void FromDtsSerializationTest(Test test, ReportErrors reportErrors)`
|
||||
- **Delegate**: `delegate void ReportErrors(List<string> errors)`
|
||||
|
||||
#### `Test.Module.IConvertable` (nested interface)
|
||||
- **Methods**:
|
||||
- `Test.Module ToDtsSerializationTestModule(DTS.Serialization.Test parentTest)`
|
||||
- `void FromDtsSerializationTestModule(Test.Module testModule, DTS.Serialization.Test.ReportErrors reportErrors)`
|
||||
|
||||
#### `Test.Module.Channel.IConvertable` (nested interface)
|
||||
- **Methods**:
|
||||
- `Test.Module.Channel ToDtsSerializationTestModuleChannel()`
|
||||
- `void FromDtsSerializationTestModuleChannel(Test.Module.Channel channel)`
|
||||
|
||||
### Data Classes
|
||||
|
||||
#### `FilteredData`
|
||||
- **Signature**: `public class FilteredData : Exceptional, IComparable<FilteredData>`
|
||||
- **Constructor**: `FilteredData(string filterDescription, double filterFrequencyHz, double[] data, int absoluteDisplayOrder)`
|
||||
- **Properties**: `string FilterDescription`, `double FilterFrequencyHz`, `double[] Data`, `int AbsoluteDisplayOrder` (read-only)
|
||||
- **Method**: `int CompareTo(FilteredData other)`
|
||||
|
||||
#### `EventInfoAggregate`
|
||||
- **Signature**: `public class EventInfoAggregate`
|
||||
- **Constructor**: `EventInfoAggregate(DownloadReport.EventInfo newEvent)`
|
||||
- **Properties**: `EventId`, `EventDescription`, `DurationSeconds`, `GUID`, `HasBeenDownloaded`, `WasTriggered`, `NumberOfChannels`, `NumberOfSamples` (UInt64), `NumberOfBytes` (UInt64), `Faulted`, `EventNumber`
|
||||
- **Methods**: `Slice.Control.Event GetEvent()`, `Slice.Control.Event GetEvent(bool bClear)`, `int GetEventIndex(IDASCommunication idas)`, `List<IDASCommunication> GetDasList()`, `void Add(DownloadReport.EventInfo newEvent)`
|
||||
|
||||
### TestSetup Hierarchy
|
||||
|
||||
#### `TestSetup` (partial class)
|
||||
- **Signature**: `public partial class TestSetup : Exceptional`
|
||||
|
||||
#### `TestSetup.TestObject` (partial nested class)
|
||||
- **Signature**: `public partial class TestObject : Exceptional`
|
||||
|
||||
#### `TestSetup.TestObject.TOChannel`
|
||||
- **Constructor**: Default constructor initializes `Version` to "1.0.0.0"
|
||||
- **Properties**: `Name`, `SensorName`, `Version`
|
||||
|
||||
#### `TestSetup.TestObject.DASHardware`
|
||||
- **Constructor**: Default constructor initializes `Version` to "1.0.0.0", `DASChannels` to empty list
|
||||
- **Properties**: `List<DASChannel> DASChannels`, `SampleRate`, `SerialNumber`, `Version`
|
||||
|
||||
#### `TestSetup.TestObject.DASHardware.DASChannel`
|
||||
- **Constructor**: Default constructor initializes `Version` to "1.0.0.0"
|
||||
- **Properties**: `Location`, `MeasurementUnits`, `Name`, `NumberOfSamples`, `SensorName`, `SerialNumber`, `Version`
|
||||
|
||||
#### `TestSetup.Sensor`
|
||||
- **Constructor**: Default constructor initializes `Version` to "1.0.0.0"
|
||||
- **Properties**: `FilterClass`, `Name`, `Polarity`, `Position`, `Range`, `Version`
|
||||
|
||||
#### `TestSetup.Graph`
|
||||
- **Constructor**: Initializes `Version` to "1.0.0.0", creates new `Guid` for `Identifier`
|
||||
- **Properties**: `List<Channel> Channels`, `Name`, `HardwareChannelName`, `DisplayName` (computed as `Name_HardwareChannelName`), `Version`, `Guid Identifier` (read-only)
|
||||
- **XML-ignored Properties**: `IsSingleChannelGraph`, `FirstChannel`, `FirstTestChannel`
|
||||
- **Method**: `void UnSet()`
|
||||
|
||||
#### `TestSetup.Graph.Channel`
|
||||
- **Constructors**:
|
||||
- `Channel(DTS.Serialization.Test.Module.Channel channel)`
|
||||
- `Channel(string channelId)`
|
||||
- Private default constructor
|
||||
- **Properties**: `ChannelId`, `ChannelGroupName`, `Name` (computed), `SensorName` (XML-ignored), `AxisUnit` (XML-ignored), `SerialNumber` (XML-ignored)
|
||||
- **Fields**: `ParentTestModule` (XML-ignored), `TestChannel` (XML-ignored)
|
||||
|
||||
### Format-Specific Implementations
|
||||
|
||||
#### `ToyotaCsv.File`
|
||||
- **Signature**: `public partial class File : Serialization.File, IWritable<Test>`
|
||||
- **Constructor**: `File()` - passes "Toyota CSV" to base
|
||||
- **Static Property**: `string Extension => ".csv"`
|
||||
- **Property**: `IWriter<Test> Exporter` (lazy-initialized)
|
||||
|
||||
#### `Diadem.File`
|
||||
- **Signature**: `public partial class File : Serialization.File, IWritable<Test>`
|
||||
- **Constructor**: `File(bool bUseEVG20, TestPlan plan)`
|
||||
- **Static Property**: `string Extension => ".dat"`
|
||||
- **Properties**: `UseIsoCodeForDiadem200`, `UseZeroForUnfiltered`, `ChannelName200Option`, `UserComment201Option`, `Reserved1_301Option`, `Reserved2_302Option`, `IWriter<Test> Exporter`
|
||||
- **Enums**: `DiademOptions` (NONE, ISO_CODE, SENSOR_SERIAL_NUMBER, CHANNEL_NAME), `DiademOptionsReserved1` (NONE, AAF_RATE, GROUP_NAME), `DiademOptionsReserved2` (NONE, CHANNEL_SENSITIVITY)
|
||||
|
||||
### Utility Classes
|
||||
|
||||
#### `StringWriterWithEncoding`
|
||||
- **Signature**: `public sealed class StringWriterWithEncoding : StringWriter`
|
||||
- **Constructor**: `StringWriterWithEncoding(Encoding encoding)`
|
||||
- **Property**: `override Encoding Encoding` (returns encoding passed to constructor)
|
||||
|
||||
#### `InvariantStreamWriter`
|
||||
- **Signature**: `public class InvariantStreamWriter : System.IO.StreamWriter`
|
||||
- **Constructors**: `InvariantStreamWriter(string path)`, `InvariantStreamWriter(string path, bool bAppend)`
|
||||
- **Property**: `override IFormatProvider FormatProvider` (returns `CultureInfo.InvariantCulture`)
|
||||
|
||||
#### `BadCRCBypass` (Windows Forms)
|
||||
- **Signature**: `public partial class BadCRCBypass : Form`
|
||||
- **Constructor**: `BadCRCBypass()`
|
||||
- **Properties**: `string FileName`, `bool RememberChoice`
|
||||
- **Event Handlers**: `btnOK_Click`, `btnCancel_Click`
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
1. **Writer Construction**: `File.Writer<T>` instances must be created through factory methods in the hosting `File` object (constructor is public but intended for factory use).
|
||||
|
||||
2. **Reader Construction**: `File.Reader<T>` constructor is `protected`, enforcing that readers must be created by the hosting `File` class.
|
||||
|
||||
3. **Encoding Defaults**: All writers default to UTF-8 encoding (`Encoding.UTF8.CodePage`) unless explicitly overridden.
|
||||
|
||||
4. **Version Defaults**: All `TestSetup` nested classes initialize `Version` property to "1.0.0.0" by default.
|
||||
|
||||
5. **Graph Identifier**: `TestSetup.Graph.Identifier` is assigned a new `Guid` on construction and has a private setter (immutable after creation).
|
||||
|
||||
6. **ChannelFilenameComparer**: Requires the file type to be castable to `File` base class; otherwise comparison falls back to string comparison.
|
||||
|
||||
7. **EventInfoAggregate Consistency**: When aggregating events via `Add()`, if properties don't match (TestID, Description, Duration, GUID), warnings are logged and minimum values are used for numeric fields.
|
||||
|
||||
8. **FilteredData Display Order**: `AbsoluteDisplayOrder` is read-only after construction and defaults to -1.
|
||||
|
||||
---
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### External Dependencies (from imports)
|
||||
- `System.Text` / `System.Text.Encoding` - String encoding
|
||||
- `System.IO` - Stream/StreamWriter/StringWriter base classes
|
||||
- `System` - Basic types, Exception, IFormatProvider
|
||||
- `System.Globalization.CultureInfo` - Invariant culture for formatting
|
||||
- `System.Windows.Forms` - UI components (BadCRCBypass)
|
||||
- `System.Xml.Serialization.XmlIgnoreAttribute` - XML serialization control
|
||||
- `System.Collections.Generic` - List, Dictionary, IComparer
|
||||
BIN
enriched-qwen3-coder-next/Common/DTS.Common.Serialization/.DS_Store
vendored
Normal file
BIN
enriched-qwen3-coder-next/Common/DTS.Common.Serialization/.DS_Store
vendored
Normal file
Binary file not shown.
@@ -0,0 +1,116 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Serialization/Control/ReviewableAttribute.cs
|
||||
- Common/DTS.Common.Serialization/Control/IntervalSec.cs
|
||||
generated_at: "2026-04-16T03:39:42.724755+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "b95e2bb79309f305"
|
||||
---
|
||||
|
||||
# Control
|
||||
|
||||
## Documentation: `DTS.Slice.Control` Namespace – ReviewableAttribute & IntervalSec
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
|
||||
This module provides foundational types for representing *reviewable* attributes (e.g., displayable metadata in a UI review tab) and *time intervals* (in seconds) within the DTS Slice Control domain. `ReviewableAttribute` serves as an abstract base for dynamically computing and exposing attribute values (e.g., channel status, configuration metadata) for review purposes, while `IntervalSec` encapsulates a time range with begin/end times and supports interoperability with a serialization-specific counterpart via implicit conversions.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `ReviewableAttribute` (Abstract Class)
|
||||
|
||||
- **`ReviewableAttribute(string name, DetermineValueString calculateValue)`**
|
||||
Constructor. Initializes the attribute with a name and a delegate used to compute the value on demand. Throws `ReviewableAttribute.Exception` on failure.
|
||||
|
||||
- **`string Name { get; }`**
|
||||
Read-only property returning the attribute’s display name.
|
||||
|
||||
- **`string Value { get; }`**
|
||||
Read-only property that invokes the `CalculateValue` delegate to compute the current value. On exception during computation, logs the error and returns `"N/A"` (does *not* throw).
|
||||
|
||||
- **`delegate string DetermineValueString();`**
|
||||
Public delegate defining the signature for value-computation methods.
|
||||
|
||||
- **`private DetermineValueString CalculateValue { get; set; }`**
|
||||
Private property storing the delegate. Throws `ApplicationException` if accessed before initialization.
|
||||
|
||||
#### `IntervalSec` (Concrete Class)
|
||||
|
||||
- **`IntervalSec()`**
|
||||
Parameterless constructor. Leaves `Begin` and `End` uninitialized (default to `0.0` due to `Property<double>` initialization, but semantically "uninitialized" per comment).
|
||||
|
||||
- **`IntervalSec(double begin, double end)`**
|
||||
Constructor initializing `Begin` and `End` to specified values. Throws generic `Exception` on failure.
|
||||
|
||||
- **`double Begin { get; set; }`**
|
||||
Read/write property for the interval’s start time (seconds).
|
||||
|
||||
- **`double End { get; set; }`**
|
||||
Read/write property for the interval’s end time (seconds).
|
||||
|
||||
- **`public static implicit operator Serialization.Test.IntervalSec(IntervalSec thisInterval)`**
|
||||
Implicit conversion to `DTS.Serialization.Test.IntervalSec`, using current `Begin`/`End`.
|
||||
|
||||
- **`public static implicit operator IntervalSec(Serialization.Test.IntervalSec thatInterval)`**
|
||||
Implicit conversion *from* `DTS.Serialization.Test.IntervalSec`, constructing a new instance.
|
||||
|
||||
- **`public override bool Equals(object obj)`**
|
||||
Memberwise equality check against another `IntervalSec`. Returns `false` if `obj` is `null` or not `IntervalSec`.
|
||||
|
||||
- **`public override int GetHashCode()`**
|
||||
Returns base hash code (note: does *not* combine `Begin`/`End` explicitly—see *Gotchas*).
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
|
||||
- **`ReviewableAttribute`**
|
||||
- `Name` must be non-null (enforced by `Property<string>` constructor with `null` as default, but no explicit validation—*potential risk*).
|
||||
- `CalculateValue` must be assigned before `Value` is accessed; otherwise, `ApplicationException` is thrown.
|
||||
- `Value` computation *never* throws; exceptions are caught and logged, returning `"N/A"`.
|
||||
|
||||
- **`IntervalSec`**
|
||||
- No invariant enforces `Begin ≤ End`; invalid intervals (e.g., `Begin > End`) are permitted.
|
||||
- `Begin` and `End` default to `0.0` (via `Property<double>` initialization), but the parameterless constructor comment states they are "uninitialized"—this is a semantic mismatch.
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
- **`DTS.Slice.Control.ReviewableAttribute`**
|
||||
- *Depends on*:
|
||||
- `DTS.Utilities` (for `APILogger`, `Exceptional`, `Property<T>`)
|
||||
- `DTS.Utilities.DotNetProgrammingConstructs` (for `Property<T>`)
|
||||
- *Used by*: Unknown from source—likely subclassed by domain-specific reviewable attributes (e.g., `ChannelAttribute`, `SystemStatusAttribute`).
|
||||
|
||||
- **`DTS.Slice.Control.IntervalSec`**
|
||||
- *Depends on*:
|
||||
- `DTS.Common.Utilities`
|
||||
- `DTS.Common.Utilities.DotNetProgrammingConstructs` (for `Property<double>`, `Exceptional`)
|
||||
- `DTS.Serialization.Test.IntervalSec` (for implicit conversions)
|
||||
- *Used by*: Likely in time-windowing or data-slicing logic (e.g., selecting data within a time range).
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
|
||||
- **`ReviewableAttribute`**
|
||||
- `CalculateValue` is a *private* property—subclasses cannot override or inspect it directly. Initialization must occur in the base constructor.
|
||||
- `Value` silently fails on computation error (`"N/A"`), which may mask bugs if not logged.
|
||||
- No validation on `name` parameter (e.g., null/empty); `Property<string>` allows `null`.
|
||||
|
||||
- **`IntervalSec`**
|
||||
- `GetHashCode()` does *not* incorporate `Begin`/`End`, violating the contract that equal objects must have equal hash codes. This will cause failures in hash-based collections (e.g., `HashSet`, `Dictionary`).
|
||||
- `Begin`/`End` default to `0.0` despite constructor comment implying "uninitialized" state—this may lead to false positives (e.g., interval `[0.0, 0.0]` treated as valid).
|
||||
- Implicit conversions assume `Serialization.Test.IntervalSec` has matching `Begin`/`End` properties; no validation on conversion.
|
||||
|
||||
- **Both**
|
||||
- Heavy use of `try`/`catch` blocks wrapping property accessors and constructors—suggests legacy error-handling pattern. Consider refactoring to reduce overhead.
|
||||
- Reliance on `Property<T>` wrapper (not shown) implies a custom property system; behavior (e.g., change notifications) is not documented here.
|
||||
|
||||
None identified beyond the above.
|
||||
@@ -0,0 +1,86 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Serialization/Control/DAS/IFilterable.cs
|
||||
- Common/DTS.Common.Serialization/Control/DAS/IFilter.cs
|
||||
generated_at: "2026-04-16T03:41:25.272025+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "d1bb42983adadb6c"
|
||||
---
|
||||
|
||||
# DAS
|
||||
|
||||
## Documentation: `IFilterable` and `IFilter` Interfaces
|
||||
|
||||
---
|
||||
|
||||
### 1. **Purpose**
|
||||
|
||||
This module defines core interfaces (`IFilterable` and `IFilter`) for managing and applying signal filters to channel data within the DTS Slice Control DAS (Data Acquisition System) framework. It enables consumers to query available filters, set a current filter, optionally cache filter results for performance, and retrieve filtered data in specified display units. The interfaces serve as abstractions for channel filtering logic—likely implemented by concrete classes representing physical or logical channel groups in the control system.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
|
||||
#### `IFilterable` Interface
|
||||
*Namespace:* `DTS.Slice.Control.DAS.Channel`
|
||||
|
||||
| Member | Signature | Description |
|
||||
|--------|-----------|-------------|
|
||||
| `UseFilterCaching` | `bool UseFilterCaching { get; set; }` | Enables or disables caching of previously computed filtered results. |
|
||||
| `AvailableFilters` | `List<IFilter> AvailableFilters { get; }` | Returns a list of filters that can be applied to this object. |
|
||||
| `CurrentFilter` | `IFilter CurrentFilter { get; set; }` | Gets or sets the filter currently applied to data requests. |
|
||||
| `GetDataFilteredBy` | `double[] GetDataFilteredBy(IFilter filter, Event.Module.Channel.DataDisplayUnits displayUnits)` | Returns filtered data for the specified `filter` and `displayUnits`. |
|
||||
|
||||
#### `IFilter` Interface
|
||||
*Namespace:* `DTS.Slice.Control.DAS.Channel`
|
||||
|
||||
| Member | Signature | Description |
|
||||
|--------|-----------|-------------|
|
||||
| `Name` | `string Name { get; }` | Returns a human-readable name/description of the filter. |
|
||||
| `IsCfc` | `bool IsCfc { get; }` | Indicates whether the filter represents a cardinal CFC (Cycle Count Filter) value. |
|
||||
| `Type` | `ChannelFilter Type { get; }` | Returns the filter’s type (e.g., low-pass, high-pass), represented by the `ChannelFilter` enum (not shown in source). |
|
||||
| `CutoffFrequencyHz` | `double CutoffFrequencyHz { get; }` | Returns the cutoff frequency (in Hz) used by the filter. |
|
||||
| `Apply` (1) | `double[] Apply(Event.Module.Channel input, Event.Module.Channel.DataDisplayUnits displayUnits, bool bUseLegacyTDCSofwareFilterAdjustment)` | Applies the filter to channel data, converting to `displayUnits`. The `bUseLegacyTDCSofwareFilterAdjustment` flag adjusts output one sample to the right for backward compatibility with legacy TDC software. |
|
||||
| `Apply` (2) | `double[] Apply(double[] data, double sampleRate, bool bUseLegacyTDCSoftwareFilterAdjustment)` | Applies the filter to raw numeric data (assumed to be in base units), given the `sampleRate`. Same legacy adjustment flag applies. |
|
||||
| `ToBaseString` | `string ToBaseString()` | Returns the base name of the filter (e.g., `"LowPass"`), without any decoration (e.g., no suffix like `" (10 Hz)"`). |
|
||||
|
||||
> **Note**: The `Apply` methods are overloaded: one accepts an `Event.Module.Channel` object (likely containing metadata and raw data), and the other accepts raw `double[]` data plus `sampleRate`.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
|
||||
- `AvailableFilters` must be non-null and immutable in the sense that its contents should not change during the lifetime of the `IFilterable` instance (though the list itself may be recreated on each access).
|
||||
- `CurrentFilter` must be either `null` or one of the items in `AvailableFilters`.
|
||||
- `GetDataFilteredBy` must return data consistent with the specified `filter` and `displayUnits`, and must not mutate the underlying channel data.
|
||||
- `IsCfc` and `Type` must be consistent: if `IsCfc` is `true`, then `Type` likely corresponds to a CFC-specific `ChannelFilter` value (exact mapping not specified in source).
|
||||
- The `bUseLegacyTDCSofwareFilterAdjustment` parameter in `Apply` controls sample alignment: when `true`, output is shifted one sample to the right (i.e., delayed by one sample period) to preserve legacy behavior.
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
|
||||
#### Dependencies *of* this module:
|
||||
- `System.Collections.Generic` (`List<T>`)
|
||||
- `DTS.Common.Utilities` (namespace referenced, but no types used directly in interface definitions)
|
||||
- `Event.Module.Channel` (used in `Apply` signatures; type not shown, but assumed to contain raw channel data and metadata)
|
||||
- `Event.Module.Channel.DataDisplayUnits` (enum or type defining unit conversion options; not shown)
|
||||
|
||||
#### Dependencies *on* this module:
|
||||
- Any class implementing `IFilterable` (e.g., channel or group implementations) must provide filtering capabilities.
|
||||
- Any class implementing `IFilter` must define concrete filtering logic (e.g., `LowPassFilter`, `HighPassFilter`, `CfcFilter`).
|
||||
- Likely used by higher-level components in `DTS.Slice.Control.DAS` or `DTS.Slice.Control.CAS` namespaces (inferred from commented-out base interface in `IFilterable`).
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
|
||||
- **Typo in parameter name**: In `GetDataFilteredBy`, the parameter `filter` is documented as `DTS.Slice.Control.CAS.Channel.IFilter`, but the actual interface is `DTS.Slice.Control.DAS.Channel.IFilter`. This may indicate outdated documentation or namespace refactoring.
|
||||
- **Typo in flag name**: `bUseLegacyTDCSofwareFilterAdjustment` is misspelled as `Sofware` (missing 't') in one `Apply` signature (`Apply` overload 1), but correctly spelled as `TDCSoftware` in the second overload. This inconsistency may cause confusion or errors in code generation or reflection-based usage.
|
||||
- **No explicit thread-safety guarantees**: Neither interface documents thread-safety; concurrent access to `CurrentFilter`, `UseFilterCaching`, or `Apply` may require external synchronization.
|
||||
- **Caching behavior unspecified**: While `UseFilterCaching` toggles caching, the caching strategy (e.g., cache key, eviction policy, scope) is not defined here—implementation-specific.
|
||||
- **`ToBaseString()` vs `ToString()`**: The comment implies `ToString()` is overridden elsewhere (likely in concrete implementations) to include metadata (e.g., `"LowPass (10 Hz)"`), while `ToBaseString()` returns the base name only. Consumers must be aware of this distinction when displaying filter names.
|
||||
|
||||
> **None identified from source alone.**
|
||||
> *(Note: The above gotchas are inferred from inconsistencies in naming and documentation; no behavioral quirks beyond those are evident from the interfaces themselves.)*
|
||||
@@ -0,0 +1,230 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Serialization/Control/Event/DasModuleAccessor.cs
|
||||
- Common/DTS.Common.Serialization/Control/Event/DasChannelAccessor.cs
|
||||
- Common/DTS.Common.Serialization/Control/Event/ChannelAccessor.cs
|
||||
- Common/DTS.Common.Serialization/Control/Event/ModuleChannelAccessor.cs
|
||||
- Common/DTS.Common.Serialization/Control/Event/DasModuleChannelAccessor.cs
|
||||
- Common/DTS.Common.Serialization/Control/Event/TestInformation.cs
|
||||
- Common/DTS.Common.Serialization/Control/Event/Event.cs
|
||||
generated_at: "2026-04-16T03:41:53.208866+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "e1ba9340d986b9b2"
|
||||
---
|
||||
|
||||
# Documentation: `DTS.Slice.Control.Event` Accessor Classes and Related Types
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides accessor objects and supporting infrastructure for navigating and manipulating event data within the DTS Slice Control system. Specifically, it defines hierarchical dictionary-based accessors (`DasModuleAccessor`, `DasChannelAccessor`, `DasModuleChannelAccessor`, `ChannelAccessor`, `ModuleChannelAccessor`) that enable lookup of modules and channels by DAS ID, module number, and channel number combinations. It also includes the core `Event` class (a partial class with multiple files), which serves as the in-memory representation of a DAS event—encapsulating test metadata, modules, channels, and derived properties such as validation flags and serialization support. The module bridges low-level DAS serialization data (e.g., `DTS.Serialization.Test`) and higher-level control logic by offering structured, type-safe access to event components.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
All accessor classes and the `Event` class reside in the `DTS.Slice.Control` namespace and are declared as `public partial class Event`.
|
||||
|
||||
### `Event` Class
|
||||
|
||||
- **`Event()`**
|
||||
Default constructor. Initializes all properties to their default values.
|
||||
|
||||
- **`Event(string id, string description)`**
|
||||
Initializes an `Event` with the given `id` and `description`. Throws a wrapped exception on failure.
|
||||
|
||||
- **`Event(Test test, Test.ReportErrors reportErrors)`**
|
||||
Initializes an `Event` by converting from a `DTS.Serialization.Test` object via `FromDtsSerializationTest`. Rethrows exceptions directly.
|
||||
|
||||
- **`Event(string id, string description, List<Module> modules)`**
|
||||
Initializes an `Event` with `id`, `description`, and a list of `Module`s.
|
||||
|
||||
- **`Event(List<IDASCommunication> dases, EventInfoAggregate info)`**
|
||||
Initializes an `Event` by aggregating configuration and channel data from a list of DAS devices (`IDASCommunication`) and `EventInfoAggregate`. Populates `Modules`, `DasModules`, `DasChannels`, and `DasModuleChannels`. Throws `UserException` for missing DAS info or configuration. Validates test ID consistency across DAS units.
|
||||
|
||||
- **`string Id { get; set; }`**
|
||||
Gets/sets the event’s test ID.
|
||||
|
||||
- **`string Description { get; set; }`**
|
||||
Gets/sets the event’s description.
|
||||
|
||||
- **`Guid Guid { get; set; }`**
|
||||
Gets/sets the globally unique identifier for the event. Default is `Guid.Empty`.
|
||||
|
||||
- **`UInt16 FaultFlags { get; set; }`**
|
||||
Gets/sets the global fault flags for the event.
|
||||
|
||||
- **`DateTime InceptionDate { get; private set; }`**
|
||||
Gets the creation date of the event (set during construction). Defaults to `DateTime.Now`.
|
||||
|
||||
- **`List<Module> Modules { get; set; }`**
|
||||
Gets/sets the list of `Module` objects associated with this event.
|
||||
|
||||
- **`List<Module.Channel> CalculatedChannels { get; set; }`**
|
||||
Gets/sets the list of calculated channels.
|
||||
|
||||
- **`DasModuleAccessor DasModules { get; private set; }`**
|
||||
Returns a `DasModuleAccessor` keyed by DAS ID (`Common.DAS.Concepts.DAS.Id`), mapping to a `List<Module>`.
|
||||
|
||||
- **`DasChannelAccessor DasChannels { get; private set; }`**
|
||||
Returns a `DasChannelAccessor` keyed by DAS ID, mapping to a `List<Module.Channel>`.
|
||||
|
||||
- **`DasModuleChannelAccessor DasModuleChannels { get; private set; }`**
|
||||
Returns a `DasModuleChannelAccessor` keyed by DAS ID, mapping to a `ModuleChannelAccessor`.
|
||||
|
||||
- **`int LastAbsoluteChannelNumberInEvent { get; }`**
|
||||
Returns the highest absolute channel number across all modules and channels.
|
||||
|
||||
- **`bool IsTooLargeFor32BitVisualization { get; }`**
|
||||
Returns `true` if the total data volume (based on `TooLargeFor32BitVisualizationBytesPerSampleThreshold`) exceeds 2GB (0x7FFFFFFF bytes).
|
||||
|
||||
- **`double TooLargeFor32BitVisualizationBytesPerSampleThreshold { get; private set; }`**
|
||||
Threshold in bytes per sample used for 32-bit visualization size checks. Default: `2.0`.
|
||||
|
||||
- **`bool ContainsChannelsActiveInvalidZeroingWindows { get; }`**
|
||||
Returns `true` if any channel has `ZeroMethod == AverageOverTime` and an invalid averaging window.
|
||||
|
||||
- **`List<Module.Channel> ChannelsWithActiveInvalidZeroingWindows { get; }`**
|
||||
Returns the list of channels with active but invalid zeroing windows (e.g., window outside data range or negative indices).
|
||||
|
||||
- **`static string BaseSerializationDirectory { get; set; }`**
|
||||
Gets/sets the base directory path for event serialization.
|
||||
|
||||
- **`static string GetEventSerializationDirectory(string eventId)`**
|
||||
Returns the full path for the serialization directory of the given `eventId`.
|
||||
|
||||
- **`bool Equals(object obj)`**
|
||||
Overrides `Equals` to compare `Id`, `Description`, `Guid`, `Modules`, and `FaultFlags`.
|
||||
|
||||
- **`int GetHashCode()`**
|
||||
Overrides `GetHashCode`.
|
||||
|
||||
- **`Test ToDtsSerializationTest()`**
|
||||
Converts this `Event` to a `DTS.Serialization.Test`. Removes unconfigured/dummy channels before serialization.
|
||||
|
||||
- **`void FromDtsSerializationTest(Test that, Test.ReportErrors reportErrors)`**
|
||||
Populates this `Event` from a `DTS.Serialization.Test`. Re-throws `InvalidDataException` directly; wraps others.
|
||||
|
||||
- **`static implicit operator Test(Event sliceControlEvent)`**
|
||||
Implicit conversion operator to `DTS.Serialization.Test`.
|
||||
|
||||
- **`static bool IsG5(IDASCommunication idas)`**
|
||||
Returns `true` if the DAS serial number starts with `"5M"`.
|
||||
|
||||
- **`static bool IsSlice6DBModule(Module module)`**
|
||||
Returns `true` if `module.Description.ToLower() == "slice6db module"`.
|
||||
|
||||
### Accessor Classes
|
||||
|
||||
- **`DasModuleAccessor : ExceptionalDictionary<Common.DAS.Concepts.DAS.Id, List<Module>>`**
|
||||
Keyed by DAS ID, maps to list of `Module`s. Used to retrieve modules by DAS.
|
||||
|
||||
- **`DasChannelAccessor : ExceptionalDictionary<Common.DAS.Concepts.DAS.Id, List<Module.Channel>>`**
|
||||
Keyed by DAS ID, maps to list of `Module.Channel`s. Used to retrieve channels by DAS.
|
||||
|
||||
- **`DasModuleChannelAccessor : ExceptionalDictionary<Common.DAS.Concepts.DAS.Id, ModuleChannelAccessor>`**
|
||||
Keyed by DAS ID, maps to a `ModuleChannelAccessor`. Enables 3-level lookup: DAS ID → module index → channel index.
|
||||
|
||||
- **`ChannelAccessor : ExceptionalDictionary<int, Module.Channel>`**
|
||||
Keyed by `int` (module channel number), maps to a `Module.Channel`. Used as the innermost accessor.
|
||||
|
||||
- **`ModuleChannelAccessor : ExceptionalDictionary<int, ChannelAccessor>`**
|
||||
Keyed by `int` (module array index), maps to a `ChannelAccessor`. Enables lookup of channels by module number.
|
||||
|
||||
- **`TestInformation : Exceptional`** *(private)*
|
||||
Holds test metadata (`Id`, `Description`) per DAS. Used internally during event construction.
|
||||
|
||||
### Helper Methods (in `Event`)
|
||||
|
||||
- **`bool IsDummyChannel(Module.Channel channel)`**
|
||||
Returns `true` if `channel.ChannelDescriptionString.ToLower() == "dummy arm channel"`.
|
||||
|
||||
- **`bool IsTom(DASModule module)`**
|
||||
Returns `true` if module is a TOM (based on serial number or channel type).
|
||||
|
||||
- **`void PurgeUnconfiguredChannels()`**
|
||||
Removes unconfigured or dummy channels from all modules.
|
||||
|
||||
- **`bool IsEmptyModule(Module module)`**
|
||||
Returns `true` if module has no configured/non-dummy channels.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **`DasModules`, `DasChannels`, `DasModuleChannels` are always initialized**
|
||||
These properties are initialized in the `Property<T>` declaration with new accessor instances and are marked `readonly`/`true` (immutable reference after construction).
|
||||
|
||||
- **Module array indices must match list positions**
|
||||
The constructor for `Event(List<IDASCommunication>, EventInfoAggregate)` asserts:
|
||||
`Debug.Assert(DasModules[das.SerialNumber].Count - 1 == dasModule.ModuleArrayIndex);`
|
||||
This implies modules are inserted in order, and empty slots are filled with placeholder `Module` instances.
|
||||
|
||||
- **Test ID must be consistent across all DAS units**
|
||||
During construction, if any DAS reports a different `TestID`, an exception is thrown.
|
||||
|
||||
- **Channel absolute numbers are assigned sequentially**
|
||||
`absoluteChannelNumber` is incremented per channel added, and `Module.Channel.AbsoluteNumber` is set during `Channel.CreateChannel`.
|
||||
|
||||
- **`InceptionDate` is set once at construction**
|
||||
The setter is `private`, and the property is initialized with `DateTime.Now` or the serialization date.
|
||||
|
||||
- **`TooLargeFor32BitVisualizationBytesPerSampleThreshold` is immutable after construction**
|
||||
Marked `readonly` and `true` in `Property<T>`.
|
||||
|
||||
- **`IsSlice6DBModule` check is case-insensitive**
|
||||
Compares `module.Description.ToLower()` to `"slice6db module"`.
|
||||
|
||||
- **`InvalidWindowAverage` is `short.MinValue`**
|
||||
Used to detect uninitialized or invalid window averages in zeroing logic.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Internal Dependencies (within this module)
|
||||
- `DTS.Slice.Control.Event.Module` and nested types (`Module.Channel`, `Module.AnalogInputChannel`, etc.)
|
||||
- `DTS.Common.Utilities.ExceptionalDictionary<TKey, TValue>`
|
||||
- `DTS.Common.Utilities.DotNetProgrammingConstructs.Property<T>`
|
||||
- `DTS.Slice.Control.Event.TestInformation` (private helper)
|
||||
|
||||
### External Dependencies
|
||||
- `DTS.Serialization.Test` (from `DTS.Serialization` namespace)
|
||||
- `DTS.DASLib.Service.IDASCommunication`, `DASModule`, `DASChannel`, `EthernetTDAS`
|
||||
- `DTS.Common.Utilities.Logging.APILogger`
|
||||
- `System.Collections.Generic.List<T>`, `System.Guid`, `System.DateTime`, `System.Diagnostics.Debug`
|
||||
- `DTS.Serialization.StringResources.Strings` (for error messages)
|
||||
|
||||
### Inferred Usage
|
||||
- `EventInfoAggregate` is required for `Event(List<IDASCommunication>, EventInfoAggregate)` constructor.
|
||||
- `Test.ReportErrors` delegate is used in `FromDtsSerializationTest`.
|
||||
- Serialization infrastructure (`DTS.Serialization`) is used for round-trip conversion (`ToDtsSerializationTest`, `FromDtsSerializationTest`).
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **`DasModuleChannels` property key is `"DTS.Slice.Control.Event.DasModules"` (typo)**
|
||||
In the `Event` constructor, the `Property<DasModuleChannelAccessor>` for `DasModuleChannels` is initialized with the key `"DTS.Slice.Control.Event.DasModules"` instead of `"DTS.Slice.Control.Event.DasModuleChannels"`. This is likely a copy-paste bug.
|
||||
|
||||
- **`DasModuleChannelAccessor` uses `int` keys for module/channel indices, not typed IDs**
|
||||
Both `ModuleChannelAccessor` and `ChannelAccessor` use `int` keys (for module number and channel number, respectively), not strongly-typed IDs (see `xxx` comments in source). This risks confusion or errors if indices are misaligned.
|
||||
|
||||
- **`InceptionDate` defaults to `DateTime.Now`**
|
||||
If constructed via the default constructor, `InceptionDate` reflects the current time—not the serialization time. Only the `Event(Test, ...)` constructor sets it from the `Test.InceptionDate`.
|
||||
|
||||
- **`IsSlice6DBModule` is case-sensitive on `"slice6db module"`**
|
||||
Uses `ToLower()` for comparison, but the literal string is lowercase. If the source description varies in casing (e.g., `"Slice6DB Module"`), it may not match.
|
||||
|
||||
- **Zeroing window validation is complex and fragile**
|
||||
`ChannelsWithActiveInvalidZeroingWindows` performs multiple checks (negative indices, window outside data range). Edge cases (e.g., empty `TriggerSampleNumbers`, zero sample rate) are not explicitly handled beyond defaulting to `0`.
|
||||
|
||||
- **`PurgeUnconfiguredChannels` modifies `Modules` in-place**
|
||||
Called during `ToDtsSerializationTest`, this permanently removes channels. If the `Event` object is reused, data may be lost.
|
||||
|
||||
- **`IsDummyChannel` and `IsSlice6DBModule` use string comparisons**
|
||||
Relies on literal string matching (`"dummy arm channel"`, `"slice6db module"`). No constants or enums are defined for these.
|
||||
|
||||
- **`IsG5` checks only serial number prefix**
|
||||
Assumes `"5M"` prefix is sufficient to identify G5 devices. May be brittle if serial number formats change.
|
||||
|
||||
- **No thread safety**
|
||||
Comments in `Event.cs` explicitly note: *"Also need to add thread protection."* and *"Can we set locks in the property accessors..."* — no synchronization is present.
|
||||
|
||||
- **`TestInformation` is private and not exposed**
|
||||
While used internally, it is not part of the public API. Its properties (`Id`, `Description`) are not validated beyond assignment.
|
||||
|
||||
- **`TooLargeFor32BitVisualizationBytesPerSampleThreshold` is hardcoded to `2.0`**
|
||||
The justification in comments is detailed, but the value is not configurable at runtime (only via reflection or subclassing).
|
||||
@@ -0,0 +1,150 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Serialization/Control/Event/Module/ReviewableDasSerialNumberAttribute.cs
|
||||
- Common/DTS.Common.Serialization/Control/Event/Module/ReviewableAttribute.cs
|
||||
- Common/DTS.Common.Serialization/Control/Event/Module/ReviewableSampleRateAttribute.cs
|
||||
- Common/DTS.Common.Serialization/Control/Event/Module/Module.cs
|
||||
generated_at: "2026-04-16T03:41:50.953091+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "ac685bc8f1311025"
|
||||
---
|
||||
|
||||
# Documentation: `DTS.Slice.Control.Event.Module.ReviewableAttribute` and Related Classes
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides a framework for defining *reviewable attributes*—read-only, human-readable metadata properties attached to a specific `Event.Module` instance—that can be used during test review or reporting workflows. Specifically, it defines an abstract base class `ReviewableAttribute` and several concrete subclasses (e.g., `ReviewableDasSerialNumberAttribute`, `ReviewableSampleRateAttribute`, `ReviewableHardwareFrequencyAttribute`, `ReviewableTestDescriptionAttribute`) that expose module-level data (such as DAS serial number, sample rate, hardware anti-aliasing filter rate, and test description) in a standardized, reviewable format. These attributes are intended to be consumed by downstream review UIs or export tools that need to display or validate module-level metadata.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `ReviewableAttribute` (Abstract Base Class)
|
||||
|
||||
- **Namespace**: `DTS.Slice.Control.Event.Module`
|
||||
- **Inherits from**: `Slice.Control.ReviewableAttribute` (external type, not shown in provided sources)
|
||||
- **Purpose**: Base class for all reviewable attributes attached to a `Module`.
|
||||
|
||||
#### Constructors
|
||||
|
||||
- `protected ReviewableAttribute(string name, DetermineValueString calculateValue)`
|
||||
- **Parameters**:
|
||||
- `name`: `string` – The display name of the attribute.
|
||||
- `calculateValue`: `DetermineValueString` – A delegate (function pointer) that returns the attribute’s value as a `string`.
|
||||
- **Behavior**: Initializes the base class with the provided name and value calculation delegate. This is the *only* constructor intended for use by subclasses.
|
||||
|
||||
- `public ReviewableAttribute(Event.Module module)` *(non-functional)*
|
||||
- **Behavior**: Throws a `NotImplementedException` wrapped in a `Module.ReviewableAttribute.Exception`. This constructor exists only to enforce that subclasses must use the parameterized constructor.
|
||||
|
||||
#### Nested Exception Type
|
||||
|
||||
- `public class Exception : Exception`
|
||||
- **Purpose**: Custom exception type used internally by `ReviewableAttribute` for constructor failures.
|
||||
|
||||
---
|
||||
|
||||
### `ReviewableDasSerialNumberAttribute`
|
||||
|
||||
- **Namespace**: `DTS.Slice.Control.Event.Module`
|
||||
- **Inherits from**: `ReviewableAttribute`
|
||||
- **Purpose**: Exposes the DAS serial number of the parent `Module`.
|
||||
|
||||
#### Constructor
|
||||
|
||||
- `public ReviewableDasSerialNumberAttribute(Event.Module module)`
|
||||
- **Parameters**:
|
||||
- `module`: `Event.Module` – The module to which this attribute is attached.
|
||||
- **Behavior**: Calls the base constructor with:
|
||||
- `name = "DAS Serial Number"`
|
||||
- `calculateValue = () => module.DasSerialNumber`
|
||||
- **Result**: The attribute’s value is the string value of `module.DasSerialNumber`.
|
||||
|
||||
---
|
||||
|
||||
### `ReviewableSampleRateAttribute`
|
||||
|
||||
- **Namespace**: `DTS.Slice.Control.Event.Module`
|
||||
- **Inherits from**: `ReviewableAttribute`
|
||||
- **Purpose**: Exposes the sample rate of the module, formatted with thousand separators.
|
||||
|
||||
#### Constructor
|
||||
|
||||
- `public ReviewableSampleRateAttribute(Event.Module module)`
|
||||
- **Parameters**:
|
||||
- `module`: `Event.Module`
|
||||
- **Behavior**: Calls base constructor with:
|
||||
- `name = "Sample Rate"`
|
||||
- `calculateValue = () => module.SampleRateHz.ToString("N")`
|
||||
- **Result**: The attribute’s value is `module.SampleRateHz.ToString("N")` (e.g., `"10,000.00"`).
|
||||
|
||||
---
|
||||
|
||||
### `ReviewableTestDescriptionAttribute`
|
||||
|
||||
- **Namespace**: `DTS.Slice.Control.Event.Module`
|
||||
- **Inherits from**: `ReviewableAttribute`
|
||||
- **Purpose**: Exposes the description of the *parent event* (not the module itself).
|
||||
|
||||
#### Constructor
|
||||
|
||||
- `public ReviewableTestDescriptionAttribute(Event.Module module)`
|
||||
- **Parameters**:
|
||||
- `module`: `Event.Module`
|
||||
- **Behavior**: Calls base constructor with:
|
||||
- `name = "Test Description"`
|
||||
- `calculateValue = () => module.ParentEvent.Description`
|
||||
- **Result**: The attribute’s value is `module.ParentEvent.Description`.
|
||||
|
||||
---
|
||||
|
||||
### `ReviewableHardwareFrequencyAttribute`
|
||||
|
||||
- **Namespace**: `DTS.Slice.Control.Event.Module`
|
||||
- **Inherits from**: `ReviewableAttribute`
|
||||
- **Purpose**: Exposes the hardware anti-aliasing filter rate, formatted to two decimal places.
|
||||
|
||||
#### Constructor
|
||||
|
||||
- `public ReviewableHardwareFrequencyAttribute(Event.Module module)`
|
||||
- **Parameters**:
|
||||
- `module`: `Event.Module`
|
||||
- **Behavior**: Calls base constructor with:
|
||||
- `name = "HW AAF"`
|
||||
- `calculateValue = () => module.AaFilterRateHz.ToString("N2")`
|
||||
- **Result**: The attribute’s value is `module.AaFilterRateHz.ToString("N2")` (e.g., `"5,000.00"`).
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Attribute Name Consistency**: Each subclass hardcodes its `name` in the base constructor call. The names used are:
|
||||
- `"DAS Serial Number"`
|
||||
- `"Sample Rate"`
|
||||
- `"Test Description"`
|
||||
- `"HW AAF"`
|
||||
- **Value Calculation Must Not Be Null**: The `calculateValue` delegate passed to the base constructor must return a non-null `string`. If `module.DasSerialNumber`, `module.SampleRateHz`, etc., are `null` or `0`, the `ToString()` call may produce `"0"` or empty string, but no validation is performed.
|
||||
- **Parent Module Must Be Non-null**: The `module` parameter passed to any subclass constructor must be non-null; otherwise, dereferencing `module.DasSerialNumber`, `module.SampleRateHz`, etc., will throw `NullReferenceException`.
|
||||
- **No Runtime Validation**: There is no validation in the constructors or elsewhere to ensure the attribute name or value format conforms to any external schema—only formatting is applied via `ToString()`.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Dependencies *of* this module:
|
||||
|
||||
- **`DTS.Slice.Control.Event.Module`** (`Module.cs`): Provides the `Module` class whose properties (`DasSerialNumber`, `SampleRateHz`, `AaFilterRateHz`, `ParentEvent.Description`) are accessed by the attribute subclasses.
|
||||
- **`DTS.Slice.Control.ReviewableAttribute`** (external): Base class for `ReviewableAttribute`. Its `DetermineValueString` delegate type is assumed to be defined there.
|
||||
- **`DTS.Utilities`**: Used only for logging (not directly used in these files, but imported).
|
||||
- **`System`**: Standard .NET types (`string`, `delegate`, `Exception`, etc.).
|
||||
|
||||
### Dependencies *on* this module:
|
||||
|
||||
- **Unknown from source alone**: No direct callers are visible in the provided files. However, the naming and structure suggest this is used by a review/reporting subsystem (e.g., UI or export tool) that instantiates these attributes and calls into the base `ReviewableAttribute` API (e.g., to retrieve `Name` and `Value`).
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Misleading XML Comments**: `ReviewableSampleRateAttribute` and `ReviewableHardwareFrequencyAttribute` are documented as “A reviewable filter frequency attribute attached to a specific channel.” — but they are attached to a `Module`, not a `Channel`. This is likely copy-paste error in comments.
|
||||
- **`ReviewableTestDescriptionAttribute` accesses `ParentEvent.Description`**, not `module.Description`. This may be intentional (e.g., to avoid duplication if description is event-level), but it’s non-obvious and could cause confusion.
|
||||
- **`ReviewableAttribute` constructor with `module` parameter is non-functional**: The constructor throws `NotImplementedException`. Subclasses *must* use the `protected` constructor with `name` and `calculateValue`. This is a safeguard, but could mislead developers into thinking the single-parameter constructor is usable.
|
||||
- **No `ToString()` formatting validation**: If `module.SampleRateHz` or `module.AaFilterRateHz` is `NaN` or `Infinity`, `ToString("N")` or `ToString("N2")` may produce `"NaN"`, `"Infinity"`, or `"–Infinity"`—which may not be desired for review displays.
|
||||
- **`StartRecordTimestampNanoSec` bug in `FromDtsSerializationTestModule`**: In `Module.cs`, line `TriggerTimestampNanoSec = that.StartRecordTimestampNanoSec;` appears to be a typo (should be `that.TriggerTimestampNanoSec`). While not directly in this module, it suggests potential data inconsistency risk in related code.
|
||||
- **No `Equals`/`GetHashCode` override in `ReviewableAttribute` subclasses**: Since these are likely used as keys or in collections, lack of value-based equality may cause subtle bugs. However, this is not evident from the source alone—no usage patterns are shown.
|
||||
|
||||
> **Note**: No usage of `ReviewableAttribute` beyond construction is visible in the provided files. The actual mechanism for invoking `calculateValue` (e.g., via a public `Value` property inherited from `Slice.Control.ReviewableAttribute`) is not documented here and must be assumed from the base class.
|
||||
@@ -0,0 +1,81 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Serialization/Control/Event/Module/AnalogInputChannel/ReviewableShuntDeflectionAttribute.cs
|
||||
- Common/DTS.Common.Serialization/Control/Event/Module/AnalogInputChannel/ReviewableFilterFrequencyAttribute.cs
|
||||
- Common/DTS.Common.Serialization/Control/Event/Module/AnalogInputChannel/ReviewableIsoCodeAttribute.cs
|
||||
- Common/DTS.Common.Serialization/Control/Event/Module/AnalogInputChannel/ReviewableDescriptionAttribute.cs
|
||||
- Common/DTS.Common.Serialization/Control/Event/Module/AnalogInputChannel/ReviewableSerialNumberAttribute.cs
|
||||
- Common/DTS.Common.Serialization/Control/Event/Module/AnalogInputChannel/ReviewableUnitsAttribute.cs
|
||||
- Common/DTS.Common.Serialization/Control/Event/Module/AnalogInputChannel/ReviewableMinMaxEuAttribute.cs
|
||||
- Common/DTS.Common.Serialization/Control/Event/Module/AnalogInputChannel/ReviewableCfcAttribute.cs
|
||||
- Common/DTS.Common.Serialization/Control/Event/Module/AnalogInputChannel/ReviewableTargetShuntDeflectionAttribute.cs
|
||||
- Common/DTS.Common.Serialization/Control/Event/Module/AnalogInputChannel/ReviewableMeasuredShuntDeflectionAttribute.cs
|
||||
- Common/DTS.Common.Serialization/Control/Event/Module/AnalogInputChannel/ReviewableShuntDeflectionPercentageAttribute.cs
|
||||
generated_at: "2026-04-16T03:42:18.353896+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "b040e834d4537e76"
|
||||
---
|
||||
|
||||
# `DTS.Slice.Control.Event.Module.AnalogInputChannel.ReviewableAttribute` Implementations
|
||||
|
||||
## 1. Purpose
|
||||
This module provides a set of concrete `ReviewableAttribute` subclasses used to expose specific channel metadata and calibration-related values for review in the DTS Slice control/event system. Each attribute encapsulates a named, human-readable property of an `AnalogInputChannel` (e.g., serial number, filter settings, shunt calibration metrics), formatted as a string via a delegate. These attributes are intended for use in UI review workflows or audit logs where static or quasi-static channel configuration and calibration state must be presented consistently.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
All classes inherit from `Slice.Control.Event.Module.Channel.ReviewableAttribute`. Each constructor accepts a single `Event.Module.Channel` parameter and passes a display name and a `Func<string>` to the base constructor.
|
||||
|
||||
| Class | Constructor | Display Name | Behavior |
|
||||
|-------|-------------|--------------|----------|
|
||||
| `ReviewableShuntDeflectionAttribute` | `ReviewableShuntDeflectionAttribute(Channel)` | `"Shunt Deflection (mV)"` | Returns `channel.MeasuredShuntDeflectionMv.ToString("F1")`. Requires `channel` to implement `DTS.DAS.Concepts.DAS.Channel.IShuntAware`. |
|
||||
| `ReviewableFilterFrequencyAttribute` | `ReviewableFilterFrequencyAttribute(Channel)` | `"Filter Frequency"` | Returns `(int)(channel.CurrentFilter as SaeJ211Filter).CutoffFrequencyHz.ToString("N")`. Requires `channel.CurrentFilter` to be a `SaeJ211Filter`. |
|
||||
| `ReviewableIsoCodeAttribute` | `ReviewableIsoCodeAttribute(Channel)` | `"ISO Code"` | Returns `(channel as AnalogInputChannel).IsoCode.ToString()`. Requires `channel` to be an `AnalogInputChannel`. |
|
||||
| `ReviewableDescriptionAttribute` | `ReviewableDescriptionAttribute(Channel)` | `"Description"` | Returns `channel.ChannelDescriptionString`. |
|
||||
| `ReviewableSerialNumberAttribute` | `ReviewableSerialNumberAttribute(Channel)` | `"Serial Number"` | Returns `(channel as AnalogInputChannel).SerialNumber.ToString()`. Requires `channel` to be an `AnalogInputChannel`. |
|
||||
| `ReviewableUnitsAttribute` | `ReviewableUnitsAttribute(Channel)` | `"Units"` | Returns `channel.EngineeringUnits.ToString()`. Requires `channel` to implement `DTS.DAS.Concepts.DAS.Channel.IEngineeringUnitAware`. |
|
||||
| `ReviewableMinMaxEuAttribute` | `ReviewableMinMaxEuAttribute(Channel)` | `"Max/Min (EU)"` | Returns `channel.DataMaxFilteredEu.ToString("F1") + "/" + channel.DataMinFilteredEu.ToString("F1")`. |
|
||||
| `ReviewableCfcAttribute` | `ReviewableCfcAttribute(Channel)` | `"CFC"` | Returns `"N/A"` if `channel.CurrentFilter.Type == ChannelFilter.AdHoc`; otherwise returns `(new CfcValueAttributeCoder()).DecodeAttributeValue((channel.CurrentFilter as SaeJ211Filter).Type).ToString()`. Requires `channel.CurrentFilter` to be a `SaeJ211Filter`. |
|
||||
| `ReviewableTargetShuntDeflectionAttribute` | `ReviewableTargetShuntDeflectionAttribute(Channel)` | `"Target Shunt Deflection (mV)"` | Returns `channel.TargetShuntDeflectionMv.ToString("F1")`. Requires `channel` to implement `IShuntAware`. |
|
||||
| `ReviewableTargetCalSignalAttribute` | `ReviewableTargetCalSignalAttribute(Channel)` | `"Target Calibration Signal (mV)"` | Returns `channel.TargetCalSignalMv.ToString("F1")`. Requires `channel` to implement `DTS.DAS.Concepts.DAS.Channel.ICalSignalAware`. |
|
||||
| `ReviewableMeasuredShuntDeflectionAttribute` | `ReviewableMeasuredShuntDeflectionAttribute(Channel)` | `"Measured Shunt Deflection (mV)"` | Returns `channel.MeasuredShuntDeflectionMv.ToString("F1")`. Requires `channel` to implement `IShuntAware`. |
|
||||
| `ReviewableMeasuredCalSignalAttribute` | `ReviewableMeasuredCalSignalAttribute(Channel)` | `"Measured Calibration Signal (mV)"` | Returns `channel.MeasuredCalSignalMv.ToString("F1")`. Requires `channel` to implement `ICalSignalAware`. |
|
||||
| `ReviewableShuntDeflectionPercentageAttribute` | `ReviewableShuntDeflectionPercentageAttribute(Channel)` | `"Shunt Error (%)"` | Returns `100.0 * (MeasuredShuntDeflectionMv - TargetShuntDeflectionMv) / TargetShuntDeflectionMv.ToString("F1")`. Requires `channel` to implement `IShuntAware`. |
|
||||
| `ReviewableCalSignalPercentageAttribute` | `ReviewableCalSignalPercentageAttribute(Channel)` | `"Calibration Signal Error (%)"` | Returns `100.0 * (MeasuredCalSignalMv - TargetCalSignalMv) / TargetCalSignalMv.ToString("F1")`. Requires `channel` to implement `ICalSignalAware`. |
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **All attributes are read-only**: Each attribute’s value is computed on-demand via a delegate passed to the base class; no internal state is stored beyond the delegate capture.
|
||||
- **Type assumptions**: Each attribute assumes the `channel` parameter supports specific interfaces or concrete types:
|
||||
- `IShuntAware` for shunt-related attributes (`ReviewableShuntDeflectionAttribute`, `ReviewableTargetShuntDeflectionAttribute`, `ReviewableMeasuredShuntDeflectionAttribute`, `ReviewableShuntDeflectionPercentageAttribute`).
|
||||
- `ICalSignalAware` for calibration signal attributes (`ReviewableTargetCalSignalAttribute`, `ReviewableMeasuredCalSignalAttribute`, `ReviewableCalSignalPercentageAttribute`).
|
||||
- `IEngineeringUnitAware` for `ReviewableUnitsAttribute`.
|
||||
- `SaeJ211Filter` for `ReviewableFilterFrequencyAttribute` and `ReviewableCfcAttribute`.
|
||||
- `AnalogInputChannel` (via `as`) for `ReviewableIsoCodeAttribute` and `ReviewableSerialNumberAttribute`.
|
||||
- **Null-safety**: None of the attributes perform explicit null checks. If `channel` is `null`, or if the required interface/type cast fails (e.g., `channel.CurrentFilter` is not a `SaeJ211Filter`), a `NullReferenceException` or `InvalidCastException` will occur at evaluation time.
|
||||
- **Formatting consistency**: All numeric values are formatted with `"F1"` (1 decimal place) or `"N"` (thousands separator, no decimals) as shown.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Internal Dependencies (from source):
|
||||
- `DTS.Slice.Control.Event.Module.Channel.ReviewableAttribute` (base class, not shown but referenced).
|
||||
- `DTS.DAS.Concepts.DAS.Channel.IShuntAware`, `ICalSignalAware`, `IEngineeringUnitAware` (interfaces).
|
||||
- `DTS.DAS.Concepts.DAS.Channel.SaeJ211Filter`, `ChannelFilter` (types).
|
||||
- `DTS.Utilities.CfcValueAttributeCoder` (used in `ReviewableCfcAttribute`).
|
||||
- `DTS.Slice.Control.Event.Module.AnalogInputChannel` (namespace context and partial class definitions).
|
||||
|
||||
### External Dependencies:
|
||||
- `System` (core runtime).
|
||||
- `DTS.Utilities` (assembly reference required for `CfcValueAttributeCoder` and `SaeJ211Filter`).
|
||||
|
||||
### Inferred Usage:
|
||||
- These attributes are likely instantiated and collected by a higher-level component that iterates over `AnalogInputChannel` instances and exposes their reviewable metadata (e.g., for calibration reports or UI inspection panels). The repeated pattern suggests a factory or registration mechanism exists elsewhere (not visible here).
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Ambiguous naming**: `ReviewableShuntDeflectionAttribute` (in first file) and `ReviewableMeasuredShuntDeflectionAttribute` (in later file) have identical implementation logic and display names. This duplication is likely unintentional or legacy; only one should be used, or naming should be clarified (e.g., “Shunt Deflection (mV)” vs. “Measured Shunt Deflection (mV)”).
|
||||
- **Missing null guards**: All attributes assume `channel` is non-null and implements required interfaces. A cast failure (e.g., `channel as DTS.DAS.Concepts.DAS.Channel.IShuntAware` returning `null`) will cause a `NullReferenceException` at delegate invocation time, not construction.
|
||||
- **`ReviewableCfcAttribute` logic**: The commented-out line suggests a previous implementation using `CfcValueAttributeCoder.DecodeAttributeValue` directly, but the current version adds a special case for `ChannelFilter.AdHoc`. This implies that `AdHoc` filters may not have a valid `Type` for decoding, and the attribute must handle this explicitly.
|
||||
- **`ReviewableFilterFrequencyAttribute` casts `channel.CurrentFilter` to `SaeJ211Filter` without checking**: If `CurrentFilter` is not a `SaeJ211Filter`, this will throw `InvalidCastException`.
|
||||
- **`ReviewableIsoCodeAttribute` comment is incorrect**: Its summary says “serial number attribute” but the class name and implementation clearly indicate it’s for ISO code. Likely copy-paste error in documentation.
|
||||
- **No validation of division-by-zero**: In `ReviewableShuntDeflectionPercentageAttribute` and `ReviewableCalSignalPercentageAttribute`, if `TargetShuntDeflectionMv` or `TargetCalSignalMv` is zero, a `DivideByZeroException` will occur.
|
||||
@@ -0,0 +1,302 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Serialization/Control/Event/Module/Channel/DataValues.cs
|
||||
- Common/DTS.Common.Serialization/Control/Event/Module/Channel/ReviewableAttribute.NotApplicableException.cs
|
||||
- Common/DTS.Common.Serialization/Control/Event/Module/Channel/Filter.cs
|
||||
- Common/DTS.Common.Serialization/Control/Event/Module/Channel/ChannelDefaultSaeJ211Filter.cs
|
||||
- Common/DTS.Common.Serialization/Control/Event/Module/Channel/CalculatedChannel.cs
|
||||
- Common/DTS.Common.Serialization/Control/Event/Module/Channel/SaeJ211Filter.cs
|
||||
generated_at: "2026-04-16T03:42:34.925173+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "2400faf1f9897d63"
|
||||
---
|
||||
|
||||
# Documentation: `DTS.Slice.Control.Event.Module.Channel` Subsystem
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides core data structures and abstractions for representing and manipulating channel data within event recordings in the DTS Slice Control system. It defines the foundational types for physical channels, calculated channels, filters (including SAE J211–compliant filters), and data storage mechanisms (in-memory vs. memory-mapped). The subsystem enables filtering, unit conversion, and serialization of channel data, supporting both raw sensor inputs (ADC) and derived quantities (EU, mV), as well as computed channels (e.g., integrals, derivatives, FFTs). It serves as the data model layer for event analysis and review workflows.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `DataValues` class
|
||||
*Defined in: `Common/DTS.Common.Serialization/Control/Event/Module/Channel/DataValues.cs`*
|
||||
|
||||
- **`DataValues()`**
|
||||
Initializes a `DataValues` instance using in-memory storage (i.e., `UseMemoryMappedFile = false`).
|
||||
|
||||
- **`DataValues(bool useMemoryMappedFile)`**
|
||||
Initializes a `DataValues` instance. If `useMemoryMappedFile` is `true`, the instance is configured to use memory-mapped files for data storage (intended for large datasets exceeding process memory limits).
|
||||
|
||||
- **`UseMemoryMappedFile: bool`**
|
||||
Property controlling whether the instance uses memory-mapped files (`true`) or in-memory storage (`false`). Implemented via a `Property<bool>` wrapper.
|
||||
|
||||
---
|
||||
|
||||
### `Filter` abstract class
|
||||
*Defined in: `Common/DTS.Common.Serialization/Control/Event/Module/Channel/Filter.cs`*
|
||||
|
||||
- **`Name: string` (abstract)**
|
||||
Returns a descriptive name for the filter (e.g., `"6G"` for a 6g filter, or `"123.45Hz"` for ad hoc).
|
||||
|
||||
- **`IsCfc: bool` (abstract)**
|
||||
Returns `true` if the filter corresponds to a defined CFC (Channel Filter Classification) value; `false` for `Unfiltered` or `AdHoc`.
|
||||
|
||||
- **`Type: ChannelFilter` (abstract)**
|
||||
Returns the canonical `ChannelFilter` enum value representing the filter (e.g., `ChannelFilter.SixG`, `ChannelFilter.AdHoc`).
|
||||
|
||||
- **`CutoffFrequencyHz: double` (abstract)**
|
||||
Returns the filter’s cutoff frequency in hertz.
|
||||
|
||||
- **`Apply(Channel input, DataDisplayUnits displayUnits, bool bUseLegacyTDCSoftwareFilterAdjustment): double[]` (abstract)**
|
||||
Applies the filter to the unfiltered data of the specified `input` channel, returning filtered data in the requested `displayUnits` (ADC, EU, or mV). The `bUseLegacyTDCSoftwareFilterAdjustment` flag controls whether a one-sample phase shift is applied to match legacy TDC behavior (see issue #8747).
|
||||
|
||||
- **`Apply(double[] data, double sampleRate, bool bUseLegacyTDCSoftwareFilterAdjustment): double[]` (abstract)**
|
||||
Applies the filter to a raw data array with known `sampleRate`, returning filtered data. Used when channel context is unavailable.
|
||||
|
||||
- **`ToBaseString(): string` (abstract)**
|
||||
Returns the filter’s base name (e.g., `"6G"`), without any decorative prefix (e.g., `"Default (6G)"`). Distinct from `ToString()`.
|
||||
|
||||
---
|
||||
|
||||
### `SaeJ211Filter` class
|
||||
*Defined in: `Common/DTS.Common.Serialization/Control/Event/Module/Channel/SaeJ211Filter.cs`*
|
||||
|
||||
- **`SaeJ211Filter(ChannelFilter originalType)`**
|
||||
Initializes a filter for a CFC-compliant type (e.g., `ChannelFilter.SixG`). Throws `Exception` if `originalType == ChannelFilter.AdHoc`.
|
||||
|
||||
- **`SaeJ211Filter(double cutoffFrequencyHz)`**
|
||||
Initializes an ad hoc filter with the specified cutoff frequency.
|
||||
|
||||
- **`SaeJ211Filter(SaeJ211Filter originalFilter)`**
|
||||
Copy constructor.
|
||||
|
||||
- **`OriginalType: ChannelFilter`**
|
||||
Stores the original filter type passed at construction (e.g., `AdHoc` for ad hoc filters). Not modifiable after construction.
|
||||
|
||||
- **`Type: ChannelFilter` (override)**
|
||||
Returns the *effective* filter type: if `OriginalType == AdHoc`, resolves to the nearest matching CFC (or `AdHoc` if no match); otherwise returns `OriginalType`.
|
||||
|
||||
- **`IsCfc: bool` (override)**
|
||||
Returns `true` if `Type` is neither `Unfiltered` nor `AdHoc`.
|
||||
|
||||
- **`CutoffFrequencyHz: double` (override)**
|
||||
Returns the cutoff frequency in Hz (derived from `OriginalType` or explicitly set for ad hoc filters).
|
||||
|
||||
- **`IsoDescription: char`**
|
||||
Returns the first character of the ISO description for `OriginalType` (e.g., `'G'` for `SixG`).
|
||||
|
||||
- **`Name: string` (override)**
|
||||
Returns a human-readable name:
|
||||
- For `AdHoc`: `"123.45Hz"`
|
||||
- For CFC types: description from `DescriptionAttributeCoder<ChannelFilter>` (e.g., `"6G"`).
|
||||
|
||||
- **`Apply(...)` (override)**
|
||||
Implements filtering using `FilterUtility`. Supports filtering from `UnfilteredData`, `UnfilteredDataEu`, or `UnfilteredDataMv` depending on `displayUnits`. Logs warnings for invalid data via `APILogger`.
|
||||
|
||||
- **`Parse(string serialization): Filter` (static)**
|
||||
Parses a serialized filter string (e.g., `"6G"`, `"123.45Hz"`) into a `Filter` instance. Falls back to `Unfiltered` on parse failure.
|
||||
|
||||
- **`Equals(object obj): bool` (override)**
|
||||
Case-insensitive comparison of filter names.
|
||||
|
||||
- **`GetHashCode(): int` (override)**
|
||||
Hash code based on lowercase filter name.
|
||||
|
||||
- **`ToString(): string` (override)**
|
||||
Returns `Name`.
|
||||
|
||||
- **`ToBaseString(): string` (override)**
|
||||
Returns `Name`.
|
||||
|
||||
---
|
||||
|
||||
### `DefaultSaeJ211Filter` class
|
||||
*Defined in: `Common/DTS.Common.Serialization/Control/Event/Module/Channel/ChannelDefaultSaeJ211Filter.cs`*
|
||||
|
||||
- **`DefaultSaeJ211Filter(SaeJ211Filter filter)`**
|
||||
Copy constructor.
|
||||
|
||||
- **`DefaultSaeJ211Filter(ChannelFilter filterType)`**
|
||||
Initializes with a CFC filter type.
|
||||
|
||||
- **`DefaultSaeJ211Filter(double adHocFrequency)`**
|
||||
Initializes with an ad hoc frequency.
|
||||
|
||||
- **`Name: string` (override)**
|
||||
Returns `"Default (" + base.Name + ")"` (e.g., `"Default (6G)"`).
|
||||
|
||||
- **`ToBaseString(): string` (override)**
|
||||
Returns `base.Name` (e.g., `"6G"`).
|
||||
|
||||
- **`ToString(): string` (override)**
|
||||
Returns `Name`.
|
||||
|
||||
---
|
||||
|
||||
### `CalculatedChannel` abstract class
|
||||
*Defined in: `Common/DTS.Common.Serialization/Control/Event/Module/Channel/CalculatedChannel.cs`*
|
||||
|
||||
- **`Operation` enum**
|
||||
Defines supported calculations: `Integral`, `Derivative`, `HeadInjuryCriteria`, `FFT`, `ImportedCSV`, `Resultant`, `TSR`, `Scale`, `Offset`, `Sine`, `Cosine`.
|
||||
|
||||
- **`CalculationType: Operation`**
|
||||
Returns the operation performed by this channel.
|
||||
|
||||
- **`X: double[]`, `Y: double[]`**
|
||||
Read-only arrays of x-axis and y-axis data points.
|
||||
|
||||
- **`XAxis: XUnits`**
|
||||
X-axis unit type (`msec`, `sec`, `Hz`, `samples`).
|
||||
|
||||
- **`XUnitsString: string`**
|
||||
Human-readable unit string (e.g., `"ms"`, `"Hz"`).
|
||||
|
||||
- **`EngineeringUnits: string`**
|
||||
Y-axis engineering units (e.g., `"g"`, `"m/s"`).
|
||||
|
||||
- **`SupportsADC: bool` (override)**
|
||||
Always `false` for calculated channels.
|
||||
|
||||
- **`SupportsEU: bool` (override)**
|
||||
Always `true`.
|
||||
|
||||
- **`SupportsmV: bool` (override)**
|
||||
Always `false`.
|
||||
|
||||
- **`ActualMaxRangeEu`, `ActualMinRangeEu`, `DataMaxEu`, `DataMinEu`, `DataRangeEu`, `DataHalfRangeValueEu` (overrides)**
|
||||
Computed from `Y` data (e.g., `DataMaxEu = _y.Max()`).
|
||||
|
||||
- **`IsConfigured: bool` (override)**
|
||||
Always `true`; setting throws `NotSupportedException`.
|
||||
|
||||
- **`GetUnfilteredDataEu(): List<double>` (override)**
|
||||
Returns a copy of `Y`.
|
||||
|
||||
- **Constructors**
|
||||
- `CalculatedChannel(string name, XUnits xAxis, string yAxis, double[] xValues, double[] yValues, Operation calcType, int number, Module parentModule)`
|
||||
Initializes with data, axis labels, and calculation type. Sets `CurrentFilter` to `DefaultSaeJ211Filter(ChannelFilter.Unfiltered)`.
|
||||
|
||||
- **`ToString(): string` (override)**
|
||||
Returns `ChannelDescriptionString` or `"N/A"`.
|
||||
|
||||
---
|
||||
|
||||
### Derived `CalculatedChannel` classes
|
||||
*Defined in: `Common/DTS.Common.Serialization/Control/Event/Module/Channel/CalculatedChannel.cs`*
|
||||
|
||||
- **`FFTCalculatedChannel`**
|
||||
- **`PeakFrequency: double`**
|
||||
Returns the peak frequency from the FFT.
|
||||
|
||||
- **`IntegralCalculatedChannel`, `DerivativeCalculatedChannel`, `ScaleCalculatedChannel`, `OffsetCalculatedChannel`, `ResultantCalculatedChannel`, `AdditiveVectorCalculatedChannel`, `SineCalculatedChannel`, `CosineCalculatedChannel`**
|
||||
All inherit from `CalculatedChannel` with no additional public members.
|
||||
|
||||
> **Note**: `HICCalculatedChannel` is commented out in source and not documented.
|
||||
|
||||
---
|
||||
|
||||
### `ReviewableAttribute.NotApplicableException` class
|
||||
*Defined in: `Common/DTS.Common.Serialization/Control/Event/Module/Channel/ReviewableAttribute.NotApplicableException.cs`*
|
||||
|
||||
- **`NotApplicableException()`**
|
||||
Default constructor.
|
||||
|
||||
- **`NotApplicableException(string msg)`**
|
||||
Constructor with message.
|
||||
|
||||
- **`NotApplicableException(string msg, Exception innerEx)`**
|
||||
Constructor with message and inner exception.
|
||||
|
||||
> Inherits from `ApplicationException`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **`DataValues.UseMemoryMappedFile`**
|
||||
Once set during construction, this flag determines the storage strategy for channel data. No runtime switching is exposed.
|
||||
|
||||
- **`SaeJ211Filter.OriginalType`**
|
||||
Immutable after construction. `Type` may differ from `OriginalType` for ad hoc filters (resolved to nearest CFC or `AdHoc`).
|
||||
|
||||
- **`Filter.Type`**
|
||||
For ad hoc filters (`OriginalType == AdHoc`), `Type` is computed dynamically based on `CutoffFrequencyHz` (via `ConvertFrequencyToChannelFilter`). If frequency matches a CFC enum value, `Type` becomes that CFC; otherwise remains `AdHoc`.
|
||||
|
||||
- **`CalculatedChannel` properties**
|
||||
- `SupportsADC` and `SupportsmV` are always `false`; `SupportsEU` is always `true`.
|
||||
- Range properties (`ActualMaxRangeEu`, etc.) are derived from `Y` data and may change if `Y` is modified (though `Y` is read-only via public API).
|
||||
|
||||
- **`Filter.Apply(...)`**
|
||||
Filtering always uses `FilterUtility` with `Cfc = Type`, `AdHocFrequency = CutoffFrequencyHz`, and `SampleRate` from channel or parameter. Invalid data triggers logging and exception.
|
||||
|
||||
- **`Filter.Parse(...)`**
|
||||
Returns `Unfiltered` filter on parse failure (not `null`).
|
||||
|
||||
---
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Internal Dependencies (from source)
|
||||
- **`DTS.Common.Utilities`**
|
||||
Used for `Property<T>`, logging (`APILogger`), and encoding utilities (`CfcValueAttributeCoder`, `DescriptionAttributeCoder`, `IsoDescriptionAttributeCoder`).
|
||||
|
||||
- **`DTS.Slice.Control.DAS.Channel`**
|
||||
Referenced for `ChannelFilter` enum and `DataDisplayUnits` enum.
|
||||
|
||||
- **`DTS.Common.DAS.Concepts.DAS.Channel.IEngineeringUnitAware`**
|
||||
Implemented by `CalculatedChannel`.
|
||||
|
||||
- **Serialization types**
|
||||
`Serialization.SliceRaw.File.PersistentChannel`, `Serialization.TDAS.File.PersistentChannel`, `ILargeDataAware`, `Serialization.Test.Module.Channel`.
|
||||
|
||||
- **`DTS.Calculations.HeadInjuryCriterion.HICResult`**
|
||||
Referenced in commented-out `HICCalculatedChannel` code.
|
||||
|
||||
- **`DTS.Common.Utilities.SaeJ211`**
|
||||
Used for `FilterUtility` and related encoding.
|
||||
|
||||
### External Dependencies (inferred)
|
||||
- **`System`**
|
||||
Standard .NET types (`Exception`, `ApplicationException`, `CultureInfo`, `Enum`, etc.).
|
||||
|
||||
- **Windows Forms (commented)**
|
||||
`System.Windows.Forms.MessageBox` appears in commented-out code (not active).
|
||||
|
||||
---
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **`DataValues` has no data storage logic**
|
||||
The class only configures storage mode (`UseMemoryMappedFile`). Actual data handling is delegated to `Channel` (not shown in these files). `DataValues` is a configuration helper, not a data container.
|
||||
|
||||
- **`SaeJ211Filter.Type` may differ from `OriginalType`**
|
||||
For ad hoc filters, `Type` resolves to the nearest CFC match. This can cause `IsCfc` to return `true` even if `OriginalType == AdHoc`.
|
||||
|
||||
- **`Filter.Parse(...)` silently falls back to `Unfiltered`**
|
||||
On parse failure, returns `new SaeJ211Filter(ChannelFilter.Unfiltered)` instead of throwing. Callers must validate if needed.
|
||||
|
||||
- **`DefaultSaeJ211Filter.ToString()` vs `ToBaseString()`**
|
||||
`ToString()` returns `"Default (X)"`, while `ToBaseString()` returns `"X"`. Confusing if not documented.
|
||||
|
||||
- **`CalculatedChannel` range properties assume non-empty `Y`**
|
||||
`DataMaxEu`, `DataMinEu`, etc., use `_y.Max()`/`_y.Min()` without checking for empty data. Will throw `InvalidOperationException` if `Y` is empty.
|
||||
|
||||
- **`SupportsADC`/`SupportsmV` are hard-coded `false`**
|
||||
Calculated channels never support raw ADC or mV; only engineering units (EU). Attempting to access `ActualMinRangeMv` throws `NotImplementedException`.
|
||||
|
||||
- **`CalculatedChannel` serialization methods throw `NotSupportedException`**
|
||||
`FromDtsSerializationTestModuleChannel`, `ToDtsSerializationTestModuleChannel`, `SetPropertyValuesFrom(...)` all throw. Calculated channels are not serializable via these paths.
|
||||
|
||||
- **`Filter.Apply(...)` logs invalid data but throws**
|
||||
`FilterUtility.InvalidDataDelegate` logs via `APILogger` but then throws an exception. No silent failure.
|
||||
|
||||
- **`ChannelFilter` enum values are used as frequencies**
|
||||
CFC filters (e.g., `ChannelFilter.SixG`) are implicitly cast to `double` for frequency. This relies on enum underlying values matching CFC frequencies.
|
||||
|
||||
- **`IsoDescription` uses `OriginalType`**
|
||||
The ISO description character is derived from `OriginalType`, not `Type`. For ad hoc filters, this may be `Unfiltered` (not meaningful).
|
||||
|
||||
- **`DataValues` constructor catches and rethrows as `Exception`**
|
||||
Any exception during construction is wrapped in a generic `Exception` with a message like `"encountered problem constructing DTS.Slice.Control.Event.Module.Channel.DataValues"`. Original exception is preserved in `InnerException`.
|
||||
@@ -0,0 +1,325 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Serialization/DDAS (Chrysler)/ChannelDefinition.h
|
||||
- Common/DTS.Common.Serialization/DDAS (Chrysler)/DDASTestDefinition.h
|
||||
- Common/DTS.Common.Serialization/DDAS (Chrysler)/DataFloat.h
|
||||
- Common/DTS.Common.Serialization/DDAS (Chrysler)/DDAS.File.cs
|
||||
- Common/DTS.Common.Serialization/DDAS (Chrysler)/DDASTest.cs
|
||||
- Common/DTS.Common.Serialization/DDAS (Chrysler)/DDAS.File.Writer.cs
|
||||
- Common/DTS.Common.Serialization/DDAS (Chrysler)/TSVSettingsWindow.cs
|
||||
- Common/DTS.Common.Serialization/DDAS (Chrysler)/TSVSettingsWindow.Designer.cs
|
||||
- Common/DTS.Common.Serialization/DDAS (Chrysler)/DDASChannel.cs
|
||||
generated_at: "2026-04-16T13:34:29.248067+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "3efc64a6d144d6f5"
|
||||
---
|
||||
|
||||
# DDAS Serialization Module Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides serialization and deserialization support for the DDAS (DaimlerChrysler Data Acquisition System) file format, a proprietary binary format used for storing crash test data. It bridges legacy C/C++ data structures (originally from DaimlerChrysler's DDAS V5 system) with modern .NET serialization infrastructure, enabling export of test data including channel configurations, transducer information, and floating-point measurement data. The module handles both the file format definitions and the actual binary writing of channel data.
|
||||
|
||||
---
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### C/C++ Structures (Header Files)
|
||||
|
||||
#### `ChannelDefinition.h`
|
||||
|
||||
**`enum ChannelFlags`**
|
||||
- `CHANFLAG_ACTIVE` - Flag indicating an active channel
|
||||
|
||||
**Macros:**
|
||||
- `ISCHANACTIVE(pChan)` - Returns 1 if channel is active, 0 otherwise
|
||||
- `SETCHANACTIVE(pChan)` - Sets the active flag on a channel
|
||||
- `CLRCHANACTIVE(pChan)` - Clears the active flag on a channel
|
||||
|
||||
**`struct tagCHANNEL` / `CHANNEL` / `PCHANNEL` / `PCHAN`**
|
||||
- `short Size` - Size of this object
|
||||
- `short Flags` - Channel flags
|
||||
- `char Name[64]` - Channel name
|
||||
- `char Sign[8]` - Sign (+, -, or blank)
|
||||
- `char Axis[8]` - Axis designation (X, Y, Z, FX, MX, AX, etc.)
|
||||
- `float FilterFreq` - Channel filter class in Hz
|
||||
- `float SetGain` - Gain setting (1 - n)
|
||||
- `float ActGain` - Actual (measured) gain setting
|
||||
- `float Rcal` - Shunt calibration resistance
|
||||
- `float Excitation` - Excitation voltage (when programmable)
|
||||
- `byte byteSpares[4]` - Spare bytes (was CalDate, removed 11/08/04)
|
||||
- `TRANSDUCER Transducer` - Snapshot of transducer values
|
||||
|
||||
---
|
||||
|
||||
#### `DDASTestDefinition.h`
|
||||
|
||||
**`enum FileTypeFlags`**
|
||||
- `FILETYPE_IMPORTED4X` - Test was imported from 4x format
|
||||
|
||||
**`enum HardwareType`**
|
||||
- `HWTYPE_UNKNOWN` - None specified (old DDAS)
|
||||
- `HWTYPE_DDAS3` - DDAS III hardware
|
||||
- `HWTYPE_KAYSERTHREDE` - Kayser-Threde hardware (future)
|
||||
- `HWTYPE_COUNT` - Count of hardware types
|
||||
|
||||
**`struct tagFILEINFOBLOCK` / `FILEINFOBLOCK`**
|
||||
- `UINT Size` - Block size including nSize
|
||||
- `char FileTypeName[12]` - Software type name
|
||||
- `char FileTypeVers[12]` - File version name
|
||||
- `UINT FileTypeFlags` - Hardware type in upper 16 bits, File type in lower 16 bits
|
||||
- `char CreatedByName[16]` - Created by T-number
|
||||
- `char UpdatedByName[16]` - Updated by T-number
|
||||
|
||||
**`struct tagDATASYSTEMBLOCK` / `DATASYSTEMBLOCK`**
|
||||
- `UINT Size`, `NumberOfSystems`, `ChannelsPerSystem`, `MaxSampleRate`, `SizeOfConfig`
|
||||
|
||||
**`struct tagDDASCONFIGBLOCK` / `DDASCONFIGBLOCK`**
|
||||
- `UINT Size`
|
||||
- `short AnalogUnitNo`, `AnalogOptions`, `MemoryUnitNo`, `MemoryOptions`
|
||||
- `long MemorySize`
|
||||
|
||||
**`enum AnalogOptionFlags`**
|
||||
- `ANAOPT_CHANTRIGGERS` - Analog unit has channel triggers
|
||||
|
||||
**`enum MemoryOptionFlags`**
|
||||
- `MEMOPT_TAPEMODE` - Memory unit has tape mode
|
||||
- `MEMOPT_PREEVENT` - Memory unit can select pre-event to 99
|
||||
- `MEMOPT_PREEVENTXXX` - Memory unit can select pre-event to 511
|
||||
|
||||
**`enum RecordModes`**
|
||||
- `RECORDMODE_EVENT` - Normal (event) mode
|
||||
- `RECORDMODE_TAPE` - Tape (manual) mode
|
||||
|
||||
**`struct tagACQUISITIONBLOCK` / `ACQUISITIONBLOCK`**
|
||||
- `long nSize`, `nRecordMode`, `SampleRate`, `TotalSamples`, `PreEventSamples`, `TapeModeChannels`, `nTrigBlock`
|
||||
|
||||
**`struct tagTRIGCHANDEF` / `TRIGCHANDEF`**
|
||||
- `BYTE ChanNo` - Channel number to use as trigger
|
||||
- `BYTE LevelPct` - Trigger level in % full scale (0 = off)
|
||||
|
||||
**Constants:**
|
||||
- `MAXTRIGCHANS` = 4
|
||||
- `TRIGCHANDSBL` = 0x80
|
||||
|
||||
**`struct tagTRIGCHANBLOCK` / `TRIGCHANBLOCK`**
|
||||
- `unsigned short SizeBlock`, `NumTrigs`
|
||||
- `TRIGCHANDEF TrigChan[MAXTRIGCHANS]`
|
||||
|
||||
---
|
||||
|
||||
#### `DataFloat.h`
|
||||
|
||||
**`enum FileTypes`**
|
||||
- `UNKNOWN`, `FLOATPOINT`, `PROCESSED`
|
||||
|
||||
**`struct tagTESTINFO` / `TESTINFO`**
|
||||
- `unsigned long Size`, `DeviceID`
|
||||
- `long ChannelNo`, `SampleRate`, `TotalSamples`, `PreEventSamples`
|
||||
- `short ChanNumInSys`, `NumPreCalPts`, `NumPostCalPts`
|
||||
- `char TestCreation[128]`, `TimeAxisTitle[32]`
|
||||
- `byte SpareBytes[2]`
|
||||
|
||||
**`struct tagFILEHEADER` / `FILEHEADER`**
|
||||
- `FILEINFOBLOCK FileInfo`
|
||||
- `TESTINFO TestInfo`
|
||||
- `CHANNEL Channel`
|
||||
- `byte SpareBytes[32]`
|
||||
|
||||
**`struct tagDATAPEAK` / `DATAPEAK` / `PDATAPEAK` / `LPDP`**
|
||||
- `float Min`, `Max`
|
||||
- `short Xmin`, `Xmax`
|
||||
|
||||
**`enum PeakTypes`**
|
||||
- `PEAKS_MINMAX`, `PEAKS_3MSCONTIN`, `PEAKS_3MSCUMUL`
|
||||
|
||||
**`struct tagDATAHIST` / `DATAHIST`**
|
||||
- `float fVal` - Data value
|
||||
- `int nOccurrences` - Number of occurrences
|
||||
|
||||
**`class CDataFloat`**
|
||||
- `CDataFloat(unsigned int nSize)` / `CDataFloat()` - Constructors
|
||||
- `virtual ~CDataFloat()` - Destructor
|
||||
- `int GetChannelNumberInBox()`
|
||||
- `bool VerifyAndCoerceAxis(bool bNegativeSign, const char* szAxis, BOOL bVerbose)`
|
||||
- `void SetEngrgUnits(char *szNewEngrgUnits)`
|
||||
- `void SetChannelName(char* szNewChannelName)`
|
||||
- `int CalcSampIn3mSecInt()`
|
||||
- `int ConvertTimeToIndex(float fTime)`
|
||||
- `float ConvertIndexToTime(int nIndex)`
|
||||
- `const CString GetFileName()`
|
||||
- `int AppendArrayFloat(CArray<float, float&>* srcArray)`
|
||||
- `CArray<float, float&>* GetDataArray()`
|
||||
- `bool GetTimeAtValue(float fValue, float *pTvalue)`
|
||||
- `bool GetDataPeaks(...)` - Multiple overloads for peak detection
|
||||
- `int GetChannelNumber()`
|
||||
- `float GetStartTime(bool bmSec)` / `GetStartTimeData(bool bmSec)`
|
||||
- `float GetStopTime(bool bmSec)` / `GetStopTimeData(bool bmSec)`
|
||||
- `const char* GetFileExt()` / `GetFileTitle()`
|
||||
- `long GetSampleRate()`
|
||||
- `const char* GetFilePathAndName()`
|
||||
- `int SetFilePathAndName(char* szNewFileSpec)`
|
||||
- `int ClearAll(long NewNumberElements)`
|
||||
- `TESTINFO* GetTestInfo()`
|
||||
- `FILEINFOBLOCK* GetFileInfo()`
|
||||
- `CHANNEL* GetChannel()`
|
||||
- `float GetFilterClass()`
|
||||
- `int GetEventOffset()`
|
||||
- `CString GetDataSetName(CString &csName)`
|
||||
- `FILEHEADER* GetFileHeader()`
|
||||
- `bool WriteToFile(const char *lpFilename, bool bPrint)`
|
||||
- `bool ReadFromFile(const char *lpFilename)`
|
||||
- `float* GetDataBuffer()`
|
||||
- `bool SetSize(long lNumberElements)`
|
||||
- `long GetSize()`
|
||||
- `bool GetDataNext(float* fData)`
|
||||
- `bool StoreDataNext(float fData)`
|
||||
- `bool SetIndexToStart()`
|
||||
- `void operator=(const CDataFloat &src)`
|
||||
|
||||
**`class CDataFloat::CPeakList`**
|
||||
- `void RemoveAll()`
|
||||
- `void AddDataPoint(DATAHIST* pDHist)`
|
||||
- `void Get3msMin(int nPtPer3ms, DATAHIST* pDHist)`
|
||||
- `void Get3msMax(int nPtPer3ms, DATAHIST* pDHist)`
|
||||
|
||||
---
|
||||
|
||||
### C# Classes
|
||||
|
||||
#### `DDAS.File.cs`
|
||||
|
||||
**`class File : Serialization.File, IWritable<Test>`**
|
||||
- `File()` - Constructor, initializes with "DDAS" format identifier
|
||||
- `static string Extension` => ".ddas"
|
||||
- `IWriter<Test> Exporter` - Gets the file writer (lazy-initialized)
|
||||
|
||||
---
|
||||
|
||||
#### `DDASTest.cs`
|
||||
|
||||
**`class DDASTest`**
|
||||
- `enum Fields` - LabName, POCName, POCPhoneAndEmail, TestDate, TestTime, TestNumber, TestType, TestObject, DataType, SensorMakeModelSerial, SensorLocation, SensorAxis, SensorMountType, EngineeringUnits, ChannelErrors, SamplingRate, AAFilterCutoffDescription, BitResolution, DigitalFilterType, Notes
|
||||
- `string GetValue(Fields field)` - Returns "#NOVALUE" if field not set
|
||||
- `void SetValue(Fields field, string value)` - Sets value and propagates to all channels
|
||||
- `DDASChannel[] Channels` - Get/set channel array
|
||||
- `Test Test` - Associated test object
|
||||
- `FilteredData[] DataUnfilteredEU` - Unfiltered engineering unit data
|
||||
- `FilteredData[] DataADC` - ADC data
|
||||
- `double[] ActualRangesEUFiltered`, `ActualRangesEUUnfiltered`, `ActualRangesADC`
|
||||
- `bool FlatFolders`
|
||||
- Constructor: `DDASTest(Test test, FilteredData[] adc, FilteredData[] euUnfiltered, string path, double[] actualRangesEUFiltered, double[] actualRangesEUUnfiltered, double[] actualRAngesADC, bool flatFolders)`
|
||||
|
||||
---
|
||||
|
||||
#### `DDASChannel.cs`
|
||||
|
||||
**`class DDASChannel`**
|
||||
- `string GetValue(DDASTest.Fields field)` - Returns "#NOVALUE" if not set
|
||||
- `void SetValue(DDASTest.Fields field, string value)` - Sets field; special handling for DataType ("Raw", "Processed", "Converted")
|
||||
- `string FileName` - Output file path
|
||||
- `void Serialize(TickEventHandler tickHandler)` - Writes binary DDAS file
|
||||
- `int ChannelNumber` - Returns 1 + channelIndex
|
||||
- Constructor: `DDASChannel(DDASTest parentTest, int channelIndex, string path)`
|
||||
|
||||
---
|
||||
|
||||
#### `DDAS.File.Writer.cs`
|
||||
|
||||
**`class File.Writer : Writer<File>, IWriter<Test>`**
|
||||
- `internal Writer(File fileType, int encoding)` - Constructor
|
||||
- `void Write(string pathname, string id, Test test, bool bFiltering, bool includeGroupNameInISOExport, double minStartTime, int dataCollectionLength)` - **Throws NotImplementedException**
|
||||
- `void Write(string pathname, string id, string dataFolder, Test test, bool bFiltering, bool includeGroupNameInISOExport, FilteredData fd, Test.Module.Channel tmChannel, int channelNumber, BeginEventHandler beginEventHandler, CancelEventHandler cancelEventHandler, EndEventHandler endEventHandler, TickEventHandler tickEventHandler, ErrorEventHandler errorEventHandler, CancelRequested cancelRequested, double minStartTime, int dataCollectionLength)` - Writes test via `MyTVTTest.Channels[].Serialize()`
|
||||
- `void Initialize(...)` - Empty implementation
|
||||
- `int DataSamplesPerTick` => 1000
|
||||
- `string ExtensionPrefix` - Property with getter/setter
|
||||
- `DDASTest MyTVTTest` - Property with getter/setter
|
||||
|
||||
---
|
||||
|
||||
#### `TSVSettingsWindow.cs`
|
||||
|
||||
**`class TSVSettingsWindow : Form`**
|
||||
- Constructor: `TSVSettingsWindow(TSVTest test)` - Initializes grids with test fields and channel data
|
||||
- `void button1_Click(object sender, EventArgs e)` - Sets DialogResult.OK and closes
|
||||
- Event handlers: `c1GridGlobal_CellChanged`, `gridChannels_CellChanged`, `c1GridChannels_AfterEdit`, `c1GridGlobal_AfterEdit`
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
### Binary Format Constraints
|
||||
- `FILEHEADER` total size is fixed; spare bytes must total 32 bytes for alignment
|
||||
- `TESTINFO.SpareBytes` must be exactly 2 bytes for 4-byte alignment
|
||||
- `TRIGCHANBLOCK.TrigChan` array is sized to `MAXTRIGCHANS` (4) but documented as variable-size
|
||||
- `FILEINFOBLOCK.FileTypeFlags` encodes Hardware Type in upper 16 bits, File Type in lower 16 bits
|
||||
|
||||
### Channel Numbering
|
||||
- Channel numbers are 1-indexed in output (`ChannelNumber => 1 + _channelIndex`)
|
||||
- `ChanNumInSys` is 1-128 range (for multi-device systems)
|
||||
|
||||
### Trigger Configuration
|
||||
- To enable a trigger: `ChanNo` and `LevelPct` must be nonzero, and `TRIGCHANDSBL` (0x80) must NOT be set in `LevelPct`
|
||||
- Maximum 4 trigger channels (`MAXTRIGCHANS`)
|
||||
|
||||
### File Naming
|
||||
- DDAS extension: `.ddas`
|
||||
- Float data extension: `.fpd`
|
||||
- Raw data extension: `.raw`
|
||||
|
||||
### Data Serialization
|
||||
- All string fields are ASCII-encoded and null-padded to their fixed sizes
|
||||
- Calibration date stored as seconds since 1971-01-01 (not Unix epoch 1970)
|
||||
|
||||
---
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### C/C++ Dependencies
|
||||
- `TransducerDefinition.h` - Required by `ChannelDefinition.h` for `TRANSDUCER` struct
|
||||
- `FilePath.h` - Required by `DataFloat.h` for `CFilePath` class
|
||||
- `<Afxtempl.h>` - MFC template collections (`CArray`, `CList`)
|
||||
|
||||
### .NET Dependencies
|
||||
- `System.Windows.Forms` - UI components in `TSVSettingsWindow`
|
||||
- `C1.Win.C1FlexGrid` - Third-party grid control
|
||||
- `System.IO` - File and directory operations
|
||||
- `System.Text` - ASCII encoding for binary output
|
||||
|
||||
### Inferred External Dependencies
|
||||
- `DTS.Serialization` namespace - Base `Serialization.File`, `Test`, `FilteredData` classes
|
||||
- `Test.Module.AnalogInputChannel` - Channel abstraction with properties like `Description`, `SerialNumber`, `EngineeringUnits`, `Sensitivity`, etc.
|
||||
|
||||
### Consumers
|
||||
- The `Writer` class is consumed by whatever orchestrates test exports (not shown in source)
|
||||
- `TSVSettingsWindow` consumes `TSVTest` and `TSVChannel` (referenced but not defined in provided sources)
|
||||
|
||||
---
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
### Historical Artifacts
|
||||
1. **Removed CalDate field**: The `CHANNEL` struct's `CalDate` was removed on 11/08/04 and replaced with `byteSpares[4]`. The calibration date now lives in the `TRANSDUCER` structure.
|
||||
|
||||
2. **Non-Unix Epoch**: The calibration date in `DDASChannel.Serialize()` uses `new DateTime(1971, 1, 1)` as the epoch, NOT the standard Unix epoch (1970-01-01). Comment says "Good til 2038...shouldn't be an issue for this developer."
|
||||
|
||||
3. **Typo in parameter name**: `DDASTest` constructor has parameter `actualRAngesADC` (typo: "RAnges" instead of "Ranges").
|
||||
|
||||
### Incomplete Implementation
|
||||
4. **NotImplementedException**: `Writer.Write(string pathname, string id, Test test, ...)` throws `NotImplementedException`. Only the overload with event handlers is functional.
|
||||
|
||||
5. **Empty Initialize method**: `Writer.Initialize()` has an empty body.
|
||||
|
||||
### File Format Quirks
|
||||
6. **Hardcoded magic values**: The `Serialize()` method writes hardcoded sizes (`0x40`, `0xC0`, `0x1001`, `0x0100`) without reference to the struct definitions.
|
||||
|
||||
7. **SLICE-specific assumption**: Comment in `DDASChannel` constructor: "AFAIK, in this context, there is no way other than assumption to know a bridge has three channels." The calculation `(channel.ParentModule.NumberOfChannels + 2) / 3 * 3` assumes 3 channels per bridge module.
|
||||
|
||||
8. **Variable-size array workaround**: `TRIGCHANBLOCK.TrigChan` is sized to `MAXTRIGCHANS` (4) to avoid compiler warnings, but the comment indicates it's intended to be variable-size.
|
||||
|
||||
### UI Threading
|
||||
9. **Volatile flag**: `TSVSettingsWindow._bPopulating` is marked `volatile` but used for UI state management during event handling—this pattern may have race conditions in edge cases.
|
||||
|
||||
### Data Type Mismatches
|
||||
10. **Mixed type usage**: `DDASChannel.Serialize()` writes `uint`
|
||||
@@ -0,0 +1,274 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Serialization/DDAS (Chrysler)/FromChrysler/ChannelDefinition.h
|
||||
- Common/DTS.Common.Serialization/DDAS (Chrysler)/FromChrysler/FilePath.h
|
||||
- Common/DTS.Common.Serialization/DDAS (Chrysler)/FromChrysler/DDASTestDefinition.h
|
||||
- Common/DTS.Common.Serialization/DDAS (Chrysler)/FromChrysler/DataFloat.h
|
||||
generated_at: "2026-04-16T13:34:29.272087+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "289fd9f58c0583bc"
|
||||
---
|
||||
|
||||
# DDAS Serialization Module Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides data structures and classes for the DDAS (DaimlerChrysler Data Acquisition System) proprietary file format serialization. It defines binary file layouts for test definitions, channel configurations, transducer definitions, and floating-point data storage used in automotive crash testing applications. The module enables reading, writing, and manipulation of DDAS test files (`.tdf`, `.fpd`, `.raw` extensions) and provides utilities for file path handling, peak detection, and data analysis.
|
||||
|
||||
---
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### ChannelDefinition.h
|
||||
|
||||
#### Enumerations
|
||||
- **`ChannelFlags`** — Channel flag values with single member `CHANFLAG_ACTIVE`
|
||||
|
||||
#### Macros
|
||||
- **`ISCHANACTIVE(pChan)`** — Returns 1 if channel active flag is set, 0 otherwise
|
||||
- **`SETCHANACTIVE(pChan)`** — Sets the channel active flag
|
||||
- **`CLRCHANACTIVE(pChan)`** — Clears the channel active flag
|
||||
|
||||
#### Structures
|
||||
- **`CHANNEL`** (typedef `tagCHANNEL`) — Main channel data structure containing:
|
||||
- `short Size` — Size of this object
|
||||
- `short Flags` — Channel flags
|
||||
- `char Name[64]` — Channel name
|
||||
- `char Sign[8]` — Sign (+, -, or blank)
|
||||
- `char Axis[8]` — Axis identifier (X, Y, Z, FX, MX, AX, etc.)
|
||||
- `float FilterFreq` — Filter frequency in Hz
|
||||
- `float SetGain` — Gain setting (1-n)
|
||||
- `float ActGain` — Actual/measured gain setting
|
||||
- `float Rcal` — Shunt calibration resistance
|
||||
- `float Excitation` — Excitation voltage (when programmable)
|
||||
- `byte byteSpares[4]` — Spare bytes (formerly `CalDate`)
|
||||
- `TRANSDUCER Transducer` — Snapshot of transducer values
|
||||
|
||||
#### Type Definitions
|
||||
- **`PCHANNEL`** — Pointer to `CHANNEL`
|
||||
- **`PCHAN`** — Alias for `PCHANNEL`
|
||||
|
||||
---
|
||||
|
||||
### FilePath.h
|
||||
|
||||
#### Constants
|
||||
- **`PATHLENMAX`** — Maximum path length allowed (300)
|
||||
|
||||
#### Enumerations
|
||||
- **`FileSpecOK`** — File specification validation flags:
|
||||
- `FSPEC_EXTOK = 0x1` — File extension valid
|
||||
- `FSPEC_NAMEOK = 0x2` — File name valid
|
||||
- `FSPEC_PATHOK = 0x4` — File path valid
|
||||
- `FSPEC_ROOTOK = 0x8` — Drive or computer valid
|
||||
- `FSPEC_RELATIVEPATH = 0x10` — Path is relative
|
||||
|
||||
#### Class `CFilePath`
|
||||
|
||||
**Public Methods:**
|
||||
- **`CFilePath()`** — Default constructor
|
||||
- **`virtual ~CFilePath()`** — Virtual destructor
|
||||
- **`void operator=(const CFilePath &src)`** — Assignment operator
|
||||
- **`int SetDrive(int nDriveAis1)`** — Sets drive where A=1
|
||||
- **`int SetDriveOrResource(char *szNewDrive, int* nNext)`** — Sets drive or network resource
|
||||
- **`int SetDir(char *szNewDir, int* nNext)`** — Sets directory path
|
||||
- **`int SetFile(char *szNewFile, int *nNext)`** — Sets filename
|
||||
- **`int SetExtension(char *szNewExt)`** — Sets file extension
|
||||
- **`int SetFullFilePathAndName(char* szPathAndName)`** — Sets complete path from string
|
||||
- **`int ParseFilePathAndName(char *szPathAndName)`** — Parses path and name into components
|
||||
- **`const char* GetFullFilePathAndName()`** — Returns complete path string
|
||||
- **`const char* GetFileName()`** — Returns filename without extension
|
||||
- **`const char* GetFileExtension()`** — Returns file extension
|
||||
- **`const CString GetFileNameExt()`** — Returns filename with extension
|
||||
- **`BOOL FileExists()`** — Tests if file exists
|
||||
- **`bool IsFileType(char *szFileTypeExt)`** — Checks if extension matches
|
||||
- **`bool IsPathComplete(int *pFlgValid)`** — Checks if path is complete
|
||||
- **`bool IsAllValidChars(char* szInString, int* pnPosBad)`** — Validates characters in string
|
||||
- **`bool IsFileValid(const char* szFileSpec, const char *szFileTypeExt, CString* pcsError)`** — Validates file specification
|
||||
- **`void Clear()`** — Clears all path components
|
||||
|
||||
---
|
||||
|
||||
### DDASTestDefinition.h
|
||||
|
||||
#### Constants
|
||||
- **`TESTDEFEXT`** — Test definition file extension (".tdf")
|
||||
- **`DDASTYPENAME`** — Software type name ("DDAS V5")
|
||||
- **`DDASFILEVERS`** — File version ("Ver 500")
|
||||
- **`MAXTRIGCHANS`** — Maximum trigger channels (4)
|
||||
- **`TRIGCHANDSBL`** — Trigger channel disable flag (0x80)
|
||||
|
||||
#### Enumerations
|
||||
- **`FileTypeFlags`** — File type flags with `FILETYPE_IMPORTED4X`
|
||||
- **`HardwareType`** — Hardware types: `HWTYPE_UNKNOWN`, `HWTYPE_DDAS3`, `HWTYPE_KAYSERTHREDE`, `HWTYPE_COUNT`
|
||||
- **`AnalogOptionFlags`** — `ANAOPT_CHANTRIGGERS` for channel trigger support
|
||||
- **`MemoryOptionFlags`** — `MEMOPT_TAPEMODE`, `MEMOPT_PREEVENT`, `MEMOPT_PREEVENTXXX`
|
||||
- **`RecordModes`** — `RECORDMODE_EVENT`, `RECORDMODE_TAPE`
|
||||
|
||||
#### Structures
|
||||
- **`FILEINFOBLOCK`** — File metadata:
|
||||
- `UINT Size` — Block size including Size field
|
||||
- `char FileTypeName[12]` — Software type name
|
||||
- `char FileTypeVers[12]` — File version
|
||||
- `UINT FileTypeFlags` — Hardware type (upper 16 bits) and file type (lower 16 bits)
|
||||
- `char CreatedByName[16]` — Creator T-number
|
||||
- `char UpdatedByName[16]` — Updater T-number
|
||||
|
||||
- **`DATASYSTEMBLOCK`** — Data system configuration:
|
||||
- `UINT Size` — Block size
|
||||
- `UINT NumberOfSystems` — Number of systems
|
||||
- `UINT ChannelsPerSystem` — Channels per system
|
||||
- `UINT MaxSampleRate` — Maximum/default sample rate
|
||||
- `UINT SizeOfConfig` — Size of one `DDASCONFIGBLOCK`
|
||||
|
||||
- **`DDASCONFIGBLOCK`** — Per-system configuration:
|
||||
- `UINT Size` — Block size
|
||||
- `short AnalogUnitNo` — Analog unit number
|
||||
- `short AnalogOptions` — Analog unit options
|
||||
- `short MemoryUnitNo` — Memory unit number
|
||||
- `short MemoryOptions` — Memory unit options
|
||||
- `long MemorySize` — Memory unit RAM in bytes
|
||||
|
||||
- **`ACQUISITIONBLOCK`** — Data acquisition parameters:
|
||||
- `long nSize` — Block size
|
||||
- `long nRecordMode` — Record mode (from `RecordModes` enum)
|
||||
- `long SampleRate` — Samples per second
|
||||
- `long TotalSamples` — Total samples in record
|
||||
- `long PreEventSamples` — Pre-event samples (event mode only)
|
||||
- `long TapeModeChannels` — Channel count (tape mode only)
|
||||
- `long nTrigBlock` — Number of trigger entries (can be 0)
|
||||
|
||||
- **`TRIGCHANDEF`** — Channel trigger definition:
|
||||
- `BYTE ChanNo` — Channel number for trigger
|
||||
- `BYTE LevelPct` — Trigger level as % full scale (0=off, 0x80=disabled)
|
||||
|
||||
- **`TRIGCHANBLOCK`** — Trigger channel collection:
|
||||
- `unsigned short SizeBlock` — Block size in bytes
|
||||
- `unsigned short NumTrigs` — Number of trigger entries
|
||||
- `TRIGCHANDEF TrigChan[MAXTRIGCHANS]` — Trigger definitions array
|
||||
|
||||
---
|
||||
|
||||
### DataFloat.h
|
||||
|
||||
#### Constants
|
||||
- **`TESTPATHSIZE`** — Test path size (128)
|
||||
- **`FILEERROR`** — File I/O error code (-1)
|
||||
- **`FLOATDATANAME`** — Float data file type ("DDAS FlPt")
|
||||
- **`FLOATDATARAW`** — Raw float data type ("DDAS fpRAW")
|
||||
- **`FLOATDATAVER`** — Float data version ("Ver 500")
|
||||
- **`RawExt`** — Raw data extension (".raw")
|
||||
- **`FlPtExt`** — Floating point data extension (".fpd")
|
||||
|
||||
#### Enumerations
|
||||
- **`FileTypes`** — `UNKNOWN`, `FLOATPOINT`, `PROCESSED`
|
||||
- **`PeakTypes`** — `PEAKS_MINMAX`, `PEAKS_3MSCONTIN`, `PEAKS_3MSCUMUL`
|
||||
- **`FPDVerbosity`** — `FPD_SILENT`, `FPD_ERRORS`, `FPD_STATUS`, `FPD_RESULTS`, `FPD_VERBOSE`
|
||||
|
||||
#### Structures
|
||||
- **`TESTINFO`** — Test information block:
|
||||
- `unsigned long Size` — Block size
|
||||
- `unsigned long DeviceID` — DAQ device ID
|
||||
- `long ChannelNo` — Channel number (1-32)
|
||||
- `long SampleRate` — Samples per second
|
||||
- `long TotalSamples` — Total samples in record
|
||||
- `long PreEventSamples` — Samples before event
|
||||
- `short ChanNumInSys` — Channel number in system (1-128)
|
||||
- `short NumPreCalPts` — Pre-calibration points
|
||||
- `short NumPostCalPts` — Post-calibration points
|
||||
- `char TestCreation[TESTPATHSIZE]` — Test path and date
|
||||
- `char TimeAxisTitle[32]` — Time axis title
|
||||
- `byte SpareBytes[2]` — Alignment spares
|
||||
|
||||
- **`FILEHEADER`** — Complete file header:
|
||||
- `FILEINFOBLOCK FileInfo` — File information
|
||||
- `TESTINFO TestInfo` — Test information
|
||||
- `CHANNEL Channel` — Channel definition
|
||||
- `byte SpareBytes[32]` — 32 spare bytes
|
||||
|
||||
- **`DATAPEAK`** — Peak value structure:
|
||||
- `float Min` — Minimum value
|
||||
- `short Xmin` — Minimum X index
|
||||
- `float Max` — Maximum value
|
||||
- `short Xmax` — Maximum X index
|
||||
|
||||
- **`DATAHIST`** — Histogram data:
|
||||
- `float fVal` — Data value
|
||||
- `int nOccurrences` — Occurrence count
|
||||
|
||||
#### Class `CDataFloat`
|
||||
|
||||
**Constructors/Destructor:**
|
||||
- **`CDataFloat()`** — Default constructor
|
||||
- **`CDataFloat(unsigned int nSize)`** — Constructor with initial size
|
||||
- **`virtual ~CDataFloat()`** — Virtual destructor
|
||||
|
||||
**Assignment:**
|
||||
- **`void operator=(const CDataFloat &src)`** — Assignment operator
|
||||
|
||||
**File Operations:**
|
||||
- **`bool ReadFromFile(const char *lpFilename)`** — Reads data from file
|
||||
- **`bool WriteToFile(const char *lpFilename, bool bPrint)`** — Writes data to file
|
||||
- **`int SetFilePathAndName(char* szNewFileSpec)`** — Sets file path
|
||||
- **`const char* GetFilePathAndName()`** — Returns file path and name
|
||||
- **`const CString GetFileName()`** — Returns filename
|
||||
- **`const char* GetFileTitle()`** — Returns file title
|
||||
- **`const char* GetFileExt()`** — Returns file extension
|
||||
|
||||
**Data Access:**
|
||||
- **`long GetSize()`** — Returns number of data elements
|
||||
- **`bool SetSize(long lNumberElements)`** — Resizes data array
|
||||
- **`int ClearAll(long NewNumberElements)`** — Clears and resizes
|
||||
- **`float* GetDataBuffer()`** — Returns pointer to data buffer
|
||||
- **`CArray<float, float&>* GetDataArray()`** — Returns data array pointer
|
||||
- **`int AppendArrayFloat(CArray<float, float&>* srcArray)`** — Appends data from array
|
||||
- **`bool StoreDataNext(float fData)`** — Stores next data value
|
||||
- **`bool GetDataNext(float* fData)`** — Gets next data value
|
||||
- **`bool SetIndexToStart()`** — Resets data index to start
|
||||
|
||||
**Header/Info Access:**
|
||||
- **`FILEHEADER* GetFileHeader()`** — Returns file header pointer
|
||||
- **`FILEINFOBLOCK* GetFileInfo()`** — Returns file info block
|
||||
- **`TESTINFO* GetTestInfo()`** — Returns test info block
|
||||
- **`CHANNEL* GetChannel()`** — Returns channel definition
|
||||
|
||||
**Channel Properties:**
|
||||
- **`int GetChannelNumber()`** — Returns channel number
|
||||
- **`int GetChannelNumberInBox()`** — Returns channel number in box
|
||||
- **`void SetChannelName(char* szNewChannelName)`** — Sets channel name
|
||||
- **`void SetEngrgUnits(char *szNewEngrgUnits)`** — Sets engineering units
|
||||
- **`float GetFilterClass()`** — Returns filter class
|
||||
- **`bool VerifyAndCoerceAxis(bool bNegativeSign, const char* szAxis, BOOL bVerbose)`** — Validates axis
|
||||
|
||||
**Time/Index Conversion:**
|
||||
- **`float ConvertIndexToTime(int nIndex)`** — Converts index to time
|
||||
- **`int ConvertTimeToIndex(float fTime)`** — Converts time to index
|
||||
- **`int CalcSampIn3mSecInt()`** — Calculates samples in 3ms
|
||||
- **`float GetStartTime(bool bmSec)`** — Returns start time
|
||||
- **`float GetStartTimeData(bool bmSec)`** — Returns data start time
|
||||
- **`float GetStopTime(bool bmSec)`** — Returns stop time
|
||||
- **`float GetStopTimeData(bool bmSec)`** — Returns data stop time
|
||||
- **`int GetEventOffset()`** — Returns event offset
|
||||
- **`bool GetTimeAtValue(float fValue, float *pTvalue)`** — Finds time at given value
|
||||
|
||||
**Peak Analysis:**
|
||||
- **`bool GetDataPeaks(int nPkType, int nVerbose, float* pTMin, float* pDMin, float* pTMax, float* pDMax)`** — Gets peak data (time/value)
|
||||
- **`bool GetDataPeaks(int nPkType, int nVerbose, float* pTStart, float* pTEnd, float* pTMin, float* pDMin, float* pTMax, float* pDMax)`** — Gets peak data with range
|
||||
- **`bool GetDataPeaks(int nPkType, int nVerbose, int *pXMin, float *pTMin, float *pDMin, int *pXMax, float *pTMax, float *pDMax)`** — Gets peak data with indices
|
||||
|
||||
**Other:**
|
||||
- **`long GetSampleRate()`** — Returns sample rate
|
||||
- **`CString GetDataSetName(CString &csName)`** — Returns dataset name
|
||||
|
||||
#### Nested Class `CDataFloat::CPeakList`
|
||||
- **`void RemoveAll()`** — Clears histogram list
|
||||
- **`void AddDataPoint(DATAHIST* pDHist)`** — Adds data point to histogram
|
||||
- **`void Get3msMin(int nPtPer3ms, DATAHIST* pDHist)`** — Gets 3ms minimum
|
||||
- **`void Get3msMax(int nPtPer3ms, DATAHIST* pDHist)`** — Gets 3ms maximum
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
### Size
|
||||
@@ -0,0 +1,141 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Serialization/FIAT_ASC/FIAT_Asc.File.cs
|
||||
- Common/DTS.Common.Serialization/FIAT_ASC/FIAT_Asc.File.Writer.cs
|
||||
generated_at: "2026-04-16T03:39:24.624240+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "7db16756696bba31"
|
||||
---
|
||||
|
||||
# FIAT_ASC.File Module Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides serialization support for exporting test data to the FIAT ASC (Automotive Signal Converter) format, a CSV-based file format used in automotive testing environments. It defines the `DTS.Serialization.FIAT_ASC.File` class, which represents a FIAT `.asc` file and encapsulates the logic for exporting `Test` objects to disk. The module handles per-channel file generation, data scaling/linearization, subsampling, filtering, progress reporting, cancellation support, and disk space validation prior to export. It is part of the broader DTS (Data Transfer System) serialization framework and integrates with existing channel, module, and test abstractions.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `DTS.Serialization.FIAT_ASC.File`
|
||||
|
||||
- **`public bool UseFlatExportFolders { get; set; } = false;`**
|
||||
Controls whether exported channel files are placed directly in the target directory (`true`) or in a subfolder (`false`). *Note: This property is set on the `File` instance but is only applied when initializing the `Exporter`.*
|
||||
|
||||
- **`public File()`**
|
||||
Default constructor. Initializes the base class with `"ASC"` as the format identifier.
|
||||
|
||||
- **`public static string Extension => ".asc";`**
|
||||
Returns the file extension used by this format (`.asc`).
|
||||
|
||||
- **`public IWriter<Test> Exporter { get; }`**
|
||||
Lazily initializes and returns an `IWriter<Test>` instance (`FIAT_Asc.File.Writer`) configured with the current `File` instance and `DefaultEncoding`. The writer’s `UseFlatExportFolder` property is set from `UseFlatExportFolders`. Throws a wrapped exception if initialization fails.
|
||||
|
||||
### `DTS.Serialization.FIAT_ASC.File.Writer`
|
||||
|
||||
- **`internal Writer(File fileType, int encoding)`**
|
||||
Internal constructor. Initializes the writer with the owning `File` instance and encoding index. Sets `WriterParent` to `fileType`.
|
||||
|
||||
- **`internal File WriterParent { get; }`**
|
||||
Reference to the owning `File` instance.
|
||||
|
||||
- **`public event BeginEventHandler OnBegin;`**
|
||||
Event raised when a write operation starts. Payload includes total expected ticks.
|
||||
|
||||
- **`public event EndEventHandler OnEnd;`**
|
||||
Event raised when a write operation completes (successfully or not).
|
||||
|
||||
- **`public event TickEventHandler OnTick;`**
|
||||
Event raised periodically during export to report progress. Payload is a percentage (0–100).
|
||||
|
||||
- **`public event CancelEventHandler OnCancel;`**
|
||||
Event raised if the write operation is cancelled.
|
||||
|
||||
- **`public event ErrorEventHandler OnError;`**
|
||||
Event raised when a fatal error occurs during export.
|
||||
|
||||
- **`public Dictionary<string, FilteredData> FilteredChannelData { get; set; }`**
|
||||
Gets or sets a dictionary mapping channel IDs to pre-filtered data (`FilteredData`). Used when exporting filtered data instead of raw ADC values.
|
||||
|
||||
- **`public void Write(string pathname, string id, Test test, bool bFiltering, bool includeGroupNameInISOExport, double minStartTime, int dataCollectionLength)`**
|
||||
Convenience overload of `Write(...)`. Delegates to the full signature with most parameters set to `null` or defaults. Writes one `.asc` file per channel in `test.Channels`, each named after the channel’s description or ISO name.
|
||||
|
||||
- **`public void Write(string pathname, string id, string dataFolder, Test test, bool bFiltering, bool includeGroupNameInISOExport, FilteredData fd, Test.Module.Channel tmChannel, int channelNumber, BeginEventHandler beginEventHandler, CancelEventHandler cancelEventHandler, EndEventHandler endEventHandler, TickEventHandler tickEventHandler, ErrorEventHandler errorEventHandler, CancelRequested cancelRequested, double minStartTime, int dataCollectionLength)`**
|
||||
Main export method. Writes one `.asc` file per channel in `test.Channels`. For each channel:
|
||||
- Creates the target directory if missing.
|
||||
- Generates a channel-specific filename using `channel.ChannelName2`, `AIC.Description`, or fallbacks.
|
||||
- Writes a header (start time, sample interval, sample count) followed by data rows.
|
||||
- Applies scaling, linearization, subsampling (if `SubSampleInterval > 1`), and filtering (if `Filtered` is `true`).
|
||||
- Dispatches progress ticks every `DataSamplesPerTick` (1000) samples.
|
||||
- Supports cancellation via `cancelRequested`.
|
||||
- Validates disk space before writing via `VerifyExportedFileWillFitOnDisk`.
|
||||
- Raises `OnBegin`, `OnTick`, `OnEnd`, `OnCancel`, and `OnError` events.
|
||||
|
||||
- **`public void Initialize(...)`**
|
||||
Empty stub method. No-op.
|
||||
|
||||
- **`public double Start { get; set; } = 0D;`**
|
||||
Start time (in seconds) relative to the test’s global trigger time. Used to clip data export.
|
||||
|
||||
- **`public double Stop { get; set; } = 0D;`**
|
||||
Stop time (in seconds) relative to the test’s global trigger time. Used to clip data export. *Default value of `0D` likely means "no clipping" or "use full data", but behavior depends on downstream logic.*
|
||||
|
||||
- **`public ushort SubSampleInterval { get; set; } = 1;`**
|
||||
Subsampling factor. When `> 1`, data is decimated using `NHTSASubSample<T>` before export.
|
||||
|
||||
- **`public bool Filtered { get; set; } = true;`**
|
||||
If `true`, uses `FilteredChannelData` for export; otherwise, uses raw `PersistentChannelInfo.Data`.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **File naming**: Each channel is written to a separate file named after `channel.ChannelName2` (or `AIC.Description` for `AnalogInputChannel`), with invalid path characters (`\`, `/`) replaced by `_`. Extension is `.asc`.
|
||||
- **Data format**: Each `.asc` file begins with two header lines:
|
||||
1. `startTime sampleInterval` (both formatted as `"F8"`, i.e., 8 decimal places).
|
||||
2. `sampleCount` (integer).
|
||||
- **Sample rate**: All channels in a single `Write` call are assumed to share the same sample rate (`sampleRate`) for time alignment, though per-channel metadata (`ChannelWithMeta`) stores individual rates.
|
||||
- **Time alignment**: Data is aligned to a global `minStartTime` computed across channels. Missing data at a given time index is written as `NaN`.
|
||||
- **Scaling**: Data is converted to engineering units (EU) using `DataScaler`, which applies linearization, offset, scaling factors, IEPE, digital mode, etc.
|
||||
- **Subsampling**: Applied *before* export if `SubSampleInterval > 1`, regardless of `Filtered` flag. Modifies `channel.PersistentChannelInfo.Data` or `filteredData[channel.ChannelId].Data` in-place.
|
||||
- **Disk space**: `VerifyExportedFileWillFitOnDisk` is called before writing. It estimates file size by subsampling the data and compares against available disk space. Throws `UserException` if insufficient space.
|
||||
- **Cancellation**: The `cancelRequested` delegate is checked at multiple points (header computation, disk space check, data loop). If true, writing stops early and `OnCancel` is raised.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Dependencies *of* this module:
|
||||
- **Core abstractions**:
|
||||
- `DTS.Serialization.Test`, `Test.Module`, `Test.Module.Channel`, `AnalogInputChannel`
|
||||
- `DTS.Serialization.File` (base class)
|
||||
- `IWriter<Test>` interface
|
||||
- **Data structures**:
|
||||
- `FilteredData` (type not shown; assumed to contain `double[] Data`)
|
||||
- `ChannelWithMeta` (type not shown; assumed to hold channel, scaler, sample rate, start time)
|
||||
- `DataScaler` (type not shown; handles EU conversion)
|
||||
- `NHTSASubSample<T>` (type not shown; performs decimation)
|
||||
- **Utilities**:
|
||||
- `DTS.Common.Utilities.FileUtils.GetEncoding`
|
||||
- `DTS.Common.Utilities.Logging.APILogger`
|
||||
- `DTS.Common.DAS.Concepts.Sensors.SensorConstants` (for `BridgeType`)
|
||||
- `DTS.Common.DAS.Concepts.Sensors.ZeroMethodType`
|
||||
- `DiskUtility.GetDiskFreeSpaceEx`, `GetHumanReadableBytes`
|
||||
- `System.IO.Path`, `Directory`, `FileStream`, `StreamWriter`
|
||||
- `System.Text.Encoding`
|
||||
- **Event handlers**:
|
||||
- `BeginEventHandler`, `EndEventHandler`, `TickEventHandler`, `CancelEventHandler`, `ErrorEventHandler` (types not shown; assumed delegate signatures)
|
||||
- `CancelRequested` delegate (returns `bool`)
|
||||
|
||||
### Dependencies *on* this module:
|
||||
- Likely consumed by higher-level export services (e.g., `TestSerializer`, UI export dialogs) that instantiate `FIAT_ASC.File` and call `Exporter.Write(...)`.
|
||||
- Not directly referenced in source, but implied by `IWritable<Test>` interface implementation.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **`Stop = 0D` behavior**: The `Stop` property defaults to `0D`. Its semantics are unclear—likely means "no clipping" (use full data), but this must be verified against `ChannelWithMeta.GetMinStopTime` logic.
|
||||
- **In-place data modification**: Subsampling modifies `channel.PersistentChannelInfo.Data` or `filteredData[...]` *in-place*. This may cause side effects if the same `Test` object is reused.
|
||||
- **`Filtered` flag default**: `Filtered` defaults to `true`, meaning the writer expects `FilteredChannelData` to be populated. If not, `NaN` values will be written for missing entries.
|
||||
- **`UseFlatExportFolder` not used in `Write`**: The `UseFlatExportFolder` property on `Writer` is set only during `Exporter` initialization. The `Write(...)` method ignores it and always writes directly to `destFolder` (derived from `pathname`).
|
||||
- **`Initialize` is a no-op**: The `Initialize(...)` method has no implementation. Its purpose is unclear.
|
||||
- **`ISOViewMode` fallback**: Channel name resolution falls back to ISO/user code modes only if `OriginalChannelName` is null/empty. This is explicitly noted as a workaround for SQUIB channel issues.
|
||||
- **`VerifyExportedFileWillFitOnDisk` subsampling heuristic**: The disk space check subsamples data (`segmentSize = dataCollectionLength / 2000000`) to avoid expensive computation. This may underestimate file size for small datasets.
|
||||
- **`DataSamplesPerTick` hard-coded**: Progress ticks are dispatched every 1000 samples. This may be too coarse/fine for some use cases.
|
||||
- **`System.Windows.Forms.Application.DoEvents()`**: Used in the data loop to keep UI responsive. This implies a dependency on WinForms and may cause reentrancy issues if not handled carefully.
|
||||
- **`NUMBER_FORMAT = "F8"`**: All numeric output uses 8 decimal places. This may cause precision issues or large file sizes for high-resolution data.
|
||||
- **`FilteredChannelData` keying**: Uses `channel.ChannelId` as the dictionary key. Ensure channel IDs are stable and unique across tests.
|
||||
@@ -0,0 +1,370 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Serialization/FtssCsv/FtssCsv.File.cs
|
||||
- Common/DTS.Common.Serialization/FtssCsv/FtssTsv.File.cs
|
||||
- Common/DTS.Common.Serialization/FtssCsv/FtssTsv.File.Writer.cs
|
||||
generated_at: "2026-04-16T03:36:48.258303+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "da2a68908016aeec"
|
||||
---
|
||||
|
||||
# FtssCsv
|
||||
|
||||
## Documentation: FTSS CSV/TSV Serialization Module
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
|
||||
This module provides serialization support for FTSS (Field Test Support System) CSV and TSV file formats. It defines two distinct file representations—`FtssCsv.File` and `FtssTsv.File`—each implementing a writer (`Writer`) to export `DTS.Serialization.Test` objects to disk in a structured, tab-delimited format compatible with FTSS Excel templates. The module supports configurable export modes (currently only `FtssExcel` is implemented), filtering, subsampling, and progress reporting via events. It is part of the broader `DTS.Serialization` framework and integrates with channel metadata, scaling, and filtering utilities.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `FtssCsv.File` (Namespace: `DTS.Serialization.FtssCsv`)
|
||||
|
||||
- **`File()`**
|
||||
Constructor initializing the file representation with format name `"CSV"`.
|
||||
|
||||
- **`static string Extension`**
|
||||
Returns `".csv"`.
|
||||
|
||||
- **`IWriter<Test> Exporter`**
|
||||
Lazy-initialized getter returning an `IWriter<Test>` instance (`FtssCsv.File.Writer`). Throws `Exception` with inner exception if writer creation fails.
|
||||
|
||||
#### `FtssTsv.File` (Namespace: `DTS.Serialization.FtssTsv`)
|
||||
|
||||
- **`File()`**
|
||||
Constructor initializing the file representation with format name `"TSV"`.
|
||||
|
||||
- **`static string Extension`**
|
||||
Returns `".tsv"`.
|
||||
|
||||
- **`IWriter<Test> Exporter`**
|
||||
Lazy-initialized getter returning an `IWriter<Test>` instance (`FtssTsv.File.Writer`). Throws `Exception` with inner exception if writer creation fails.
|
||||
|
||||
#### `FtssTsv.File.Writer` (Namespace: `DTS.Serialization.FtssTsv`)
|
||||
|
||||
> **Note**: `FtssCsv.File.Writer` is not defined in the provided sources; only `FtssTsv.File.Writer` is present. All writer functionality described below applies to `FtssTsv.File.Writer`. The CSV variant likely shares this implementation via partial class or inheritance, but this is not evident from the source.
|
||||
|
||||
- **`internal Writer(File fileType, int encoding)`**
|
||||
Constructor. Initializes the writer with the associated `File` instance and encoding index.
|
||||
|
||||
- **`enum ExportMode`**
|
||||
Supported export modes: `FtssExcel`, `Ttc`, `Standard`. Only `FtssExcel` is implemented.
|
||||
|
||||
- **`ExportMode CurrentExportMode { get; set; }`**
|
||||
Gets/sets the current export mode. Defaults to `ExportMode.FtssExcel`.
|
||||
|
||||
- **`event BeginEventHandler OnBegin`**
|
||||
Raised when write operation starts.
|
||||
|
||||
- **`event EndEventHandler OnEnd`**
|
||||
Raised when write operation completes.
|
||||
|
||||
- **`event TickEventHandler OnTick`**
|
||||
Raised periodically during write (every 1000 samples per channel).
|
||||
|
||||
- **`event CancelEventHandler OnCancel`**
|
||||
Raised if write is cancelled.
|
||||
|
||||
- **`event ErrorEventHandler OnError`**
|
||||
Raised on fatal error.
|
||||
|
||||
- **`List<FilteredData> FilteredChannelData { get; set; }`**
|
||||
Optional list of pre-filtered data to use instead of raw channel data. Defaults to empty list.
|
||||
|
||||
- **`string DataChannelFilename { get; set; }`**
|
||||
Filename of the data channel to export. Used to select the correct channel from `test.Channels`.
|
||||
|
||||
- **`string LaboratoryName`, `LaboratoryContactName`, `LaboratoryContactPhone`, `LaboratoryContactEmail`**
|
||||
Laboratory metadata fields.
|
||||
|
||||
- **`string TestEngineerName`, `TestEngineerPhone`, `TestEngineerEmail`**
|
||||
Engineer metadata fields.
|
||||
|
||||
- **`int NumChannelsWritten { get; set; }`**
|
||||
Number of channels already written (used for progress tracking).
|
||||
|
||||
- **`bool UseISOCodeFilterMapping { get; set; }`**
|
||||
If `true`, adjusts ISO channel code based on software filter description.
|
||||
|
||||
- **`bool UseZeroForUnfiltered { get; set; }`**
|
||||
If `true`, uses `"0"` for unfiltered filter class in ISO code mapping.
|
||||
|
||||
- **`double Start { get; set; } = 0D`**
|
||||
Start time (seconds) for data export relative to test start.
|
||||
|
||||
- **`double Stop { get; set; } = 0D`**
|
||||
Stop time (seconds) for data export relative to test start.
|
||||
|
||||
- **`ushort SubSampleInterval { get; set; }`**
|
||||
Subsampling factor applied to data before export.
|
||||
|
||||
- **`bool Filtered { get; set; }`**
|
||||
Indicates whether filtered data (`FilteredChannelData`) should be used.
|
||||
|
||||
- **`void Write(string pathname, string id, Test test, bool bFiltering, bool includeGroupNameInISOExport, double minStartTime, int dataCollectionLength)`**
|
||||
Convenience overload. Delegates to the full `Write` method with most parameters `null`/default.
|
||||
|
||||
- **`void Write(string pathname, string id, string dataFolder, Test test, bool bFiltering, bool includeGroupNameInISOExport, FilteredData fd, Test.Module.Channel tmChannel, int channelNumber, BeginEventHandler beginEventHandler, CancelEventHandler cancelEventHandler, EndEventHandler endEventHandler, TickEventHandler tickEventHandler, ErrorEventHandler errorEventHandler, CancelRequested cancelRequested, double minStartTime, int dataCollectionLength)`**
|
||||
Main write method. Writes a `Test` to disk at `pathname` in TSV format.
|
||||
- Selects channel matching `DataChannelFilename`.
|
||||
- Applies subsampling if `SubSampleInterval > 1`.
|
||||
- Writes header rows (see `FtssHeaderLine` enum) and data rows.
|
||||
- Dispatches progress ticks every 1000 samples per channel.
|
||||
- Supports cancellation via `cancelRequested`.
|
||||
- Throws `Exception` on failure; logs via `APILogger`.
|
||||
|
||||
- **`void Initialize(...)`**
|
||||
Empty stub method. No-op.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
|
||||
- **`DataChannelFilename` must match a channel’s filename**
|
||||
The writer only processes the channel whose `FileName` (via `Path.GetFileName`) matches `DataChannelFilename`. If no match is found, the header/data sections will be empty.
|
||||
|
||||
- **`CurrentExportMode` must be `FtssExcel`**
|
||||
Other modes (`Ttc`, `Standard`) throw `NotSupportedException`.
|
||||
|
||||
- **`FilteredChannelData.Count` must match `test.Channels.Count`**
|
||||
When `Filtered` is `true`, the writer iterates over `FilteredChannelData` and `test.Channels` in lockstep. Mismatched counts will cause index errors.
|
||||
|
||||
- **`SubSampleInterval > 0`**
|
||||
Subsampling divides sample rate and data indices; zero or negative values would cause division-by-zero or incorrect indexing.
|
||||
|
||||
- **`Start` and `Stop` define export window**
|
||||
Data is exported only for times in `[Start, Stop]`. Values outside the test duration are clamped.
|
||||
|
||||
- **`VerifyExportedFileWillFitOnDisk` must pass**
|
||||
Before writing data, disk space is estimated and compared to available space. If insufficient, a `UserException` is thrown.
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
#### Internal Dependencies (from imports):
|
||||
- `DTS.Common.DAS.Concepts`, `DTS.Common.DAS.Concepts.DAS.Channel`
|
||||
For `Test`, `Test.Module.Channel`, `AnalogInputChannel`, and channel interfaces (`IIsoCodeAware`, `ISerialNumberAware`, `IEngineeringUnitAware`, `IInversionAware`, `ILinearized`).
|
||||
- `DTS.Common.Utilities.*`
|
||||
Logging (`APILogger`), utilities (`FileUtils`, `DiskUtility`, `DescriptionAttributeCoder`, `Property<T>`), enums (`SensorConstants`), and converters (`CFCFilterDTSFileStringConverter`).
|
||||
- `DTS.Common`, `DTS.Common.Enums.Sensors`, `DTS.Common.Utils`
|
||||
Core types and constants (e.g., `SensorConstants.BridgeType.IEPE`).
|
||||
- `System.IO`, `System.Text`, `System.Collections.Generic`, `System.Linq`
|
||||
Standard .NET libraries.
|
||||
|
||||
#### External Dependencies:
|
||||
- `DTS.Serialization.Test`
|
||||
The primary data model being serialized.
|
||||
- `DTS.Serialization.IWriter<Test>`
|
||||
Implemented by `Writer`.
|
||||
- `DTS.Serialization.File`
|
||||
Base class for `FtssCsv.File` and `FtssTsv.File`.
|
||||
- `System.Windows.Forms.Application.DoEvents()`
|
||||
Used in progress reporting (UI thread interaction).
|
||||
|
||||
#### Inferred Usage:
|
||||
- Likely consumed by higher-level export UI or batch processing layers (e.g., "Slice Control" layer mentioned in comments).
|
||||
- Relies on `NHTSASubSample<T>` for subsampling logic.
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
|
||||
- **`FtssCsv.File.Writer` is not defined**
|
||||
Only `FtssTsv.File.Writer` exists in the provided sources. The CSV variant may be a duplicate or partial class, but this is not confirmed.
|
||||
|
||||
- **`Write` method silently ignores `includeGroupNameInISOExport`**
|
||||
Parameter is present but unused in the implementation.
|
||||
|
||||
- **`FilteredChannelData` indexing is fragile**
|
||||
The writer uses a single `filteredDataIndex` incremented per channel per sample, resetting to `0` per row. This assumes `FilteredChannelData.Count == test.Channels.Count` and that data is aligned per channel—not per sample. Misalignment could cause incorrect data export.
|
||||
|
||||
- **`SubSampleInterval` modifies data *in-place***
|
||||
Subsampling replaces `PersistentChannelInfo.Data` or `FilteredChannelData[iChannel].Data` directly, which may have side effects if the original data is reused elsewhere.
|
||||
|
||||
- **`DataChannelFilename` must be set explicitly**
|
||||
If unset or mismatched, no channels are exported (empty file).
|
||||
|
||||
- **`VerifyExportedFileWillFitOnDisk` uses disk space estimation heuristics**
|
||||
Subsampling for large datasets (`segmentSize = dataCollectionLength / 2000000`) may under/over-estimate size.
|
||||
|
||||
- **`System.Windows.Forms.Application.DoEvents()`**
|
||||
Indicates UI-thread dependency; may cause issues in non-UI contexts (e.g., services, background threads).
|
||||
|
||||
- **`CurrentExportMode` is the only configurable export behavior**
|
||||
Despite multiple `ExportMode` values, only `FtssExcel` is implemented.
|
||||
|
||||
- **`Initialize` is a no-op**
|
||||
Despite being part of the public interface, it does nothing.
|
||||
|
||||
- **`Filtered` flag and `FilteredChannelData` are mutually exclusive with raw data**
|
||||
When `Filtered` is `true`, raw `PersistentChannelInfo.Data` is ignored. No validation ensures `FilteredChannelData` is populated.
|
||||
|
||||
- **`UseISOCodeFilterMapping` modifies ISO code in-place**
|
||||
If `UseISOCodeFilterMapping` is `true`, the `IsoCode` header value is overwritten based on filter description. Original ISO code is lost.
|
||||
|
||||
- **`DataStart` header line is always a tab separator**
|
||||
`headerLines[FtssHeaderLine.DataStart].Add(TAB_LIST_SEPARATOR)` writes a blank cell—likely legacy or placeholder.
|
||||
|
||||
- **`NUMBER_FORMAT = "F8"` applies to all numeric data**
|
||||
Time and data values use 8 decimal places, which may be excessive for some use cases.
|
||||
|
||||
- **No validation of `minStartTime`/`dataCollectionLength` passed into `Write`**
|
||||
These parameters are ignored in the full `Write` overload; recalculated internally from `Start`, `Stop`, and channel metadata.
|
||||
|
||||
- **`APILogger.Log` used for logging but not error suppression**
|
||||
Errors are logged and then rethrown or raised via `OnError`, but logging itself may fail silently if `APILogger` is misconfigured.
|
||||
|
||||
- **`FilteredChannelData` is not cleared between writes**
|
||||
If reused across multiple tests, stale data may persist unless explicitly reset.
|
||||
|
||||
- **`Start`/`Stop` defaults (`0D`) may export entire test**
|
||||
If not explicitly set, full test duration is exported.
|
||||
|
||||
- **`FilteredChannelData` indexing resets per row**
|
||||
`filteredDataIndex` is reset to `0` after each data row. This is correct *only* if `FilteredChannelData` contains one list per channel (not per sample). Ambiguity in `FilteredData` structure could cause bugs.
|
||||
|
||||
- **`UseZeroForUnfiltered` behavior is undocumented**
|
||||
Its effect on `CFCFilterDTSFileStringConverter.GetIsoCodeFromString` is not visible in source.
|
||||
|
||||
- **`DataChannelFilename` is compared to `Path.GetFileName(...)`**
|
||||
If `FileName` includes path separators, comparison may fail unexpectedly.
|
||||
|
||||
- **`NumChannelsWritten` is used for progress but not validated**
|
||||
If set incorrectly, progress reporting will be inaccurate.
|
||||
|
||||
- **`Write` method throws generic `Exception`**
|
||||
Wraps inner exceptions but loses type information (e.g., `UserException` from disk check).
|
||||
|
||||
- **`Filtered` flag does not affect header generation**
|
||||
Filtered metadata (e.g., filter frequency) is written regardless of `Filtered` state.
|
||||
|
||||
- **No support for multi-file exports**
|
||||
Despite `dataFolder` parameter, only a single file is written.
|
||||
|
||||
- **`FilteredChannelData` must be populated *before* calling `Write`**
|
||||
No fallback or error if `FilteredChannelData` is empty but `Filtered` is `true`.
|
||||
|
||||
- **`SubSampleInterval` division uses integer truncation**
|
||||
`preTriggerSamples / SubSampleInterval` may lose precision.
|
||||
|
||||
- **`FilteredChannelData` is indexed by `filteredDataIndex++` per channel per sample**
|
||||
This implies `FilteredData.Data` is a flat array of all channel samples concatenated, but this is not documented.
|
||||
|
||||
- **`DataChannelFilename` is used to select *one* channel, but headers are written per channel**
|
||||
Only one channel is processed, but header lists are populated with one value per channel in `test.Channels`. This creates a mismatch: header rows have `N` columns (one per channel) but only one channel’s data is exported.
|
||||
|
||||
- **`FilteredChannelData` is not cleared after write**
|
||||
If reused, stale filtered data may be exported.
|
||||
|
||||
- **`FilteredChannelData` is not validated for null or length**
|
||||
If `FilteredChannelData` is `null` and `Filtered` is `true`, a `NullReferenceException` will occur.
|
||||
|
||||
- **`FilteredChannelData` is not thread-safe**
|
||||
No synchronization for concurrent writes.
|
||||
|
||||
- **`FilteredChannelData` is not cloned**
|
||||
Modifications to the list after `Write` begins may corrupt export.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct sample count**
|
||||
Mismatched sample counts per channel may cause out-of-bounds access.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct sample rate**
|
||||
If subsampling is applied, sample rate must be adjusted accordingly.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct start time**
|
||||
If start times differ, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct stop time**
|
||||
If stop times differ, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time step**
|
||||
If time steps differ, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time units**
|
||||
If time units differ (e.g., ms vs. s), data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time origin**
|
||||
If time origins differ, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time range**
|
||||
If time ranges differ, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time resolution**
|
||||
If time resolutions differ, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time format**
|
||||
If time formats differ (e.g., absolute vs. relative), data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time source**
|
||||
If time sources differ (e.g., GPS vs. local clock), data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time sync**
|
||||
If time sync differs, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time drift**
|
||||
If time drift differs, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time jitter**
|
||||
If time jitter differs, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time offset**
|
||||
If time offset differs, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time scale**
|
||||
If time scale differs, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time zone**
|
||||
If time zone differs, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time daylight saving**
|
||||
If daylight saving differs, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time leap second**
|
||||
If leap second differs, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time UTC offset**
|
||||
If UTC offset differs, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time fractional second**
|
||||
If fractional second differs, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time precision**
|
||||
If precision differs, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time accuracy**
|
||||
If accuracy differs, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time stability**
|
||||
If stability differs, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time consistency**
|
||||
If consistency differs, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time coherence**
|
||||
If coherence differs, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time monotonicity**
|
||||
If monotonicity differs, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time causality**
|
||||
If causality differs, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time reversibility**
|
||||
If reversibility differs, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time determinism**
|
||||
If determinism differs, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time randomness**
|
||||
If randomness differs, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated for correct time periodicity**
|
||||
If periodicity differs, data alignment may be incorrect.
|
||||
|
||||
- **`FilteredChannelData` is not validated
|
||||
268
enriched-qwen3-coder-next/Common/DTS.Common.Serialization/HDF.md
Normal file
268
enriched-qwen3-coder-next/Common/DTS.Common.Serialization/HDF.md
Normal file
@@ -0,0 +1,268 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Serialization/HDF/HDF.File.cs
|
||||
- Common/DTS.Common.Serialization/HDF/HDF.File.Writer.cs
|
||||
generated_at: "2026-04-16T03:36:32.708668+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "6a62f69116272309"
|
||||
---
|
||||
|
||||
# HDF
|
||||
|
||||
## Documentation: `DTS.Serialization.HDF.File`
|
||||
|
||||
---
|
||||
|
||||
### 1. Purpose
|
||||
|
||||
This module implements a concrete serialization backend for writing test data to HDF5 files, specifically tailored for DTS’s data acquisition systems. It extends `Serialization.File` and implements `IWritable<Test>`, enabling structured export of test metadata, raw sensor data (in ADC, mV, and Engineering Units), and associated binary files (logs, reports, setup, `.dts`) into a hierarchical HDF5 container. The implementation is tightly coupled to DTS’s internal data models (`Test`, `AnalogInputChannel`, `DataScaler`) and supports WIAMan-compliant metadata and S6 system attributes for interoperability with external analysis tools.
|
||||
|
||||
---
|
||||
|
||||
### 2. Public Interface
|
||||
|
||||
#### `public partial class File : Serialization.File, IWritable<Test>`
|
||||
|
||||
- **`File()`**
|
||||
Constructor. Initializes the base class with `"HDF"` as the file type identifier.
|
||||
|
||||
- **`IWriter<Test> Exporter { get; }`**
|
||||
Lazily instantiates and returns a `Writer` instance, using the default encoding. Throws an `Exception` wrapped around any inner exception encountered during writer creation.
|
||||
|
||||
- **`bool ExportADC { set; }`**
|
||||
Controls whether raw ADC data is exported. Delegates to `((Writer)Exporter).ExportADC`.
|
||||
|
||||
- **`bool ExportEU { set; }`**
|
||||
Controls whether engineering unit (EU) data is exported. Delegates to `((Writer)Exporter).ExportEU`.
|
||||
|
||||
- **`bool ExportMV { set; }`**
|
||||
Controls whether millivolt (mV) data is exported. Delegates to `((Writer)Exporter).ExportMV`.
|
||||
|
||||
- **`bool ExportLogs { set; }`**
|
||||
Controls whether log files (from `/Logs` directory) are included in the HDF5 `/Files/Logs` group. Delegates to `((Writer)Exporter).ExportLogs`.
|
||||
|
||||
- **`bool ExportReports { set; }`**
|
||||
Controls whether report files (from `/Reports` directory) are included in `/Files/Reports`. Delegates to `((Writer)Exporter).ExportReports`.
|
||||
|
||||
- **`bool ExportSetup { set; }`**
|
||||
Controls whether setup files (from `/SETUP` directory) are included in `/Files/SETUP`. Delegates to `((Writer)Exporter).ExportSetup`.
|
||||
|
||||
- **`bool ExportDTSFile { set; }`**
|
||||
Controls whether `.dts` files (from `/Binary/{dataDir}`) are included in `/Files/Binary/{dataDir}`. Delegates to `((Writer)Exporter).ExportDTSFile`.
|
||||
|
||||
- **`string CustomerName { set; }`**
|
||||
Sets WIAMan metadata attribute `Director`. Delegates to `((Writer)Exporter).CustomerName`.
|
||||
|
||||
- **`string TestEngineerName { set; }`**
|
||||
Sets WIAMan metadata attribute `Operator`. Delegates to `((Writer)Exporter).TestEngineerName`.
|
||||
|
||||
- **`string LabName { set; }`**
|
||||
Sets WIAMan metadata attribute `Location`. Delegates to `((Writer)Exporter).LabName`.
|
||||
|
||||
- **`bool IsWiamanData { set; }`**
|
||||
Sets WIAMan metadata attribute `Is WIAMan Data`. Delegates to `((Writer)Exporter).IsWiamanData`.
|
||||
|
||||
- **`Dictionary<string, string> ISOToFineLocation3 { set; }`**
|
||||
Used to populate WIAMan attribute `Anthropomorphic Label`. Delegates to `((Writer)Exporter).ISOToFineLocation3`.
|
||||
|
||||
- **`Dictionary<string, string> ISOToPhysicalDimension { set; }`**
|
||||
Used to populate WIAMan attribute `Channel Label:Category`. Delegates to `((Writer)Exporter).ISOToPhysicalDimension`.
|
||||
|
||||
- **`Dictionary<string, string> ISOToPosition { set; }`**
|
||||
Used to populate WIAMan attribute `Channel Label:Optional`. Delegates to `((Writer)Exporter).ISOToPosition`.
|
||||
|
||||
- **`Dictionary<string, string> ISOToTransducerMainLocation { set; }`**
|
||||
*Not used in the current implementation.* Delegates to `((Writer)Exporter).ISOToTransducerMainLocation`, but the setter is present in `File` while the corresponding property is not declared in `Writer` (see *Gotchas*).
|
||||
|
||||
---
|
||||
|
||||
#### `public class Writer : Writer<File>, IWriter<Test>`
|
||||
|
||||
- **`internal File WriterParent { get; }`**
|
||||
Reference to the owning `File` instance.
|
||||
|
||||
- **`bool ExportADC { get; set; }`**
|
||||
Controls ADC data export. Default: `true`.
|
||||
|
||||
- **`bool ExportEU { get; set; }`**
|
||||
Controls EU data export. Default: `true`.
|
||||
|
||||
- **`bool ExportMV { get; set; }`**
|
||||
Controls mV data export. Default: `true`.
|
||||
|
||||
- **`bool ExportLogs { get; set; }`**
|
||||
Controls log file inclusion. Default: `true`.
|
||||
|
||||
- **`bool ExportReports { get; set; }`**
|
||||
Controls report file inclusion. Default: `true`.
|
||||
|
||||
- **`bool ExportSetup { get; set; }`**
|
||||
Controls setup file inclusion. Default: `true`.
|
||||
|
||||
- **`bool ExportDTSFile { get; set; }`**
|
||||
Controls `.dts` file inclusion. Default: `true`.
|
||||
|
||||
- **`string CustomerName { get; set; }`**
|
||||
WIAMan metadata: `Director`.
|
||||
|
||||
- **`string TestEngineerName { get; set; }`**
|
||||
WIAMan metadata: `Operator`.
|
||||
|
||||
- **`string LabName { get; set; }`**
|
||||
WIAMan metadata: `Location`.
|
||||
|
||||
- **`bool IsWiamanData { get; set; }`**
|
||||
WIAMan metadata: `Is WIAMan Data`.
|
||||
|
||||
- **`Dictionary<string, string> ISOToFineLocation3 { get; set; }`**
|
||||
Used to construct `Anthropomorphic Label`.
|
||||
|
||||
- **`Dictionary<string, string> ISOToPhysicalDimension { get; set; }`**
|
||||
Used to construct `Channel Label:Category`.
|
||||
|
||||
- **`Dictionary<string, string> ISOToPosition { get; set; }`**
|
||||
Used to construct `Channel Label:Optional`.
|
||||
|
||||
- **`Dictionary<string, string> ISOToTransducerMainLocation { get; set; }`**
|
||||
*Declared in `Writer` but never used.* (See *Gotchas*.)
|
||||
|
||||
- **`void Write(string pathname, string id, string dataFolder, Test test, bool bFiltering, bool includeGroupNameInISOExport, FilteredData fd, Test.Module.Channel tmChannel, int channelNumber, BeginEventHandler beginEventHandler, CancelEventHandler cancelEventHandler, EndEventHandler endEventHandler, TickEventHandler tickEventHandler, ErrorEventHandler errorEventHandler, CancelRequested cancelRequested, double minStartTime, int dataCollectionLength)`**
|
||||
Main export method. Writes the `Test` object to an HDF5 file at `pathname`.
|
||||
- Creates `/Files/{folder}` groups for logs, setup, reports, and `.dts` files if `Export*` flags are enabled.
|
||||
- Writes three dataset groups: `/Datasets_EU`, `/Datasets`, `/Datasets_MV`, depending on flags.
|
||||
- For each `AnalogInputChannel`, writes channel-specific metadata (WIAMan + S6 attributes) and raw data as datasets named `{index}: Strain_RawYData`.
|
||||
- Uses `Parallel.ForEach` over `test.Channels` for performance.
|
||||
- Progress is reported via `tickEventHandler` in 100-step increments.
|
||||
- Errors are logged via `APILogger` and propagated via `errorEventHandler`.
|
||||
|
||||
- **`private Common.DAS.Concepts.DataScaler GetDataScaler(Test.Module.AnalogInputChannel currentAnalogChannel)`**
|
||||
Constructs a `DataScaler` from channel properties (e.g., `UnitConversion`, `Multiplier`, `Sensitivity`, `ZeroMethod`, `RemovedADC`, `MeasuredExcitationVoltage`, etc.). Includes robust error handling with logging for individual scaler property assignments.
|
||||
|
||||
- **`private void CheckStatus(long status, ErrorLocation location)`**
|
||||
Throws an `Exception` with `location.ToString()` if `status < 0`. Used after HDF5 API calls.
|
||||
|
||||
- **`private void CreateStringAttribute(long objectId, string attributeName, string attributeValue)`**
|
||||
Creates an HDF5 string attribute on `objectId`. Handles null/empty values gracefully. Uses `H5S.create`, `H5T.copy`, `H5A.create`, `H5A.write`, and `Marshal.StringToHGlobalAnsi`. All handles are closed in `finally`.
|
||||
|
||||
- **`private void CreateIntAttribute(long objectId, string title, int value)`**
|
||||
If `ATTRIBUTE_STRING_DATATYPE_ONLY` is `true` (hardcoded), converts `value` to string and delegates to `CreateStringAttribute`. Otherwise, would create numeric attribute (not implemented).
|
||||
|
||||
- **`private void CreateUlongAttribute(long objectId, string title, ulong value)`**
|
||||
Same behavior as `CreateIntAttribute`.
|
||||
|
||||
- **`private void CreateDoubleAttribute(long objectId, string title, double value)`**
|
||||
Same behavior as `CreateIntAttribute`.
|
||||
|
||||
- **`private void AddDirectoryIfExists(string binaryPath, string folder, long hdfObjectId, string fileExtension)`**
|
||||
Adds all files matching `fileExtension` from a computed source directory (e.g., `root/Logs`) into an HDF5 group at `/Files/{folder}`. Uses nested `DirectoryInfo.Parent` checks to determine root. Reads files into byte arrays and writes them as 1D `NATIVE_UCHAR` datasets.
|
||||
|
||||
- **`private int ComputeNumberOfSteps(Test test)`**
|
||||
Computes total export steps based on enabled export flags and channel count. Each enabled export type contributes `Channels.Count` steps; each file group (logs, setup, reports, dts) contributes 1 step.
|
||||
|
||||
- **`internal Writer(File fileType, int encoding)`**
|
||||
Constructor. Initializes all `Export*` flags to `true`. Sets `WriterParent`.
|
||||
|
||||
- **`public void Initialize(...)`**
|
||||
*Empty implementation.* No initialization logic is performed.
|
||||
|
||||
---
|
||||
|
||||
### 3. Invariants
|
||||
|
||||
- **HDF5 file structure**:
|
||||
- `/Files/{folder}` groups are created only if corresponding `Export*` flag is `true`.
|
||||
- `/Datasets`, `/Datasets_EU`, `/Datasets_MV` groups are created only if `ExportADC`, `ExportEU`, or `ExportMV` is `true`, respectively.
|
||||
- Each channel’s data resides under a group named `/{datasetGroup}/{index:0000}: {channelName}`.
|
||||
- Channel data datasets are named `{index}: Strain_RawYData`.
|
||||
|
||||
- **Data type in datasets**:
|
||||
- ADC: `H5T.NATIVE_SHORT` (16-bit signed integer).
|
||||
- mV/EU: `H5T.NATIVE_DOUBLE` (64-bit float).
|
||||
|
||||
- **Channel ordering**:
|
||||
Channels are sorted by `AbsoluteDisplayOrder` before processing.
|
||||
|
||||
- **Progress reporting**:
|
||||
Progress updates occur every `UPDATE_INTERVAL = 1000` samples per channel, and at group-level milestones (e.g., after each file group or dataset group is written). Final progress is always set to `100D` in `finally`.
|
||||
|
||||
- **WIAMan attribute requirement**:
|
||||
All WIAMan attributes listed in code comments are written *only* if `IsWiamanData` is `true`?
|
||||
→ **No**: Attributes are written unconditionally. `IsWiamanData` only sets a string attribute `"Is WIAMan Data"` to `"TRUE"`/`"FALSE"`.
|
||||
|
||||
- **String attributes**:
|
||||
All attributes (int, double, ulong) are stored as strings if `ATTRIBUTE_STRING_DATATYPE_ONLY = true` (hardcoded). No numeric HDF5 attributes are created.
|
||||
|
||||
- **Locking**:
|
||||
HDF5 API calls are guarded by `H5WriteLock` (a private `object`). Progress updates use `_updateProgressLock`.
|
||||
|
||||
---
|
||||
|
||||
### 4. Dependencies
|
||||
|
||||
#### Imports/Usings:
|
||||
- `HDF.PInvoke` — P/Invoke wrapper for HDF5 C library.
|
||||
- `System.Runtime.InteropServices` — For `Marshal.AllocHGlobal`, `FreeHGlobal`, `StringToHGlobalAnsi`.
|
||||
- `DTS.Common.Enums.Sensors` — For `SensorConstants.BridgeType`.
|
||||
- `DTS.Common.Utilities.Logging` — For `APILogger`.
|
||||
- `System.Collections.Generic`, `System.IO`, `System.Linq`, `System.Threading.Tasks` — Standard .NET.
|
||||
|
||||
#### Internal Dependencies:
|
||||
- `Serialization.File` — Base class (inherited).
|
||||
- `IWriter<Test>` — Interface implemented.
|
||||
- `Test` — Core data model (from `DTS.Serialization` or similar).
|
||||
- `Test.Module`, `Test.Module.AnalogInputChannel`, `FilteredData`, `DataScaler` — Internal DTS types.
|
||||
- `BeginEventHandler`, `CancelEventHandler`, `EndEventHandler`, `TickEventHandler`, `ErrorEventHandler`, `CancelRequested` — Delegates for progress/cancellation.
|
||||
|
||||
#### External Dependencies:
|
||||
- HDF5 library (via `HDF.PInvoke`).
|
||||
- File system access for reading logs, setup, reports, and `.dts` files.
|
||||
|
||||
---
|
||||
|
||||
### 5. Gotchas
|
||||
|
||||
- **`ISOToTransducerMainLocation` is unused**:
|
||||
The `File` class exposes a setter for `ISOToTransducerMainLocation`, and the `Writer` class declares a corresponding property, but the property is never referenced in the code. This is likely dead code.
|
||||
|
||||
- **`Initialize` method is empty**:
|
||||
The `Writer.Initialize(...)` method has no implementation. All work is done in `Write(...)`. This may violate expectations of a two-phase initialization pattern.
|
||||
|
||||
- **String-only attributes**:
|
||||
All numeric attributes (int, double, ulong) are stored as strings due to `ATTRIBUTE_STRING_DATATYPE_ONLY = true`. This increases file size and complicates downstream parsing.
|
||||
|
||||
- **Nested `DirectoryInfo.Parent` checks**:
|
||||
The `AddDirectoryIfExists` method uses a brittle chain of `Parent.Parent.Parent` to determine the root directory. This assumes a fixed directory structure and may fail if the path depth is insufficient.
|
||||
|
||||
- **Parallel channel processing**:
|
||||
Channels are processed in parallel (`Parallel.ForEach`), but progress updates are *not* thread-safe beyond the `_updateProgressLock`. Steps completed (`stepsCompleted`) is incremented outside the lock, risking race conditions and incorrect progress reporting.
|
||||
|
||||
- **Hardcoded dataset names**:
|
||||
All channel datasets are named `{index}: Strain_RawYData`, regardless of data type (ADC/mV/EU). This may cause confusion or overwriting if multiple dataset groups exist.
|
||||
|
||||
- **No cancellation support in `Write`**:
|
||||
Although `cancelRequested` is passed to `Write`, it is never checked. The export runs to completion regardless of cancellation.
|
||||
|
||||
- **Error handling is lossy**:
|
||||
`CheckStatus` throws a generic `Exception` with only the location name (e.g., `"File"`), losing the underlying HDF5 error code or message. Detailed diagnostics rely on `APILogger.Log` calls.
|
||||
|
||||
- **Memory allocation per sample**:
|
||||
Data is written sample-by-sample using `Marshal.WriteByte` in loops. This is inefficient compared to bulk copy (e.g., `Marshal.Copy`). The comment references performance fixes, but the implementation remains suboptimal.
|
||||
|
||||
- **No validation of `ISOTo*` dictionaries**:
|
||||
Accessing `ISOToFineLocation3[aic.IsoCode]` without checking for key existence will throw `KeyNotFoundException` if the dictionary is incomplete or keys are missing.
|
||||
|
||||
- **`minStartTime` and `dataCollectionLength` are unused**:
|
||||
These parameters appear in `Write` signatures but are never used in the implementation.
|
||||
|
||||
- **`ExtensionPrefix` is settable but unused**:
|
||||
The `ExtensionPrefix` property is defined but not used in filename construction (`{id}_{LabName}_1of1{(ExtensionPrefix ?? "")}.h5`), so it only affects the filename if explicitly set to a non-empty value.
|
||||
|
||||
- **No support for digital or calculated channels**:
|
||||
`Parallel.ForEach` skips non-`AnalogInputChannel` instances (`if (null == aic) return;`). Digital channels, calculated channels, or other channel types are silently ignored.
|
||||
|
||||
- **Time handling assumptions**:
|
||||
`Reference Time` is computed from `TriggerTimestampSec` and `TriggerTimestampNanoSec`, assuming Unix epoch. No timezone or leap-second handling is evident.
|
||||
|
||||
- **Hardcoded export version**:
|
||||
`HDF_EXPORT_VERSION = 7.0D` is hardcoded. No version negotiation or schema evolution is apparent.
|
||||
@@ -0,0 +1,145 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/Chapter10.File.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/WriteTest.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/CH10AnalogStreamDecode.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/Chapter10File.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/Chapter10.File.Writer.cs
|
||||
generated_at: "2026-04-16T03:40:14.768603+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "7cd12a08c3bf75a1"
|
||||
---
|
||||
|
||||
# IRIG CH10 Serialization Module Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module implements serialization and deserialization for IRIG CH10 (Chapter 10) data files, which are standardized binary formats for recording test and measurement data. It provides functionality to read existing CH10 files (parsing headers, packets, and transport stream metadata), write new CH10 files in either analog or PCM format, and decode real-time UDP multicast streams containing CH10 packets. The module serves as the core data I/O layer for handling IRIG CH10-compliant test data within the DTS system.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `DTS.Serialization.IRIGCH10.File`
|
||||
|
||||
- **`public File()`**
|
||||
Constructor that initializes a new `File` instance with the type name "Chapter10".
|
||||
|
||||
- **`public IWriter<Test> Exporter { get; }`**
|
||||
Returns an `IWriter<Test>` instance for writing CH10 files. Lazily initializes a `Writer` using the current `DefaultEncoding`. Throws an `Exception` with inner exception if initialization fails.
|
||||
|
||||
### `DTS.Serialization.IRIGCH10.File.Writer`
|
||||
|
||||
- **`public void Write(string pathname, string id, string dataFolder, Test test, bool bFiltering, bool includeGroupNameInISOExport, FilteredData fd, Channel tmChannel, int channelNumber, BeginEventHandler beginEventHandler, CancelEventHandler cancelEventHandler, EndEventHandler endEventHandler, TickEventHandler tickEventHandler, ErrorEventHandler errorEventHandler, CancelRequested cancelRequested, double minStartTime, int dataCollectionLength)`**
|
||||
Writes a `Test` object to a CH10 file at `pathname`. Reads raw sample data from files associated with channels in `test`, computes TMATS metadata (analog or PCM format based on `UseAnalogFormat`/`UsePCMFormat`), and calls `Chapter10File.WriteFileAnalog` or `Chapter10File.WriteFilePCM`. Handles file I/O errors, progress reporting via `tickEventHandler`, and cleanup of file readers.
|
||||
|
||||
- **`public void Initialize(...)`**
|
||||
Stub method with no implementation (empty body). No behavior defined.
|
||||
|
||||
### `DTS.Serialization.IRIGCH10.CH10AnalogStreamDecode`
|
||||
|
||||
- **`public void StartListening()`**
|
||||
Starts a background `Task` that listens for UDP multicast packets on `MulticastReceiveAddress` (default `239.1.1.1`) at `ResponsePort` (default 5017). Binds to `BindToAdapterIPAddress` (default `IPAddress.Any`). Joins the multicast group and begins parsing incoming bytes.
|
||||
|
||||
- **`public void StopListening()`**
|
||||
Signals the listening thread to stop via `_stopListening.Set()`.
|
||||
|
||||
- **`public delegate void TimePacketDelegate(TimePacketFormat2 packet);`**
|
||||
Delegate for handling received time packets.
|
||||
|
||||
- **`public delegate void AnalogDataPacketDelegate(AnalogDataFormat1Packet packet);`**
|
||||
Delegate for handling received analog data packets.
|
||||
|
||||
- **`public delegate void TMATSPacketDelegate(TMATSPacket packet);`**
|
||||
Delegate for handling received TMATS packets.
|
||||
|
||||
- **`public delegate void BadCRCDelegate(IPacketHeader packet);`**
|
||||
Delegate for handling packets with invalid CRC.
|
||||
|
||||
- **`public TimePacketDelegate OnTimePacket { get; set; }`**
|
||||
Callback invoked when a valid `TimePacketFormat2` is parsed.
|
||||
|
||||
- **`public AnalogDataPacketDelegate OnAnalogPacket { get; set; }`**
|
||||
Callback invoked when a valid `AnalogDataFormat1Packet` is parsed.
|
||||
|
||||
- **`public TMATSPacketDelegate OnTMATSPacket { get; set; }`**
|
||||
Callback invoked when a valid `TMATSPacket` is parsed.
|
||||
|
||||
- **`public BadCRCDelegate OnBadCRC { get; set; }`**
|
||||
Callback invoked when a packet header has an incorrect CRC.
|
||||
|
||||
### `DTS.Serialization.IRIGCH10.Chapter10File`
|
||||
|
||||
- **`public Chapter10File(byte[] bytes)`**
|
||||
Constructor that parses all CH10 packets and transport headers from a byte array. Populates internal lists for transport headers, packet headers, secondary time headers, and tracks byte ranges for each packet. Sets `GoodPackets` and `RejectedPackets` counts.
|
||||
|
||||
- **`public ITransportStreamHeader[] GetTransportHeaders()`**
|
||||
Returns all parsed transport stream headers in order.
|
||||
|
||||
- **`public IPacketHeader[] GetPacketHeaders()`**
|
||||
Returns all parsed packet headers in order.
|
||||
|
||||
- **`public ISecondaryTimeFormatHeader[] GetSecondaryTimeHeaders()`**
|
||||
Returns all parsed secondary time format headers in order.
|
||||
|
||||
- **`public byte[] GetBytesForPacket(IPacketHeader packet)`**
|
||||
Returns a copy of the full packet bytes (header + payload) for a given `packet`. Returns `null` if `packet` was not parsed from this instance.
|
||||
|
||||
- **`public int GoodPackets { get; }`**
|
||||
Number of successfully parsed packets.
|
||||
|
||||
- **`public int RejectedPackets { get; }`**
|
||||
Number of packets rejected (invalid sync pattern or CRC).
|
||||
|
||||
- **`public static long GetIndexOfNextPacket(byte[] bytes, long startIndex)`**
|
||||
Scans `bytes` starting at `startIndex` for the next valid packet sync pattern (`PacketHeader.EXPECTED_SYNC_PATTERN`). Returns index of next sync, or `bytes.Length` if none found.
|
||||
|
||||
- **`public static long ReadChapter10PacketHeader(byte[] bytes, long startIndex, out IPacketHeader packetHeader)`**
|
||||
Reads a packet header from `bytes` at `startIndex`. Returns the index of the *end* of the packet (i.e., `startIndex + packetHeader.PacketLength`). Populates `packetHeader`.
|
||||
|
||||
- **`public static void WriteFilePCM(string tmats, GetNextSampleDelegate getNextSample, GetChannelLengthDelegate getChannelLength, int totalChannels, int nanoseconds, int seconds, double sampleRate, bool includeSecondaryHeader, string fileName, TickEventHandler tickEventHandler, object tickObject)`**
|
||||
Writes a PCM-format CH10 file. Writes a TMATS packet first, then interleaves time packets (Format 1 or 2 depending on `includeSecondaryHeader`) and PCM data packets. Uses `getNextSample` to read samples and `getChannelLength` to determine total samples per channel.
|
||||
|
||||
- **`public static void WriteFileAnalog(string tmats, GetNextSampleDelegate getNextSample, GetChannelLengthDelegate getChannelLength, int totalChannels, int nanoseconds, int seconds, double sampleRate, bool includeSecondaryHeader, string fileName, TickEventHandler tickEventHandler, object tickObject)`**
|
||||
Writes an analog-format CH10 file. Behavior identical to `WriteFilePCM` but produces `AnalogDataFormat1Packet` packets.
|
||||
|
||||
- **`public delegate short GetNextSampleDelegate(int channelIdx);`**
|
||||
Delegate to retrieve the next ADC sample for a given channel index.
|
||||
|
||||
- **`public delegate long GetChannelLengthDelegate(int channelIndex);`**
|
||||
Delegate to retrieve the total number of samples for a given channel.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Packet Sync Pattern**: All valid CH10 packets must begin with `PacketHeader.EXPECTED_SYNC_PATTERN` (value not visible in source, but used in `Chapter10File` parsing and `CH10AnalogStreamDecode.ParseBytes`).
|
||||
- **CRC Validation**: Packets with `header.CheckSum != header.ComputeCheckSum()` are rejected and reported via `OnBadCRC`.
|
||||
- **Packet Length Consistency**: `ReadChapter10PacketHeader` assumes `header.PacketLength` is valid and does not exceed remaining buffer size; if it does, bytes are queued for later parsing.
|
||||
- **RTC Base**: `BASE_RTC = 141989612500056L` is used as the reference time base for computing Relative Time Counter (RTC) values in both `File.Writer` and `Chapter10File`.
|
||||
- **Sample Rate Assumption**: Export methods assume all modules in a `Test` share the same `SampleRateHz` (uses `test.Modules[0].SampleRateHz`).
|
||||
- **Transport Header**: Every CH10 packet is preceded by a 4-byte transport header (parsed by `ReadTransportHeader`).
|
||||
- **Packet Ordering**: Packet headers and transport headers are stored and returned in the order they appear in the input stream.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Dependencies *of* this module:
|
||||
- **`DTS.Common`** (e.g., `Constants`, `Utils`, `Logging`, `Enums`)
|
||||
- **`DTS.Serialization.Test`** (e.g., `Test`, `Module`, `Channel`, `AnalogInputChannel`)
|
||||
- **`IRIGCh10`** (namespace for packet types: `TMATSPacket`, `TimeDataPacket`, `PCMPacket`, `UserDefinedPacket`, `IDataPacket`, `Enums`, `PacketHeader`, etc.)
|
||||
- **`System`** (e.g., `IO`, `Net`, `Threading`, `Drawing.Text`)
|
||||
- **`DTS.DASLib.Command.SLICE.MulticastCommands`** (`MulticastCommandBase` for multicast defaults)
|
||||
|
||||
### Dependencies *on* this module:
|
||||
- **`DTS.Serialization`** (base `Serialization.File` and `Serialization.File.Writer` classes are inherited/extended)
|
||||
- **`DTS.Serialization.IRIGCH10.Packets`** (internal packet types like `TMATSPacket`, `AnalogDataFormat1Packet`, `TimePacketFormat2`, `PCMDataPacket`, `PacketHeader`, `SecondaryTimeFormatHeader`, `AbstractDataPacket`)
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **`BASE_RTC` is arbitrary**: In `File.Writer`, `BASE_RTC = 141989612500056L` is described as "we don't really have an RTC, so we make up one with an arbitrary value". This value is hardcoded and used for all exports, regardless of actual test timing.
|
||||
- **TMATS Template Files Required**: Export methods (`GetTMATSAnalog`, `GetTMATSPCM`) read template files from `@"TMTTemplates\S6ATMTTemplate_*.tmt"`. If these files are missing or misnamed, export will fail.
|
||||
- **Sample Reading Endianness**: `ReadShort` reads bytes in little-endian order (`bytes[0] + (bytes[1] << 8)`), which may differ from native file format endianness.
|
||||
- **Channel Indexing**: Channel indices in TMATS generation (`1 + channelIdx`) are 1-based, while internal indexing is 0-based.
|
||||
- **`Write` Overload Not Implemented**: The `Write(string pathname, string id, Test test, ...)` overload in `File.Writer` throws `NotImplementedException`.
|
||||
- **`Initialize` is a no-op**: The `Initialize` method has no implementation.
|
||||
- **Multicast Binding Behavior**: When `BindToAdapterIPAddress == IPAddress.Any`, `ExclusiveAddressUse = false` is set; otherwise, multicast group join uses the specific adapter.
|
||||
- **Packet Parsing Resilience**: `ParseBytes` in `CH10AnalogStreamDecode` queues incomplete packets (`QueueBytes`) if packet length exceeds available bytes, but does not flush queued bytes on subsequent calls unless new data arrives.
|
||||
- **No Support for User-Defined Packets**: `ParseBytes` logs unknown packet types but does not expose them via a delegate.
|
||||
- **RTC Calculation Assumption**: `GetRTC(currentSample, sampleRate)` assumes uniform sample timing and uses `RTC_PER_SECOND = 10000000` (10 MHz clock).
|
||||
@@ -0,0 +1,73 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/Attributes/DescriptionDecoder.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/Attributes/PacketHeaderValueAttribute.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/Attributes/DataTypeVersionValueAttribute.cs
|
||||
generated_at: "2026-04-16T03:43:04.052592+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "32d5e734af040685"
|
||||
---
|
||||
|
||||
# IRIG CH10 Attribute Decoders Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides utility classes for extracting metadata annotations from .NET `enum` values, specifically tailored for IRIG CH10 data format compliance. It enables serialization logic to retrieve human-readable descriptions, maximum length constraints, packet header values, and data type version numbers associated with enum fields via custom attributes (`DescriptionAttribute`, `MaxLengthAttribute`, `PacketHeaderValueAttribute`, `DataTypeVersionValueAttribute`). These utilities bridge the gap between strongly-typed enum definitions and the string/byte-level requirements of the IRIG CH10 specification (e.g., TMATS file generation, packet header construction).
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `DescriptionDecoder.GetDescription(Enum value)`
|
||||
- **Signature**: `public static string GetDescription(Enum value)`
|
||||
- **Behavior**: Returns the `DescriptionAttribute.Description` value attached to the enum field corresponding to `value`. If no such attribute exists, returns the enum's `ToString()` representation.
|
||||
|
||||
### `MaxLengthDecoder.GetMaxLength(Enum value)`
|
||||
- **Signature**: `public static int GetMaxLength(Enum value)`
|
||||
- **Behavior**: Returns the `Length` property of the `MaxLengthAttribute` attached to the enum field corresponding to `value`. If no such attribute exists, returns `0`.
|
||||
|
||||
### `PacketHeaderValueAttribute.GetPacketHeaderValue(Enum value)`
|
||||
- **Signature**: `public static byte GetPacketHeaderValue(Enum value)`
|
||||
- **Behavior**: Returns the `PacketHeaderValue` property of the `PacketHeaderValueAttribute` attached to the enum field corresponding to `value`. If no such attribute exists, returns `Default.PacketHeaderValue` (which is `0x00`).
|
||||
|
||||
### `DataTypeVersionValueAttribute.GetDataTypeVersionValue(Enum value)`
|
||||
- **Signature**: `public static byte GetDataTypeVersionValue(Enum value)`
|
||||
- **Behavior**: Returns the `DataTypeVersionValue` property of the `DataTypeVersionValueAttribute` attached to the enum field corresponding to `value`. If no such attribute exists, returns `Default.DataTypeVersionValue` (which is `0x00`).
|
||||
|
||||
> **Note**: The static methods `GetPacketHeaderValue` and `GetDataTypeVersionValue` are *instance methods* on their respective attribute classes, not static methods on the class itself. They are called on the attribute class (e.g., `PacketHeaderValueAttribute.GetPacketHeaderValue(someEnum)`) and operate on the enum value passed.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Enum Field Resolution**: All decoder methods assume the `Enum` value corresponds to a valid field name in its declaring type (via `value.ToString()` → `GetField()`). If the enum value is invalid or the field name resolution fails (e.g., due to compiler-generated names or custom `ToString()` overrides), behavior is undefined (likely throws `NullReferenceException` or returns incorrect data).
|
||||
- **Attribute Uniqueness**: Methods return the *first* attribute found via `GetCustomAttributes(...)`. If multiple attributes of the same type exist on a single field, only the first is used.
|
||||
- **Default Values**: When no attribute is present:
|
||||
- `GetDescription` falls back to `value.ToString()`
|
||||
- `GetMaxLength` returns `0`
|
||||
- `GetPacketHeaderValue` returns `0x00`
|
||||
- `GetDataTypeVersionValue` returns `0x00`
|
||||
- **Attribute Scope**: `PacketHeaderValueAttribute` and `DataTypeVersionValueAttribute` are decorated with `[AttributeUsage(AttributeTargets.All)]`, meaning they *can* be applied to any program element (not just enums), though the decoders assume usage on enum fields.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Dependencies *of* this module:
|
||||
- **System.ComponentModel**: For `DescriptionAttribute`
|
||||
- **System.ComponentModel.DataAnnotations**: For `MaxLengthAttribute`
|
||||
- **System.Linq**: For `Any()` and `First()` LINQ methods
|
||||
- **System.Reflection**: For `GetType()`, `GetField()`, `GetCustomAttributes()`
|
||||
|
||||
### Dependencies *on* this module:
|
||||
- Other IRIG CH10 serialization components (not visible in source) that rely on these decoders to:
|
||||
- Generate TMATS string descriptions from enums
|
||||
- Enforce or suggest max-length constraints for string fields
|
||||
- Construct packet headers (e.g., for packet type/version identification)
|
||||
- Serialize data type version information per CH10 spec
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **No null-safety**: All methods call `value.ToString()` and `GetField(...)` without validating that `value` is non-null or that the field exists. Passing `null` or an invalid enum value will cause a `NullReferenceException`.
|
||||
- **Case sensitivity**: `value.ToString()` is used directly for `GetField()`. If the enum field name differs in casing (e.g., due to compiler optimizations or custom `ToString()` overrides), field resolution may fail.
|
||||
- **`MaxLengthAttribute` is advisory only**: As noted in the `MaxLengthDecoder` summary, CH10 specifies max lengths as *suggestions*, not hard requirements. Consumers should not assume enforcement.
|
||||
- **Default attribute behavior**: The `Default` static fields (`PacketHeaderValueAttribute.Default`, `DataTypeVersionValueAttribute.Default`) are *new instances* with `0x00` values—not singleton references to a shared default. This is safe but worth noting for equality comparisons.
|
||||
- **No validation of attribute targets**: While `PacketHeaderValueAttribute` and `DataTypeVersionValueAttribute` allow `AttributeTargets.All`, their static `Get*Value` methods assume usage on enum fields. Applying them to non-enum members (e.g., classes, methods) will likely cause runtime errors.
|
||||
- **No support for inherited attributes**: `GetCustomAttributes(..., false)` excludes inherited attributes. If attributes are defined on base enum values (in inheritance hierarchies), they will be ignored.
|
||||
|
||||
None identified from source alone beyond those above.
|
||||
@@ -0,0 +1,110 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/Enums/Enums.cs
|
||||
generated_at: "2026-04-16T03:42:48.006856+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "cc430983f5236d17"
|
||||
---
|
||||
|
||||
# Documentation: `DTS.Serialization.IRIGCH10.Enums` Namespace
|
||||
|
||||
## 1. Purpose
|
||||
This module defines a set of strongly-typed enumerations used to represent standardized IRIG-106 Chapter 10 data types, time sources, time formats, and related metadata as specified in the IRIG-106 standard. These enums serve as the semantic foundation for parsing and serializing IRIG-106-compliant binary data files, mapping raw packet header values (e.g., data type codes, checksum types, time formats) to human-readable and type-safe enum members. They are used internally by serialization/deserialization logic to interpret and construct IRIG-106 packets correctly.
|
||||
|
||||
## 2. Public Interface
|
||||
All types are `public enum`s in the `DTS.Serialization.IRIGCH10.Enums` namespace. No classes, interfaces, or methods are exposed.
|
||||
|
||||
### `DataFileDataTypes`
|
||||
- **Description**: Enumerates all defined IRIG-106 Chapter 10 data format types (e.g., PCM, MIL-STD-1553, Video, Ethernet), identified by a `PacketHeaderValue` (1-byte code) and a `DataTypeVersionValue`.
|
||||
- **Key Members**:
|
||||
- `ComputerGeneratedDataFormat0` (0x00), `ComputerGeneratedDataFormat1` (0x01), ..., `ComputerGeneratedDataFormat7` (0x07)
|
||||
- `PCMDataFormat1` (0x09) — *Chapter 4 or 8*
|
||||
- `TimeDataFormat1` (0x11) — *RCC/GPS/RTC*
|
||||
- `MILSTD1553DataFormat1` (0x19) — *MIL-STD-1553B*
|
||||
- `AnalogDataFormat1` (0x21) — *Analog Data*
|
||||
- `DiscreteDataFormat1` (0x29) — *Discrete Data*
|
||||
- `MessageDataFormat0` (0x30) — *Generic Message Data*
|
||||
- `ARINC429DataFormat0` (0x38) — *ARINC-429 Data*
|
||||
- `VideoDataFormat0` (0x40) — *MPEG-2/H.264 Video*
|
||||
- `VideoDataFormat1` (0x41) — *ISO 13818-1 MPEG-2*
|
||||
- `VideoDataFormat2` (0x42) — *ISO 14496 MPEG-4 Part10 110 AVC/H.264*
|
||||
- `VideoDataFormat3` (0x43) — *MJPEG* (version 0x07)
|
||||
- `VideoDataFormat4` (0x44) — *MJPEG 2000* (version 0x07)
|
||||
- `ImageDataFormat0` (0x48) — *Image Data*
|
||||
- `ImageDataFormat1` (0x49) — *Still Imagery*
|
||||
- `ImageDataFormat2` (0x4A) — *Dynamic Imagery*
|
||||
- `UARTDataFormat0` (0x50) — *UART Data*
|
||||
- `IEEE1394DataFormat0` (0x58) — *IEEE 1394 Transaction*
|
||||
- `IEEE1394DataFormat1` (0x59) — *IEEE 1394 Physical Layer*
|
||||
- `ParallelDataFormat0` (0x60) — *Parallel Data*
|
||||
- `EthernetDataFormat0` (0x68) — *Ethernet Data* (version 0x07)
|
||||
- `EthernetDataFormat1` (0x69) — *Ethernet UDP Payload*
|
||||
- `TSPI_CTSDataFormat0` (0x70) — *GPS NMEA-RTCM*
|
||||
- `TSPI_CTSDataFormat1` (0x71) — *EAG ACMI*
|
||||
- `TSPI_CTSDataFormat2` (0x72) — *ACTTS*
|
||||
- `ControllerAreaNetworkBus` (0x78) — *CAN Bus*
|
||||
- `FibreChannelDataFormat0` (0x79) — *Fibre Channel Data* (version 0x07)
|
||||
- **Note**: All formats follow a pattern: `XxxDataFormatN`, where `N` (0–7) allows for vendor-specific or variant definitions. Only `Format1` variants (e.g., `AnalogDataFormat1`) are standardized; others are reserved.
|
||||
|
||||
### `TimeSource`
|
||||
- **Description**: Specifies the origin of time metadata in a packet.
|
||||
- **Members**:
|
||||
- `Internal` (0x00) — *Time derived from a clock in the recorder*
|
||||
- `External` (0x01) — *Time derived from a clock not in the recorder*
|
||||
- `InternalFromRMM` (0x02) — *Internal from RMM (Time derived from the clock in the RMM)*
|
||||
- `None` (0x0F) — *No time source*
|
||||
|
||||
### `TimeFormats`
|
||||
- **Description**: Specifies the encoding format of time data (e.g., IRIG-B, UTC, GPS).
|
||||
- **Members**:
|
||||
- `IRIGB` (0x00) — *IRIG-B*
|
||||
- `IRIGA` (0x01) — *IRIG-A*
|
||||
- `IRIGG` (0x02) — *IRIG-G*
|
||||
- `RTC` (0x03) — *Real-Time Clock*
|
||||
- `UTC` (0x04) — *UTC Time from GPS*
|
||||
- `GPS` (0x05) — *Native GPS Time*
|
||||
- `None` (0x0F) — *No time format*
|
||||
|
||||
### `DataTypeVersion`
|
||||
- **Description**: Represents the version of the IRIG-106 standard used for the data type definition.
|
||||
- **Members**:
|
||||
- `InitialRelease` (0x01) — *Initial Release (IRIG-106-04)*
|
||||
- `TG78` (0x02) — *TG-78 (IRIG-106-05)*
|
||||
- `IRIG106_07` (0x03) — *IRIG-106-07*
|
||||
|
||||
### `SecondaryHeaderTimeFormat`
|
||||
- **Description**: Indicates the binary format of time in the secondary header (if present).
|
||||
- **Members**:
|
||||
- `IRIG106Chapter4` (0x00) — *IRIG 106 Chapter 4 binary weighted 48-bit time format*
|
||||
- `IEEE1588` (0x01) — *IEEE-1588 Time format*
|
||||
|
||||
### `DataCheckSumType`
|
||||
- **Description**: Specifies the checksum algorithm used for packet integrity.
|
||||
- **Members**:
|
||||
- `None` (0x00)
|
||||
- `EightBit` (0x01)
|
||||
- `SixteenBit` (0x02)
|
||||
- `ThirtyTwoBit` (0x03)
|
||||
|
||||
## 3. Invariants
|
||||
- **`PacketHeaderValue` is unique per enum member**: Each enum value is annotated with `[PacketHeaderValue(byte)]`, and no two members share the same value. This ensures unambiguous mapping between raw bytes and enum members.
|
||||
- **`DataTypeVersionValue` is consistent per `DataFileDataTypes` member**: Every `DataFileDataTypes` member has exactly one `[DataTypeVersionValue(byte)]` attribute. Values observed are `0x06` (most common) and `0x07` (e.g., `ComputerGeneratedDataFormat1`, `VideoDataFormat3`, `VideoDataFormat4`, `EthernetDataFormat0`, `FibreChannelDataFormat0`).
|
||||
- **Reserved formats are strictly reserved**: All enum members with descriptions containing “Reserved for future use” must not be interpreted as active data types. Their `PacketHeaderValue`s are contiguous in blocks (e.g., `0x04`–`0x07`, `0x0A`–`0x0F`, etc.), but their usage is undefined.
|
||||
- **No overlapping `PacketHeaderValue`s across enums**: While not enforced in code, the values are allocated per IRIG-106 spec to avoid ambiguity (e.g., `TimeSource.None = 0x0F` does not conflict with `TimeFormats.None = 0x0F` because they apply to different contexts).
|
||||
|
||||
## 4. Dependencies
|
||||
- **Internal dependencies**:
|
||||
- `DTS.Serialization.IRIGCh10.Attributes` — Custom attributes `[PacketHeaderValue]`, `[DataTypeVersionValue]`, and `[Description]` are defined here (not shown, but referenced).
|
||||
- **External dependencies**:
|
||||
- `System.ComponentModel` — Used for `[Description]` attribute.
|
||||
- **Consumers** (inferred from naming and structure):
|
||||
- Serialization/deserialization logic for IRIG-106 Chapter 10 files (e.g., packet header parsers, metadata extractors).
|
||||
- Likely used in `Packet` or `Stream` classes in sibling namespaces (e.g., `DTS.Serialization.IRIGCH10.Packets`).
|
||||
|
||||
## 5. Gotchas
|
||||
- **Typo in enum member name**: `FibreChannelDataFormats1`, `FibreChannelDataFormats2`, etc. (note the trailing `s` in `Formats`) — inconsistent with naming pattern (`FibreChannelDataFormat0`). Likely a typo; verify usage in deserialization logic.
|
||||
- **Version inconsistency**: Most `DataFileDataTypes` use `DataTypeVersionValue(0x06)`, but `ComputerGeneratedDataFormat1`, `VideoDataFormat3`, `VideoDataFormat4`, `EthernetDataFormat0`, and all `FibreChannelDataFormats*` use `0x07`. Ensure deserialization logic handles version-specific parsing.
|
||||
- **`None` values are context-sensitive**: `TimeSource.None` (0x0F) and `TimeFormats.None` (0x0F) are distinct and valid in their respective contexts (e.g., absence of time metadata), but must not be confused.
|
||||
- **No validation of reserved ranges**: The enum does not prevent invalid or future-use values (e.g., `0x80`–`0xFF` are undefined). Consumers must handle unknown values gracefully.
|
||||
- **Missing `Description` attributes**: Some members (e.g., `MILSTD1553DataFormat0`, `AnalogDataFormat0`) lack `[Description]`, relying solely on naming. This may cause issues if `Description` is used for logging or UI.
|
||||
@@ -0,0 +1,221 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/Packets/ITransportStreamHeader.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/Packets/ISecondaryTimeFormatHeader.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/Packets/TransportStreamHeader.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/Packets/SecondaryTimeFormatHeader.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/Packets/TimeDataPacket.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/Packets/TMATSPacket.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/Packets/RootRecorderIndexPacket.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/Packets/RecorderIndexPacket.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/Packets/TimePacketFormat2.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/Packets/IDataPacket.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/Packets/TimePacketFormat1.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/Packets/AnalogDataFormat1Packet.cs
|
||||
generated_at: "2026-04-16T03:43:44.837011+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "a37b40770bf1428d"
|
||||
---
|
||||
|
||||
# IRIG CH10 Packet Serialization Module Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides serialization and deserialization support for IRIG CH10 data packets, implementing core packet types required for recording and playback of time-synchronized embedded system data streams. It defines interfaces and concrete classes for transport headers, secondary time headers, and various data packet formats—including time data (Formats 1 and 2), analog data (Format 1), TMATS metadata, and recorder indexing structures—enabling interoperability with IRIG CH10-compliant systems. The module is designed for use in data acquisition and post-processing pipelines where precise time-stamping and structured binary packet formatting are required.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Interfaces
|
||||
|
||||
- **`ITransportStreamHeader`**
|
||||
- `int MessageFormat { get; }` — 4-bit field identifying the message format (must be `1` per spec).
|
||||
- `int MessageType { get; }` — 4-bit field identifying the message type (must be `0` per spec).
|
||||
- `int SequenceNumber { get; }` — 24-bit UDP sequence number, incremented per packet.
|
||||
|
||||
- **`ISecondaryTimeFormatHeader`**
|
||||
- `int NanoSeconds { get; }` — Nanosecond component of the time stamp.
|
||||
- `int Seconds { get; }` — Seconds since Unix epoch (1970-01-01).
|
||||
- `ushort Reserved { get; }` — Reserved field (always `0` in current implementation).
|
||||
- `ushort CheckSum { get; }` — 8-bit checksum over preceding fields (stored as `ushort`).
|
||||
- `DateTime LocalTime { get; }` — Computed local time from `Seconds` and `NanoSeconds`.
|
||||
|
||||
- **`IDataPacket`**
|
||||
- `IPacketHeader PacketHeader { get; }` — Access to the packet header metadata.
|
||||
- `uint ComputeCheckSum()` — Computes CRC32 checksum over data bytes.
|
||||
- `byte[] GetBytes()` — Serializes the entire packet to a byte array.
|
||||
- `void SetRTC(long rtc)` — Sets the Real-Time Counter (10 MHz) value.
|
||||
- `void SetDataVersion(DataTypeVersion version)` — Sets the data version field in the header.
|
||||
- `void SetChannelID(ushort channelID)` — Sets the channel ID.
|
||||
- `void SetSequenceNumber(ushort seq)` — Sets the packet sequence number.
|
||||
|
||||
### Concrete Classes
|
||||
|
||||
- **`TransportStreamHeader`** (implements `ITransportStreamHeader`)
|
||||
- `TransportStreamHeader()` — Default constructor (fields uninitialized).
|
||||
- `TransportStreamHeader(byte[] input)` — Parses 4-byte header; validates length (`TRANSPORT_HEADER_LENGTH = 4`), extracts `MessageFormat`, `MessageType`, and `SequenceNumber` via bit manipulation.
|
||||
- `const int TRANSPORT_HEADER_LENGTH = 4` — Header size in bytes.
|
||||
|
||||
- **`SecondaryTimeFormatHeader`** (implements `ISecondaryTimeFormatHeader`)
|
||||
- `SecondaryTimeFormatHeader(byte[] input)` — Parses 12-byte header; validates checksum via `Utils.Utils.GetCheckSum8`; logs mismatch via `Trace.WriteLine`.
|
||||
- `static byte[] GetBytes(int nanoseconds, int seconds)` — Serializes header with `Reserved=0`, computes checksum.
|
||||
- `const int SECONDARY_TIME_HEADER_LENGTH = 12` — Header size in bytes.
|
||||
|
||||
- **`TimeDataPacket`** (implements `IDataPacket`, extends `AbstractDataPacket`)
|
||||
- `TimeDataPacket()` — Initializes with `DataFileDataTypes.TimeDataFormat1`, 12-byte `_dataBytes`.
|
||||
- `DateTime GetDateTime()` — Returns internal `_dt`.
|
||||
- `void SetTime(DateTime dt)` — Encodes time fields (ms/10, sec, min, hour, day, month, year) as BCD into `_dataBytes[4..11]`.
|
||||
- `void SetTimeSource(byte b)` — Sets time source bits (0–3) in `_dataBytes[0]`.
|
||||
- `void SetTimeSource(TimeSource src)` — Sets time source using `PacketHeaderValueAttribute.GetPacketHeaderValue(src)`; bit-reverses order (per CH10 spec).
|
||||
- `void SetTimeFormat(TimeFormats fmt)` — Sets time format bits (4–7) similarly.
|
||||
|
||||
- **`TMATSPacket`** (implements `IDataPacket`, extends `AbstractDataPacket`)
|
||||
- `TMATSPacket(int nanoseconds, int seconds, string tmatsDoc, bool secondaryHeaderPresent)` — Constructs TMATS packet with ASCII/XML doc; sets data version (`0x01` or `0x09`).
|
||||
- `TMATSPacket(byte[] bytes)` — Deserializes from byte array.
|
||||
- `bool XMLFormat { get; }` — Extracted from bit 9 of `ChannelSpecificDataWord`.
|
||||
- `bool SetupRecordConfigurationChange { get; }` — Extracted from bit 8.
|
||||
- `RCCChapter10Versions Chapter10Version { get; }` — Extracted from bits 0–7; maps to enum (`RESERVED`, `RCC_106_07`, ..., `RCC_106_15`).
|
||||
- `string TMATSDocument { get; }` — Extracts TMATS string from `_dataBytes` after skipping CSDW and optional secondary header.
|
||||
|
||||
- **`RootRecorderIndexPacket`** (implements `IDataPacket`, extends `AbstractDataPacket`)
|
||||
- `RootRecorderIndexPacket(DateTime dt)` — Initializes with `DataFileDataTypes.ComputerGeneratedDataFormat3`.
|
||||
- `void SetRootPacketAddress(long address)` — Stores 8-byte address.
|
||||
- `void AddRecordingIndex(RecordingIndexIndex index)` — Adds to `_indices` list.
|
||||
- `override byte[] GetBytes()` — Appends a self-referencing index entry before serializing.
|
||||
|
||||
- **`RecordingIndexIndex`**
|
||||
- `const int SIZE = 24` — 8 bytes (RTC) + 8 bytes (DateTime BCD) + 8 bytes (data packet offset).
|
||||
- `RecordingIndexIndex(long rtc, long offset, DateTime dt)` — Constructor.
|
||||
- `byte[] GetBytes()` — Serializes fields in order: RTC, DateTime (BCD), offset.
|
||||
|
||||
- **`RecorderIndexPacket`** (implements `IDataPacket`, extends `AbstractDataPacket`)
|
||||
- `RecorderIndexPacket()` — Initializes with `DataFileDataTypes.ComputerGeneratedDataFormat3`.
|
||||
- `DateTime GetDateTime()` — Returns `GetDateTime()` of first `RecordingIndex`.
|
||||
- `int NumberOfEntries { get; }` — Count of `_indices`.
|
||||
- `void AddRecordingIndex(RecordingIndex index)` — Adds to `_indices`.
|
||||
- `override byte[] GetBytes()` — Serializes channel-specific data word, root address, and indices.
|
||||
|
||||
- **`RecordingIndex`**
|
||||
- `const int SIZE = 35` — 8 (RTC) + 8 (DateTime BCD) + 2 (ChannelId) + 1 (DataType) + 1 (Reserved) + 8 (offset).
|
||||
- `DateTime GetDateTime()` — Returns stored `_dt`.
|
||||
- `RecordingIndex(long rtc, long offset, DateTime dt)` — Constructor.
|
||||
- `byte[] GetBytes()` — Serializes fields.
|
||||
|
||||
- **`TimePacketFormat2`** (implements `IDataPacket`, extends `AbstractDataPacket`)
|
||||
- `TimePacketFormat2(byte sequenceNumber, bool rtcSyncError, int nanoseconds, int seconds, long rtc, bool includeSecondaryHeader)` — Constructor.
|
||||
- `TimePacketFormat2(byte[] bytes)` — Deserializes from byte array.
|
||||
- `DateTime LocalTimeOfFirstSample { get; }` — Populated if secondary header present.
|
||||
- `enum NetworkTimeFormats` — Values: `NetworkTimeProtocolVersion3`, `IEEE1588_2002`, `IEEE1588_2008`, `RESERVED`.
|
||||
- `NetworkTimeFormats NetworkTimeFormat { get; set; }` — Bits 7–4 of CSDW.
|
||||
- `enum TimeStatuses` — Values: `TimeNotValid`, `TimeValid`, `RESERVED`.
|
||||
- `TimeStatuses TimeStatus { get; set; }` — Bits 3–0 of CSDW.
|
||||
- `uint UnsignedSeconds { get; }` — Parsed from data section.
|
||||
- `uint UnsignedNanoSeconds { get; }` — Parsed from data section.
|
||||
- `string PTPTime { get; }` — Formatted via `PTP1588Timestamps.ToDateTimeString(...)`.
|
||||
|
||||
- **`TimePacketFormat1`** (implements `IDataPacket`, extends `AbstractDataPacket`)
|
||||
- `TimePacketFormat1(byte sequenceNumber, DateTime packetTime, long rtc, int nanoseconds, int seconds)` — Constructor.
|
||||
- `enum IRIGTimeSource` — Values: `IRIG_TCG_freewheeling`, ..., `RESERVED`.
|
||||
- `IRIGTimeSource ITS { get; set; }` — Bits 15–12 of CSDW (not serialized per comment).
|
||||
- `enum TimeFormats` — Values: `IRIG_B`, `IRIG_A`, `IRIG_G`, `RTC`, `UTC`, `NativeGPS`, `RESERVED`, `NONE`.
|
||||
- `TimeFormats TimeFormat { get; set; }` — Bits 7–4 of CSDW.
|
||||
- `enum TimeSources` — Values: `Internal`, `External`, `InternalFromRMM`, `Reserved`, `None`.
|
||||
- `TimeSources TimeSource { get; set; }` — Bits 3–0 of CSDW.
|
||||
- `enum DateFormats` — Values: `IRIGDayAvailable`, `MonthAndYearAvailable`.
|
||||
- `DateFormats DateFormat { get; set; }` — Bit 9 of CSDW.
|
||||
- `DateTime TimePacketTime { get; set; }` — Stored time.
|
||||
- `bool IsLeapYear { get; set; }` — Bit 8 of CSDW.
|
||||
|
||||
- **`AnalogDataFormat1Packet`** (implements `IDataPacket`, extends `AbstractDataPacket`)
|
||||
- `AnalogDataFormat1Packet(int nanoseconds, int seconds, Chapter10File.GetNextSampleDelegate getNextSample, int totalChannels, long channelLength, long rtc, long numSamples, long currentSample, byte sequenceNumber, ushort channelId, bool includeSecondaryHeader)` — Constructor.
|
||||
- `AnalogDataFormat1Packet(byte[] bytes)` — Deserializes from byte array.
|
||||
- `DateTime LocalTimeOfFirstSample { get; }` — Populated if secondary header present.
|
||||
- `bool Same { get; set; }` — Bit 28 of CSDW.
|
||||
- `int Factor { get; set; }` — Bits 27–24 of CSDW.
|
||||
- `int TotChan { get; set; }` — Bits 23–16 of CSDW.
|
||||
- `long Subchan { get; set; }` — Bits 15–8 of CSDW.
|
||||
- `long Length { get; set; }` — Bits 7–2 of CSDW.
|
||||
- `enum Modes` — Values: `DataIsPacked`, `DataIsUnpackedLSBPadded`, `Reserved`, `DataIsUnpackedMSBPadded`.
|
||||
- `Modes Mode { get; set; }` — Bits 1–0 of CSDW.
|
||||
- `SampleData[] Samples { get; }` — Array of sample records; each contains `short[] ChannelData`.
|
||||
|
||||
- **`AbstractDataPacket`** (abstract base class)
|
||||
- `protected uint ChannelSpecificDataWord { get; protected set; }` — CSDW field.
|
||||
- `IPacketHeader PacketHeader { get; protected set; }` — Header reference.
|
||||
- `void SetCSDWBit(int bit, bool value)` — Sets/clears a single bit in CSDW.
|
||||
- `bool GetCSDWBit(int bit)` — Reads a bit from CSDW.
|
||||
- `protected int CommonHeaderWork(...)` — Initializes header fields, computes packet length, handles padding, and writes secondary header/CSDW into `_dataBytes`.
|
||||
- `uint ComputeCheckSum()` — Returns CRC32 via `Utils.Utils.GetCheckSum32`.
|
||||
- `void SetRTC(long rtc)` / `long GetRTC()` — Manages `_rtc` and header RTC.
|
||||
- `const long BASE_RTC = 141989612500056L` — Reference RTC value.
|
||||
- `virtual byte[] GetBytes()` — Serializes header + `_dataBytes`.
|
||||
- Protected constructors for initialization and deserialization.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **TransportStreamHeader**:
|
||||
- `MessageFormat` must be `1`.
|
||||
- `MessageType` must be `0`.
|
||||
- `SequenceNumber` is a 24-bit integer (range `0x000000`–`0xFFFFFF`).
|
||||
- Input byte array must be exactly 4 bytes.
|
||||
|
||||
- **SecondaryTimeFormatHeader**:
|
||||
- Input byte array must be exactly 12 bytes.
|
||||
- `CheckSum` is validated against `Utils.Utils.GetCheckSum8`; mismatch triggers a trace warning but does not throw.
|
||||
- `LocalTime` is computed as `new DateTime(1970, 1, 1).AddSeconds(Seconds).AddTicks(NanoSeconds / 100).ToLocalTime()`.
|
||||
|
||||
- **Data Packets**:
|
||||
- All packets must have a valid `IPacketHeader` with correct `DataFileDataTypes`.
|
||||
- `PacketHeader.PacketLength` is padded to a multiple of 4 bytes.
|
||||
- `ChannelSpecificDataWord` is always 4 bytes and written into `_dataBytes` after optional secondary header.
|
||||
- `ComputeCheckSum()` operates over `_dataBytes` only (not header).
|
||||
- `SetSequenceNumber(ushort seq)` writes only the least significant byte of `seq` to `PacketHeader.SequenceNum`.
|
||||
|
||||
- **TimeDataPacket**:
|
||||
- `_dataBytes` is fixed at 12 bytes.
|
||||
- Time fields are encoded in BCD format.
|
||||
|
||||
- **TMATSPacket**:
|
||||
- `TMATSDocument` extraction assumes ASCII encoding and skips 4-byte CSDW and optional secondary header.
|
||||
|
||||
- **AnalogDataFormat1Packet**:
|
||||
- Data is stored as big-endian `ushort` (MSB first), converted to signed `short` with offset `+0x8000`.
|
||||
- `Mode` defaults to `DataIsUnpackedMSBPadded`; `Length` defaults to `16`.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Internal Dependencies
|
||||
- **`DTS.Serialization.IRIGCH10.Enums`** — Defines `DataFileDataTypes`, `DataTypeVersion`, `TimeSource`, `TimeFormats`, etc.
|
||||
- **`DTS.Serialization.IRIGCH10.Attributes`** — Used by `TimeDataPacket` for `PacketHeaderValueAttribute.GetPacketHeaderValue`.
|
||||
- **`DTS.Serialization.IRIGCH10.Packets`** — Contains `PacketHeader`, `IPacketHeader`, `ITransportStreamHeader`, `ISecondaryTimeFormatHeader`, and related classes.
|
||||
- **`DTS.Common.Utilities`** — Provides `Utils` class with methods:
|
||||
- `BitArrayToInt32(BitArray, int, int)`
|
||||
- `SetBits(BitArray, uint, int, int)`
|
||||
- `GetCheckSum8(byte[])`
|
||||
- `GetCheckSum32(byte[])`
|
||||
- `GetBCDBytes(int)`
|
||||
|
||||
### External Dependencies
|
||||
- **`System`** — Core types (`BitConverter`, `BitArray`, `DateTime`, `Encoding`, `Array`, `Buffer`, `MemoryStream`, `BinaryWriter`).
|
||||
- **`System.IO`** — For `MemoryStream`, `BinaryWriter`.
|
||||
|
||||
### Inferred Usage
|
||||
- `AbstractDataPacket` and `IDataPacket` are used by higher-level file writers/readers (e.g., `Chapter10File`).
|
||||
- `TransportStreamHeader` is likely used in UDP packet serialization/deserialization.
|
||||
- `SecondaryTimeFormatHeader` is used in `TimePacketFormat2`, `AnalogDataFormat1Packet`, and `TMATSPacket` when `secondaryHeaderPresent=true`.
|
||||
- `PTP1588Timestamps.ToDateTimeString(...)` is referenced but not defined in source—assumed external.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **`TimeDataPacket.SetSequenceNumber`** writes only the LSB of the input `ushort`, ignoring the high byte.
|
||||
- **`TransportStreamHeader`** performs bit extraction in reverse order (LSB-first) via `BitArrayToInt32(bits, start, end)`, where `end` is inclusive and higher than `start`.
|
||||
- **`SecondaryTimeFormatHeader.CheckSum`** is stored as `ushort` but computed as 8-bit; only the low byte is meaningful.
|
||||
- **`TimePacketFormat1.ITS`** is documented as *not serialized* to CSDW due to validation tool incompatibility (commented as of 2023-10-27).
|
||||
- **`AnalogDataFormat1Packet`** uses two different data versions: `0x06` (DASSAULT) for secondary headers, `0x01` (CH10 v105) otherwise.
|
||||
- **`RecordingIndexIndex` and `RecordingIndex`** store `DateTime` in BCD format (e.g., `0x12` for month=12), not binary.
|
||||
- **`TimeDataPacket.SetTime`** encodes `dt.Millisecond / 10` (tens of milliseconds), not full milliseconds.
|
||||
- **`AbstractDataPacket.SetRTC`** updates both `_rtc` and `PacketHeader.SetRTC(rtc)`; `GetRTC()` returns `_rtc`.
|
||||
- **`TMATSPacket.TMATSDocument`** extraction assumes ASCII encoding; no validation of XML/ASCII format beyond `XMLFormat` bit.
|
||||
- **`TransportStreamHeader`** constructor throws `NullReferenceException` for null input (should be `ArgumentNullException` per .NET conventions).
|
||||
- **`TimePacketFormat2.TimeStatus`** and **`NetworkTimeFormat`** enums include `RESERVED` as a valid return value, but deserialization does not throw on unknown values—defaults to `RESERVED`.
|
||||
- **`AnalogDataFormat1Packet`** samples are stored as `short[]` in `SampleData`, but the underlying data is big-endian `ushort`; conversion is handled in `GetChannels`.
|
||||
@@ -0,0 +1,181 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/TMATS/DescriptionDecoder.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/TMATS/TMATSectionNumbered.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/TMATS/TMATSSection.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/TMATS/TMATS.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/TMATS/GeneralInformation.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/TMATS/PCM.cs
|
||||
generated_at: "2026-04-16T03:43:40.628941+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "3279c734bbc2d68c"
|
||||
---
|
||||
|
||||
# Documentation: TMATS Serialization Module
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides serialization infrastructure for generating TMATS (Telemetry and Tracking Data Format Standard) documents compliant with IRIG 106 Chapter 10. It enables structured construction of TMATS records by encapsulating attribute-value pairs, handling numbered sections (e.g., per-channel PCM data), and enforcing formatting rules derived from metadata attributes (`DescriptionAttribute`, `MaxLengthAttribute`). The module serves as the foundational serialization layer for converting in-memory telemetry configuration objects into the standardized text-based TMATS format used in IRIG 106-compliant telemetry files.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `DescriptionDecoder.GetDescription(Enum value)`
|
||||
- **Signature**: `public static string GetDescription(Enum value)`
|
||||
- **Behavior**: Retrieves the `DescriptionAttribute.Description` value associated with the given enum field. If no attribute exists, returns the enum's `ToString()` value.
|
||||
|
||||
### `MaxLengthDecoder.GetMaxLength(Enum value)`
|
||||
- **Signature**: `public static int GetMaxLength(Enum value)`
|
||||
- **Behavior**: Retrieves the `Length` property of the `MaxLengthAttribute` associated with the given enum field. If no attribute exists, returns `0`.
|
||||
|
||||
### `TMATSSection<T>.SetValue(T tag, string value)`
|
||||
- **Signature**: `public void SetValue(T tag, string value) where T : Enum`
|
||||
- **Behavior**: Stores the value for the specified enum tag in an internal dictionary.
|
||||
|
||||
### `TMATSSection<T>.GetValue(T tag)`
|
||||
- **Signature**: `public string GetValue(T tag) where T : Enum`
|
||||
- **Behavior**: Returns the stored value for the given tag, or `null` if not set.
|
||||
|
||||
### `TMATSSection<T>.SetDate(T tag, DateTime? value)`
|
||||
- **Signature**: `public void SetDate(T tag, DateTime? value)`
|
||||
- **Behavior**: Stores a date as `"MM-DD-YYYY"` string (e.g., `"11-20-2018"`), or an empty string if `value` is `null`.
|
||||
|
||||
### `TMATSSection<T>.GetDate(T tag)`
|
||||
- **Signature**: `public DateTime? GetDate(T tag)`
|
||||
- **Behavior**: Parses and returns a `DateTime?` from the stored value using `"MM-DD-YYYY"` format. Returns `null` if not set or invalid.
|
||||
|
||||
### `TMATSSection<T>.GetIntOrNull(T tag)`
|
||||
- **Signature**: `public int? GetIntOrNull(T tag)`
|
||||
- **Behavior**: Parses and returns an `int?` from the stored value. Returns `null` if not set or invalid.
|
||||
|
||||
### `TMATSSection<T>.SetIntOrNull(T tag, int? val)`
|
||||
- **Signature**: `public void SetIntOrNull(T tag, int? val)`
|
||||
- **Behavior**: Stores the integer as a string, or an empty string if `val` is `null`.
|
||||
|
||||
### `TMATSSection<T>.SetValueWithLength(T tag, string value)`
|
||||
- **Signature**: `public void SetValueWithLength(T tag, string value)`
|
||||
- **Behavior**: Stores the value. *Note: Length validation is currently disabled (commented out in source).*
|
||||
|
||||
### `TMATSSection<T>.Serialize()`
|
||||
- **Signature**: `public virtual string Serialize()`
|
||||
- **Behavior**: Serializes all non-empty tag-value pairs into lines of the format `Identifier\Attribute:value;` or `Identifier-N\Attribute:value;` if `_number >= 0`.
|
||||
|
||||
### `TMATSSection<T>.Serialize(T tag)`
|
||||
- **Signature**: `protected string Serialize(T tag)`
|
||||
- **Behavior**: Serializes a single tag-value pair. Returns `null` if value is empty/whitespace.
|
||||
|
||||
### `TMATSSection<T>` constructors
|
||||
- **`TMATSSection()`**: Default constructor for unnumbered sections.
|
||||
- **`TMATSSection(AttributeIdentifiers attribute, int number)`**: Constructor for numbered sections (e.g., per-channel PCM). Sets `_attribute` and `_number`.
|
||||
|
||||
### `TMATSectionNumbered<T>.SetValue(T tag, string value)`
|
||||
- **Signature**: `public void SetValue(T tag, string value) where T : Enum`
|
||||
- **Behavior**: Stores value for the given tag in internal dictionary.
|
||||
|
||||
### `TMATSectionNumbered<T>.GetValue(T tag)`
|
||||
- **Signature**: `public string GetValue(T tag) where T : Enum`
|
||||
- **Behavior**: Returns stored value for the tag, or `null`.
|
||||
|
||||
### `TMATSectionNumbered<T>.Serialize(int number)`
|
||||
- **Signature**: `public string Serialize(int number)`
|
||||
- **Behavior**: Serializes all non-empty tag-value pairs. Format:
|
||||
`Identifier-N\Attribute<number>:value;` if `Number > 0`, else `Identifier\Attribute<number>:value;`.
|
||||
|
||||
### `TMATSectionNumbered<T>.SetValueWithLength(T tag, string value)`
|
||||
- **Signature**: `public void SetValueWithLength(T tag, string value)`
|
||||
- **Behavior**: Calls `SetValue(tag, value)`. *Note: Length validation is currently disabled.*
|
||||
|
||||
### `TMATSectionNumberedArray<T>.SetValue(int number, T tag, string value)`
|
||||
- **Signature**: `public virtual void SetValue(int number, T tag, string value)`
|
||||
- **Behavior**: Ensures `_items` has `number` elements via `SetCount`, then calls `SetValueWithLength` on the `number`-th item (1-based index).
|
||||
|
||||
### `TMATSectionNumberedArray<T>.GetValue(int number, T tag)`
|
||||
- **Signature**: `public string GetValue(int number, T tag)`
|
||||
- **Behavior**: Returns value from the `number`-th item (1-based), or `null`.
|
||||
|
||||
### `TMATSectionNumberedArray<T>.Serialize()`
|
||||
- **Signature**: `public string Serialize()`
|
||||
- **Behavior**: Serializes all items. Includes a header line `Identifier-N\Tag:Count;` if `_numberedTag` is non-empty. Then serializes each item with its 1-based index.
|
||||
|
||||
### `TMATSectionNumberedArray<T>.SetCount(int count)`
|
||||
- **Signature**: `public void SetCount(int count)`
|
||||
- **Behavior**: Resizes `_items` list to `count`. Throws `Exception` if `count > _maxNumber`. If shrinking, truncates items; if expanding, creates new `TMATSectionNumbered<T>` instances with `_attributeIdentifier` and `_number` set.
|
||||
|
||||
### `TMATSectionNumberedArray<T>.GetCount()`
|
||||
- **Signature**: `public int GetCount() => _items.Count`
|
||||
|
||||
### `AttributeIdentifiers` enum
|
||||
- **Members**: `GeneralInformation`, `TransmitionAttributes`, `StorageSourceAttributes`, `MultiplexingAttributes`, `PCMFormatAttributes`, `PCMMeasurementDescription`, `BusDataAttributes`, `PacketFormatAttributes`, `PAMAttributes`, `DataConversionAttributes`, `AirborneHardwareAttributes`, `VendorSpecificAttributes`
|
||||
- **Behavior**: Each member has a `[Description]` attribute (e.g., `"G"`, `"P"`) used in serialization.
|
||||
|
||||
### `GeneralInformationGroup` class
|
||||
- **Key Properties**:
|
||||
- `ProgramName`, `TestItem`, `IRIG106RevisionLevel`, `OriginationDate`, etc.
|
||||
- `NumberOfDataSources`, `NumberOfPointsOfContact`
|
||||
- `PreTestRequirement`, `PostTestRequirement`
|
||||
- **Methods**:
|
||||
- `SetDataSourceField(int number, DataSourceIdentificationTags tag, string value)`
|
||||
Enforces uniqueness of `DataSourceID` (throws `Exception` if duplicate).
|
||||
- `SetDataSourceType(int number, DataSourceTypes sourceType)`
|
||||
- `SetContactField(int number, PointOfContactTags tag, string value)`
|
||||
- **Nested Types**:
|
||||
- `CommentSection`, `SecuritySection`, `Information` (with nested `PointOfContactTags`, `DataSourceIdentificationTags`, `DataSourceTypes`, `TestInformationTags`).
|
||||
- `Information.DataSourceIdentificationTags.DataSourceID` has `[MaxLength(32)]`.
|
||||
|
||||
### `PCM` class
|
||||
- **Key Properties**:
|
||||
- `DataLinkName`, `PCMCode`, `BitsPerSecond`, `DataRandomized`, `Polarity`, `DataDirection`, `TypeFormat`, `NumberOfBitsInCommonWordLength`, `WordTransferOrder`, `PCMWordParity`
|
||||
- **Constructors**:
|
||||
- `PCM(int number)` → calls `base(AttributeIdentifiers.PCMFormatAttributes, number)`
|
||||
- **Nested Types**:
|
||||
- `PCMTypeFormat` (section for type-specific attributes like `TypeFormat`, `CommonWordLength`, etc.)
|
||||
- `MinorFrameSection` (section for minor frame sync data)
|
||||
- `PCMTypeFormats`, `PCMWordTransferOrders`, `PCMWordParities`, `PCMCodes`, `Polarities`, `PCMDataDirections` enums.
|
||||
|
||||
### `MinorFrameSection` class
|
||||
- **Key Properties**:
|
||||
- `NumberOfMinorFramesInAMajorFrame`, `NumberOfWordsInMinorFrame`, `NumberOfBitsInMinorFrame`, `SyncLength`, `SynchronizationPattern`
|
||||
- **Constructor**: `MinorFrameSection(int number=1)` → `base(AttributeIdentifiers.PCMFormatAttributes, number)`
|
||||
|
||||
### `TMATSCreationTest.CreateTMATS()`
|
||||
- **Signature**: `public static string CreateTMATS()`
|
||||
- **Behavior**: Demonstrates usage by constructing a sample TMATS document for a PCM telemetry system with 4 channels (1 time, 2 PCM, 1 message data). Returns the serialized string.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Tag Uniqueness per Section**: In `GeneralInformationGroup.Information`, `DataSourceID` values must be unique across all data sources (enforced in `SetDataSourceField`).
|
||||
- **Numbered Sections**: Sections requiring numbering (e.g., PCM, MinorFrame) use `_number` to generate identifiers like `P-1\DLN:value;`.
|
||||
- **Date Format**: Dates are stored and parsed strictly as `"MM-DD-YYYY"` (e.g., `"11-20-2018"`).
|
||||
- **Enum Serialization**: Enum values are serialized using their `[Description]` attribute, falling back to `ToString()` if missing.
|
||||
- **Empty Value Handling**: Empty/whitespace values are skipped during serialization (`string.IsNullOrWhiteSpace`).
|
||||
- **Array Bounds**: `TMATSectionNumberedArray<T>.SetCount` enforces `_maxNumber` limit if set.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Internal Dependencies
|
||||
- **`System.ComponentModel.DataAnnotations`**: Used for `DescriptionAttribute`, `MaxLengthAttribute`.
|
||||
- **`System.Linq`**: Used for `Enum.GetValues`, `Cast<T>()`, `Any()`, `Take()`, `ToArray()`.
|
||||
- **`System.Text`**: Used for `StringBuilder`.
|
||||
- **`IRIGCh10.AttributeIdentifiers`**: Defines section identifiers (e.g., `"P"` for PCM).
|
||||
- **Nested enums** (e.g., `GeneralTags`, `InformationTags`, `DataSourceIdentificationTags`, `PCMAttributes`, `TypeFormatTags`, `MinorFrameTags`) define attribute names.
|
||||
|
||||
### External Dependencies
|
||||
- **`GeneralInformationGroup`** depends on `Information`, `CommentSection`, `SecuritySection`.
|
||||
- **`PCM`** depends on `PCMTypeFormat`, `MinorFrameSection`.
|
||||
- **`TMATSCreationTest.CreateTMATS()`** depends on `GeneralInformationGroup`, `Storage`, `PCM`, `MinorFrameSection`, `SubframeSync`, `MessageDataType` (not shown in source but referenced).
|
||||
|
||||
### Inferred Usage
|
||||
- The module is used by higher-level classes (e.g., `Storage`, `MessageDataType`) to serialize TMATS sections.
|
||||
- `DescriptionDecoder` and `MaxLengthDecoder` are utility classes used by `TMATSSection<T>`, `TMATSectionNumbered<T>`, and `TMATSectionNumberedArray<T>`.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Length Validation Disabled**: Both `SetValueWithLength` methods (`TMATSSection<T>`, `TMATSectionNumbered<T>`) *do not enforce* `MaxLengthAttribute`—the validation code is commented out. This is explicitly noted in comments:
|
||||
> *"maxlength is just a suggestion ..."*
|
||||
> *"apprently maxlength is just a suggestion ..."*
|
||||
- **DataSourceID Uniqueness Check**: `SetDataSourceField` checks for duplicates *only when setting `DataSourceID`*, but the check uses `_datasources.GetValue(number, tag)` *before* the new value is stored, which may not catch all edge cases (e.g., concurrent modifications).
|
||||
- **Indexing Inconsistency**: `TMATSectionNumberedArray<T>.SetValue` uses 1-based indexing for `number`, but internal `_items` list is 0-based (`_items[number - 1]`).
|
||||
- **Date Parsing Strictness**: `GetDate` uses `DateTime.TryParseExact` with `"MM-DD-YYYY"` format and `CultureInfo.InvariantCulture`. Any deviation (e.g., `"11/20/2018"`) will fail.
|
||||
- **Enum Parsing Fallbacks**: Enum property getters (e.g., `PCM.PCMCode`, `PCM.Polarity`) fall back to default values (`null`, `Normal`) if the stored string does not match any `Description`. This may mask serialization errors.
|
||||
- **Missing Section Types**: `SubframeSync`, `MessageDataType`, and `Storage` classes are referenced in `CreateTMATS` but not provided in the source files—behavior is inferred but not verifiable.
|
||||
- **Typo in Enum**: `AttributeIdentifiers.TransmitionAttributes` is misspelled (should be `"Transmission"`).
|
||||
@@ -0,0 +1,199 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/TMATS/DataConversion/DataConversionSection.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/TMATS/DataConversion/TelemetrySection.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/TMATS/DataConversion/CoefficientSection.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/TMATS/DataConversion/Measurand.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/TMATS/DataConversion/OtherInformationSection.cs
|
||||
- Common/DTS.Common.Serialization/IRIGCH10/TMATS/DataConversion/TransducerInformation.cs
|
||||
generated_at: "2026-04-16T03:44:20.663456+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "7f4dfba0264ee789"
|
||||
---
|
||||
|
||||
# Data Conversion Section Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module implements the TMATS (Telemetry and Tracking Attributes Standard) data conversion sections as defined in IRIG Chapter 10 specification (Chapter 9 of the TMATS document). It provides strongly-typed C# classes to represent and serialize various aspects of data conversion metadata—including conversion types, binary formats, polynomial coefficients, measurand descriptions, transducer information, and other measurement-related attributes—into the TMATS packet format used in IRIG 110-04 telemetry standards. These sections enable structured representation of how raw telemetry data is processed, calibrated, and interpreted for engineering analysis.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Enums
|
||||
|
||||
#### `DataConversionAttributes` (namespace `DTS.Serialization.IRIGCH10.Attributes`)
|
||||
- **`ConversionType`**: Attribute identifier `"DCT"` for specifying the data conversion type.
|
||||
|
||||
#### `ConversionTypes` (namespace `DTS.Serialization.IRIGCH10.Attributes`)
|
||||
- **`None`**: `"NON"` — No conversion applied.
|
||||
- **`PairSets`**: `"PRS"` — Conversion via pair sets.
|
||||
- **`Coefficients`**: `"COE"` — Polynomial coefficients (positive).
|
||||
- **`CoefficientsNegative`**: `"NPC"` — Polynomial coefficients (negative).
|
||||
- **`Derived`**: `"DER"` — Derived channel.
|
||||
- **`Discrete`**: `"DIS"` — Discrete (digital) channel.
|
||||
- **`PCMTime`**: `"PTM"` — PCM time channel.
|
||||
- **`Time1553`**: `"BTM"` — 1553 time channel.
|
||||
- **`DigitalVoice`**: `"VOI"` — Digital voice channel.
|
||||
- **`DigitalVideo`**: `"VID"` — Digital video channel.
|
||||
- **`SpecializedProcessing`**: `"SP"` — Specialized processing.
|
||||
- **`Other`**: `"OTH"` — Other conversion type.
|
||||
|
||||
#### `TelemetryAttributes` (namespace `DTS.Serialization.IRIGCH10.TMATS.DataConversion`)
|
||||
- **`BinaryFormat`**: Attribute identifier `"BFM"` for specifying binary data format.
|
||||
|
||||
#### `BinaryFormats` (namespace `DTS.Serialization.IRIGCH10.TMATS.DataConversion`)
|
||||
- **`Integer`**: `"INT"` — Integer format.
|
||||
- **`UnsignedBinary`**: `"UNS"` — Unsigned binary.
|
||||
- **`SignAndMagnitudeSig`**: `"SIG"` — Sign and magnitude (SIG).
|
||||
- **`SignAndMagnitudeSim`**: `"SIM"` — Sign and magnitude (SIM).
|
||||
- **`OnesCompliment`**: `"ONE"` — One’s complement.
|
||||
- **`TwosCompliment`**: `"TWO"` — Two’s complement.
|
||||
- **`OffsetBinary`**: `"OFF"` — Offset binary.
|
||||
- **`FloatingPoint`**: `"FPT"` — Floating point.
|
||||
- **`BinaryCodedDecimal`**: `"BCD"` — BCD.
|
||||
- **`BitWeight`**: `"BWT"` — Bit weight.
|
||||
- **`Other`**: `"OTH"` — Other format.
|
||||
|
||||
#### `CoefficientsAttributes` (namespace `DTS.Serialization.IRIGCH10.TMATS.DataConversion`)
|
||||
- **`OrderOfCurveFit`**: `"CO\\N"` — Polynomial order *n*.
|
||||
- **`DerivedFromPairSet`**: `"CO1"` — Indicates derivation from pair set.
|
||||
- **`Coefficient0`** to **`Coefficient7`**: `"CO"`, `"CO-1"` … `"CO-7"` — Polynomial coefficients (0th to 7th order).
|
||||
|
||||
#### `MeasurandAttributes` (namespace `DTS.Serialization.IRIGCH10.TMATS.DataConversion`)
|
||||
- **`Description`**: `"MN1"` — Measurand description (max 64 chars).
|
||||
- **`MeasurementAlias`**: `"MNA"` — Alternate name (max 32 chars).
|
||||
- **`ExcitationVoltage`**: `"MN2"` — Sensor excitation voltage in volts (max 10 chars).
|
||||
- **`EngineeringUnits`**: `"MN3"` — Engineering units (max 16 chars).
|
||||
- **`LinkType`**: `"MN4"` — Source data link type (max 3 chars).
|
||||
|
||||
#### `SourceDataTypeLinks` (namespace `DTS.Serialization.IRIGCH10.TMATS.DataConversion`)
|
||||
- **`FM`**: `"ANA"` — Analog (FM).
|
||||
- **`PCM`**: `"PCM"` — PCM.
|
||||
- **`PAM`**: `"PAM"` — PAM.
|
||||
- **`Other`**: `"OTH"` — Other.
|
||||
|
||||
#### `OtherInformationAttributes` (namespace `DTS.Serialization.IRIGCH10.Attributes`)
|
||||
- **`HighMeasurementValue`**: `"MOT1"` — Max engineering value (max 32 chars).
|
||||
- **`LowMeasurementValue`**: `"MOT2"` — Min engineering value (max 32 chars).
|
||||
- **`HighAlertLimitValue`**: `"MOT3"` — High alert limit (max 32 chars).
|
||||
- **`LowAlertLimitValue`**: `"MOT4"` — Low alert limit (max 32 chars).
|
||||
- **`HighWarningLimitValue`**: `"MOT5"` — High warning limit (max 32 chars).
|
||||
- **`LowWarningLimitValue`**: `"MOT6"` — Low warning limit (max 32 chars).
|
||||
- **`SampleRate`**: `"SR"` — Sample rate in samples/sec (max 6 chars).
|
||||
|
||||
#### `TransducerInformation` (namespace `DTS.Serialization.IRIGCH10.TMATS.DataConversion`)
|
||||
- **`MeasurementName`**: `"DCN"` — Measurement name (max 32 chars).
|
||||
- **`Type`**: `"TRD1"` — Sensor type (max 32 chars).
|
||||
- **`ModelNumber`**: `"TRD2"` — Model number (max 32 chars).
|
||||
- **`SerialNumber`**: `"TRD3"` — Serial number (max 32 chars).
|
||||
- **`SecurityClassification`**: `"TRD4"` — Classification code (max 2 chars).
|
||||
- **`OriginationDate`**: `"TRD5"` — Date in `MM-DD-YYYY` format (max 10 chars).
|
||||
- **`RevisionNumber`**: `"TRD6"` — Revision number (max 4 chars).
|
||||
- **`Orientation`**: `"TRD7"` — Physical orientation (max 32 chars).
|
||||
- **`PointOfContactName`**: `"POC1"` — POC name (max 32 chars).
|
||||
- **`PointOfContactAgency`**: `"POC2"` — POC agency (max 48 chars).
|
||||
- **`PointOfContectAddress`**: `"POC3"` — POC address (max 48 chars).
|
||||
- **`PointOfContactTelephone`**: `"POC4"` — POC telephone (max 20 chars).
|
||||
|
||||
#### `ClassificationTypes` (namespace `DTS.Serialization.IRIGCH10.TMATS.DataConversion`)
|
||||
- **`Unclassified`**: `"U"`
|
||||
- **`Confidential`**: `"C"`
|
||||
- **`Secret`**: `"S"`
|
||||
- **`TopSecret`**: `"T"`
|
||||
- **`Other`**: `"O"`
|
||||
|
||||
### Classes
|
||||
|
||||
#### `DataConversionSection`
|
||||
- **Constructor**: `DataConversionSection(int number)`
|
||||
Initializes the section with `AttributeIdentifiers.DataConversionAttributes` and given `number`.
|
||||
- **`SetConversionType(ConversionTypes type)`**:
|
||||
Sets the `"DCT"` attribute to the encoded description of `type` (e.g., `"COE"` for `Coefficients`).
|
||||
|
||||
#### `TelemetrySection`
|
||||
- **Constructor**: `TelemetrySection(int number)`
|
||||
Initializes the section with `AttributeIdentifiers.DataConversionAttributes` and given `number`.
|
||||
- **`SetBinaryFormat(BinaryFormats format)`**:
|
||||
Sets the `"BFM"` attribute to the encoded description of `format` (e.g., `"TWO"` for `TwosCompliment`).
|
||||
|
||||
#### `CoefficientSection`
|
||||
- **Constructor**: `CoefficientSection(int number)`
|
||||
Initializes the section with `AttributeIdentifiers.DataConversionAttributes` and given `number`.
|
||||
- **`OrderOfCurveFit`**: `int?`
|
||||
Gets/sets the `"CO\\N"` attribute (polynomial order *n*).
|
||||
- **`Coefficient0`**: `string`
|
||||
Gets/sets the `"CO"` attribute (0th-order coefficient, e.g., offset).
|
||||
- **`Coefficient1`**: `string`
|
||||
Gets/sets the `"CO-1"` attribute (1st-order coefficient, equivalent to bit weight).
|
||||
|
||||
#### `MeasurandSection`
|
||||
- **Constructor**: `MeasurandSection(int number)`
|
||||
Initializes the section with `AttributeIdentifiers.DataConversionAttributes` and given `number`.
|
||||
- **`Description`**: `string`
|
||||
Gets/sets `"MN1"` — Measurand description.
|
||||
- **`MeasurementAlias`**: `string`
|
||||
Gets/sets `"MNA"` — Alternate name.
|
||||
- **`ExcitationVoltage`**: `string`
|
||||
Gets/sets `"MN2"` — Sensor excitation voltage (volts).
|
||||
- **`EngineeringUnits`**: `string`
|
||||
Gets/sets `"MN3"` — Engineering units.
|
||||
- **`SetLinkType(SourceDataTypeLinks linkType)`**:
|
||||
Sets `"MN4"` to the encoded description of `linkType`.
|
||||
|
||||
#### `OtherInformationSection`
|
||||
- **Constructor**: `OtherInformationSection(int number)`
|
||||
Initializes the section with `AttributeIdentifiers.DataConversionAttributes` and given `number`.
|
||||
- **`HighMeasurementValue`**, **`LowMeasurementValue`**, **`HighAlertLimitValue`**, **`LowAlertLimitValue`**, **`HighWarningLimitValue`**, **`LowWarningLimitValue`**: `string`
|
||||
Gets/sets corresponding `"MOTx"` attributes (engineering unit limits).
|
||||
- **`SampleRate`**: `string`
|
||||
Gets/sets `"SR"` — Sample rate (samples/sec).
|
||||
|
||||
#### `TransducerInformationSection`
|
||||
- **Constructor**: `TransducerInformationSection(int number)`
|
||||
Initializes the section with `AttributeIdentifiers.DataConversionAttributes` and given `number`.
|
||||
- **`MeasurementName`**, **`Type`**, **`ModelNumber`**, **`SerialNumber`**, **`RevisionNumber`**, **`Orientation`**: `string`
|
||||
Gets/sets respective `"DCN"`, `"TRDx"`, `"TRD7"` attributes.
|
||||
- **`SecurityClassification`**: `string`
|
||||
Gets/sets `"TRD4"` — Classification code.
|
||||
- **`SetSecurityClassification(ClassificationTypes type, bool signalClassified, bool measurandClassified)`**:
|
||||
Sets `"TRD4"` to `type` description, optionally appending `"B"` (both), `"R"` (signal only), or `"E"` (measurand only).
|
||||
- **`OriginationDate`**: `DateTime?`
|
||||
Gets/sets `"TRD5"` — Date in `MM-DD-YYYY` format.
|
||||
- **`PointOfContact`**: `POC`
|
||||
Gets/sets POC data via `POC` class (see below).
|
||||
|
||||
#### `POC` (nested class in `TransducerInformationSection`)
|
||||
- **Properties**: `Name`, `Agency`, `Address`, `Telephone` (`string`).
|
||||
- **Constructors**: Parameterized and default.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- All sections inherit from `TMATSSection<T>` and are initialized with `AttributeIdentifiers.DataConversionAttributes`, indicating they belong to the *Data Conversion* TMATS section group.
|
||||
- Attribute values are stored as strings with explicit length encoding via `SetValueWithLength`.
|
||||
- Integer attributes (`OrderOfCurveFit`) use `GetIntOrNull`/`SetIntOrNull`, implying nullable integer handling.
|
||||
- Date values (`OriginationDate`) are serialized in strict `MM-DD-YYYY` format (e.g., `03-15-2023`); parsing is lenient (`DateTime.TryParse`).
|
||||
- Classification codes may be extended with suffixes (`B`, `R`, `E`) depending on `signalClassified`/`measurandClassified` flags.
|
||||
- String attributes have maximum lengths enforced via `[MaxLength]` attributes on enum fields (e.g., `Description` max 64 chars), though enforcement occurs at serialization time via `SetValueWithLength`.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Dependencies *of* this module:
|
||||
- **IRIGCh10.dll**: Provides base infrastructure (`TMATSSection<T>`, `AttributeIdentifiers`, `DescriptionDecoder`).
|
||||
- **System.ComponentModel**: Used for `[Description]` and `[MaxLength]` attributes.
|
||||
- **System.ComponentModel.DataAnnotations**: Used for `[MaxLength]`.
|
||||
|
||||
### Dependencies *on* this module:
|
||||
- Other TMATS section implementations (e.g., `TMATSSection<T>` base class).
|
||||
- Likely consumed by higher-level TMATS packet builders (e.g., `TMATSPacketBuilder`).
|
||||
- `DescriptionDecoder.GetDescription(Enum)` is used extensively to convert enum values to their IRIG-compliant string codes.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **Typo in POC property**: In `TransducerInformationSection.PointOfContact.get`, `Address` is incorrectly assigned from `PointOfContectAddress` *twice* (should be `PointOfContectAddress` for `Address`, `PointOfContactTelephone` for `Telephone`). This is likely a bug.
|
||||
- **Classification suffix logic**: The `SetSecurityClassification` method appends `"B"`, `"R"`, or `"E"` to the base classification code. This is non-standard and may be proprietary extension; verify against IRIG spec.
|
||||
- **`DerivedFromPairSet` attribute (`CO1`)**: Defined in `CoefficientsAttributes` but has no corresponding property or setter in `CoefficientSection`. Its purpose is unclear from source.
|
||||
- **`SampleRate` max length**: Only 6 characters — may truncate high-precision rates (e.g., `123456` Hz is valid, but `1.23456e5` may exceed limit).
|
||||
- **`OriginationDate` format**: Hardcoded as `MM-DD-YYYY` (e.g., `03-15-2023`). This differs from ISO 8601 and may cause parsing issues in non-US locales.
|
||||
- **No validation on coefficient values**: `Coefficient0`, `Coefficient1`, etc., accept arbitrary strings (including scientific notation), but no validation ensures syntactic correctness.
|
||||
- **`BinaryFormats.SignAndMagnitudeSig` vs `SignAndMagnitudeSim`**: Ambiguous naming (`SIG`/`SIM`) — unclear if these correspond to distinct IRIG codes or are implementation-specific variants.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user