using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Globalization; using System.IO.Ports; using System.Linq; using System.Windows; using DTS.Common.Classes; using DTS.Common.Classes.Groups; using DTS.Common.Classes.Groups.ChannelSettings; using DTS.Common.Classes.Sensors; using DTS.Common.Enums.Groups.GroupList; using DTS.Common.Enums.Sensors; using DTS.Common.Interface.Channels; using DTS.Common.Interface.Channels.ChannelCodes; using DTS.Common.Interface.DataRecorders; using DTS.Common.Interface.Groups.GroupList; using DTS.Common.Interface.Sensors; using DTS.Common.Interface.Tags; using DTS.Common.Interface.Groups; using DTS.Common.Interface.TestSetups.TestSetupsList; using DTS.Common.ISO; using DTS.Common.Storage; using DTS.Common.Utilities.Logging; using DTS.SensorDB; using Prism.Ioc; using IGroup = DTS.Common.Interface.Groups.GroupList.IGroup; using DTS.Common.Enums.DASFactory; using Newtonsoft.Json; using DTS.Common.Enums; using Prism.Events; using Unity; namespace GroupList.Model { public class Group : TagAwareBase, IGroup { public override TagTypes TagType => TagTypes.Group; private bool _bHardwareLoaded = false; private int[] _includedHardware = new int[0]; public int[] IncludedHardware { get { if (!_bHardwareLoaded) { LoadHardware(); } return _includedHardware; } set => _includedHardware = value; } public void SetIncludedHardware(int[] hardware) { _includedHardware = hardware; _bHardwareLoaded = true; } private List _includedHarwareStringList = new List(); public string[] IncludedHardwareStringList { get => _includedHarwareStringList.ToArray(); set => _includedHarwareStringList = new List(value); } public List GroupChannelList { get; set; } private int _channelCount = 0; public int ChannelCount { get => _channelCount; set => SetProperty(ref _channelCount, value, "ChannelCount"); } public int Id { get; set; } = -1; public bool HasValidId() { return Id >= 0; } public string Name { get; set; } public string DisplayName { get; set; } public string Tags { get; set; } public int? StaticGroupId { get; set; } public bool Embedded { get; set; } public DateTime LastModified { get; set; } public string LastModifiedBy { get; set; } private string _description = ""; public string Description { get => _description; set => SetProperty(ref _description, value, "Description"); } // FB14276: Add Custom ISO Key-Value Pairs public List> ExtraProperties { get; set; } private List _associatedTestSetups; public List AssociatedTestSetups { get => _associatedTestSetups; set { _associatedTestSetups = value; OnPropertyChanged("UnmodifiedTestSetupStringList"); OnPropertyChanged("ModifiedTestSetupStringList"); } } public List UnmodifiedTestSetupStringList { get { if (null == AssociatedTestSetups) { return new List(); } return AssociatedTestSetups.Where(x => !x.Modified).Select(x => x.Name).ToList(); } } public List ModifiedTestSetupStringList { get { if (null == AssociatedTestSetups) { return new List(); } return AssociatedTestSetups.Where(x => x.Modified).Select(x => x.Name).ToList(); } } private bool _isDifferentThanStaticGroup; public bool IsDifferentThanStaticGroup { get => _isDifferentThanStaticGroup; set => SetProperty(ref _isDifferentThanStaticGroup, value, "IsDifferentThanStaticGroup"); } public bool Filter(string term) { if (string.IsNullOrWhiteSpace(term)) { return true; } var index = CultureInfo.CurrentCulture.CompareInfo.IndexOf(DisplayName, term, CompareOptions.IgnoreCase); if (index >= 0) { return true; } index = CultureInfo.CurrentCulture.CompareInfo.IndexOf(Description, term, CompareOptions.IgnoreCase); if (index >= 0) { return true; } index = CultureInfo.CurrentCulture.CompareInfo.IndexOf(ChannelCount.ToString(), term, CompareOptions.IgnoreCase); if (index >= 0) { return true; } index = CultureInfo.CurrentCulture.CompareInfo.IndexOf(LastModifiedBy, term, CompareOptions.IgnoreCase); if (index >= 0) { return true; } var testSetups = new List(); if (AssociatedTestSetups == null) { return true; } foreach (var assoc in AssociatedTestSetups) { testSetups.Add(assoc.Name); } var associatedTestSettups = string.Join(",", testSetups.ToArray()); index = CultureInfo.CurrentCulture.CompareInfo.IndexOf(associatedTestSettups, term, CompareOptions.IgnoreCase); if (index >= 0) { return true; } var timeString = LastModified.ToString(CultureInfo.CurrentCulture); index = CultureInfo.CurrentCulture.CompareInfo.IndexOf(timeString, term, CompareOptions.IgnoreCase); return index >= 0; } public Group(bool bHardwareLoaded = false) { Embedded = false; LastModified = DateTime.Now; LastModifiedBy = "---"; Name = ""; DisplayName = ""; Tags = ""; IncludedHardwareStringList = new string[0]; GroupChannelList = new List(); _bHardwareLoaded = bHardwareLoaded; ExtraProperties = new List>(); } public Group(List includedHardwareStringList) { Embedded = false; LastModified = DateTime.Now; LastModifiedBy = "---"; Name = ""; DisplayName = ""; Tags = ""; IncludedHardwareStringList = includedHardwareStringList.ToArray(); GroupChannelList = new List(); ExtraProperties = new List>(); } public Group(IDataReader reader) { InitializeGroup(reader); } public Group(IGroupDbRecord groupRecord) { InitializeGroup(groupRecord); } public Group(IDataReader reader, List includedHardwareStringList, List dasIdList) { InitializeGroup(reader); IncludedHardwareStringList = includedHardwareStringList.ToArray(); SetIncludedHardware(dasIdList.ToArray()); } public Group(IGroupDbRecord groupRecord, List includedHardwareStringList, List dasIdList) { InitializeGroup(groupRecord); IncludedHardwareStringList = includedHardwareStringList.ToArray(); SetIncludedHardware(dasIdList.ToArray()); } public static IGroup CreateGroupIfNeeded(ITestSetup testSetup, string groupName) { var group = CreateGroupIfNeededDontAdd(testSetup, groupName); if (!testSetup.Groups.Contains(group)) { testSetup.Groups.Add(group); } return group; } private static IGroup CreateGroupIfNeededDontAdd(ITestSetup testSetup, string groupName) { //refactored to not use loop for one element only and filter the result //https://rules.sonarsource.com/csharp/RSPEC-3267/ var groups = testSetup.Groups.Where(x => groupName.Equals(x.DisplayName)); if (groups.Any()) { return groups.FirstOrDefault(); } var newGroup = new Group(true); var displayOrder = 1; if (testSetup.Groups.Any()) { displayOrder = 1 + testSetup.Groups.Max(g => g.DisplayOrder); } newGroup.DisplayOrder = displayOrder; newGroup.DisplayName = groupName; newGroup.Name = Guid.NewGuid().ToString(); testSetup.ChannelsForGroup[newGroup] = new DTS.Common.Interface.Channels.IGroupChannel[0]; return newGroup; } private void InitializeGroup(IDataReader reader) { Id = Convert.ToInt32(reader["Id"]); Name = (string)reader["SerialNumber"]; DisplayName = (string)reader["DisplayName"]; Embedded = Convert.ToBoolean(reader["Embedded"]); LastModified = Convert.ToDateTime(reader["LastModified"]); LastModifiedBy = (string)reader["LastModifiedBy"]; if (reader["StaticGroupId"] == DBNull.Value) { StaticGroupId = null; } else { StaticGroupId = Convert.ToInt32(reader["StaticGroupId"]); } Description = (string)reader["Description"]; ExtraProperties = new List>(); try { var sExtraProperties = Utility.GetString(reader, "ExtraProperties"); ExtraProperties = JsonConvert.DeserializeObject>>(sExtraProperties); if (ExtraProperties == null) { ExtraProperties = new List>(); } } catch (Exception ex) { APILogger.Log(ex); } var tagIdList = GetTagIdList(Id, TagType, DbOperations.TagAssignmentsGet); TagIDs = tagIdList.ToArray(); Tags = GetTagsAsCommaSeparatedString(DbOperations.TagsGet); GroupChannelList = new List(); } private void InitializeGroup(IGroupDbRecord groupRecord) { Id = groupRecord.Id; Name = groupRecord.SerialNumber; DisplayName = groupRecord.DisplayName; Embedded = groupRecord.Embedded; LastModified = groupRecord.LastModified; LastModifiedBy = groupRecord.LastModifiedBy; StaticGroupId = groupRecord.StaticGroupId; Description = groupRecord.Description; ExtraProperties = new List>(); try { ExtraProperties = JsonConvert.DeserializeObject>>(groupRecord.ExtraProperties); if (ExtraProperties == null) { ExtraProperties = new List>(); } } catch (Exception ex) { APILogger.Log(ex); } var tagIdList = GetTagIdList(Id, TagType, DbOperations.TagAssignmentsGet); TagIDs = tagIdList.ToArray(); Tags = GetTagsAsCommaSeparatedString(DbOperations.TagsGet); GroupChannelList = new List(); } public void SetTestSetupLists() { var testSetupsList = new List(); GetTestSetupsUsingThisGroup(ref testSetupsList); AssociatedTestSetups = testSetupsList.OrderBy(tsh => tsh.Name).OrderByDescending(tsh => tsh.Modified).ToList(); } public bool StaticGroupIsEqual() { var embeddedGroupHelper = new GroupHelper(); var staticGroupHelper = new GroupHelper(); //Set Embedded Group Id embeddedGroupHelper.Id = Id; GetStaticGroupHelper(StaticGroupId, ref staticGroupHelper); if (staticGroupHelper.Id == 0) return true; if (GroupsEqual(staticGroupHelper, embeddedGroupHelper)) { return true; } return false; } private void GetEmbeddedGroupHelpers(int? staticGroupId, ref List embeddedGroupHelpers, ref Dictionary lookup) { //Get Ids of all embedded Groups with this StaticGroupId if (staticGroupId == null) return; using (var embeddedGroupsCmd = DbOperations.GetSQLCommand(true)) { try { embeddedGroupsCmd.CommandType = CommandType.StoredProcedure; embeddedGroupsCmd.CommandText = @"sp_GroupsAndTestGet"; embeddedGroupsCmd.Parameters.Add(new SqlParameter("@StaticGroupId", SqlDbType.Int) { Value = staticGroupId }); var reader = embeddedGroupsCmd.ExecuteReader(); while (reader.Read()) { var embeddedGroupHelper = new GroupHelper { Id = Convert.ToInt32(reader["Id"]) }; var otestId = reader["TestSetupId"]; if (!DBNull.Value.Equals(otestId)) { var testSetupId = Convert.ToInt32(otestId); var name = (string)reader["TestSetupName"]; var helper = new TestSetupParentHelper() { Id = testSetupId, Name = name }; lookup[embeddedGroupHelper.Id] = helper; } embeddedGroupHelpers.Add(embeddedGroupHelper); } } finally { embeddedGroupsCmd.Connection.Dispose(); } } } private void GetStaticGroupHelper(int? staticGroupId, ref GroupHelper staticGroupHelper) { //Get Static Group Id from database if (staticGroupId == null) return; var hResult = DbOperations.GroupsGet(staticGroupId, null, null, null, null, out var dbGroups); if (0 == hResult && null != dbGroups && dbGroups.Any()) { foreach (var groupRecord in dbGroups) //shouldn't be a loop { staticGroupHelper.Id = (int)staticGroupId; staticGroupHelper.DisplayName = groupRecord.DisplayName; staticGroupHelper.Description = groupRecord.Description; } } } private class GroupHelper { public int Id; public string DisplayName; public string Description; } private void GetTestSetupsUsingThisGroup(ref List testSetupsList) { //Get Ids of all Groups (embedded and one static) with this DisplayName var embeddedGroupHelpers = new List(); var staticGroupHelper = new GroupHelper(); GetStaticGroupHelper(Id, ref staticGroupHelper); var lookup = new Dictionary(); GetEmbeddedGroupHelpers(Id, ref embeddedGroupHelpers, ref lookup); //Make a list of which embedded Groups differ from the static Group, and a list of which embedded Groups are the same as the static Group foreach (var embeddedGroupHelper in embeddedGroupHelpers) { if (!lookup.ContainsKey(embeddedGroupHelper.Id)) { continue; } var tsh = lookup[embeddedGroupHelper.Id]; //GetTestSetupHelperFromEmbeddedGroupId(embeddedGroupHelper.Id); tsh.Modified = !GroupsEqual(staticGroupHelper, embeddedGroupHelper); if (!string.IsNullOrWhiteSpace(tsh.Name)) { testSetupsList.Add(tsh); } } } private bool GroupsEqual(GroupHelper staticGroupHelper, GroupHelper embeddedGroupHelper) { SqlParameter result; result = new SqlParameter("@Result", SqlDbType.Bit) { Direction = ParameterDirection.Output }; using (var compareGroupsCmd = DbOperations.GetSQLCommand(true)) { try { compareGroupsCmd.CommandType = CommandType.StoredProcedure; compareGroupsCmd.CommandText = @"sp_CompareGroups"; compareGroupsCmd.Parameters.Add(new SqlParameter("@StaticDisplayName", SqlDbType.NVarChar, 255) { Value = staticGroupHelper.DisplayName }); compareGroupsCmd.Parameters.Add(new SqlParameter("@StaticDescription", SqlDbType.NVarChar, 255) { Value = staticGroupHelper.Description }); compareGroupsCmd.Parameters.Add(new SqlParameter("@StaticGroupId", SqlDbType.Int) { Value = staticGroupHelper.Id }); compareGroupsCmd.Parameters.Add(new SqlParameter("@EmbeddedGroupId", SqlDbType.Int) { Value = embeddedGroupHelper.Id }); result = new SqlParameter("@Result", SqlDbType.Bit) { Direction = ParameterDirection.Output }; compareGroupsCmd.Parameters.Add(result); compareGroupsCmd.ExecuteNonQuery(); } catch (Exception ex) { var temp = ex.Message; result.Value = false; } finally { compareGroupsCmd.Connection.Dispose(); } } return (result.Value != null) && (bool)result.Value; } private int[] GetExistingHardware() { if (Id < 0) { return new int[0]; } var hResult = DbOperations.GroupHardwareGet(Id, null, null, out GroupHardwareDbRecord[] groupHardwareDbRecords); var ids = new List(); if (0 == hResult && null != groupHardwareDbRecords && groupHardwareDbRecords.Any()) { foreach (var groupHardwareDbRecord in groupHardwareDbRecords) { var dasId = groupHardwareDbRecord.DASId; ids.Add(dasId); } } return ids.ToArray(); } private int[] GetExistingHardware(out List includedHardwareStringList) { includedHardwareStringList = new List(); if (Id < 0) { return new int[0]; } var hResult = DbOperations.GroupHardwareGet(Id, null, null, out GroupHardwareDbRecord[] groupHardwareDbRecords); var ids = new List(); if (0 == hResult && null != groupHardwareDbRecords && groupHardwareDbRecords.Any()) { foreach (var groupHardwareDbRecord in groupHardwareDbRecords) { var dasId = groupHardwareDbRecord.DASId; ids.Add(dasId); includedHardwareStringList.Add(groupHardwareDbRecord.SerialNumber); } } return ids.ToArray(); } public void LoadHardware() { var includedHardwareStringList = new List(); _bHardwareLoaded = true; IncludedHardware = GetExistingHardware(out includedHardwareStringList); IncludedHardwareStringList = includedHardwareStringList.ToArray(); } public static void Delete(int id) { var errorNumber = DbOperations.GroupsDelete(id, out string errorMessage); if (errorNumber != 0) { throw new Exception(errorMessage); } } public static IGroup[] GetAllGroups(int? id = null) { var groups = new List(); var hResult = DbOperations.GroupsGet(id, null, null, false, null, out var dbGroups); if (0 == hResult && null != dbGroups && dbGroups.Any()) { foreach (var groupRecord in dbGroups) //shouldn't be a loop { groups.Add(new Group(groupRecord)); } } var lookup = GetUniqueChannelIdCountPerGroupLookup(); foreach (var g in groups) { if (lookup.ContainsKey(g.Id)) { g.ChannelCount = lookup[g.Id]; } } return groups.ToArray(); } private static IReadOnlyDictionary GetUniqueChannelIdCountPerGroupLookup() { var lookup = new Dictionary(); var hr = DbOperations.ChannelsGet(null, null, null, null, null, null, out var channels); if (0 == hr) { foreach (var channel in channels) { if (!lookup.ContainsKey(channel.GroupId)) { lookup[channel.GroupId] = 0; } lookup[channel.GroupId] = 1 + lookup[channel.GroupId]; } } return lookup; } public static IGroup[] GetAllGroups(string displayName) { var groups = new List(); var hResult = DbOperations.GroupsGet(null, null, displayName, false, null, out var dbGroups); if (0 == hResult && null != dbGroups && dbGroups.Any()) { foreach (var groupRecord in dbGroups) //shouldn't be a loop { groups.Add(new Group(groupRecord)); } } return groups.ToArray(); } public static IGroup[] GetAllRelatedEmbeddedGroups(int staticGroupId) { var groups = new List(); var hResult = DbOperations.GroupsGet(null, null, null, false, staticGroupId, out var dbGroups); if (0 == hResult && null != dbGroups && dbGroups.Any()) { foreach (var groupRecord in dbGroups) //shouldn't be a loop { groups.Add(new Group(groupRecord)); } } return groups.ToArray(); } public static void SetNullStaticGroupId(IGroup embeddedGroup) { var group = embeddedGroup.GetIGroupDbRecord(); _ = DbOperations.GroupsUpdate(group); } public IGroupDbRecord GetIGroupDbRecord() { return new GroupDbRecord(this, ExtraProperties); } private void SaveGroup() { if (!Embedded) //FB14600: Always overwrite Name/serialNumber with the DisplayName on static group saves. Embedded groups use guids for SN. { Name = DisplayName; } var group = GetIGroupDbRecord(); if (Id >= 0) { _ = DbOperations.GroupsUpdate(group); } else { _ = DbOperations.GroupsInsert(ref group); Id = group.Id; } InsertTagsFromCommaSeparatedString(Id, TagType, Tags, DbOperations.GetSQLCommand, DbOperations.TagsGet, DbOperations.TagsGetId, DbOperations.TagsInsert, DbOperations.TagAssignmentsDelete, DbOperations.TagAssignmentsInsert); } public void ConvertToEmbedded(DTS.Common.Interface.Channels.IGroupChannel[] groupChannels) { if (Embedded) { return; } if (Id == -1) { StaticGroupId = null; } else { StaticGroupId = Id; // Store the Id of the static Group that we are now an embedded copy of Id = -1; } Name = Guid.NewGuid().ToString(); Embedded = true; foreach (var channel in groupChannels) { channel.Id = -1; } } public void DeterminePositionAndTestObject(DTS.Common.Interface.Channels.IGroupChannel[] channels) { var testObject = string.Empty; var position = string.Empty; bool testObjectMixed = false; bool positionMixed = false; foreach (var ch in channels) { if (ch.IsBlank()) { continue; } //33051 UARTs, Stream Outs, and Stream Ins do not have ISOCodes, so don't include them when //determining whether a Group contains channels for multiple Test Objects or multiple Positions ("Mixed") if (string.IsNullOrEmpty(ch.IsoCode) && (ch.IsUart || ch.IsStreamOut || ch.IsStreamIn)) { continue; } var isocode = new DTS.Common.ISO.IsoCode(ch.IsoCode); var chTestObject = isocode.TestObject; if (string.IsNullOrEmpty(ch.IsoCode)) { chTestObject = ""; } if (string.IsNullOrEmpty(testObject)) { testObject = chTestObject; } else { if (testObject != chTestObject) { testObjectMixed = true; } } var chPosition = isocode.Position; if (string.IsNullOrEmpty(ch.IsoCode) || ch.IsoCode.Length < 2) { chPosition = ""; } if (string.IsNullOrEmpty(position)) { position = chPosition; } else { if (position != chPosition) { positionMixed = true; } } } PositionIsMixed = positionMixed; if (positionMixed) { Position = ""; } else { if (!string.Empty.Equals(position)) { Position = position; } else { if (ExtraProperties.Exists(p => p.Key == "POSITION")) { var match = ExtraProperties.Find(p => p.Key == "POSITION"); Position = match.Value; } } } if (testObjectMixed) { TestObject = ""; } else { if (!string.Empty.Equals(testObject)) { TestObject = testObject; } else { if (ExtraProperties.Exists(p => p.Key == "TESTOBJECT")) { var match = ExtraProperties.Find(p => p.Key == "TESTOBJECT"); TestObject = match.Value; } } } TestObjectIsMixed = testObjectMixed; } private bool _positionIsMixed = false; public bool PositionIsMixed { get => _positionIsMixed; set { SetProperty(ref _positionIsMixed, value, "PositionIsMixed"); OnPropertyChanged("PositionIsTextbox"); OnPropertyChanged("PositionIsCombobox"); } } private bool _positionIsTextbox = false; public bool PositionIsTextbox { get { if (!DFConstantsAndEnums.UseDropDownForTestObjectAndPosition) { return true; } return _positionIsMixed ? false : _positionIsTextbox; } set => SetProperty(ref _positionIsTextbox, value, "PositionIsTextbox"); } public bool PositionIsCombobox { get { if (!DFConstantsAndEnums.UseDropDownForTestObjectAndPosition) { return false; } return _positionIsMixed ? false : !_positionIsTextbox; } set => SetProperty(ref _positionIsTextbox, !value, "PositionIsCombobox"); } private string _position = "?"; public string Position { get => _position; set { SetProperty(ref _position, value, "Position"); if (ExtraProperties.Exists(x => x.Key == "POSITION")) { var match = ExtraProperties.First(x => x.Key == "POSITION"); ExtraProperties.Remove(match); } ExtraProperties.Add(new KeyValuePair("POSITION", value)); } } private List _availablePositions = new List(); public List AvailablePositions { get { return _availablePositions; } set => SetProperty(ref _availablePositions, value, "AvailablePositions"); } private string _selectedPositionItem; public string SelectedPositionItem { get { _selectedPositionItem = _availablePositions.Where(x => x.StartsWith(Position)).FirstOrDefault(); return _selectedPositionItem; } set { Position = value.Substring(0, 1); SetProperty(ref _selectedPositionItem, value, "SelectedPositionItem"); } } private bool _testObjectIsMixed = false; public bool TestObjectIsMixed { get => _testObjectIsMixed; set { SetProperty(ref _testObjectIsMixed, value, "TestObjectIsMixed"); OnPropertyChanged("TestObjectIsTextbox"); OnPropertyChanged("TestObjectIsCombobox"); } } private bool _testObjectIsTextbox = false; public bool TestObjectIsTextbox { get { if (!DFConstantsAndEnums.UseDropDownForTestObjectAndPosition) { return true; } return _testObjectIsMixed ? false : _testObjectIsTextbox; } set => SetProperty(ref _testObjectIsTextbox, value, "TestObjectIsTextbox"); } public bool TestObjectIsCombobox { get { if (!DFConstantsAndEnums.UseDropDownForTestObjectAndPosition) { return false; } return _testObjectIsMixed ? false : !_testObjectIsTextbox; } set => SetProperty(ref _testObjectIsTextbox, !value, "TestObjectIsCombobox"); } private List _availableTestObjects = new List(); public List AvailableTestObjects { get { return _availableTestObjects; } set => SetProperty(ref _availableTestObjects, value, "AvailableTestObjects"); } private string _selectedTestObjectItem; public string SelectedTestObjectItem { get { _selectedTestObjectItem = _availableTestObjects.Where(x => x.StartsWith(TestObject)).FirstOrDefault(); return _selectedTestObjectItem; } set { TestObject = value.Substring(0, 1); SetProperty(ref _selectedTestObjectItem, value, "SelectedTestObjectItem"); } } private string _testObject = "?"; public string TestObject { get => _testObject; set { SetProperty(ref _testObject, value, "TestObject"); if (ExtraProperties.Exists(x => x.Key == "TESTOBJECT")) { var match = ExtraProperties.First(x => x.Key == "TESTOBJECT"); ExtraProperties.Remove(match); } ExtraProperties.Add(new KeyValuePair("TESTOBJECT", value)); } } private int _displayOrder = -1; public static long[] GetExistingChannelIds(int Id) { var list = new List(); var hResult = DbOperations.ChannelsGet(null, Id, null, null, null, null, out var dbChannels); if (0 == hResult && null != dbChannels && dbChannels.Any()) { foreach (var channel in dbChannels) { var id = Convert.ToInt64(channel.Id); if (!list.Contains(id)) { list.Add(id); } } } return list.ToArray(); } public int DisplayOrder { get => _displayOrder; set => SetProperty(ref _displayOrder, value, "DisplayOrder"); } public ISensorData GetSensor(DTS.Common.Interface.Channels.IGroupChannel channel, ISensorData sensorData, bool bUseISOFilter) { if (null == channel.ChannelSettings || !channel.ChannelSettings.Any()) { return sensorData; } if (null == sensorData) { return null; } if (sensorData.IsSquib()) { return GetSensorSquib(channel, sensorData); } if (sensorData.IsDigitalInput()) { return GetSensorDigitalIn(channel, sensorData); } if (sensorData.IsDigitalOutput()) { return GetSensorDigitalOut(channel, sensorData); } if (sensorData.IsUart()) { return GetSensorUart(channel, sensorData); } if (sensorData.IsStreamOutput()) { return GetSensorStreamOut(channel, sensorData); } if (sensorData.IsStreamInput()) { return GetSensorStreamIn(channel, sensorData); } if (sensorData.IsCan()) { return GetSensorCan(channel, sensorData); } if (sensorData.IsTestSpecificEmbedded) { sensorData = GetSensorEmbeddedAnalog(channel, sensorData); } else if (sensorData.IsTestSpecificThermo) { sensorData = GetSensorEmbeddedThermo(channel, sensorData); } else { sensorData = GetSensorAnalog(channel, sensorData); } if (bUseISOFilter) { var isoCode = new DTS.Common.ISO.IsoCode(channel.IsoCode); sensorData.FilterClassIso = isoCode.FilterClass; } return sensorData; } private static ISensorData GetSensorSquib(DTS.Common.Interface.Channels.IGroupChannel channel, ISensorData sensorData) { foreach (var setting in channel.ChannelSettings) { switch (setting.SettingName) { case ChannelSettingBase.SQMODE: sensorData.SquibFireMode = (DTS.Common.Enums.SquibFireMode)setting.IntValue; break; case ChannelSettingBase.SQUIB_DELAY: sensorData.SquibFireDelayMS = setting.DoubleValue; break; case ChannelSettingBase.SQUIB_CURRENT: sensorData.SquibOutputCurrent = setting.DoubleValue; break; case ChannelSettingBase.SQUIB_DURATION: sensorData.SquibFireDurationMS = setting.DoubleValue; break; case ChannelSettingBase.SQUIB_LIMIT_DURATION: sensorData.LimitSquibFireDuration = setting.BoolValue; break; } } return sensorData; } private ISensorData GetSensorDigitalIn(DTS.Common.Interface.Channels.IGroupChannel channel, ISensorData sensorData) { //DIMode, defaultValue,ActiveValue foreach (var setting in channel.ChannelSettings) { switch (setting.SettingName) { case ChannelSettingBase.DIMODE: sensorData.InputMode = (DTS.Common.Enums.DigitalInputModes)setting.IntValue; break; case ChannelSettingBase.DEFAULT_VALUE: sensorData.InputDefaultValue = setting.DoubleValue; break; case ChannelSettingBase.ACTIVE_VALUE: sensorData.InputActiveValue = setting.DoubleValue; break; } } return sensorData; } private ISensorData GetSensorDigitalOut(DTS.Common.Interface.Channels.IGroupChannel channel, ISensorData sensorData) { //OutputMode foreach (var setting in channel.ChannelSettings) { switch (setting.SettingName) { case ChannelSettingBase.OUTPUT_MODE: sensorData.DigitalOutputMode = (DTS.Common.Enums.DigitalOutputModes)setting.IntValue; break; case ChannelSettingBase.DIGITALOUT_LIMIT_DURATION: sensorData.DigitalOutputLimitDuration = setting.BoolValue; break; case ChannelSettingBase.DIGITALOUT_DURATION: sensorData.DigitalOutputDurationMS = setting.DoubleValue; break; case ChannelSettingBase.DIGITALOUT_DELAY: sensorData.DigitalOutputDelayMS = setting.DoubleValue; break; } } return sensorData; } private ISensorData GetSensorUart(DTS.Common.Interface.Channels.IGroupChannel channel, ISensorData sensorData) { //Uart foreach (var setting in channel.ChannelSettings) { try { switch (setting.SettingName) { case ChannelSettingBase.BAUD_RATE: sensorData.UartBaudRate = (uint)setting.IntValue; break; case ChannelSettingBase.DATA_BITS: sensorData.UartDataBits = (uint)setting.IntValue; break; case ChannelSettingBase.STOP_BITS: sensorData.UartStopBits = (StopBits)Enum.Parse(typeof(StopBits), setting.Value); break; case ChannelSettingBase.PARITY: sensorData.UartParity = (Parity)Enum.Parse(typeof(Parity), setting.Value); break; case ChannelSettingBase.FLOW_CONTROL: //FB 30486 Hardcode FlowControl to NONE for UART sensor type //It's always NONE break; case ChannelSettingBase.DATA_FORMAT: sensorData.UartDataFormat = (DTS.Common.Enums.UartDataFormat)Enum.Parse(typeof(DTS.Common.Enums.UartDataFormat), setting.Value); break; } } catch (Exception ex) { APILogger.Log($"Failed to process: {setting.SettingName} value: {setting.Value}", ex); } } return sensorData; } private ISensorData GetSensorStreamIn(DTS.Common.Interface.Channels.IGroupChannel channel, ISensorData sensorData) { //StreamInputMode foreach (var setting in channel.ChannelSettings) { try { switch (setting.SettingName) { case ChannelSettingBase.UDP_ADDRESS_IN: sensorData.StreamInUDPAddress = setting.Value; break; } } catch (Exception ex) { APILogger.Log($"Failed to process: {setting.SettingName} value: {setting.Value}", ex); } } return sensorData; } private ISensorData GetSensorStreamOut(DTS.Common.Interface.Channels.IGroupChannel channel, ISensorData sensorData) { //StreamOutputMode foreach (var setting in channel.ChannelSettings) { try { switch (setting.SettingName) { case ChannelSettingBase.UDP_PROFILE: sensorData.StreamOutUDPProfile = (DTS.Common.Enums.UDPStreamProfile)Enum.Parse(typeof(DTS.Common.Enums.UDPStreamProfile), setting.Value); break; case ChannelSettingBase.UDP_ADDRESS: sensorData.StreamOutUDPAddress = setting.Value; break; case ChannelSettingBase.UDP_TIME_CHID: sensorData.StreamOutUDPTimeChannelId = (ushort)setting.IntValue; break; case ChannelSettingBase.UDP_DATA_CHID: sensorData.StreamOutUDPDataChannelId = (ushort)setting.IntValue; break; case ChannelSettingBase.UDP_TMNS_CONFIG: sensorData.StreamOutUDPTmNSConfig = setting.Value; break; case ChannelSettingBase.IRIG_TDP_INTERVAL_MS: sensorData.StreamOutIRIGTimeDataPacketIntervalMs = (ushort)setting.IntValue; break; } } catch (Exception ex) { APILogger.Log($"Failed to process: {setting.SettingName} value: {setting.Value}", ex); } } return sensorData; } private static ISensorData GetSensorCan(DTS.Common.Interface.Channels.IGroupChannel channel, ISensorData sensorData) { //CAN foreach (var setting in channel.ChannelSettings) { try { switch (setting.SettingName) { case ChannelSettingBase.CAN_IS_FD: sensorData.CanIsFD = setting.BoolValue; break; case ChannelSettingBase.CAN_ARB_BASE_BITRATE: sensorData.CanArbBaseBitrate = setting.IntValue; break; case ChannelSettingBase.CAN_ARB_BASE_SJW: sensorData.CanArbBaseSJW = setting.IntValue; break; case ChannelSettingBase.CAN_DATA_BITRATE: sensorData.CanDataBitrate = setting.IntValue; break; case ChannelSettingBase.CAN_DATA_SJW: sensorData.CanDataSJW = setting.IntValue; break; case ChannelSettingBase.CAN_FILE_TYPE: sensorData.CanFileType = setting.ToString(); break; } } catch (Exception ex) { APILogger.Log($"Failed to process: {setting.SettingName} value: {setting.Value}", ex); } } return sensorData; } private ISensorData GetSensorAnalog(DTS.Common.Interface.Channels.IGroupChannel channel, ISensorData sensorData) { //Range,CFC,Polarity foreach (var setting in channel.ChannelSettings) { switch (setting.SettingName) { case ChannelSettingBase.RANGE: sensorData.Capacity = setting.DoubleValue; break; case ChannelSettingBase.CFC: sensorData.FilterClassIso = setting.Value; break; //FB 13120 parse and set the filter class from setting case ChannelSettingBase.FilterClass: if (null == setting.Value) { setting.Value = setting.DefaultValue; } string[] settings = setting.Value.Split(','); if (Enum.TryParse(settings[0], out FilterClassType filterClassType)) { if (filterClassType == FilterClassType.AdHoc) { sensorData.FilterClass = new FilterClass(Convert.ToDouble(settings[1])); } else { sensorData.FilterClass = new FilterClass(filterClassType); } } break; case ChannelSettingBase.POLARITY: sensorData.Polarity = setting.Value; break; case ChannelSettingBase.USERVALUE1: sensorData.UserValue1 = setting.Value; break; case ChannelSettingBase.USERVALUE2: sensorData.UserValue2 = setting.Value; break; case ChannelSettingBase.USERVALUE3: sensorData.UserValue3 = setting.Value; break; case ChannelSettingBase.INITIAL_OFFSET: { sensorData.InitialOffset = new InitialOffset(setting.Value); } break; } } return sensorData; } private static ISensorData GetSensorEmbeddedThermo(DTS.Common.Interface.Channels.IGroupChannel channel, ISensorData sensorData) { sensorData.FilterClass = FilterClass.GetFilterClassFromFilterClassType(FilterClassType.Unfiltered); var units = "C"; sensorData.Calibration.Records.Records[0].EngineeringUnits = units; return sensorData; } private ISensorData GetSensorEmbeddedAnalog(DTS.Common.Interface.Channels.IGroupChannel channel, ISensorData sensorData) { //Range,CFC,Polarity foreach (var setting in channel.ChannelSettings) { switch (setting.SettingName) { case ChannelSettingBase.RANGE: sensorData.Capacity = setting.DoubleValue; break; case ChannelSettingBase.CFC: sensorData.FilterClassIso = setting.Value; break; //FB 13120 parse and set the filter class from setting case ChannelSettingBase.FilterClass: if (null == setting.Value) { setting.Value = setting.DefaultValue; } string[] settings = setting.Value.Split(','); if (Enum.TryParse(settings[0], out FilterClassType filterClassType)) { if (filterClassType == FilterClassType.AdHoc) { sensorData.FilterClass = new FilterClass(Convert.ToDouble(settings[1])); } else { sensorData.FilterClass = new FilterClass(filterClassType); } } break; case ChannelSettingBase.ACCouplingEnabled: ((SensorData)sensorData).ACCouplingModeEnabled = setting.BoolValue; break; case ChannelSettingBase.POLARITY: sensorData.Polarity = setting.Value; break; case ChannelSettingBase.USERVALUE1: sensorData.UserValue1 = setting.Value; break; case ChannelSettingBase.USERVALUE2: sensorData.UserValue2 = setting.Value; break; case ChannelSettingBase.USERVALUE3: sensorData.UserValue3 = setting.Value; break; case ChannelSettingBase.INITIAL_OFFSET: { sensorData.InitialOffset = new InitialOffset(setting.Value); } break; } } //TODO: REMOVE THIS HACK when we have proper get cal functions var units = "g"; //http://manuscript.dts.local/f/cases/29719/change-bme-pressure-dimension-to-PSI-and-bmi-angular-rate-dimension-to-degrees-per-second if (channel.Sensor.Contains("Angular Rate")) units = "deg/s"; if (channel.Sensor.Contains("Pressure")) units = "PSI"; if (channel.Sensor.Contains("Temperature")) units = "C"; if (channel.Sensor.Contains("Humidity")) units = "% RH"; if (null != channel.HardwareChannel && !channel.HardwareChannel.IsTSRAIR) { units = "mV"; sensorData.Calibration.RemoveOffset = false; sensorData.Calibration.ZeroMethods = new ZeroMethods(new[] { new ZeroMethod(ZeroMethodType.None, -.05, .05), new ZeroMethod(ZeroMethodType.UsePreEventDiagnosticsZero, -.05, .05), new ZeroMethod(ZeroMethodType.AverageOverTime, -.05, .05) }); //this is another way of turning off shunt (-1 resistance) sensorData.BridgeResistance = -1; } sensorData.Calibration.Records.Records[0].EngineeringUnits = units; return sensorData; } private void SetSensorSquib(DTS.Common.Interface.Channels.IGroupChannel channel, ISensorData sensorData) { //limitduration,duration,delay,sqmode var dictionary = DbOperations.GetSettingsLookup(); var settings = new List(); var limitDurationTuple = dictionary[ChannelSettingBase.SQUIB_LIMIT_DURATION]; settings.Add( new ChannelSettingBase(limitDurationTuple.Item1, limitDurationTuple.Item2, limitDurationTuple.Item3) { BoolValue = sensorData.LimitSquibFireDuration }); var durationTuple = dictionary[ChannelSettingBase.SQUIB_DURATION]; settings.Add(new ChannelSettingBase(durationTuple.Item1, durationTuple.Item2, durationTuple.Item3) { DoubleValue = sensorData.SquibFireDurationMS }); var delayTuple = dictionary[ChannelSettingBase.SQUIB_DELAY]; settings.Add(new ChannelSettingBase(delayTuple.Item1, delayTuple.Item2, delayTuple.Item3) { DoubleValue = sensorData.SquibFireDelayMS }); var currentTuple = dictionary[ChannelSettingBase.SQUIB_CURRENT]; settings.Add(new ChannelSettingBase(currentTuple.Item1, currentTuple.Item2, currentTuple.Item3) { DoubleValue = sensorData.SquibOutputCurrent }); var sqModeTuple = dictionary[ChannelSettingBase.SQMODE]; settings.Add(new ChannelSettingBase(sqModeTuple.Item1, sqModeTuple.Item2, sqModeTuple.Item3) { IntValue = (int)sensorData.SquibFireMode }); channel.ChannelSettings = settings.ToArray(); } private void SetSensorDigitalIn(DTS.Common.Interface.Channels.IGroupChannel channel, ISensorData sensorData) { //DIMode, defaultValue,ActiveValue var dictionary = DbOperations.GetSettingsLookup(); var settings = new List(); var modeTuple = dictionary[ChannelSettingBase.DIMODE]; settings.Add(new ChannelSettingBase(modeTuple.Item1, modeTuple.Item2, modeTuple.Item3) { IntValue = (int)sensorData.InputMode }); var defaultValueTuple = dictionary[ChannelSettingBase.DEFAULT_VALUE]; settings.Add( new ChannelSettingBase(defaultValueTuple.Item1, defaultValueTuple.Item2, defaultValueTuple.Item3) { DoubleValue = sensorData.InputDefaultValue }); var activeValueTuple = dictionary[ChannelSettingBase.ACTIVE_VALUE]; settings.Add(new ChannelSettingBase(activeValueTuple.Item1, activeValueTuple.Item2, activeValueTuple.Item3) { DoubleValue = sensorData.InputActiveValue }); channel.ChannelSettings = settings.ToArray(); } private void SetSensorDigitalOut(DTS.Common.Interface.Channels.IGroupChannel channel, ISensorData sensorData) { //OutputMode var dictionary = DbOperations.GetSettingsLookup(); var settings = new List(); var tuple = dictionary[ChannelSettingBase.OUTPUT_MODE]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { IntValue = (int)sensorData.DigitalOutputMode }); tuple = dictionary[ChannelSettingBase.DIGITALOUT_LIMIT_DURATION]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { BoolValue = sensorData.DigitalOutputLimitDuration }); tuple = dictionary[ChannelSettingBase.DIGITALOUT_DURATION]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { DoubleValue = (double)sensorData.DigitalOutputDurationMS }); tuple = dictionary[ChannelSettingBase.DIGITALOUT_DELAY]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { DoubleValue = (double)sensorData.DigitalOutputDelayMS }); channel.ChannelSettings = settings.ToArray(); } private void SetSensorUart(DTS.Common.Interface.Channels.IGroupChannel channel, ISensorData sensorData) { //uartBaudRate, uartDataBits,... etc var dictionary = DbOperations.GetSettingsLookup(); var settings = new List(); var tupleBaudRate = dictionary[ChannelSettingBase.BAUD_RATE]; settings.Add(new ChannelSettingBase(tupleBaudRate.Item1, tupleBaudRate.Item2, tupleBaudRate.Item3) { IntValue = Convert.ToInt32(sensorData.UartBaudRate) }); var tupleDataBits = dictionary[ChannelSettingBase.DATA_BITS]; settings.Add(new ChannelSettingBase(tupleDataBits.Item1, tupleDataBits.Item2, tupleDataBits.Item3) { IntValue = Convert.ToInt32(sensorData.UartDataBits) }); var tupleStopBits = dictionary[ChannelSettingBase.STOP_BITS]; settings.Add(new ChannelSettingBase(tupleStopBits.Item1, tupleStopBits.Item2, tupleStopBits.Item3) { Value = sensorData.UartStopBits.ToString() }); var tupleParity = dictionary[ChannelSettingBase.PARITY]; settings.Add(new ChannelSettingBase(tupleParity.Item1, tupleParity.Item2, tupleParity.Item3) { Value = sensorData.UartParity.ToString() }); var tupleFlowControl = dictionary[ChannelSettingBase.FLOW_CONTROL]; settings.Add(new ChannelSettingBase(tupleFlowControl.Item1, tupleFlowControl.Item2, tupleFlowControl.Item3) { Value = sensorData.UartFlowControl.ToString() }); var tupleDataFormat = dictionary[ChannelSettingBase.DATA_FORMAT]; settings.Add(new ChannelSettingBase(tupleDataFormat.Item1, tupleDataFormat.Item2, tupleDataFormat.Item3) { Value = sensorData.UartDataFormat.ToString() }); channel.ChannelSettings = settings.ToArray(); } private void SetSensorCan(DTS.Common.Interface.Channels.IGroupChannel channel, ISensorData sensorData) { var dictionary = DbOperations.GetSettingsLookup(); var settings = new List(); var tupleIsFD = dictionary[ChannelSettingBase.CAN_IS_FD]; settings.Add(new ChannelSettingBase(tupleIsFD.Item1, tupleIsFD.Item2, tupleIsFD.Item3) { BoolValue = Convert.ToBoolean(sensorData.CanIsFD) }); var tupleArbBaseBitrate = dictionary[ChannelSettingBase.CAN_ARB_BASE_BITRATE]; settings.Add(new ChannelSettingBase(tupleArbBaseBitrate.Item1, tupleArbBaseBitrate.Item2, tupleArbBaseBitrate.Item3) { IntValue = Convert.ToInt32(sensorData.CanArbBaseBitrate) }); var tupleArbBaseSJW = dictionary[ChannelSettingBase.CAN_ARB_BASE_SJW]; settings.Add(new ChannelSettingBase(tupleArbBaseSJW.Item1, tupleArbBaseSJW.Item2, tupleArbBaseSJW.Item3) { IntValue = Convert.ToInt32(sensorData.CanArbBaseSJW) }); var tupleDataBitrate = dictionary[ChannelSettingBase.CAN_DATA_BITRATE]; settings.Add(new ChannelSettingBase(tupleDataBitrate.Item1, tupleDataBitrate.Item2, tupleDataBitrate.Item3) { IntValue = Convert.ToInt32(sensorData.CanDataBitrate) }); var tupleDataSJW = dictionary[ChannelSettingBase.CAN_DATA_SJW]; settings.Add(new ChannelSettingBase(tupleDataSJW.Item1, tupleDataSJW.Item2, tupleDataSJW.Item3) { IntValue = Convert.ToInt32(sensorData.CanDataSJW) }); var tupleFileType = dictionary[ChannelSettingBase.CAN_FILE_TYPE]; settings.Add(new ChannelSettingBase(tupleFileType.Item1, tupleFileType.Item2, tupleFileType.Item3) { Value = sensorData.CanFileType.ToString() }); channel.ChannelSettings = settings.ToArray(); } private void SetSensorAnalog(DTS.Common.Interface.Channels.IGroupChannel channel, ISensorData sensorData) { //Range,CFC,Polarity var settings = new List(); var dictionary = DbOperations.GetSettingsLookup(); var rangeTuple = dictionary[ChannelSettingBase.RANGE]; settings.Add(new ChannelSettingBase(rangeTuple.Item1, rangeTuple.Item2, rangeTuple.Item3) { DoubleValue = sensorData.Capacity }); var CFCTuple = dictionary[ChannelSettingBase.CFC]; settings.Add(new ChannelSettingBase(CFCTuple.Item1, CFCTuple.Item2, CFCTuple.Item3) { Value = sensorData.FilterClassIso }); //FB 13120 set filter class var FilterClassTuple = dictionary[ChannelSettingBase.FilterClass]; settings.Add(new ChannelSettingBase(FilterClassTuple.Item1, FilterClassTuple.Item2, FilterClassTuple.Item3) { Value = $"{ sensorData?.FilterClass?.FClass},{ sensorData?.FilterClass?.Frequency}" }); var polarityTuple = dictionary[ChannelSettingBase.POLARITY]; settings.Add(new ChannelSettingBase(polarityTuple.Item1, polarityTuple.Item2, polarityTuple.Item3) { Value = sensorData.Polarity }); channel.ChannelSettings = settings.ToArray(); } public void SetSensor(DTS.Common.Interface.Channels.IGroupChannel channel, ISensorData sensorData) { if (sensorData.IsSquib()) { SetSensorSquib(channel, sensorData); } else if (sensorData.IsDigitalInput()) { SetSensorDigitalIn(channel, sensorData); } else if (sensorData.IsDigitalOutput()) { SetSensorDigitalOut(channel, sensorData); } else if (sensorData.IsUart()) { SetSensorUart(channel, sensorData); } else if (sensorData.IsCan()) { SetSensorCan(channel, sensorData); } else SetSensorAnalog(channel, sensorData); } private List SaveChannels(DTS.Common.Interface.Channels.IGroupChannel[] groupChannels, bool canUserSaveChannelCodes) { var newGroupChannelList = new List(); var args = new List(); var idsToKeep = new HashSet(); var idsToDelete = new List(); foreach (var channel in groupChannels) { if (channel.Id < 0) { continue; } if (channel.IsBlank()) { continue; } idsToKeep.Add(channel.Id); } var existingIds = GetExistingChannelIds(Id); foreach (var id in existingIds) { if (!idsToKeep.Contains(id)) { idsToDelete.Add(id); } } if (idsToDelete.Any()) { foreach (var id in idsToDelete) { DeleteChannel(id); } } //step 2, update any existing channels foreach (var channel in groupChannels) { if (channel.Id < 0) { continue; } if (channel.IsBlank()) { continue; } UpdateChannel(channel); args.AddRange(new[] { new DTS.Common.Events.ChannelCodes.ChannelCodeCommittedEventArgs(DTS.Common.Enums.Channels.ChannelEnumsAndConstants.ChannelCodeType.ISO, channel.IsoCode, channel.IsoChannelName, canUserSaveChannelCodes), new DTS.Common.Events.ChannelCodes.ChannelCodeCommittedEventArgs(DTS.Common.Enums.Channels.ChannelEnumsAndConstants.ChannelCodeType.User, channel.UserCode, channel.UserChannelName, canUserSaveChannelCodes) } ); } //step 3, add any new channels foreach (var channel in groupChannels) { if (channel.Id >= 0) { continue; } if (channel.IsBlank()) { continue; } InsertChannel(channel); newGroupChannelList.Add(channel); args.AddRange(new[] { new DTS.Common.Events.ChannelCodes.ChannelCodeCommittedEventArgs(DTS.Common.Enums.Channels.ChannelEnumsAndConstants.ChannelCodeType.ISO, channel.IsoCode, channel.IsoChannelName, canUserSaveChannelCodes), new DTS.Common.Events.ChannelCodes.ChannelCodeCommittedEventArgs(DTS.Common.Enums.Channels.ChannelEnumsAndConstants.ChannelCodeType.User, channel.UserCode, channel.UserChannelName, canUserSaveChannelCodes) } ); } PublishCodes(args.ToArray()); return newGroupChannelList; } private static object _vm = null; private void PublishCodes(DTS.Common.Events.ChannelCodes.ChannelCodeCommittedEventArgs[] args) { if (!Application.Current.Dispatcher.CheckAccess()) { Application.Current.Dispatcher.BeginInvoke(new Action(() => { PublishCodes(args); })); } else { if (null == _vm) { //13868 Custom codes are added to a group, but does not appear in the channel codes tile //make sure this vm is initialized and listening var UnityContainer = ContainerLocator.Container.Resolve(); _vm = UnityContainer.Resolve(); } var eg = ContainerLocator.Container.Resolve(); eg.GetEvent().Publish(args); } } private void DeleteHardware(int id) { var errorNumber = DbOperations.GroupHardwareDelete(Id, id, out string errorMessage); if (errorNumber != 0) { throw new Exception(errorMessage); } } private void SaveHardware() { //step 1, delete any hardware that no longer exists var existingIds = GetExistingHardware(); var hash = new HashSet(); if (existingIds.Any()) { foreach (var id in existingIds) { if (!IncludedHardware.Contains(id)) { DeleteHardware(id); } else { hash.Add(id); } } } //step 2, insert any new hardware foreach (var id in IncludedHardware) { if (hash.Contains(id)) { continue; } else { InsertHardware(id); } } } private void InsertHardware(int id) { var groupHardwareDbRecord = new GroupHardwareDbRecord(); groupHardwareDbRecord.GroupId = Id; groupHardwareDbRecord.DASId = id; var errorNumber = DbOperations.GroupHardwareInsert(groupHardwareDbRecord, out int newId, out string errorMessage); if (errorNumber != 0) { throw new Exception(errorMessage); } } public bool Save(DTS.Common.Interface.Channels.IGroupChannel[] groupChannels, bool canUserSaveChannelCodes) { DisplayName = DisplayName.Trim(); Name = Name.Trim(); Tags = Tags.Trim(); SaveGroup(); SaveChannels(groupChannels, canUserSaveChannelCodes); SaveHardware(); return true; } public bool Save(DTS.Common.Interface.Channels.IGroupChannel[] groupChannels, bool canUserSaveChannelCodes, ref List newGroupChannelList) { DisplayName = DisplayName.Trim(); Name = Name.Trim(); Tags = Tags.Trim(); SaveGroup(); newGroupChannelList = SaveChannels(groupChannels, canUserSaveChannelCodes); SaveHardware(); return true; } public DTS.Common.Interface.Channels.IGroupChannel[] GetAllChannels(bool bEditable, IDictionary sensorLookup, IDictionary hardwareLookup, IChannelSetting[] channelDefaults, bool allowSensorPushAndPull = false) { if (Id < 0) { return new DTS.Common.Interface.Channels.IGroupChannel[0]; } var list = new List(); var hResult = DbOperations.ChannelsGet(null, Id, null, null, null, null, out var dbChannels); if (0 == hResult && null != dbChannels && dbChannels.Any()) { foreach (var channel in dbChannels) { list.Add(new GroupChannel(channel, this, bEditable, sensorLookup, hardwareLookup, channelDefaults, allowSensorPushAndPull)); } } var defaults = DbOperations.GetSettingsLookup2(); var channelIdList = new List(); foreach (var channel in list) { channelIdList.Add(channel.Id); } var channelList = LoadSettings(channelIdList, defaults); foreach (var channel in list) { channel.ChannelSettings = channelList[channel.Id].ToArray(); channel.BorderShouldShowOutOfDate = allowSensorPushAndPull; if (channel.IsCan) { channel.AdjustCANSources(channel.CanIsFD, channel.CanArbBaseBitrate, channel.CanDataBitrate); } } return list.ToArray(); } private static Dictionary>> _cachedGroupChannelSettings = new Dictionary>>(); private static Dictionary> _cachedChannelSettings = new Dictionary>(); public void ClearGroupChannelSettingCache(long groupId) { _cachedGroupChannelSettings.Remove(groupId); } private Dictionary> LoadSettings(List channelIdList, Dictionary> defaults) { var settingsList = new Dictionary>(); if (channelIdList.Count <= 0) { return settingsList; } var channelList = new Dictionary>(); if (RunTestVariables.InRunTest && _cachedGroupChannelSettings != null && _cachedGroupChannelSettings.Any() && _cachedGroupChannelSettings.ContainsKey(Id)) { var cacheIsUpToDate = true; foreach (var channelId in channelIdList) { if (_cachedGroupChannelSettings[Id] == null || !_cachedGroupChannelSettings[Id].ContainsKey(channelId)) { cacheIsUpToDate = false; break; } } if (cacheIsUpToDate) { DbOperations.LogDBCaching("****** Using cached group channel settings in LoadSettings"); channelList = _cachedGroupChannelSettings[Id]; return channelList; } } foreach (var id in channelIdList) { channelList[id] = new List(); } //Can't return the cache, so get them all var hr = DbOperations.GroupChannelSettingsGet(channelIdList, out var records, out var errors); if (0 == hr && null != records && records.Any()) { foreach (var record in records) { if (defaults.ContainsKey(record.SettingId)) { var defaultData = defaults[record.SettingId]; var channelSetting = new ChannelSettingBase(record.SettingId, defaultData.Item1, defaultData.Item2) { Value = record.SettingValue }; if (!channelList.ContainsKey(record.ChannelId)) { channelList[record.ChannelId] = new List(); } channelList[record.ChannelId].Add(channelSetting); } } } if (_cachedGroupChannelSettings != null) { _cachedGroupChannelSettings[Id] = RunTestVariables.InRunTest ? channelList : null; } return channelList; } private void UpdateChannel(DTS.Common.Interface.Channels.IGroupChannel channel) { var iChannelDbRecord = (IChannelDbRecord)channel; iChannelDbRecord.GroupId = Id; iChannelDbRecord.LastModified = LastModified; iChannelDbRecord.LastModifiedBy = LastModifiedBy; _ = DbOperations.ChannelsUpdate(iChannelDbRecord); //delete any channel settings for channel DeleteSettings(channel.Id); //insert new channel settings for channel foreach (var setting in channel.ChannelSettings) { setting.ChannelId = channel.Id; InsertSetting(setting); } } private void InsertSetting(IChannelSetting setting) { if (null == setting.Value) { return; } _ = DbOperations.GroupChannelSettingsInsert(setting.ChannelId, new GroupChannelSettingRecord(setting.ChannelId, setting.SettingTypeId, setting.Value)); } private void DeleteSettings(long channelId) { _ = DbOperations.GroupChannelSettingsDelete(channelId, null); } private void InsertChannel(DTS.Common.Interface.Channels.IGroupChannel channel) { var iChannelDbRecord = (IChannelDbRecord)channel; channel.GroupId = Id; channel.LastModified = LastModified; channel.LastModifiedBy = LastModifiedBy; _ = DbOperations.ChannelsInsert(ref iChannelDbRecord); //insert new channel settings for channel foreach (var setting in channel.ChannelSettings) { //When Inserting a channel, the three UserValueX settings will be "", but we want them //inserted because any subsequent Update will be setting them and we want them to be //identical when a Group is added to a Test Setup (which will do an Insert). if (string.IsNullOrWhiteSpace(setting.Value) && setting.SettingName != ChannelSettingBase.USERVALUE1 && setting.SettingName != ChannelSettingBase.USERVALUE2 && setting.SettingName != ChannelSettingBase.USERVALUE3) { continue; } setting.ChannelId = channel.Id; InsertSetting(setting); } } private static void DeleteChannel(long id) { var errorNumber = DbOperations.ChannelsDelete(id, out string errorMessage); if (errorNumber != 0) { throw new Exception(errorMessage); } } public int CompareTo(IGroup other) { var ret = DisplayOrder.CompareTo(other.DisplayOrder); if (0 != ret) { return ret; } ret = Id.CompareTo(other.Id); if (0 != ret) { return ret; } return DisplayName.CompareTo(other.DisplayName); } public override bool Equals(object o) { if (o is IGroup other) { return CompareTo(other) == 0; } return base.Equals(o); } public override int GetHashCode() { return base.GetHashCode(); } public void WriteXML(ref System.Xml.XmlWriter writer) { writer.WriteStartElement("Group"); var fields = Enum.GetValues(typeof(DbOperations.TestSetups.GroupsGroupFields)).Cast().ToArray(); foreach (var f in fields) { writer.WriteStartElement(f.ToString()); switch (f) { case DbOperations.TestSetups.GroupsGroupFields.Name: writer.WriteString(Name); break; case DbOperations.TestSetups.GroupsGroupFields.LastModified: writer.WriteString(LastModified.ToString(CultureInfo.InvariantCulture)); break; case DbOperations.TestSetups.GroupsGroupFields.LastModifiedBy: writer.WriteString(LastModifiedBy); break; case DbOperations.TestSetups.GroupsGroupFields.Id: writer.WriteString(Id.ToString()); break; case DbOperations.TestSetups.GroupsGroupFields.Tags: writer.WriteString(Tags); break; default: throw new NotSupportedException("Group::WriteXML unsupported field: " + f.ToString()); } writer.WriteEndElement(); //f.ToString() } writer.WriteStartElement("HardwareList"); foreach (var hId in IncludedHardwareStringList) { writer.WriteStartElement("Hardware"); writer.WriteString(hId); writer.WriteEndElement(); //Hardware } writer.WriteEndElement(); //hardwarelist var sensorLookup = new Dictionary(); var sensors = SensorsCollection.SensorsList.GetAllSensors(false); foreach (var s in sensors) { sensorLookup[s.DatabaseId] = s; } //var hardwareLookup = new Dictionary(); //var hardware = DASHardwareList.GetAllHardware(); //foreach (var h in hardware) // foreach (var dasId in IncludedHardware) // { // //hardwareLookup[h.DASId] = h; // var h = "xxx"; //Get name, etc. from id? // hardwareLookup[dasId] = new DASHardware(h); // } foreach (var ch in GroupChannelList) { writer.WriteStartElement("Channel"); writer.WriteStartElement(DbOperations.TestSetups.GroupsGroupChannelFields.IsoChannelName.ToString()); writer.WriteString(ch.IsoChannelName); writer.WriteEndElement(); //IsoChannelName writer.WriteStartElement(DbOperations.TestSetups.GroupsGroupChannelFields.IsoCode.ToString()); writer.WriteString(ch.IsoCode); writer.WriteEndElement(); //IsoCode writer.WriteStartElement(DbOperations.TestSetups.GroupsGroupChannelFields.UserChannelName.ToString()); writer.WriteString(ch.UserChannelName); writer.WriteEndElement(); //UserChannelName writer.WriteStartElement(DbOperations.TestSetups.GroupsGroupChannelFields.UserCode.ToString()); writer.WriteString(ch.UserCode); writer.WriteEndElement(); //UserCode writer.WriteStartElement(DbOperations.TestSetups.GroupsGroupChannelFields.DASId.ToString()); writer.WriteString(ch.DASId.ToString()); writer.WriteEndElement(); //DASId writer.WriteStartElement(DbOperations.TestSetups.GroupsGroupChannelFields.DASChannelIndex.ToString()); writer.WriteString(ch.DASChannelIndex.ToString()); writer.WriteEndElement(); //DASChannelIndex writer.WriteStartElement(DbOperations.TestSetups.GroupsGroupChannelFields.GroupChannelOrder.ToString()); writer.WriteString(ch.GroupChannelOrder.ToString()); writer.WriteEndElement(); //DASChannelIndex writer.WriteStartElement(DbOperations.TestSetups.GroupsGroupChannelFields.SensorId.ToString()); writer.WriteString(ch.SensorId.ToString()); writer.WriteEndElement(); //SensorId writer.WriteStartElement(DbOperations.TestSetups.GroupsGroupChannelFields.Disabled.ToString()); writer.WriteString(ch.IsDisabled.ToString()); writer.WriteEndElement(); //Disabled writer.WriteStartElement(DbOperations.TestSetups.GroupsGroupChannelFields.LastModified.ToString()); writer.WriteString(ch.LastModified.ToString(CultureInfo.InvariantCulture)); writer.WriteEndElement(); //LastModified writer.WriteStartElement(DbOperations.TestSetups.GroupsGroupChannelFields.LastModifiedBy.ToString()); writer.WriteString(ch.LastModifiedBy); writer.WriteEndElement(); //LastModifiedBy writer.WriteStartElement("ChannelSettings"); foreach (var channelSetting in ch.ChannelSettings) { writer.WriteStartElement(channelSetting.SettingName); writer.WriteString(channelSetting.Value); writer.WriteEndElement(); //channelSettingName (Range, etc.) } writer.WriteEndElement(); //ChannelSettings writer.WriteEndElement(); //Channel } writer.WriteEndElement(); //Group } private string GetHardwareString(IEnumerable hardwareList, int hId) { foreach (var hardware in hardwareList) { if (hardware.DASId == hId) { return hardware.SerialNumber + "_" + hardware.DASType; } } return string.Empty; } public IGroup ReadXML(System.Xml.XmlElement node, Dictionary channelLookup, List sensors) { try { var group = new Group(); foreach (var child in node.ChildNodes) { if (child is System.Xml.XmlElement element) { if (Enum.TryParse(element.Name, out DbOperations.TestSetups.GroupsGroupFields field)) { switch (field) { case DbOperations.TestSetups.GroupsGroupFields.Name: group.Name = element.InnerText; break; case DbOperations.TestSetups.GroupsGroupFields.LastModifiedBy: group.LastModifiedBy = element.InnerText; break; case DbOperations.TestSetups.GroupsGroupFields.LastModified: group.LastModified = DateTime.Parse(element.InnerText, CultureInfo.InvariantCulture); break; case DbOperations.TestSetups.GroupsGroupFields.Id: group.Id = Convert.ToInt32(element.InnerText); break; case DbOperations.TestSetups.GroupsGroupFields.Tags: group.Tags = element.InnerText; break; default: throw new NotSupportedException("TestObject::ProcessXMLElement unsupported field: " + field.ToString()); } } else if (element.Name == "HardwareList") { var list = new List(); foreach (var hardwareChild in element.ChildNodes) { if (hardwareChild is System.Xml.XmlElement childElement) { list.Add(childElement.InnerText); } } group.IncludedHardwareStringList = list.ToArray(); } else if (element.Name == "Channel") { var channel = new GroupChannel(false, group.Name, group, new IChannelSetting[0]); foreach (var channelChild in element.ChildNodes) { if (channelChild is System.Xml.XmlElement childElement) { if (Enum.TryParse(childElement.Name, out DbOperations.TestSetups.GroupsGroupChannelFields channelField)) { switch (channelField) { case DbOperations.TestSetups.GroupsGroupChannelFields.IsoCode: channel.IsoCode = childElement.InnerText; break; case DbOperations.TestSetups.GroupsGroupChannelFields.IsoChannelName: channel.IsoChannelName = childElement.InnerText; break; case DbOperations.TestSetups.GroupsGroupChannelFields.UserCode: channel.UserCode = childElement.InnerText; break; case DbOperations.TestSetups.GroupsGroupChannelFields.UserChannelName: channel.UserChannelName = childElement.InnerText; break; case DbOperations.TestSetups.GroupsGroupChannelFields.DASId: channel.DASId = Convert.ToInt32(childElement.InnerText, CultureInfo.InvariantCulture); break; case DbOperations.TestSetups.GroupsGroupChannelFields.DASChannelIndex: channel.DASChannelIndex = Convert.ToInt32(childElement.InnerText, CultureInfo.InvariantCulture); break; case DbOperations.TestSetups.GroupsGroupChannelFields.GroupChannelOrder: channel.GroupChannelOrder = Convert.ToInt32(childElement.InnerText, CultureInfo.InvariantCulture); break; case DbOperations.TestSetups.GroupsGroupChannelFields.Sensor: /*Test Setup exports that were generated by 2.0.250 through 2.0.476 are Version=3 but contain */ channel.SensorId = ConvertToDatabaseId((channelChild as System.Xml.XmlElement).InnerText, sensors); break; case DbOperations.TestSetups.GroupsGroupChannelFields.SensorId: /*Test Setup exports that were generated by 2.0.477 or later contain */ channel.SensorId = Convert.ToInt32((channelChild as System.Xml.XmlElement).InnerText, CultureInfo.InvariantCulture); break; case DbOperations.TestSetups.GroupsGroupChannelFields.Disabled: channel.IsDisabled = Convert.ToBoolean(childElement.InnerText); break; case DbOperations.TestSetups.GroupsGroupChannelFields.LastModified: channel.LastModified = DateTime.Parse(childElement.InnerText, CultureInfo.InvariantCulture); break; case DbOperations.TestSetups.GroupsGroupChannelFields.LastModifiedBy: channel.LastModifiedBy = childElement.InnerText; break; } } else if (childElement.Name == "ChannelSettings") { ProcessSettingsNode(childElement, channel, sensors); } } } channelLookup[group.ChannelCount] = channel; group.ChannelCount++; } } } return group; } catch (Exception ex) { //FB 15530 Log the exception and trace log APILogger.LogException(ex); throw; } } private int ConvertToDatabaseId(string sensorSerialNumber, List sensors) { return (from sensor in sensors where sensor.SerialNumber == sensorSerialNumber select sensor.DatabaseId).FirstOrDefault(); } private void ProcessSettingsNode(System.Xml.XmlElement root, GroupChannel channel, List sensors) { try { var range = ""; var acCoupling = ""; //FB 13120 set filter class var filterclass = ""; var polarity = ""; //33415 Voltage insertion channel should be half bridge var bridgeType = ""; var limitDuration = ""; var duration = ""; var delay = ""; var outputMode = ""; var digitalOutDelay = ""; var digitalOutDuration = ""; var digitalOutLimitDuration = ""; var sqMode = ""; var squibDelay = ""; var squibCurrent = ""; var squibDuration = ""; var squibLimitDuration = ""; var diMode = ""; var defaultValue = ""; var activeValue = ""; var uartBaudRate = ""; var uartDataBits = ""; var uartStopBits = ""; var uartParity = ""; var uartFlowControl = ""; var uartDataFormat = ""; //15270 Sensor Import does not import most channel settings string userValue1, userValue2, userValue3, zeroMethod, zeroStart, zeroEnd, initialOffset; userValue1 = userValue2 = userValue3 = zeroMethod = zeroStart = zeroEnd = initialOffset = String.Empty; if (root.ChildNodes.Count > 0) { foreach (var node in root.ChildNodes) { if (node is System.Xml.XmlElement child) { if (Enum.TryParse(child.Name, out DbOperations.TestSetups.SettingsFields field)) { switch (field) { case DbOperations.TestSetups.SettingsFields.Range: range = string.IsNullOrWhiteSpace(child.InnerText) ? GetSensorRange(channel, sensors) : child.InnerText; break; //FB 13120 set filter class case DbOperations.TestSetups.SettingsFields.FilterClass: filterclass = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.Polarity: polarity = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.LimitDuration: limitDuration = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.Duration: duration = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.Delay: delay = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.OutputMode: outputMode = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.DigitalOutDelay: digitalOutDelay = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.DigitalOutDuration: digitalOutDuration = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.DigitalOutLimitDuration: digitalOutLimitDuration = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.SQMode: sqMode = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.SquibDelay: squibDelay = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.SquibCurrent: squibCurrent = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.SquibDuration: squibDuration = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.SquibLimitDuration: squibLimitDuration = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.DIMode: diMode = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.DefaultValue: defaultValue = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.ActiveValue: activeValue = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.UserValue1: userValue1 = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.UserValue2: userValue2 = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.UserValue3: userValue3 = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.ZeroMethod: zeroMethod = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.ZeroMethodStart: zeroStart = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.ZeroMethodEnd: zeroEnd = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.InitialOffset: initialOffset = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.UartBaudRate: uartBaudRate = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.UartDataBits: uartDataBits = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.UartStopBits: uartStopBits = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.UartParity: uartParity = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.UartFlowControl: uartFlowControl = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.UartDataFormat: uartDataFormat = child.InnerText; break; case DbOperations.TestSetups.SettingsFields.ACCouplingEnabled: acCoupling = child.InnerText; break; //33415 Voltage insertion channel should be half bridge case DbOperations.TestSetups.SettingsFields.BridgeType: bridgeType = child.InnerText; break; } } } } } else { //ChannelSettings is empty, so get Range from sensor's Capacity range = GetSensorRange(channel, sensors); } //Range,CFC,Polarity var settings = new List(); var dictionary = DbOperations.GetSettingsLookup(); if (!string.IsNullOrWhiteSpace(range)) { var rangeTuple = dictionary[ChannelSettingBase.RANGE]; settings.Add(new ChannelSettingBase(rangeTuple.Item1, rangeTuple.Item2, rangeTuple.Item3) { DoubleValue = Convert.ToDouble(range, CultureInfo.InvariantCulture) }); } if (!string.IsNullOrWhiteSpace(acCoupling)) { var acTuple = dictionary[ChannelSettingBase.ACCouplingEnabled]; var setting = new ChannelSettingBase(acTuple.Item1, acTuple.Item2, acTuple.Item3); if (bool.TryParse(acCoupling, out var b)) { setting.BoolValue = b; } settings.Add(setting); } //FB 13120 set filter class if (!string.IsNullOrWhiteSpace(filterclass)) { var FilterClassTuple = dictionary[ChannelSettingBase.FilterClass]; settings.Add(new ChannelSettingBase(FilterClassTuple.Item1, FilterClassTuple.Item2, FilterClassTuple.Item3) { Value = filterclass }); } if (!string.IsNullOrWhiteSpace(polarity)) { var polarityTuple = dictionary[ChannelSettingBase.POLARITY]; settings.Add(new ChannelSettingBase(polarityTuple.Item1, polarityTuple.Item2, polarityTuple.Item3) { Value = polarity }); } //33415 Voltage insertion channel should be half bridge if (!string.IsNullOrWhiteSpace(bridgeType)) { var bridgeTypeTuple = dictionary[ChannelSettingBase.BRIDGE_TYPE]; settings.Add(new ChannelSettingBase(bridgeTypeTuple.Item1, bridgeTypeTuple.Item2, bridgeTypeTuple.Item3) { Value = bridgeType }); } if (!string.IsNullOrWhiteSpace(limitDuration)) { var tuple = dictionary[ChannelSettingBase.DIGITALOUT_LIMIT_DURATION]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { BoolValue = Convert.ToBoolean(limitDuration) }); tuple = dictionary[ChannelSettingBase.SQUIB_LIMIT_DURATION]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { BoolValue = Convert.ToBoolean(limitDuration) }); } if (!string.IsNullOrWhiteSpace(duration)) { var tuple = dictionary[ChannelSettingBase.DIGITALOUT_DURATION]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { DoubleValue = Convert.ToDouble(duration, CultureInfo.InvariantCulture) }); tuple = dictionary[ChannelSettingBase.SQUIB_DURATION]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { DoubleValue = Convert.ToDouble(duration, CultureInfo.InvariantCulture) }); } if (!string.IsNullOrWhiteSpace(delay)) { var tuple = dictionary[ChannelSettingBase.DIGITALOUT_DELAY]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { DoubleValue = Convert.ToDouble(delay, CultureInfo.InvariantCulture) }); tuple = dictionary[ChannelSettingBase.SQUIB_DELAY]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { DoubleValue = Convert.ToDouble(delay, CultureInfo.InvariantCulture) }); } if (!string.IsNullOrWhiteSpace(outputMode)) { var tuple = dictionary[ChannelSettingBase.OUTPUT_MODE]; if (!int.TryParse(outputMode, out int iTemp)) { APILogger.Log("invalid output mode: outputMode for channel", channel.IsoChannelName); //FIX THIS } settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { IntValue = iTemp }); } if (!string.IsNullOrWhiteSpace(digitalOutDelay)) { var tuple = dictionary[ChannelSettingBase.DIGITALOUT_DELAY]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { DoubleValue = Convert.ToDouble(digitalOutDelay, CultureInfo.InvariantCulture) }); } if (!string.IsNullOrWhiteSpace(digitalOutDuration)) { var tuple = dictionary[ChannelSettingBase.DIGITALOUT_DURATION]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { DoubleValue = Convert.ToDouble(digitalOutDuration, CultureInfo.InvariantCulture) }); } if (!string.IsNullOrWhiteSpace(digitalOutLimitDuration)) { var tuple = dictionary[ChannelSettingBase.DIGITALOUT_LIMIT_DURATION]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { BoolValue = Convert.ToBoolean(digitalOutLimitDuration) }); } if (!string.IsNullOrWhiteSpace(sqMode)) { var tuple = dictionary[ChannelSettingBase.SQMODE]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { IntValue = Convert.ToInt32(sqMode) }); } if (!string.IsNullOrWhiteSpace(squibDelay)) { var tuple = dictionary[ChannelSettingBase.SQUIB_DELAY]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { DoubleValue = Convert.ToDouble(squibDelay, CultureInfo.InvariantCulture) }); } if (!string.IsNullOrWhiteSpace(squibCurrent)) { var tuple = dictionary[ChannelSettingBase.SQUIB_CURRENT]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { DoubleValue = Convert.ToDouble(squibCurrent, CultureInfo.InvariantCulture) }); } if (!string.IsNullOrWhiteSpace(squibDuration)) { var tuple = dictionary[ChannelSettingBase.SQUIB_DURATION]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { DoubleValue = Convert.ToDouble(squibDuration, CultureInfo.InvariantCulture) }); } if (!string.IsNullOrWhiteSpace(squibLimitDuration)) { var tuple = dictionary[ChannelSettingBase.SQUIB_LIMIT_DURATION]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { BoolValue = Convert.ToBoolean(squibLimitDuration) }); } if (!string.IsNullOrWhiteSpace(uartBaudRate)) { var tuple = dictionary[ChannelSettingBase.BAUD_RATE]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { IntValue = Convert.ToInt32(uartBaudRate) }); } if (!string.IsNullOrWhiteSpace(uartDataBits)) { var tuple = dictionary[ChannelSettingBase.DATA_BITS]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { IntValue = Convert.ToInt32(uartDataBits) }); } if (!string.IsNullOrWhiteSpace(uartStopBits)) { var tuple = dictionary[ChannelSettingBase.STOP_BITS]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { Value = uartStopBits }); } if (!string.IsNullOrWhiteSpace(uartParity)) { var tuple = dictionary[ChannelSettingBase.PARITY]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { Value = uartParity }); } if (!string.IsNullOrWhiteSpace(uartFlowControl)) { var tuple = dictionary[ChannelSettingBase.FLOW_CONTROL]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { Value = uartFlowControl }); } if (!string.IsNullOrWhiteSpace(uartDataFormat)) { var tuple = dictionary[ChannelSettingBase.DATA_FORMAT]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { Value = uartDataFormat }); } if (!string.IsNullOrWhiteSpace(diMode)) { var tuple = dictionary[ChannelSettingBase.DIMODE]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { IntValue = Convert.ToInt32(diMode) }); } if (!string.IsNullOrWhiteSpace(defaultValue)) { var tuple = dictionary[ChannelSettingBase.DEFAULT_VALUE]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { DoubleValue = Convert.ToDouble(defaultValue, System.Globalization.CultureInfo.InvariantCulture) }); } if (!string.IsNullOrWhiteSpace(activeValue)) { var tuple = dictionary[ChannelSettingBase.ACTIVE_VALUE]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { DoubleValue = Convert.ToDouble(activeValue, System.Globalization.CultureInfo.InvariantCulture) }); } ProcessUserValues(userValue1, userValue2, userValue3, dictionary, ref settings); ProcessZeroMethod(zeroMethod, zeroStart, zeroEnd, dictionary, ref settings); if (!string.IsNullOrWhiteSpace(initialOffset)) { var tuple = dictionary[ChannelSettingBase.INITIAL_OFFSET]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { Value = initialOffset }); } channel.ChannelSettings = settings.ToArray(); } catch (Exception ex) { //FB 15530 Log the exception and trace log APILogger.LogException(ex); throw; } } /// /// handles processing of zero method settings for a group channel from import xml /// this appears to only be used for static groups and not embedded groups /// 15270 Sensor Import does not import most channel settings /// private void ProcessZeroMethod(string zeroMethod, string zeroStart, string zeroEnd, IReadOnlyDictionary> dictionary, ref List settings) { if (!string.IsNullOrWhiteSpace(zeroMethod)) { var tuple = dictionary[ChannelSettingBase.ZEROMETHOD]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { Value = zeroMethod }); } if (!string.IsNullOrWhiteSpace(zeroStart)) { var tuple = dictionary[ChannelSettingBase.ZEROMETHODSTART]; if (double.TryParse(zeroStart, NumberStyles.Any, CultureInfo.InvariantCulture, out var d)) { settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { DoubleValue = d }); } } if (!string.IsNullOrWhiteSpace(zeroEnd)) { var tuple = dictionary[ChannelSettingBase.ZEROMETHODEND]; if (double.TryParse(zeroEnd, NumberStyles.Any, CultureInfo.InvariantCulture, out var d)) { settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { DoubleValue = d }); } } } /// /// handles processing of user values settings for a gorup channel from import xml /// this appears to only be used for static groups and not embedded groups /// 15270 Sensor Import does not import most channel settings /// private void ProcessUserValues(string userValue1, string userValue2, string userValue3, IReadOnlyDictionary> dictionary, ref List settings) { if (!string.IsNullOrWhiteSpace(userValue1)) { var tuple = dictionary[ChannelSettingBase.USERVALUE1]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { Value = userValue1 }); } if (!string.IsNullOrWhiteSpace(userValue2)) { var tuple = dictionary[ChannelSettingBase.USERVALUE2]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { Value = userValue2 }); } if (!string.IsNullOrWhiteSpace(userValue3)) { var tuple = dictionary[ChannelSettingBase.USERVALUE3]; settings.Add(new ChannelSettingBase(tuple.Item1, tuple.Item2, tuple.Item3) { Value = userValue3 }); } } private string GetSensorRange(GroupChannel channel, List sensors) { foreach (var sensor in sensors) { if (sensor.DatabaseId != channel.SensorId) continue; return sensor.Capacity.ToString("N2"); //get sensor's capacity } return string.Empty; } } public class GroupComparer : IComparer { public GroupFields SortField { get; set; } public bool SortAscending { get; set; } public int Compare(IGroup left, IGroup right) { if (left == right) { return 0; } var a = left; var b = right; if (!SortAscending) { a = right; b = left; } if (null == a) { return -1; } if (null == b) { return 1; } switch (SortField) { case GroupFields.Name: return string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase); case GroupFields.LastModifiedBy: return string.Compare(a.LastModifiedBy, b.LastModifiedBy, StringComparison.OrdinalIgnoreCase); case GroupFields.LastModified: return DateTime.Compare(a.LastModified, b.LastModified); case GroupFields.DisplayName: return string.Compare(a.DisplayName, b.DisplayName, StringComparison.OrdinalIgnoreCase); case GroupFields.Description: return string.Compare(a.Description, b.Description, StringComparison.OrdinalIgnoreCase); case GroupFields.ChannelCount: return a.ChannelCount.CompareTo(b.ChannelCount); case GroupFields.AssociatedTestSetups: { var aAssociatedTestSetups = new List(); var bAssociatedTestSetups = new List(); foreach (var assoc in a.AssociatedTestSetups) { aAssociatedTestSetups.Add(assoc.Name); } foreach (var assoc in b.AssociatedTestSetups) { bAssociatedTestSetups.Add(assoc.Name); } var aString = string.Join(", ", aAssociatedTestSetups.ToArray()); var bString = string.Join(", ", bAssociatedTestSetups.ToArray()); return string.Compare(aString, bString, StringComparison.OrdinalIgnoreCase); } default: throw new ArgumentOutOfRangeException(); } } } }