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

12 KiB

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
DataPRO/Modules/TestSetups/Imports/TTS/ViewModel/DigitalOutputChannelsViewModel.cs
DataPRO/Modules/TestSetups/Imports/TTS/ViewModel/LevelTriggerViewModel.cs
DataPRO/Modules/TestSetups/Imports/TTS/ViewModel/DigitalInputChannelsViewModel.cs
DataPRO/Modules/TestSetups/Imports/TTS/ViewModel/TOMChannelsViewModel.cs
2026-04-17T15:49:35.967692+00:00 zai-org/GLM-5-FP8 1 038dac49bea7aac0

TTS Import ViewModels Documentation

1. Purpose

This module provides four ViewModel classes for managing channel configuration within a TTS (Test Setup) Import workflow. Each ViewModel handles a specific channel type—Digital Output, Digital Input, Level Triggers, and TOM (Squib) channels—facilitating the mapping between physical hardware channels (IDASHardware/IHardwareChannel) and logical channel records (ITTSChannelRecord) in test setups. The ViewModels coordinate via IEventAggregator to respond to hardware scan results, file imports, and channel assignment changes, providing UI binding properties and commands for user interaction.


2. Public Interface

DigitalOutputChannelsViewModel

Implements: IDigitalOutputChannelsViewModel

Member Signature Description
View public IDigitalOutputChannelsView View { get; set; } The associated view instance; DataContext is set to this in constructor.
NotificationRequest public InteractionRequest<Notification> NotificationRequest { get; } Used to raise notification dialogs.
ConfirmationRequest public InteractionRequest<Confirmation> ConfirmationRequest { get; } Used to raise confirmation dialogs.
DASChannels public ObservableCollection<DASChannel> DASChannels { get; set; } Collection of digital output channels from hardware.
SelectedDASChannel public DASChannel SelectedDASChannel { get; set; } Currently selected DAS channel in UI.
EnableOrDisableText public string EnableOrDisableText { get; } Returns localized "Enable" or "Disable" text based on SelectedDASChannel.Channel.Disabled.
IsBusy public bool IsBusy { get; set; } Bound to busy indicator state.
IsMenuIncluded public bool IsMenuIncluded { get; set; } Unclear purpose from source alone.
IsNavigationIncluded public bool IsNavigationIncluded { get; set; } Unclear purpose from source alone.
IsDirty public bool IsDirty { get; private set; } Indicates unsaved changes (never set to true in visible source).
Cleanup() public void Cleanup() Empty implementation.
CleanupAsync() public Task CleanupAsync() Returns Task.CompletedTask.
Initialize() public void Initialize() Empty implementation.
Initialize(object) public void Initialize(object parameter) Empty implementation.
Initialize(object, object) public void Initialize(object parameter, object model) Empty implementation.
InitializeAsync() public Task InitializeAsync() Returns Task.CompletedTask.
InitializeAsync(object) public Task InitializeAsync(object parameter) Returns Task.CompletedTask.
Activated() public void Activated() Empty implementation.
OnPropertyChanged(string) public void OnPropertyChanged(string propertyName) Raises PropertyChanged event.
PropertyChanged public event PropertyChangedEventHandler PropertyChanged Standard INotifyPropertyChanged event.

LevelTriggerViewModel

Implements: ILevelTriggerViewModel

Member Signature Description
View public ILevelTriggerView View { get; set; } The associated view instance.
LevelTriggers public ILevelTrigger[] LevelTriggers { get; } Returns _setup?.LevelTriggers; provides access to level trigger configurations.
IsBusy, IsMenuIncluded, IsNavigationIncluded, IsDirty Same as above Standard state properties.
NotificationRequest, ConfirmationRequest Same as above Interaction requests.
Lifecycle methods (Cleanup, Initialize, etc.) Same signatures as above All return empty or Task.CompletedTask.
OnPropertyChanged(string) Same as above Raises PropertyChanged event.
PropertyChanged Same as above INotifyPropertyChanged event.

DigitalInputChannelsViewModel

Implements: IDigitalInputChannelsViewModel

Member Signature Description
View public IDigitalInputChannelsView View { get; set; } The associated view instance.
DASChannels public ObservableCollection<DASChannel> DASChannels { get; set; } Physical digital input channels from hardware.
RemainingChannels public ObservableCollection<ITTSChannelRecord> RemainingChannels { get; set; } Channel records not yet assigned to hardware.
SelectedDASChannel public DASChannel SelectedDASChannel { get; set; } Currently selected hardware channel.
SelectedRemainingChannel public ITTSChannelRecord SelectedRemainingChannel { get; set; } Currently selected unassigned channel record.
AssignEnabled public bool AssignEnabled { get; set; } Enables/disables Assign button in UI.
RemoveEnabled public bool RemoveEnabled { get; set; } Enables/disables Remove button in UI.
EnableOrDisableEnabled public bool EnableOrDisableEnabled { get; set; } Enables/disables Enable/Disable button.
EnableOrDisableText public string EnableOrDisableText { get; } Localized "Enable" or "Disable" text.
AssignCommand public DelegateCommand AssignCommand { get; } Assigns SelectedRemainingChannel to SelectedDASChannel.
RemoveCommand public DelegateCommand RemoveCommand { get; } Removes channel assignment from SelectedDASChannel.
EnableOrDisableCommand public DelegateCommand EnableOrDisableCommand { get; } Toggles Disabled state on selected channel.
Other members Same as above IsBusy, IsDirty, lifecycle methods, PropertyChanged.

TOMChannelsViewModel

Implements: ITOMChannelsViewModel

Member Signature Description
View public ITOMChannelsView View { get; set; } The associated view instance.
DASChannels public ObservableCollection<Model.DASChannel> DASChannels { get; set; } Physical squib channels from hardware (every other channel, i += 2).
RemainingChannels public ObservableCollection<ITTSChannelRecord> RemainingChannels { get; set; } Unassigned squib channel records.
SelectedDASChannel public Model.DASChannel SelectedDASChannel { get; set; } Currently selected squib hardware channel.
SelectedRemainingChannel public ITTSChannelRecord SelectedRemainingChannel { get; set; } Currently selected unassigned squib record.
AssignCommand, RemoveCommand, EnableOrDisableCommand Same as DigitalInputChannelsViewModel Same command implementations for squib channels.
Other members Same as above Standard state properties and lifecycle methods.

3. Invariants

  1. Singleton Lifetime: All four ViewModels are decorated with [PartCreationPolicy(CreationPolicy.Shared)], ensuring a single shared instance per container.

  2. Event Subscription Thread Affinity: All IEventAggregator subscriptions use ThreadOption.PublisherThread with keepSubscriberReferenceAlive = true, meaning handlers execute on the publisher's thread and subscribers are held strongly.

  3. UI Thread Requirement: OnAssignedChannelsChangedEvent in DigitalOutputChannelsViewModel, DigitalInputChannelsViewModel, and TOMChannelsViewModel explicitly check Application.Current.Dispatcher.CheckAccess() and marshal to the UI thread via BeginInvoke if necessary.

  4. Hardware Channel Filtering:

    • DigitalOutputChannelsViewModel: Filters for ch.IsDigitalOut == true
    • DigitalInputChannelsViewModel: Filters for ch.IsDigitalIn == true
    • TOMChannelsViewModel: Filters for ch.IsSquib == true and iterates by i += 2 (squib channels are paired)
  5. Channel Record Validation: All ViewModels skip channel records where:

    • channelRecord.IsEmptyRecord == true
    • channelRecord.IsChannelCodeValid == false
    • channelRecord.ChannelCode == TTSChannelRecord.NONE
  6. EID Mapping: DigitalOutputChannelsViewModel and LevelTriggerViewModel maintain a mapping (_hardwareChannelIdToSensorId / _sensorIdToChannelId) from EIDMappingEvent for sensor-to-channel resolution.


4. Dependencies

External Dependencies (from imports)

  • Prism Framework: Prism.Events, Prism.Regions, Prism.Commands — Event aggregation, region management, delegate commands.
  • Unity: Unity — Dependency injection container (IUnityContainer).
  • MEF: System.ComponentModel.Composition — Part creation policy.
  • WPF: System.Windows, System.Windows.Data, System.Collections.ObjectModel — UI collections and dispatcher.

Internal Dependencies (DTS.* namespaces)

  • DTS.Common.Events / DTS.Common.Events.TTSImport — Event types: RaiseNotification, BusyIndicatorChangeNotification, AssignedChannelsChangedEvent, TTSImportHardwareScanFinishedEvent, EIDMappingEvent, TTSImportReadFileStatusEvent, TTSImportSavedChangesStatusEvent, TTSImportTestSetupChangedEvent.
  • DTS.Common.Interface.DataRecordersIDASHardware, IHardwareChannel.
  • DTS.Common.Interface.TestSetups.Imports.TTS.*ITTSSetup, ITTSChannelRecord, ILevelTrigger, view interfaces.
  • DTS.Common.InteractivityInteractionRequest<T>, Notification, Confirmation, NotificationContentEventArgs.
  • DTS.Common.EnumsDigitalInputModes, ExcitationVoltageOptions.
  • TTSImport.ModelDASChannel model class.
  • TTSImport.ResourcesStringResources for localized strings.

Consumers

  • Unclear from source alone; these ViewModels are likely resolved by the DI container and bound to their respective Views (IDigitalOutputChannelsView, ILevelTriggerView, etc.).

5. Gotchas

  1. Logic Bug in DetermineRemoveEnableStatus (present in DigitalInputChannelsViewModel and TOMChannelsViewModel):

    if (!string.IsNullOrWhiteSpace(_selectedDASChannel.EID) &&
        _selectedDASChannel.EID == _selectedDASChannel.Channel.SensorEID)
    {
        RemoveEnabled = false;
    }
    RemoveEnabled = true;  // This always overwrites the above!
    

    The RemoveEnabled = true assignment always executes, making the preceding conditional check ineffective.

  2. Empty Async Lifecycle Methods: All InitializeAsync and CleanupAsync methods return Task.CompletedTask with no actual async work. This may indicate incomplete implementation or a placeholder pattern.

  3. IsDirty Never Set to true: The IsDirty property has a private setter but is never assigned true anywhere in the visible source. Its purpose is unclear.

  4. Historical Bug References in Comments (LevelTriggerViewModel.cs):

    • Comment references "11245" and "15643" (likely defect tracking IDs) describing edge cases around EID assignment and channel code validation.
    • A comment notes: "the below condition I think was missing a not" indicating past confusion about boolean logic.
  5. Squib Channel Pairing (TOMChannelsViewModel): Hardware channels are iterated with i += 2, implying squib channels are paired (voltage/initiation vs. current). This is not documented elsewhere and could cause confusion if the hardware configuration changes.

  6. Task.Run for MessageBox (DigitalInputChannelsViewModel.Assign and TOMChannelsViewModel.Assign): The code uses Task.Run(() => MessageBox.Show(...)) followed by Application.Current.Dispatcher.BeginInvoke for the actual assignment work. This pattern is unusual—MessageBox is typically shown on the UI thread directly.

  7. Pre-Assigned Channels Logic (LevelTriggerViewModel.UpdateLevelTriggers): The method modifies _setup.PreAssignedSensorIdAndHwId in-place, reassigning it to a filtered list. This mutates shared state that may be observed elsewhere.

  8. Exception Swallowing (LevelTriggerViewModel.VoltageIsValid): The method contains an empty catch { } block that silently ignores exceptions from GetExcitationVoltageEnumFromMagnitude, returning false for invalid voltages.