1098 lines
53 KiB
C#
1098 lines
53 KiB
C#
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.ComponentModel;
|
|||
|
|
using System.ComponentModel.Composition;
|
|||
|
|
using System.Globalization;
|
|||
|
|
using System.IO;
|
|||
|
|
using System.Linq;
|
|||
|
|
using System.Text;
|
|||
|
|
using System.Threading;
|
|||
|
|
using System.Threading.Tasks;
|
|||
|
|
using System.Windows;
|
|||
|
|
using DTS.Common.Base;
|
|||
|
|
using DTS.Common.Classes;
|
|||
|
|
using DTS.Common.Enums;
|
|||
|
|
using DTS.Common.Enums.TTS;
|
|||
|
|
using DTS.Common.Events;
|
|||
|
|
using DTS.Common.Interface;
|
|||
|
|
using DTS.Common.Interface.TestSetups.Imports.TTS.ReadFile;
|
|||
|
|
using DTS.Common.Utilities.Logging;
|
|||
|
|
using DTS.Common.Utils;
|
|||
|
|
using Prism.Events;
|
|||
|
|
using Unity;
|
|||
|
|
using DTS.Common.Interactivity;
|
|||
|
|
using Prism.Regions;
|
|||
|
|
using Prism.Commands;
|
|||
|
|
using TTSImport.Model;
|
|||
|
|
using TTSImport.Properties;
|
|||
|
|
using DTS.SensorDB;
|
|||
|
|
using TTSImport.Resources;
|
|||
|
|
using DTS.Common.Interface.Sensors;
|
|||
|
|
using DTS.Common.Classes.Groups.ChannelSettings;
|
|||
|
|
using DTS.Common.Enums.Sensors;
|
|||
|
|
|
|||
|
|
// ReSharper disable CheckNamespace
|
|||
|
|
// ReSharper disable MemberCanBePrivate.Global
|
|||
|
|
// ReSharper disable InconsistentNaming
|
|||
|
|
|
|||
|
|
namespace TTSImport
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// this class handles ReadFile functionality
|
|||
|
|
/// </summary>
|
|||
|
|
[PartCreationPolicy(CreationPolicy.Shared)]
|
|||
|
|
public class ReadFileViewModel : IReadFileViewModel
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// The Status and Progress bars
|
|||
|
|
/// </summary>
|
|||
|
|
public IStatusAndProgressBarView StatusAndProgressBarView { get; private set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// The ReadFile view
|
|||
|
|
/// </summary>
|
|||
|
|
public IReadFileView View { get; set; }
|
|||
|
|
|
|||
|
|
private string _fileToImport = string.Empty;
|
|||
|
|
|
|||
|
|
public string FileToImport
|
|||
|
|
{
|
|||
|
|
get => _fileToImport;
|
|||
|
|
set
|
|||
|
|
{
|
|||
|
|
_fileToImport = value;
|
|||
|
|
OnPropertyChanged("FileToImport");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private IEventAggregator _eventAggregator { get; set; }
|
|||
|
|
private IRegionManager _regionManager;
|
|||
|
|
private IUnityContainer UnityContainer { get; set; }
|
|||
|
|
|
|||
|
|
public InteractionRequest<Notification> NotificationRequest { get; private set; }
|
|||
|
|
public InteractionRequest<Confirmation> ConfirmationRequest { get; private set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Creates a new instance of the TechnologyDomainEditViewModel.
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="readFileView">The ReadFile View.</param>
|
|||
|
|
/// <param name="view"></param>
|
|||
|
|
/// <param name="regionManager">The logical placeholder defined within the application's UI (in the shell or within views) into which views are displayed.</param>
|
|||
|
|
/// <param name="eventAggregator">The EventAggregator which allows different components to publish/subscribe to events without being coupled to each other.</param>
|
|||
|
|
/// <param name="unityContainer">The unityContainer.</param>
|
|||
|
|
public ReadFileViewModel(IReadFileView view, IRegionManager regionManager, IEventAggregator eventAggregator,
|
|||
|
|
IUnityContainer unityContainer)
|
|||
|
|
{
|
|||
|
|
View = view;
|
|||
|
|
View.DataContext = this;
|
|||
|
|
|
|||
|
|
NotificationRequest = new InteractionRequest<Notification>();
|
|||
|
|
ConfirmationRequest = new InteractionRequest<Confirmation>();
|
|||
|
|
|
|||
|
|
_eventAggregator = eventAggregator;
|
|||
|
|
UnityContainer = unityContainer;
|
|||
|
|
_regionManager = regionManager;
|
|||
|
|
_eventAggregator.GetEvent<RaiseNotification>().Subscribe(OnRaiseNotification);
|
|||
|
|
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>()
|
|||
|
|
.Subscribe(OnBusyIndicatorNotification, ThreadOption.PublisherThread, true);
|
|||
|
|
_eventAggregator.GetEvent<TTSImportReadXMLFileResponseEvent>()
|
|||
|
|
.Subscribe(OnXMLFileRead, ThreadOption.UIThread, true);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#region Methods
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// handles when an XML TTS file has been read
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="arg"></param>
|
|||
|
|
private void OnXMLFileRead(TTSImportReadXMLFileResponseEventArg arg)
|
|||
|
|
{
|
|||
|
|
if (null != arg.TestSetup && null != arg.TTSSetup && !arg.Errors.Any())
|
|||
|
|
{
|
|||
|
|
ProcessToyotaXMLFile(arg);
|
|||
|
|
//let any consumers know that file has been read and processed
|
|||
|
|
var statusArg = new ReadFileStatusArg { Status = true, TTSSetup = arg.TTSSetup };
|
|||
|
|
_eventAggregator.GetEvent<TTSImportReadFileStatusEvent>().Publish(statusArg);
|
|||
|
|
//mark as done
|
|||
|
|
SetStatus(StringResources.ImportTestSetup_PossibleStatus_Done);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
//if we have an error message push it to user
|
|||
|
|
if (arg.Errors.Any())
|
|||
|
|
{
|
|||
|
|
_eventAggregator.GetEvent<PageErrorEvent>().Publish(new PageErrorArg(arg.Errors, null));
|
|||
|
|
}
|
|||
|
|
//finally, mark as failed
|
|||
|
|
SetStatus(StringResources.ImportTestSetup_PossibleStatus_Failed);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void Cleanup() //Duplicate of ImportTestSetup
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public Task CleanupAsync()
|
|||
|
|
{
|
|||
|
|
return Task.CompletedTask;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void Initialize()
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void Initialize(object parameter)
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void Initialize(object parameter, object model)
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public Task InitializeAsync()
|
|||
|
|
{
|
|||
|
|
StatusAndProgressBarView = GetStatusAndProgressBarView(this);
|
|||
|
|
return Task.CompletedTask;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public Task InitializeAsync(object parameter)
|
|||
|
|
{
|
|||
|
|
return Task.CompletedTask;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void Activated()
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Private Event handler for OnBusyIndicatorNotification event.
|
|||
|
|
/// </summary>
|
|||
|
|
private void OnBusyIndicatorNotification(bool eventArg)
|
|||
|
|
{
|
|||
|
|
IsBusy = eventArg;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Private Event handler for RaiseNotification event.
|
|||
|
|
/// </summary>
|
|||
|
|
private void OnRaiseNotification(NotificationContentEventArgs eventArgsWithTitle)
|
|||
|
|
{
|
|||
|
|
// The NotificationRequest.Raise triggers the Invoke() method of the PopupWindowAction object to show the NotificationWindow window
|
|||
|
|
// Notification object expects a NotificationContentEventArgsWithoutTitle object and a Title string.
|
|||
|
|
var eventArgsWithoutTitle = new NotificationContentEventArgs(eventArgsWithTitle.Message, "",
|
|||
|
|
eventArgsWithTitle.Image, string.Empty);
|
|||
|
|
|
|||
|
|
NotificationRequest.Raise(new Notification
|
|||
|
|
{
|
|||
|
|
Content = eventArgsWithoutTitle,
|
|||
|
|
Title = eventArgsWithTitle.Title
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private readonly StatusAndProgressBarEventArgs statusAndProgressBarEventArgs = new StatusAndProgressBarEventArgs();
|
|||
|
|
|
|||
|
|
public void SetStatus(string status)
|
|||
|
|
{
|
|||
|
|
SetStatus(status, string.Empty);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Sets the text, background color, progress value, and/or progress visibility
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="status"></param>
|
|||
|
|
public void SetStatus(string status, string error)
|
|||
|
|
{
|
|||
|
|
switch (status)
|
|||
|
|
{
|
|||
|
|
case "Waiting": //change this to string resources but use the same one in DataPRO and here???
|
|||
|
|
statusAndProgressBarEventArgs.StatusColor =
|
|||
|
|
DTS.Common.BrushesAndColors.Brush_ApplicationStatus_Waiting.Color;
|
|||
|
|
statusAndProgressBarEventArgs.ProgressBarVisibility = Visibility.Collapsed;
|
|||
|
|
break;
|
|||
|
|
case "Working":
|
|||
|
|
statusAndProgressBarEventArgs.StatusColor =
|
|||
|
|
DTS.Common.BrushesAndColors.Brush_ApplicationStatus_Busy.Color;
|
|||
|
|
statusAndProgressBarEventArgs.ProgressValue = 0;
|
|||
|
|
statusAndProgressBarEventArgs.ProgressBarVisibility = Visibility.Visible;
|
|||
|
|
break;
|
|||
|
|
case "Failed":
|
|||
|
|
statusAndProgressBarEventArgs.StatusColor =
|
|||
|
|
DTS.Common.BrushesAndColors.Brush_ApplicationStatus_Failed.Color;
|
|||
|
|
statusAndProgressBarEventArgs.ProgressBarVisibility = Visibility.Collapsed;
|
|||
|
|
break;
|
|||
|
|
case "Done":
|
|||
|
|
statusAndProgressBarEventArgs.StatusColor =
|
|||
|
|
DTS.Common.BrushesAndColors.Brush_ApplicationStatus_Complete.Color;
|
|||
|
|
statusAndProgressBarEventArgs.ProgressBarVisibility = Visibility.Collapsed;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
statusAndProgressBarEventArgs.StatusText = status;
|
|||
|
|
statusAndProgressBarEventArgs.ErrorText = error;
|
|||
|
|
|
|||
|
|
statusAndProgressBarEventArgs.Requester = this;
|
|||
|
|
_eventAggregator.GetEvent<StatusAndProgressBarEvent>().Publish(statusAndProgressBarEventArgs);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Sets the progress value on the Status and Progress bar
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="progress"></param>
|
|||
|
|
public void SetProgress(double progress)
|
|||
|
|
{
|
|||
|
|
statusAndProgressBarEventArgs.ProgressValue = (int)progress;
|
|||
|
|
statusAndProgressBarEventArgs.Requester = this;
|
|||
|
|
_eventAggregator.GetEvent<StatusAndProgressBarEvent>().Publish(statusAndProgressBarEventArgs);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private IStatusAndProgressBarView GetStatusAndProgressBarView(IBaseViewModel parent)
|
|||
|
|
{
|
|||
|
|
var view = UnityContainer.Resolve<IStatusAndProgressBarView>();
|
|||
|
|
var viewModel = UnityContainer.Resolve<IStatusAndProgressBarViewModel>();
|
|||
|
|
view.DataContext = viewModel;
|
|||
|
|
viewModel.Initialize(parent);
|
|||
|
|
return view;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Browse to import file
|
|||
|
|
/// </summary>
|
|||
|
|
private DelegateCommand _browseClicked;
|
|||
|
|
|
|||
|
|
public DelegateCommand BrowseClicked => _browseClicked ?? (_browseClicked = new DelegateCommand(BrowseMethod));
|
|||
|
|
|
|||
|
|
public void BrowseMethod()
|
|||
|
|
{
|
|||
|
|
FileToImport = string.Empty;
|
|||
|
|
using (var fo = new System.Windows.Forms.OpenFileDialog())
|
|||
|
|
{
|
|||
|
|
fo.CheckFileExists = true;
|
|||
|
|
fo.CheckPathExists = true;
|
|||
|
|
fo.Filter = @"TTS (*.csv, *.xml)|*.csv; *.xml|All Files (*.*)|*.*";
|
|||
|
|
fo.FilterIndex = Settings.Default.DefaultTestImportMethod;
|
|||
|
|
if (fo.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;
|
|||
|
|
Settings.Default.DefaultTestImportMethod = fo.FilterIndex;
|
|||
|
|
Settings.Default.Save();
|
|||
|
|
FileToImport = fo.FileName;
|
|||
|
|
}
|
|||
|
|
ReadFile(FileToImport, _defaultSampleRate, _defaultRecordingMode, _defaultTTSPreTrigger, _defaultTTSPostTrigger,
|
|||
|
|
_defaultTTSROIStart, _defaultTTSROIEnd, _defaultRequireEIDsFound, _defaultDigitalInputMode, _squibDefaults);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void ReadFile(string importFile, double defaultSampleRate, RecordingModes defaultRecordingMode, double defaultTTSPreTrigger, double defaultTTSPostTrigger,
|
|||
|
|
double defaultTTSROIStart, double defaultTTSROIEnd, bool defaultRequireEIDsFound, string defaultDigitalInputMode, ISquibSettingDefaults squibDefaults)
|
|||
|
|
{
|
|||
|
|
SetStatus(StringResources.ImportTestSetup_PossibleStatus_Working);
|
|||
|
|
FileToImport = importFile;
|
|||
|
|
_defaultSampleRate = defaultSampleRate;
|
|||
|
|
_defaultRecordingMode = defaultRecordingMode;
|
|||
|
|
_defaultTTSPreTrigger = defaultTTSPreTrigger;
|
|||
|
|
_defaultTTSPostTrigger = defaultTTSPostTrigger;
|
|||
|
|
_defaultTTSROIStart = defaultTTSROIStart;
|
|||
|
|
_defaultTTSROIEnd = defaultTTSROIEnd;
|
|||
|
|
_defaultRequireEIDsFound = defaultRequireEIDsFound;
|
|||
|
|
_defaultDigitalInputMode = defaultDigitalInputMode;
|
|||
|
|
_squibDefaults = squibDefaults;
|
|||
|
|
var data = new WorkFunctionThreadData();
|
|||
|
|
ThreadPool.QueueUserWorkItem(ReadFileWorkThread, data);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void SetAppBusy()
|
|||
|
|
{
|
|||
|
|
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(true);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void SetAppAvailable()
|
|||
|
|
{
|
|||
|
|
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>().Publish(false);
|
|||
|
|
}
|
|||
|
|
private void ReadFileWorkThread(object obj)
|
|||
|
|
{
|
|||
|
|
SetAppBusy();
|
|||
|
|
//_sensorSerialToHwId.Clear();
|
|||
|
|
var data = obj as WorkFunctionThreadData;
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
ITTSSetup setup;
|
|||
|
|
string error = string.Empty;
|
|||
|
|
ReadFileStatusArg statusArg;
|
|||
|
|
switch (Path.GetExtension(FileToImport))
|
|||
|
|
{
|
|||
|
|
case ".csv":
|
|||
|
|
setup = ProcessToyotaCSVFile(FileToImport, ref error);
|
|||
|
|
if (setup == null)
|
|||
|
|
{
|
|||
|
|
statusArg = new ReadFileStatusArg { Status = false, ErrorMessage = error };
|
|||
|
|
_eventAggregator.GetEvent<TTSImportReadFileStatusEvent>().Publish(statusArg);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
if (!string.IsNullOrWhiteSpace(error))
|
|||
|
|
{
|
|||
|
|
_eventAggregator.GetEvent<PageErrorEvent>().Publish(new PageErrorArg(new[] { error }, null));
|
|||
|
|
}
|
|||
|
|
statusArg = new ReadFileStatusArg { Status = true, TTSSetup = setup };
|
|||
|
|
_eventAggregator.GetEvent<TTSImportReadFileStatusEvent>().Publish(statusArg);
|
|||
|
|
SetStatus(StringResources.ImportTestSetup_PossibleStatus_Done);
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case ".xml":
|
|||
|
|
_eventAggregator.GetEvent<AppStatusEvent>().Publish(AppStatusArg.Busy);
|
|||
|
|
var setupToPass = new TTSTestSetup() { SquibDefaults = _squibDefaults };
|
|||
|
|
_eventAggregator.GetEvent<TTSImportReadXMLFileRequestEvent>()
|
|||
|
|
.Publish(new TTSImportReadXMLFileRequestArg(FileToImport, setupToPass));
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
SetStatus(StringResources.ImportTestSetup_PossibleStatus_Failed,
|
|||
|
|
StringResources.ImportTestSetup_MustBeCSVOrXML);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
APILogger.Log("failed to read file: ", ex);
|
|||
|
|
SetStatus(StringResources.ImportTestSetup_PossibleStatus_Failed, ex.Message);
|
|||
|
|
}
|
|||
|
|
finally
|
|||
|
|
{
|
|||
|
|
data?.DoneEvent.Set();
|
|||
|
|
SetAppAvailable();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// returns true if the file is an old style tts file(prior to 18396)
|
|||
|
|
/// it does this simply by counting the number of fields in the line
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="fields"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
private bool IsOldSchoolFile(string[] fields)
|
|||
|
|
{
|
|||
|
|
return fields.Length > 20;
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// returns the Toyota field/column corresponding to the column index
|
|||
|
|
/// if the input is the old style it uses the old rules, other wise it uses the columns specified in
|
|||
|
|
/// 18396 TTS import has too many columns and it makes confusion
|
|||
|
|
/// it makes this determination by counting the columns present, if there's atleast 20 it'll use the old order
|
|||
|
|
/// </summary>
|
|||
|
|
private ToyotaFieldOrder GetToyotaField(string[] line, int curToken)
|
|||
|
|
{
|
|||
|
|
//original format
|
|||
|
|
if (IsOldSchoolFile(line)) { return (ToyotaFieldOrder)curToken; }
|
|||
|
|
var allFields = Enum.GetValues(typeof(ToyotaFieldOrder)).Cast<ToyotaFieldOrder>().ToArray();
|
|||
|
|
var list = new List<ToyotaFieldOrder>();
|
|||
|
|
foreach (var field in allFields)
|
|||
|
|
{
|
|||
|
|
var supportLevel = FieldSupportAttribute.GetSupportLevel(field);
|
|||
|
|
if (supportLevel == FieldSupportLevel.RemovedParameter) { continue; }
|
|||
|
|
list.Add(field);
|
|||
|
|
}
|
|||
|
|
if (curToken >= list.Count) { throw new Exception($"Invalid parameter, field {curToken}"); }
|
|||
|
|
return list[curToken];
|
|||
|
|
}
|
|||
|
|
public ITTSSetup ProcessToyotaCSVFile(string importFile, ref string error)
|
|||
|
|
{
|
|||
|
|
var errors = new List<string>();
|
|||
|
|
var records = new List<ITTSChannelRecord>();
|
|||
|
|
var setup = new TTSTestSetup()
|
|||
|
|
{
|
|||
|
|
Filename = importFile,
|
|||
|
|
SampleRate = _defaultSampleRate,
|
|||
|
|
Mode = _defaultRecordingMode,
|
|||
|
|
PreTrigger = _defaultTTSPreTrigger,
|
|||
|
|
PostTrigger = _defaultTTSPostTrigger,
|
|||
|
|
ROIStart = Math.Max(_defaultTTSROIStart, _defaultTTSPreTrigger * -1),
|
|||
|
|
ROIEnd = Math.Min(_defaultTTSROIEnd, _defaultTTSPostTrigger),
|
|||
|
|
RequireEIDFound = _defaultRequireEIDsFound,
|
|||
|
|
DefaultDigitalInputMode = _defaultDigitalInputMode,
|
|||
|
|
SquibDefaults = _squibDefaults
|
|||
|
|
};
|
|||
|
|
setup.PreAssignedSensorIdAndHwId = new Tuple<string, string>[0];
|
|||
|
|
setup.OriginalImportFile = importFile;
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
var totalLines = 0.0D;
|
|||
|
|
using (var parser =
|
|||
|
|
new Microsoft.VisualBasic.FileIO.TextFieldParser(importFile, Encoding.GetEncoding("Shift-JIS"),
|
|||
|
|
true))
|
|||
|
|
{
|
|||
|
|
while (!parser.EndOfData)
|
|||
|
|
{
|
|||
|
|
parser.ReadLine();
|
|||
|
|
totalLines++;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
using (var parser =
|
|||
|
|
new Microsoft.VisualBasic.FileIO.TextFieldParser(importFile, Encoding.GetEncoding("Shift-JIS"),
|
|||
|
|
true))
|
|||
|
|
{
|
|||
|
|
parser.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited;
|
|||
|
|
parser.SetDelimiters(",");
|
|||
|
|
|
|||
|
|
setup.Line1 = parser.ReadLine();
|
|||
|
|
|
|||
|
|
setup.Line2 = parser.ReadLine();
|
|||
|
|
setup.DummyList = new string[8];
|
|||
|
|
if (setup.Line2 != null)
|
|||
|
|
{
|
|||
|
|
var fields = setup.Line2.Split(',');
|
|||
|
|
setup.TestId = fields[0];
|
|||
|
|
|
|||
|
|
if (5 < fields.Length)
|
|||
|
|
{
|
|||
|
|
setup.DummyList[0] = fields[1];
|
|||
|
|
setup.DummyList[2] = fields[2];
|
|||
|
|
setup.DummyList[4] = fields[3];
|
|||
|
|
setup.DummyList[6] = fields[4];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
setup.Line3 = parser.ReadLine();
|
|||
|
|
if (setup.Line3 != null)
|
|||
|
|
{
|
|||
|
|
var fields = setup.Line3.Split(',');
|
|||
|
|
if (5 < fields.Length)
|
|||
|
|
{
|
|||
|
|
setup.DummyList[1] = fields[1];
|
|||
|
|
setup.DummyList[3] = fields[2];
|
|||
|
|
setup.DummyList[5] = fields[3];
|
|||
|
|
setup.DummyList[7] = fields[4];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
setup.Line4 = parser.ReadLine();
|
|||
|
|
|
|||
|
|
while (!parser.EndOfData)
|
|||
|
|
{
|
|||
|
|
var bErrored = false;
|
|||
|
|
var fields = parser.ReadFields();
|
|||
|
|
|
|||
|
|
var record = new TTSChannelRecord();
|
|||
|
|
|
|||
|
|
for (var curToken = 0; curToken < fields.Length; curToken++)
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
//squid (and digital) don't have the rest of the columns filled out ...
|
|||
|
|
if (curToken >= 5 && record.IsSquib || curToken >= 3 && record.IsDigitalInput ||
|
|||
|
|
curToken >= 3 && record.IsDigitalOutput)
|
|||
|
|
{
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
if (curToken >= (int)ToyotaFieldOrder.KyowaSpecificField_1)
|
|||
|
|
{
|
|||
|
|
var curValue = Utils.EscapeString(fields[curToken]);
|
|||
|
|
if (curValue.Equals(TTSChannelRecord.DIAGNOSTICSMODE, StringComparison.OrdinalIgnoreCase))
|
|||
|
|
{
|
|||
|
|
record.DiagnosticsMode = true;
|
|||
|
|
}
|
|||
|
|
continue;
|
|||
|
|
} //ignore fields after ours.
|
|||
|
|
var value = Utils.EscapeString(fields[curToken]);
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
#region Another very long switch
|
|||
|
|
|
|||
|
|
var field = GetToyotaField(fields, curToken);
|
|||
|
|
|
|||
|
|
//if remaining but not used, just silently don't use the value passed in ... ignore it (unless it's an old school file, in which case do what we used to do)
|
|||
|
|
if (FieldSupportAttribute.GetSupportLevel(field) == FieldSupportLevel.RemainedButNotUsed && !IsOldSchoolFile(fields)) { continue; }
|
|||
|
|
switch (field)
|
|||
|
|
{
|
|||
|
|
case ToyotaFieldOrder.ChannelNumber: //A
|
|||
|
|
if (int.TryParse(value, out int channelNumber))
|
|||
|
|
{
|
|||
|
|
record.ChannelNumber = channelNumber;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
//FB12439: Reserved Sensors no longer supported
|
|||
|
|
if (!errors.Contains(StringResources.ReservedSensorFound)) errors.Add(StringResources.ReservedSensorFound);
|
|||
|
|
bErrored = true;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.ChannelCode: //B
|
|||
|
|
if (!string.IsNullOrWhiteSpace(value))
|
|||
|
|
{
|
|||
|
|
if (DuplicateChannelCode(value, records))
|
|||
|
|
{
|
|||
|
|
error = string.Format(StringResources.ImportTestSetup_DuplicateChannelCode, value);
|
|||
|
|
SetStatus(StringResources.ImportTestSetup_PossibleStatus_Failed, error);
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
record.ChannelCode = value;
|
|||
|
|
record.OriginallyRequestedChannel = true;
|
|||
|
|
|
|||
|
|
if (value.StartsWith("DO"))
|
|||
|
|
{
|
|||
|
|
var rest = value.Substring(2);
|
|||
|
|
if (rest.StartsWith("_"))
|
|||
|
|
{
|
|||
|
|
rest = rest.Substring(1);
|
|||
|
|
}
|
|||
|
|
if (int.TryParse(rest, out var tempInt))
|
|||
|
|
{
|
|||
|
|
record.IsDigitalOutput = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (value.StartsWith("DI"))
|
|||
|
|
{
|
|||
|
|
var rest = value.Substring(2);
|
|||
|
|
if (rest.StartsWith("_"))
|
|||
|
|
{
|
|||
|
|
rest = rest.Substring(1);
|
|||
|
|
}
|
|||
|
|
if (int.TryParse(rest, out var temptInt))
|
|||
|
|
{
|
|||
|
|
record.IsDigitalInput = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (value.StartsWith("SQ") ||
|
|||
|
|
value.StartsWith("TF"))
|
|||
|
|
{
|
|||
|
|
record.IsSquib = true;
|
|||
|
|
record.LimitDuration = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
record.OriginallyRequestedChannel = false;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.JCodeOrDescription: //C
|
|||
|
|
if (!string.IsNullOrWhiteSpace(record.ChannelCode))
|
|||
|
|
{
|
|||
|
|
if (string.IsNullOrWhiteSpace(value))
|
|||
|
|
{
|
|||
|
|
record.IsJCodeValid = false;
|
|||
|
|
}
|
|||
|
|
if (DuplicateJCode(value, records))
|
|||
|
|
{
|
|||
|
|
record.IsJCodeValid = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
record.JCodeOrDescription = value;
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.ChannelRange: //D
|
|||
|
|
if (double.TryParse(value, out double dChannelRange))
|
|||
|
|
{
|
|||
|
|
record.ChannelRange = dChannelRange;
|
|||
|
|
record.SquibFireDelayMs = dChannelRange;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.ChannelFilterHz: //E
|
|||
|
|
if (int.TryParse(value, out int iTemp))
|
|||
|
|
{
|
|||
|
|
record.ChannelFilterHz = iTemp;
|
|||
|
|
record.SquibFireDurationMs = (iTemp != 0 ? iTemp : _squibDefaults.FireDurationMS);
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.SensorID: //F
|
|||
|
|
record.SensorEID = value;
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.SensorSerialNumber: //G
|
|||
|
|
if (DuplicateSensorSerialNumber(value, records))
|
|||
|
|
{
|
|||
|
|
error = string.Format(StringResources.ImportTestSetup_DuplicateSensorSerialNumber, value);
|
|||
|
|
SetStatus(StringResources.ImportTestSetup_PossibleStatus_Failed, error);
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
record.SensorSerialNumber = value;
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.SensorSensitivity: //H
|
|||
|
|
if (double.TryParse(value, out double d))
|
|||
|
|
{
|
|||
|
|
record.SensorSensitivity = d;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.SensorExcitationVolts: //I
|
|||
|
|
if (double.TryParse(value, out d))
|
|||
|
|
{
|
|||
|
|
record.SensorExcitationVolts = d;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.SensorCapacity: //J
|
|||
|
|
if (double.TryParse(value, out d))
|
|||
|
|
{
|
|||
|
|
record.SensorCapacity = d;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.SensorEU: //K
|
|||
|
|
record.SensorEU = value;
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.SensorPolarity: //L
|
|||
|
|
record.SensorPolarity = value == "+" || value == "1";
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.ChannelType: //M
|
|||
|
|
if (!string.IsNullOrWhiteSpace(value))
|
|||
|
|
{
|
|||
|
|
record.ChannelType =
|
|||
|
|
new DTS.Common.Utilities.DescriptionAttributeCoder<ToyotaBridgeType>()
|
|||
|
|
.EncodeAttributeValue(value);
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.Description: //N
|
|||
|
|
//FB12439: removed "no duplicate description" requirement from FB11238
|
|||
|
|
record.Description = value;
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.ProportionalToExcitation: //O
|
|||
|
|
if ("mv/v/eu" == value.ToLower())
|
|||
|
|
{
|
|||
|
|
record.ProportionalToExcitation = true;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
record.ProportionalToExcitation = false;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.BridgeResistance: //P
|
|||
|
|
if (double.TryParse(value, out d))
|
|||
|
|
{
|
|||
|
|
record.BridgeResistance = d;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.InitialOffsetVoltage: //Q
|
|||
|
|
if (double.TryParse(value, out d))
|
|||
|
|
{
|
|||
|
|
record.InitialOffsetVoltage = d;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.InitialOffsetVoltageTolerance: //R
|
|||
|
|
if (double.TryParse(value, out d))
|
|||
|
|
{
|
|||
|
|
record.InitialOffsetVoltageTolerance = d;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.RemoveOffset: //S
|
|||
|
|
record.RemoveOffset = "1" == value;
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.ZeroMethod: //T
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
if (string.IsNullOrWhiteSpace(value))
|
|||
|
|
{
|
|||
|
|
record.ZeroMethod = ToyotaZeroMethods.AverageOverTime;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
record.ZeroMethod =
|
|||
|
|
new DTS.Common.Utilities.DescriptionAttributeCoder<ToyotaZeroMethods>()
|
|||
|
|
.EncodeAttributeValue(value);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch
|
|||
|
|
{
|
|||
|
|
record.ZeroMethod = ToyotaZeroMethods.AverageOverTime;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.CableCompensationMultiplier: //U
|
|||
|
|
if (double.TryParse(value, NumberStyles.Any,
|
|||
|
|
System.Globalization.CultureInfo.InvariantCulture, out var dTemp))
|
|||
|
|
{
|
|||
|
|
record.CableMultiplier = dTemp;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.InitialEUInMV: //V
|
|||
|
|
if (double.TryParse(value, out d))
|
|||
|
|
{
|
|||
|
|
record.InitialEUInMV = d;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.InitialEUInEU: //W
|
|||
|
|
if (double.TryParse(value, out d))
|
|||
|
|
{
|
|||
|
|
record.InitialEUInEU = d;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.IRTRACCExponent: //X
|
|||
|
|
if (double.TryParse(value, out d))
|
|||
|
|
{
|
|||
|
|
record.IRTraccExponent = d;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.PolynomialConstant: //Y
|
|||
|
|
if (double.TryParse(value, out d))
|
|||
|
|
{
|
|||
|
|
record.PolynomialConstant = d;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.PolynomialCoefficentC: //Z
|
|||
|
|
if (double.TryParse(value, out d))
|
|||
|
|
{
|
|||
|
|
record.PolynomialCoefficientC = d;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.PolynomialCoefficentB: //AA
|
|||
|
|
if (double.TryParse(value, out d))
|
|||
|
|
{
|
|||
|
|
record.PolynomialCoefficentB = d;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.PolynomialCoefficentA: //AB
|
|||
|
|
if (double.TryParse(value, out d))
|
|||
|
|
{
|
|||
|
|
record.PolynomialCoefficientA = d;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.PolynomialCoefficentAlpha: //AC
|
|||
|
|
if (double.TryParse(value, out d))
|
|||
|
|
{
|
|||
|
|
record.PolynomialCoefficientAlpha = d;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.ISOCode: //AD
|
|||
|
|
record.ISOCode = value;
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.ISODescription: //AE
|
|||
|
|
record.ISODescription = value;
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.ISOPolarity: //AF
|
|||
|
|
record.ISOPolarity = value;
|
|||
|
|
break;
|
|||
|
|
case ToyotaFieldOrder.KyowaSpecificField_1: //AG
|
|||
|
|
// http://fogbugz/fogbugz/default.asp?5433
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
throw new NotSupportedException(
|
|||
|
|
"ImportTestSetup::ProcessToyotaFile unknown field: " + fields[curToken]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion Another very long switch
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
errors.Add($"field {curToken} error {ex.Message} (check input locale)");
|
|||
|
|
bErrored = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (bErrored) continue;
|
|||
|
|
if (record.IsDigitalInput || record.IsDigitalOutput || record.IsSquib)
|
|||
|
|
{
|
|||
|
|
record.SensorEU = "V"; //What is this for?
|
|||
|
|
record.SensorSerialNumber = record.JCodeOrDescription;
|
|||
|
|
}
|
|||
|
|
// FB12439: TTS Sensors need to be in DB first
|
|||
|
|
if (record.IsSquib || record.IsDigitalInput || record.IsDigitalOutput)
|
|||
|
|
{
|
|||
|
|
//we can use test specific values?
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
var sd = SensorsCollection.SensorsList.GetSensorBySerialNumber(record.SensorSerialNumber);
|
|||
|
|
if (null == sd)
|
|||
|
|
{
|
|||
|
|
error = string.Format(StringResources.SensorNotFound, record.SensorSerialNumber);
|
|||
|
|
SetStatus(StringResources.ImportTestSetup_PossibleStatus_Failed, error);
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
else if (sd.IsAnalog() && !IsOldSchoolFile(fields))
|
|||
|
|
{
|
|||
|
|
//18396 TTS import has too many columns and it makes confusion
|
|||
|
|
//these fields now come exclusively from the db and not from the import anymore
|
|||
|
|
var latestCal = SensorCalibrationList.GetLatestCalibrationBySerialNumber(sd);
|
|||
|
|
if (null != latestCal)
|
|||
|
|
{
|
|||
|
|
record.SensorSensitivity = latestCal.Records.Records[0].Sensitivity;
|
|||
|
|
}
|
|||
|
|
record.SensorEID = sd.EID;
|
|||
|
|
record.CableMultiplier = 1;
|
|||
|
|
record.SensorCapacity = sd.Capacity;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
record.IsChannelCodeValid = !string.IsNullOrWhiteSpace(record.ChannelCode) &&
|
|||
|
|
record.ChannelCode != TTSChannelRecord.NONE;
|
|||
|
|
records.Add(record);
|
|||
|
|
|
|||
|
|
SetProgress(records.Count / totalLines * 100);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
errors.Add(ex.Message);
|
|||
|
|
}
|
|||
|
|
error += string.Join(Environment.NewLine, errors.ToArray());
|
|||
|
|
setup.Channels = records.ToArray();
|
|||
|
|
SetProgress(100);
|
|||
|
|
return setup;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private bool DuplicateSensorSerialNumber(string sensorSerialNumber, List<ITTSChannelRecord> records)
|
|||
|
|
{
|
|||
|
|
return records.Exists(record => record.SensorSerialNumber == sensorSerialNumber);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private bool DuplicateChannelCode(string channelCode, List<ITTSChannelRecord> records)
|
|||
|
|
{
|
|||
|
|
return records.Exists(record => record.ChannelCode == channelCode);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private bool DuplicateJCode(string jcode, List<ITTSChannelRecord> records)
|
|||
|
|
{
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
private bool DuplicateDescription(string description, List<ITTSChannelRecord> records)
|
|||
|
|
{
|
|||
|
|
return records.Exists(record => record.Description == description);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// ProcessToyotaXMLFile
|
|||
|
|
/// 14698 Cannot import XML file generated from TTS and auto advance to "Hardware Scan" nav step
|
|||
|
|
/// once the xml file has been read we can manipulate the TTSSetup and TTSChannelRecords to
|
|||
|
|
/// create the information needed as if we had read a CSV to start
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="arg"></param>
|
|||
|
|
public void ProcessToyotaXMLFile(TTSImportReadXMLFileResponseEventArg arg)
|
|||
|
|
{
|
|||
|
|
var records = new List<ITTSChannelRecord>();
|
|||
|
|
var preAssignedChannels = new List<Tuple<string, string>>();
|
|||
|
|
|
|||
|
|
//process the channels from xml and create tts records
|
|||
|
|
var channels = arg.TestSetup.GetChannels();
|
|||
|
|
foreach (var ch in channels)
|
|||
|
|
{
|
|||
|
|
if (ch.IsBlank() || ch.IsDisabled) { continue; }
|
|||
|
|
|
|||
|
|
var newCh = new TTSChannelRecord();
|
|||
|
|
|
|||
|
|
if (ch.SensorValid)
|
|||
|
|
{
|
|||
|
|
//not sure why this is done, but it was being done in ProcessSensor previously, so I preserved it...
|
|||
|
|
ch.SensorData.UUID = ch.SensorData.SerialNumber;
|
|||
|
|
|
|||
|
|
//declare a newchannel using the sensor data, this will set a bunch of channel properties using the sensor ...
|
|||
|
|
newCh = new TTSChannelRecord((SensorData)ch.SensorData);
|
|||
|
|
|
|||
|
|
//now some properties are not set using the sensor in 2.4 and 2.5, so we have to set those explicitly
|
|||
|
|
//those properties will come from the channel or channel settings
|
|||
|
|
newCh.ISOCode = ch.IsoCode;
|
|||
|
|
newCh.ISODescription = ch.IsoChannelName;
|
|||
|
|
newCh.ChannelCode = ch.UserCode;
|
|||
|
|
newCh.Description = ch.UserChannelName;
|
|||
|
|
|
|||
|
|
//in modern channel settings these properties are explicit to the sensor type (digital out,squib)
|
|||
|
|
//but are common in older xml and in tts channel records ...
|
|||
|
|
var limit = false;
|
|||
|
|
var delay = double.NaN;
|
|||
|
|
var duration = double.NaN;
|
|||
|
|
|
|||
|
|
foreach (var setting in ch.ChannelSettings)
|
|||
|
|
{
|
|||
|
|
switch (setting.SettingName)
|
|||
|
|
{
|
|||
|
|
case ChannelSettingBase.ACTIVE_VALUE:
|
|||
|
|
case ChannelSettingBase.DEFAULT_VALUE:
|
|||
|
|
//ignore?
|
|||
|
|
break;
|
|||
|
|
case ChannelSettingBase.DIMODE:
|
|||
|
|
newCh.DigitalInputMode = (DigitalInputModes)setting.IntValue;
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case ChannelSettingBase.CFC:
|
|||
|
|
ch.SensorData.FilterClassIso = setting.Value;
|
|||
|
|
break;
|
|||
|
|
case ChannelSettingBase.POLARITY:
|
|||
|
|
newCh.SensorPolarity = setting.Value == "+";
|
|||
|
|
break;
|
|||
|
|
case ChannelSettingBase.RANGE:
|
|||
|
|
newCh.ChannelRange = setting.DoubleValue;
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case ChannelSettingBase.DIGITALOUT_DELAY:
|
|||
|
|
newCh.DigitalOutputDelay = setting.DoubleValue;
|
|||
|
|
break;
|
|||
|
|
case ChannelSettingBase.DIGITALOUT_DURATION:
|
|||
|
|
newCh.DigitalOutputDuration = setting.DoubleValue;
|
|||
|
|
break;
|
|||
|
|
case ChannelSettingBase.DIGITALOUT_LIMIT_DURATION:
|
|||
|
|
if (setting.BoolValue) { limit = true; }
|
|||
|
|
break;
|
|||
|
|
case ChannelSettingBase.OUTPUT_MODE:
|
|||
|
|
newCh.DigitalOutputMode = (DigitalOutputModes)setting.IntValue;
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case ChannelSettingBase.SQUIB_DELAY:
|
|||
|
|
newCh.SquibFireDelayMs = setting.DoubleValue;
|
|||
|
|
break;
|
|||
|
|
case ChannelSettingBase.SQUIB_DURATION:
|
|||
|
|
newCh.SquibFireDurationMs = setting.DoubleValue;
|
|||
|
|
break;
|
|||
|
|
case ChannelSettingBase.SQUIB_LIMIT_DURATION:
|
|||
|
|
if (setting.BoolValue) { limit = true; }
|
|||
|
|
break;
|
|||
|
|
case ChannelSettingBase.SQMODE:
|
|||
|
|
newCh.SquibFireMode = (SquibFireMode)setting.IntValue;
|
|||
|
|
break;
|
|||
|
|
case ChannelSettingBase.SQUIB_CURRENT:
|
|||
|
|
newCh.SquibFireCurrent = setting.DoubleValue;
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case ChannelSettingBase.POSITION: break; //ignore, this should be stored in ISOCode
|
|||
|
|
|
|||
|
|
case ChannelSettingBase.ZEROMETHOD:
|
|||
|
|
var zmType = (DTS.Common.Enums.Sensors.ZeroMethodType)Enum.Parse(typeof(DTS.Common.Enums.Sensors.ZeroMethodType), setting.Value);
|
|||
|
|
switch (zmType)
|
|||
|
|
{
|
|||
|
|
case DTS.Common.Enums.Sensors.ZeroMethodType.AverageOverTime:
|
|||
|
|
newCh.ZeroMethod = ToyotaZeroMethods.AverageOverTime;
|
|||
|
|
break;
|
|||
|
|
case DTS.Common.Enums.Sensors.ZeroMethodType.UsePreEventDiagnosticsZero:
|
|||
|
|
newCh.ZeroMethod = ToyotaZeroMethods.UsePreEventDiagnosticsZero;
|
|||
|
|
break;
|
|||
|
|
case DTS.Common.Enums.Sensors.ZeroMethodType.None:
|
|||
|
|
newCh.ZeroMethod = ToyotaZeroMethods.None;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case ChannelSettingBase.ZEROMETHODSTART:
|
|||
|
|
case ChannelSettingBase.ZEROMETHODEND:
|
|||
|
|
case ChannelSettingBase.USERVALUE1:
|
|||
|
|
case ChannelSettingBase.USERVALUE3:
|
|||
|
|
case ChannelSettingBase.INITIAL_OFFSET:
|
|||
|
|
break;
|
|||
|
|
case ChannelSettingBase.USERVALUE2:
|
|||
|
|
newCh.CableMultiplier = setting.DoubleValue;
|
|||
|
|
break;
|
|||
|
|
case "LimitDuration": //deprecated, only needed for migrating to current version xml?
|
|||
|
|
limit = setting.BoolValue;
|
|||
|
|
break;
|
|||
|
|
case "Delay": //deprecated, only needed for migrating to current version xml?
|
|||
|
|
delay = setting.DoubleValue;
|
|||
|
|
break;
|
|||
|
|
case "Duration": //deprecated, only needed for migrating to current version xml?
|
|||
|
|
duration = setting.DoubleValue;
|
|||
|
|
break;
|
|||
|
|
case ChannelSettingBase.FilterClass:
|
|||
|
|
break;
|
|||
|
|
default: throw new NotImplementedException("unknown setting: " + setting.SettingName);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
newCh.LimitDuration = limit;
|
|||
|
|
if (!double.IsNaN(delay))
|
|||
|
|
{
|
|||
|
|
newCh.DigitalOutputDelay = delay;
|
|||
|
|
newCh.SquibFireDelayMs = delay;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!double.IsNaN(duration))
|
|||
|
|
{
|
|||
|
|
newCh.DigitalOutputDuration = duration;
|
|||
|
|
newCh.SquibFireDurationMs = duration;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (ch.HardwareValid)
|
|||
|
|
{
|
|||
|
|
preAssignedChannels.Add(new Tuple<string, string>(ch.SensorData.SerialNumber,
|
|||
|
|
ch.HardwareChannel.GetId()));
|
|||
|
|
}
|
|||
|
|
records.Add(newCh);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var recordLookup = records.ToDictionary(r => r.SensorSerialNumber);
|
|||
|
|
arg.TTSSetup.PreAssignedSensorIdAndHwId = preAssignedChannels.ToArray();
|
|||
|
|
arg.TTSSetup.Channels = records.ToArray();
|
|||
|
|
//finally process level triggers, now TTS has a set number of level triggers, which are all empty by default
|
|||
|
|
//we want to just set those level triggers properly if we have a level trigger from xml
|
|||
|
|
if (arg.LevelTriggers.Any())
|
|||
|
|
{
|
|||
|
|
for (var i = 0; i < arg.LevelTriggers.Length && i < arg.TTSSetup.LevelTriggers.Length; i++)
|
|||
|
|
{
|
|||
|
|
var ltXml = arg.LevelTriggers[i];
|
|||
|
|
var ltSetup = arg.TTSSetup.LevelTriggers[i];
|
|||
|
|
if (!recordLookup.ContainsKey(ltXml.SensorSerialNumber))
|
|||
|
|
{
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
ltSetup.Channel = recordLookup[ltXml.SensorSerialNumber];
|
|||
|
|
ltSetup.ValueEU = ltXml.Threshold;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
private double _defaultSampleRate;
|
|||
|
|
private RecordingModes _defaultRecordingMode;
|
|||
|
|
private double _defaultTTSPreTrigger;
|
|||
|
|
private double _defaultTTSPostTrigger;
|
|||
|
|
private double _defaultTTSROIStart;
|
|||
|
|
private double _defaultTTSROIEnd;
|
|||
|
|
private ISquibSettingDefaults _squibDefaults;
|
|||
|
|
public bool _defaultRequireEIDsFound;
|
|||
|
|
public string _defaultDigitalInputMode;
|
|||
|
|
public bool IsDirty { get; private set; }
|
|||
|
|
private bool _isBusy = false;
|
|||
|
|
|
|||
|
|
public bool IsBusy
|
|||
|
|
{
|
|||
|
|
get => _isBusy;
|
|||
|
|
set
|
|||
|
|
{
|
|||
|
|
_isBusy = value;
|
|||
|
|
OnPropertyChanged("IsBusy");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private bool _isMenuIncluded = false;
|
|||
|
|
|
|||
|
|
public bool IsMenuIncluded
|
|||
|
|
{
|
|||
|
|
get => _isMenuIncluded;
|
|||
|
|
set
|
|||
|
|
{
|
|||
|
|
_isMenuIncluded = value;
|
|||
|
|
OnPropertyChanged("IsMenuIncluded");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private bool _isNavigationIncluded = false;
|
|||
|
|
|
|||
|
|
public bool IsNavigationIncluded
|
|||
|
|
{
|
|||
|
|
get => _isNavigationIncluded;
|
|||
|
|
set
|
|||
|
|
{
|
|||
|
|
_isNavigationIncluded = value;
|
|||
|
|
OnPropertyChanged("IsNavigationIncluded");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#region properties
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// all properties that are exposed
|
|||
|
|
/// </summary>
|
|||
|
|
public enum PropertyNames
|
|||
|
|
{
|
|||
|
|
ImportFileName
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private string _importFileName = "";
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// full path to import file
|
|||
|
|
/// </summary>
|
|||
|
|
public string ImportFileName
|
|||
|
|
{
|
|||
|
|
get => _importFileName;
|
|||
|
|
set
|
|||
|
|
{
|
|||
|
|
_importFileName = value;
|
|||
|
|
OnPropertyChanged(PropertyNames.ImportFileName.ToString());
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
///<summary>
|
|||
|
|
///Occurs when a property value changes.
|
|||
|
|
///</summary>
|
|||
|
|
public event PropertyChangedEventHandler PropertyChanged;
|
|||
|
|
|
|||
|
|
public void OnPropertyChanged(string propertyName)
|
|||
|
|
{
|
|||
|
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|