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

14 KiB

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
DataPRO/Modules/Hardware/HardwareList/Model/HardwareChannelAssignment.cs
DataPRO/Modules/Hardware/HardwareList/Model/SLICE6TreeNode.cs
DataPRO/Modules/Hardware/HardwareList/Model/Hardware.cs
2026-04-16T04:38:28.250792+00:00 Qwen/Qwen3-Coder-Next-FP8 1 e010e06b613fee2c

HardwareList.Model Module Documentation

1. Purpose

This module provides data models and persistence logic for representing and managing hardware devices (DAS units) in the DataPRO diagnostics system. It defines core entities (HardwareChannelAssignment, SLICE6TreeNode, HardwareModel) that model hardware topology, channel assignments, and device metadata. The module enables querying device hierarchies (e.g., SLICE6DB parent-child relationships), persisting association changes to the database, and exposing hardware properties for UI binding (via INotifyPropertyChanged). It serves as the data layer for the Hardware List view, supporting configuration, sorting, filtering, and calibration tracking.

2. Public Interface

HardwareChannelAssignment

  • HardwareChannelAssignment(string channelNumber, string sensor, string name)
    Constructor. Initializes immutable properties with provided values. Represents a mapping between a hardware channel, its connected sensor type, and a user-defined name.

  • string ChannelNumber { get; }
    Channel identifier (e.g., "CH1", "A0").

  • string Sensor { get; }
    Type of sensor connected to the channel.

  • string Name { get; }
    User-assigned name for the channel.


SLICE6TreeNode

  • SLICE6TreeNode(int dasId, string serialNumber, int port, int number, int positionOnChain)
    Constructor. Initializes properties for a SLICE6 device node in a tree structure.

  • int DASId { get; set; }
    Primary key ID from the DAS database table.

  • string SerialNumber { get; set; }
    Device serial number.

  • int Port { get; set; }
    Physical port number on the S6DB (distributor) to which the device is connected.

  • string PortString { get; }
    Readable string representation of Port; returns "---" if Port < 0.

  • int Number { get; set; }
    Order of the device on the S6DB (i.e., its position index among siblings).

  • int PositionOnChain { get; set; }
    Position of the device within its daisy-chain on a given port.

  • string PositionOnChainString { get; }
    Readable string representation of PositionOnChain; returns "---" if PositionOnChain < 0.

  • static ISLICE6TreeNode[] GetAvailableTreeNodes(string serialNumberParent)
    Queries the database for all SLICE6 devices not associated with serialNumberParent. Returns an array of ISLICE6TreeNode instances sorted by SerialNumber. Returns empty array if serialNumberParent is null/empty.

  • static ISLICE6TreeNode[] GetTreeNodes(string serialNumberParent)
    Queries the database for all SLICE6 devices associated with serialNumberParent. Returns an array of ISLICE6TreeNode instances sorted by Number (i.e., PositionOnDistributor). Returns empty array if serialNumberParent is null/empty.

  • static void SwapNodes(string serialNumberA, string serialNumberB)
    Swaps all child devices between two SLICE6DB units (serialNumberA and serialNumberB) in the database. Note: There is a bug in the implementation—both listA and listB are associated to serialNumberB in the second Associate call, not serialNumberA and serialNumberB respectively.

  • static void SaveAssociations(string serialNumber, ISLICE6TreeNode[] attachedSLICE6)
    Commits the current association state of SLICE6 devices to a parent SLICE6DB (serialNumber). First clears all existing associations for serialNumber, then updates each device in attachedSLICE6 with its new ParentDAS, PositionOnDistributor, PositionOnChain, and Port.


HardwareModel

  • HardwareModel(IISOHardware d, ...)
    Constructor. Populates properties from an IISOHardware instance and calculates derived values (e.g., CalDueDate, ChannelCount). Requires calibration period parameters per hardware type.

  • int DASId { get; set; }
    Database ID of the device.

  • bool Disabled { get; set; }
    Whether the device is disabled.

  • string SerialNumber { get; set; }
    Device serial number.

  • string HardwareType { get; set; }
    Localized string description of the hardware type (e.g., "SLICE6_BASE").

  • string ChannelCount { get; set; }
    Human-readable string listing channel types and counts (e.g., "8 Analog, 2 Digital In").

  • bool HasIncludedChildren { get; set; }
    Indicates if this device has child devices marked as Included.

  • string Firmware { get; set; }
    Firmware version string.

  • double? MaxSampleRate { get; set; }
    Maximum supported sample rate (Hz); null if unknown or not applicable.

  • double TestSampleRate { get; set; }
    Current test/sample rate selected for the device.

  • double TestAAFilterRateHz { get; set; }
    Anti-aliasing filter rate (Hz) corresponding to TestSampleRate.

  • DateTime? CalDate { get; set; }
    Last calibration date.

  • DateTime? CalDueDate { get; set; }
    Calculated calibration due date based on CalDate and hardware-specific period.

  • string[] AvailableSampleRates { get; set; }
    Array of available sample rate strings (e.g., ["1000", "2000"]).

  • string SelectedSampleRateItem { get; set; }
    Currently selected sample rate string.

  • int SelectedSampleRateIndex { get; set; }
    Index of the current sample rate in _availableSampleRates. Setter updates TestSampleRate and TestAAFilterRateHz.

  • object Hardware { get; set; }
    Backing IISOHardware instance.

  • int AnalogChannels { get; set; }
    Number of analog input channels.

  • int SquibChannels { get; set; }
    Number of squib (explosive device) channels.

  • int DigitalInChannels { get; set; }, int DigitalOutChannels { get; set; }, int UartChannels { get; set; }, int StreamOutChannels { get; set; }, int StreamInChannels { get; set; }, int CanChannels { get; set; }
    Channel counts for respective interface types.

  • string IPAddress { get; set; }
    IP address or "USB" if connected via USB.

  • bool Included { get; set; }
    Whether the device is included in the current configuration.

  • double DSPStreamingFilter { get; set; }
    DSP streaming filter value.

  • DTS.Common.ClockSyncProfile MasterProfile { get; set; }, DTS.Common.ClockSyncProfile SlaveProfile { get; set; }
    Clock synchronization profiles (master/slave).

  • bool IsClockMaster { get; set; }
    Whether the device is configured as a clock master. Only valid if IsClockedDAS is true.

  • bool IsClockedDAS { get; }
    Returns true if the device type supports clocking (e.g., SLICE6, S6A_EthernetRecorder, TSR_AIR).

  • byte PTPDomainID { get; set; }
    PTP domain ID for precision time protocol.

  • bool IsPTPSync { get; }
    Returns true if PTP synchronization is active (E2E profile in use).

  • bool MixedRates { get; set; }
    Whether the device is part of a mixed-sample-rate configuration.

  • bool IsDistributor { get; }
    Returns true if the device is a distributor (e.g., SLICE6DB, SLICE_Distributor).

  • bool IsBattery { get; }
    Returns true if the device is a PowerPro.

  • bool IsTSRAIR { get; }
    Returns true if the device is a TSR_AIR or embedded sensor type.

  • bool IncludedAndNotMixedRatesAndCompactOrNotDistributor { get; }, bool IncludedAndMixedRatesAndCompact { get; }
    Derived UI flags for conditional rendering.

  • string ParentDAS { get; set; }
    Serial number of the parent device (distributor).

  • int PositionOnChain { get; set; }, int PositionOnDistributor { get; set; }, int Port { get; set; }
    Position metadata for hierarchical placement.

  • bool HasTreeView { get; set; }
    Indicates if a tree view should be shown for this device (e.g., for SLICE6DB).

  • string SerialNumberDisplay { get; }
    Display name: SerialNumber unless StandIn is true, in which case it returns the hardware type description.

  • static IHardware[] GetAvailableSLICE6DB(string serialNumber)
    Returns all SLICE6DB devices (including SLICE6DB_InDummy) not currently assigned to any parent, excluding serialNumber.

  • void DetermineChannelCount(bool showCompact, IHardware[] allHardware)
    Updates ChannelCount and MaxSampleRate based on device type and child devices. For distributors, calculates min sample rate among children if showCompact is true.

  • void SetIncluded(bool bIncluded), void SetMixedRates(bool mixedRates)
    Updates state and fires property change notifications.

  • bool Filter(string term)
    Returns true if SerialNumber, Firmware, or HardwareType contains term (case-insensitive).

  • class HardwareComparer : IComparer<IHardware>
    Implements sorting for IHardware objects. Supports sorting by HardwareListTags (e.g., SerialNumber, CalDate, FirstUseDate). Handles nulls and double?/DateTime? comparisons. FirstUseDate sorts nulls last when valid.


3. Invariants

  • SLICE6TreeNode

    • Port, Number, and PositionOnChain must be non-negative integers for valid hardware placements. Negative values are represented as "---" in UI via PortString/PositionOnChainString.
    • GetAvailableTreeNodes and GetTreeNodes only query devices with Type = SLICE6_Base and Position ≠ 'Prototype' (for GetAvailableTreeNodes).
    • SwapNodes assumes all child devices of both parents are retrieved in one query and re-associated. Bug: Both lists are associated to serialNumberB.
  • HardwareModel

    • CalDueDate is derived from CalDate (or FirstUseDate if IsFirstUseValid) plus a hardware-specific calibration period.
    • MaxSampleRate is null if d.MaxSampleRate is <= 0 or uint.MaxValue.
    • IsClockedDAS is determined by a fixed set of HardwareTypes.
    • Included and MixedRates flags affect derived properties (IncludedAndNotMixedRatesAndCompactOrNotDistributor, IncludedAndMixedRatesAndCompact).
    • ChannelCount for distributors is "N/A" if showCompact is false or no children exist.
  • General

    • All database operations use DTS.Common.Storage.DbOperations.GetSQLCommand() and explicitly dispose connections in finally blocks.
    • HardwareModel instances are constructed with a non-null HardwareListViewModel (_vm) reference for event callbacks.

4. Dependencies

Dependencies of this module:

  • DTS.Common.*

    • DTS.Common.Base.BasePropertyChanged (base class for SLICE6TreeNode)
    • DTS.Common.Storage.DbOperations (database access)
    • DTS.Common.Enums.Hardware.HardwareTypes (device type enumeration)
    • DTS.Common.Interface.DASFactory.Diagnostics.IISOHardware, IHardware (hardware abstraction interfaces)
    • DTS.Common.Converters.EnumDescriptionTypeConverter (localized enum descriptions)
    • DTS.Common.ClockSyncProfile (clock sync profiles)
  • HardwareList.Resources.StringResources

    • Used for localized strings (e.g., "Analog", "USB", "N/A").

Dependencies on this module:

  • HardwareList.HardwareListViewModel
    • Passed into HardwareModel constructor; used for event callbacks (FireSampleRate, FireClockMaster, etc.).
  • UI Layer
    • HardwareModel properties (e.g., Included, CalDueDate, ChannelCount) are bound to views.
    • SLICE6TreeNode is used to populate tree views for SLICE6DB hierarchies.
  • HardwareList Module
    • HardwareList.Model is the core data model for the HardwareList module.

5. Gotchas

  • SLICE6TreeNode.SwapNodes Bug:
    The Associate method is called twice—once for listA with serialNumberB, and again for listB also with serialNumberB. This means devices originally under serialNumberB are incorrectly moved to serialNumberB (no-op), and devices under serialNumberA are moved to serialNumberB, but the reverse move does not occur. The intended behavior is likely Associate(serialNumberB, listA) and Associate(serialNumberA, listB).

  • HardwareModel.CalDueDate Calculation:
    Uses FirstUseDate only if IsFirstUseValid is true. If FirstUseDate is null and IsFirstUseValid is true, it defaults to DateTime.Today. This may cause unexpected recalculations if FirstUseDate is set later.

  • HardwareModel.TestSampleRate Setter Side Effect:
    Setting TestSampleRate triggers OnPropertyChanged("SelectedSampleRateIndex"), but the getter for SelectedSampleRateIndex re-computes SelectedSampleRateItem and calls _vm.FireSampleRate. This could cause redundant UI updates if TestSampleRate is set multiple times.

  • HardwareModel.DetermineChannelCount for Distributors:
    MaxSampleRate is recalculated as the minimum sample rate of child devices. If children have no sample rate (null), ChannelCount becomes "N/A" and MaxSampleRate is set to null. This may mask missing configuration.

  • HardwareModel.Filter Case Sensitivity:
    Filtering is case-insensitive (term.ToLower()), but SerialNumberDisplay uses isoHW.StandIn logic, which may cause display mismatches if StandIn is toggled dynamically.

  • HardwareModel.Hardware is object:
    The Hardware property is typed as object, requiring casting to IISOHardware for type-specific checks (e.g., IsClockedDAS, IsDistributor). This risks runtime errors if the underlying type is not IISOHardware.

  • SLICE6TreeNode SQL Injection Risk:
    GetAvailableTreeNodes uses string interpolation for HardwareTypes.SLICE6_Base in the WHERE clause ([(int)HardwareTypes.SLICE6_Base]). While the enum value is fixed, this pattern is fragile and error-prone.

  • HardwareModel Constructor Side Effects:
    The constructor calls d.GetChannelsString(...) and computes CalDueDate based on d.DASTypeEnum. If Hardware is null or DASTypeEnum is invalid, it throws ArgumentOutOfRangeException.

  • HardwareComparer.NumericCompare Logic:
    For double/DateTime, a > b returns -1 (descending order), but the method returns 1 for all other cases. This may cause inconsistent sorting if types are mixed (e.g., double vs DateTime).