using System; using System.Collections.Generic; using System.Linq; using System.Data; using System.ComponentModel; using System.Data.SqlClient; using System.Text; using DTS.Common.DAS.Concepts; using DTS.Common.Storage; using DTS.Common.Utilities.Logging; using DTS.Common.Interface.DASFactory.Diagnostics; using DTS.Common.Enums.Hardware; using DTS.Common.Enums.Sensors; using DTS.Common.Enums.DASFactory; using ISO.Strings; using DTS.Common.Classes.Hardware; using DTS.Common.Interface.DataRecorders; // ReSharper disable InconsistentNaming // ReSharper disable CheckNamespace // ReSharper disable PossibleNullReferenceException // ReSharper disable ConvertToAutoProperty namespace DTS.Common.ISO { public class Hardware : DASDBRecord, INotifyPropertyChanged, IISOHardware { public enum ChannelType { Analog, IEPE, Squib, DigitalOutput, RTC, UART, StreamOutput, StreamInput, Thermocoupler, CAN } #region Properties public bool IsInvalidDate(DateTime input) { return input.Date.Equals(DASDBRecord.INVALID_DATE.Date); } private int _calInterval = 365; public int CalInterval { get => _calInterval; set => _calInterval = value; } public void GetChannelsString(out int analog, out int digitalIn, out int digitalOut, out int squib, out int uart, out int streamOut, out int streamIn, out int can) { var sb = new StringBuilder(); analog = 0; digitalIn = 0; digitalOut = 0; squib = 0; uart = 0; streamOut = 0; streamIn = 0; can = 0; //was returning "1" for ethernet controllers which don't have a channel ... switch (DASTypeEnum) { case HardwareTypes.SLICE_LabEthernet: case HardwareTypes.SLICE_EthernetController: case HardwareTypes.SLICE_Mini_Distributor: case HardwareTypes.SLICE_Distributor: return; } if (null != ISOChannels && ISOChannels.Any()) { foreach (var ch in ISOChannels) { if (ch.IsSupported(SensorConstants.BridgeType.SQUIB)) { squib++; } else if (ch.IsSupported(SensorConstants.BridgeType.DigitalInput)) { digitalIn++; } else if (ch.IsSupported(SensorConstants.BridgeType.TOMDigital)) { digitalOut++; } else if (ch.IsSupported(SensorConstants.BridgeType.UART)) { uart++; } else if (ch.IsSupported(SensorConstants.BridgeType.StreamOut)) { streamOut++; } else if (ch.IsSupported(SensorConstants.BridgeType.StreamIn)) { streamIn++; } else if (ch.IsSupported(SensorConstants.BridgeType.CAN)) { can++; } else analog++; } } } public string IPAddress { get => Connection; set { Connection = value; OnPropertyChanged("IPAddress"); } } #endregion Properties public Hardware() { } public Hardware(Hardware copy) { DASId = copy.DASId; Version = copy.Version; SerialNumber = copy.SerialNumber; ProtocolVersion = copy.ProtocolVersion; Position = copy.Position; MinSampleRate = copy.MinSampleRate; MaxSampleRate = copy.MaxSampleRate; MaxAAFRate = copy.MaxAAFRate; MaxModules = copy.MaxModules; MaxMemory = copy.MaxMemory; LocalOnly = copy.LocalOnly; LastUsedBy = copy.LastUsedBy; LastUsed = copy.LastUsed; LastModifiedBy = copy.LastModifiedBy; LastModified = copy.LastModified; IsReconfigurable = copy.IsReconfigurable; IsProgrammable = copy.IsProgrammable; ISOChannels = copy.ISOChannels.Select(c => new HardwareChannel(c, this)).ToArray(); IPAddress = copy.IPAddress; FirmwareVersion = copy.FirmwareVersion; DASType = copy.DASType; var channeltypes = new int[copy?.ChannelTypes.Length??0]; Array.Copy(copy.ChannelTypes, channeltypes, copy.ChannelTypes.Length); ChannelTypes = channeltypes; Channels = copy.Channels; CalInterval = copy.CalInterval; CalDate = copy.CalDate; IsModule = copy.IsModule; ParentDAS = copy.ParentDAS; PositionOnChain = copy.PositionOnChain; PositionOnDistributor = copy.PositionOnDistributor; Port = copy.Port; IsFirstUseValid = copy.IsFirstUseValid; FirstUseDate = copy.FirstUseDate; StandIn = copy.StandIn; TestId = copy.TestId; GroupId = copy.GroupId; } public HardwareTypes DASTypeEnum { get => (HardwareTypes)DASType; set { DASType = (int)value; OnPropertyChanged("DASTypeEnum"); } } public bool IsPseudoRackModule() { switch (DASTypeEnum) { case HardwareTypes.SLICE6_AIR_BR: case HardwareTypes.SLICE6_AIR: case HardwareTypes.SLICE6_Base: case HardwareTypes.SLICE2_TOM: case HardwareTypes.SLICE2_SLT: case HardwareTypes.SLICE2_SLS: case HardwareTypes.SLICE2_SLD: case HardwareTypes.SLICE2_SIM: case HardwareTypes.SLICE2_DIM: case HardwareTypes.SLICE2_Base: return true; default: return false; } } public bool IsTSRAIR() { return IsTSRAIR(DASTypeEnum); } public static bool IsTSRAIR(HardwareTypes dasType) { switch (dasType) { case HardwareTypes.TSR_AIR: case HardwareTypes.TSR_AIR_RevB: case HardwareTypes.DKR: case HardwareTypes.DIR: return true; default: return false; } } public bool IsTSRAIRModule() { return IsTSRAIRModule(DASTypeEnum); } public static bool IsTSRAIRModule(HardwareTypes dasType) { switch (dasType) { case HardwareTypes.EMB_ANG_ACC: case HardwareTypes.EMB_ANG_ARS: case HardwareTypes.EMB_ATM: case HardwareTypes.EMB_LIN_ACC_HI: case HardwareTypes.EMB_LIN_ACC_LO: case HardwareTypes.EMB_MAG: case HardwareTypes.EMB_MAG_SWITCH: case HardwareTypes.EMB_MIC: case HardwareTypes.EMB_OPT: case HardwareTypes.EMB_RTC_S_MARK: case HardwareTypes.EMB_RTC_NS_PAD: return true; default: return false; } } public Hardware(IDASDBRecord copy) : base(copy) { } public Hardware(IDataReader reader) : base(reader) { } public static List GetDASISOChannels(string hardwareId, Hardware das) { var channelList = new List(); var hResult = DbOperations.DASChannelsGet(hardwareId, out var dbChannels); if (0 == hResult && null != dbChannels && dbChannels.Any()) { foreach (var dbChannel in dbChannels) { channelList.Add(new HardwareChannel(dbChannel, das)); } } channelList.Sort(HardwareChannel.PhysicalCompare); return channelList; } private static void GetAllDASISOChannels(Dictionary serialNumberToHardware) { var channelsByDASKey = new Dictionary>(); var hResult = DbOperations.DASChannelsGet(null, out var dbChannels); foreach (var dbChannel in dbChannels) { if (!serialNumberToHardware.ContainsKey(dbChannel.HardwareId)) { continue; } var hardware = serialNumberToHardware[dbChannel.HardwareId]; var hc = new HardwareChannel(dbChannel, hardware); if (!channelsByDASKey.ContainsKey(dbChannel.HardwareId)) { channelsByDASKey[dbChannel.HardwareId] = new List(); } channelsByDASKey[dbChannel.HardwareId].Add(hc); } using (var enumHardware = serialNumberToHardware.GetEnumerator()) { while (enumHardware.MoveNext()) { var hardware = enumHardware.Current.Value; if (!channelsByDASKey.ContainsKey(enumHardware.Current.Key)) { continue; } var list = channelsByDASKey[enumHardware.Current.Key]; list.Sort(HardwareChannel.PhysicalCompare); hardware.ISOChannels = list.ToArray(); } } } private List _isoChannels = new List(); public HardwareChannel[] ISOChannels { get => _isoChannels.ToArray(); set => SetProperty(ref _isoChannels, new List(value), "ISOChannels"); } public static Hardware[] GetAllDAS() { return GetAllDAS(null, null); } public static Hardware[] GetSingleDAS(string serialNumber, string position) { var list = new List(); try { var hResult = DbOperations.DASGet(serialNumber, position, out var dbDAS); if (0 == hResult) { foreach (var curDas in dbDAS) { list.Add(new Hardware(curDas)); } } foreach (var das in list) { var channels = GetDASISOChannels(das.SerialNumber, das); channels.Sort(HardwareChannel.PhysicalCompare); das.ISOChannels = channels.ToArray(); } } catch (Exception ex) { APILogger.Log("failed to retrieve all das, ", ex); } list.Sort(new HardwareCompare()); return list.ToArray(); } public static Hardware[] GetAllDAS(string serialNumber, string position) { if (!string.IsNullOrWhiteSpace(serialNumber)) { return GetSingleDAS(serialNumber, position); } var list = new List(); try { var hResult = DbOperations.DASGet(serialNumber, position, out var dbDAS); if (0 == hResult && null != dbDAS) { foreach (var curDas in dbDAS) { list.Add(new Hardware(curDas)); } } var serialNumberToDAS = new Dictionary(); foreach (var das in list) { serialNumberToDAS[$"{das.SerialNumber}_{das.DASType}"] = das; } GetAllDASISOChannels(serialNumberToDAS); } catch (Exception ex) { APILogger.Log("failed to retrieve all das, ", ex); } list.Sort(new HardwareCompare()); return list.ToArray(); } public class HardwareCompare : Comparer { public override int Compare(Hardware x, Hardware y) { var ret = string.Compare(x.SerialNumber, y.SerialNumber, StringComparison.Ordinal); if (0 == ret) { ret = string.Compare(x.IPAddress, y.IPAddress, StringComparison.Ordinal); } return ret; } } public void Delete() { var embedded = HardwareConstants.HasEmbeddedSensors(DASTypeEnum); _ = DbOperations.DASDelete(DASId, null, embedded); } private void DeleteChannels() { _ = DbOperations.DASChannelsDelete(GetId()); } public void Insert() { var result = DbOperations.DASInsert(this); //ErrorCodes.ERROR_SUCCESS = 0 //We only want to insert the DAS Channels if the DAS was inserted successfully. //It could be unsuccessful, for example, if an older database is in use. if (result == 0) { InsertChannels(); } } private void InsertChannels() { foreach (var channel in ISOChannels) { channel.Insert(); } } public bool IsDummyObject => SerialNumber.Contains("Dummy"); public void Update() { DbOperations.DASUpdate(this); DeleteChannels(); InsertChannels(); } public string GetId() { return GetId(SerialNumber, DASType.ToString(), IPAddress); } public string GetIdOld() { return $"{SerialNumber}_{DASType}_{IPAddress}"; } public static string GetId(string sn, string dastype, string ip) { return $"{sn}_{dastype}"; } public void SetChannel(HardwareChannel channel) { for (var i = 0; i < _isoChannels.Count; i++) { if (ISOChannels[i].ChannelIdx != channel.ChannelIdx) continue; _isoChannels[i] = channel; return; } _isoChannels.Add(channel); } private const string TDAS_RACK_PREPEND = "DR"; private const string TDAS_LABRACK_PREPEND = "LR"; private const string SLICE6_PREPEND = "SL6"; private const string SLICE6AIR_PREPEND = "S6A"; private const string SLICE6AIRBR_PREPEND = "S6BR"; private const string SLICE6AIRBR_PREPEND2 = "S6ABR"; private const string SLICE2SIM_PREPEND = "SPS"; private const string SLICE2LABSIM_PREPEND = "SLS"; private const string SLICE2TOM_PREPEND = "SPT"; private const string SLICE2LABTOM_PREPEND = "SLT"; private const string SLICE2DIM_PREPEND = "SPD"; private const string SLICE2LABDIM_PREPEND = "SLD"; private const string SLICENANO_PREPEND = "BA5"; private const string SLICEMICRO_PREPEND = "BA0"; private const string SLICE15NANO_PREPEND = "BA5"; private const string SLICE15MICRO_PREPEND = "BA0"; private const string SLICELABETHERNET_PREPEND = "SLE"; private const string SLICE_PRO_DB_PREPEND = "SPDB"; private const string SLICE6DB_PREPEND = "S6DB"; private const string SLICE6DB3_PREPEND = "S6DB3"; private const string SLICEG5_PREPEND = "SG5"; private const string G5_PREPEND = "5M"; private const string SLICEPROETHERNET_PREPEND = "SPE"; private const string SLICEDB_PREPEND = "SD"; private const string POWERPRO_PREPEND = "PPR"; private const string SLICEMINIDB_PREPEND = "SPM"; private const string DIR_PREPEND = "DI"; private const string DKR_PREPEND = "DK"; private const string SLICETC_PREPEND = "STC"; private const string SLICE_PRO_CAN_FD_PREPEND = "SPFD"; private void ValidateSN(ref List errors, ref bool bValid, string prepend, string error, string alternativePrepend = null) { if (SerialNumber.Contains(DFConstantsAndEnums.SERIAL_SEPARATOR) && !StandIn) { bValid = false; errors.Add($"{Strings.Strings.InvalidCharacterInSerialNumber} '{DFConstantsAndEnums.SERIAL_SEPARATOR}'"); } if (SerialNumber.Contains(DFConstantsAndEnums.CHANNEL_SEPARATOR) && !StandIn) { bValid = false; errors.Add($"{Strings.Strings.InvalidCharacterInSerialNumber} '{DFConstantsAndEnums.CHANNEL_SEPARATOR}'"); } if (!SerialNumber.StartsWith(prepend) && (string.IsNullOrEmpty(alternativePrepend) || !SerialNumber.StartsWith(alternativePrepend))) { bValid = false; errors.Add(error); } } private void ValidateNotSN(ref List errors, ref bool bValid, string prepend, string error) { if (SerialNumber.StartsWith(prepend)) { bValid = false; errors.Add($"{error} ({DASTypeEnum.ToString()})"); } } public bool ValidateIPAddress(ref List errors) { var bValid = true; switch (DASTypeEnum) { case HardwareTypes.SLICE_Distributor: case HardwareTypes.SLICE_EthernetController: case HardwareTypes.SLICE_Mini_Distributor: case HardwareTypes.SLICE6DB: case HardwareTypes.SLICE6DB3: case HardwareTypes.SLICE_Pro_Distributor: //case HardwareTypes.SLICE6DB_AIR: case HardwareTypes.SLICE6DB_InDummy: case HardwareTypes.SLICE_LabEthernet: case HardwareTypes.TDAS_Pro_Rack: case HardwareTypes.TDAS_LabRack: case HardwareTypes.G5VDS: //case ISODll.Hardware.HardwareTypes.G5IPORT: case HardwareTypes.G5INDUMMY: case HardwareTypes.TSR_AIR: case HardwareTypes.TSR_AIR_RevB: { if (string.IsNullOrWhiteSpace(IPAddress)) { bValid = false; errors.Add(StringResources.AutoDetectDAS_IPAddressRequired); } } break; } return bValid; } public bool ValidateSerialNumber(ref List errors) { var bValid = true; if (string.IsNullOrWhiteSpace(SerialNumber)) { bValid = false; errors.Add(StringResources.AutoDetectDAS_SerialNumberRequired); } else { switch (DASTypeEnum) { case HardwareTypes.TDAS_Pro_Rack: ValidateSN(ref errors, ref bValid, TDAS_RACK_PREPEND, StringResources.AutoDetectDas_TDASRackShouldStartWith); break; case HardwareTypes.TDAS_LabRack: ValidateSN(ref errors, ref bValid, TDAS_LABRACK_PREPEND, StringResources.AutoDetectDAS_TDASLabRackShouldStartWith); break; case HardwareTypes.SLICE6_Base: ValidateSN(ref errors, ref bValid, SLICE6_PREPEND, StringResources.AutoDetectDas_SLICE6ShouldStartWith); break; case HardwareTypes.SLICE6_AIR: ValidateSN(ref errors, ref bValid, SLICE6AIR_PREPEND, StringResources.AutoDetectDas_SLICE6AIRShouldStartWith); break; case HardwareTypes.SLICE6_AIR_BR: ValidateSN(ref errors, ref bValid, SLICE6AIRBR_PREPEND, StringResources.AutoDetectDas_SLICE6AIRBRShouldStartWith, SLICE6AIRBR_PREPEND2); break; case HardwareTypes.SLICE2_SIM: ValidateSN(ref errors, ref bValid, SLICE2SIM_PREPEND, StringResources.AutoDetectDas_SIMShouldStartWithSPS); break; case HardwareTypes.SLICE2_SLS: ValidateSN(ref errors, ref bValid, SLICE2LABSIM_PREPEND, StringResources.AutoDetectDAS_SLSShouldStartWithSLS); break; case HardwareTypes.SLICE2_TOM: ValidateSN(ref errors, ref bValid, SLICE2TOM_PREPEND, StringResources.AutoDetectDas_TOMShouldStartWithSPT); break; case HardwareTypes.SLICE2_SLT: ValidateSN(ref errors, ref bValid, SLICE2LABTOM_PREPEND, StringResources.AutoDetectDAS_SLTShouldStartWithSLT); break; case HardwareTypes.SLICE2_DIM: ValidateSN(ref errors, ref bValid, SLICE2DIM_PREPEND, StringResources.AutoDetectDas_DIMShouldStartWithSPD); break; case HardwareTypes.SLICE2_SLD: ValidateSN(ref errors, ref bValid, SLICE2LABDIM_PREPEND, StringResources.AutoDetectDAS_SLDShouldStartWithSLD); break; case HardwareTypes.SLICE_NANO_Base: ValidateSN(ref errors, ref bValid, SLICENANO_PREPEND, StringResources.AutoDetectDas_SLICENanoShouldStartWithBA5); break; case HardwareTypes.SLICE_Micro_Base: ValidateSN(ref errors, ref bValid, SLICEMICRO_PREPEND, StringResources.AutoDetectDas_MicroSerialNumberShouldStartWithBA0); break; case HardwareTypes.SLICE1_5_Nano_Base: ValidateSN(ref errors, ref bValid, SLICE15NANO_PREPEND, StringResources.AutoDetectDAS_NANOBasePlusShouldStartWithBA5); break; case HardwareTypes.SLICE1_5_Micro_Base: ValidateSN(ref errors, ref bValid, SLICE15MICRO_PREPEND, StringResources.AutoDetectDAS_MICROBasePlusShouldStartWithBA0); break; case HardwareTypes.SLICE_LabEthernet: ValidateSN(ref errors, ref bValid, SLICELABETHERNET_PREPEND, StringResources.AutoDetectDAS_SliceLabEthernetShouldStartWithSLE); break; case HardwareTypes.SLICE_Pro_Distributor: ValidateSN(ref errors, ref bValid, SLICE_PRO_DB_PREPEND, StringResources.AutoDetectDAS_SLICEPRODBShouldStartWithSPDB); break; case HardwareTypes.SLICE6DB3: ValidateSN(ref errors, ref bValid, SLICE6DB3_PREPEND, StringResources.AutoDetectDas_SLICE6DB3ShouldStartWith); break; case HardwareTypes.SLICE6DB: ValidateSN(ref errors, ref bValid, SLICE6DB_PREPEND, StringResources.AutoDetectDas_Slice6DBShouldStartWithS6DB); break; case HardwareTypes.SLICE1_G5Stack: ValidateSN(ref errors, ref bValid, SLICEG5_PREPEND, StringResources.AutoDetectDas_SliceG5ShouldStartWithSG5); break; case HardwareTypes.G5INDUMMY: case HardwareTypes.G5VDS: ValidateSN(ref errors, ref bValid, G5_PREPEND, StringResources.AutoDetectDas_G5ShouldStartWith5M); break; case HardwareTypes.SLICE_EthernetController: ValidateSN(ref errors, ref bValid, SLICEPROETHERNET_PREPEND, StringResources.AutoDetectDas_SliceECM); break; case HardwareTypes.SLICE_Mini_Distributor: ValidateSN(ref errors, ref bValid, SLICEMINIDB_PREPEND, StringResources.AutoDetectDas_SliceSPM); break; case HardwareTypes.SLICE_Distributor: ValidateSN(ref errors, ref bValid, SLICEDB_PREPEND, StringResources.AutoDetectDas_SliceDBShouldStartWithSDB); break; case HardwareTypes.PowerPro: ValidateSN(ref errors, ref bValid, POWERPRO_PREPEND, StringResources.AutoDetectDas_PowerProShouldStartWithPPRO); break; case HardwareTypes.TSR_AIR: case HardwareTypes.TSR_AIR_RevB: ValidateSN(ref errors, ref bValid, HardwareConstants.TSR_AIR_PREPEND, StringResources.AutoDetectDas_TSRAIRShouldStartWithTA); break; case HardwareTypes.DKR: ValidateSN(ref errors, ref bValid, DKR_PREPEND, StringResources.AutoDetectDas_DKRShouldStartWithDK); break; case HardwareTypes.DIR: ValidateSN(ref errors, ref bValid, DIR_PREPEND, StringResources.AutoDetectDas_DIRShouldStartWithDI); break; case HardwareTypes.SLICE6_AIR_TC: ValidateSN(ref errors, ref bValid, SLICETC_PREPEND, string.Format(StringResources.AutoDetectDas_TypeShouldStartWithPrepend, Strings.Strings.SLICE_TC_Description, SLICETC_PREPEND)); break; case HardwareTypes.SLICE_PRO_CAN_FD: ValidateSN(ref errors, ref bValid, SLICE_PRO_CAN_FD_PREPEND, string.Format(StringResources.AutoDetectDas_TypeShouldStartWithPrepend, Strings.Strings.SLICE_PRO_CAN_FD_Description, SLICE_PRO_CAN_FD_PREPEND)); break; default: ValidateNotSN(ref errors, ref bValid, G5_PREPEND, StringResources.AutoDetectDAS_SerialNumberBelongsToAG5); ValidateNotSN(ref errors, ref bValid, TDAS_RACK_PREPEND, StringResources.AutoDetectDas_SerialNumberBelongsToATDASRack); ValidateNotSN(ref errors, ref bValid, SLICENANO_PREPEND, StringResources.AutoDetectDas_SerialNumberBelongsToANano); ValidateNotSN(ref errors, ref bValid, SLICEMICRO_PREPEND, StringResources.AutoDetectDAS_SerialNumberBelongsToAMicro); ValidateNotSN(ref errors, ref bValid, SLICE2SIM_PREPEND, StringResources.AutoDetectDas_SerialNumberBelongsToASLICEProSim); ValidateNotSN(ref errors, ref bValid, SLICE2LABSIM_PREPEND, StringResources.AutoDetectDAS_SerialNumberBelongsToASLICEPROLabSIM); ValidateNotSN(ref errors, ref bValid, SLICEG5_PREPEND, StringResources.AutoDetectDas_SerialNumberBelongsToASLICEG5); ValidateNotSN(ref errors, ref bValid, SLICELABETHERNET_PREPEND, StringResources.AutoDetectDAS_SerialNumberBelongsToASlicePROLabSLE); ValidateNotSN(ref errors, ref bValid, SLICE2DIM_PREPEND, StringResources.AutoDetectDas_SLICE_SerialNumberBelongsToASLICEProDIM); ValidateNotSN(ref errors, ref bValid, SLICE2LABTOM_PREPEND, StringResources.AutoDetectDAS_SLICE_SerialNumberBelongsToASLICELABTOM); ValidateNotSN(ref errors, ref bValid, SLICE2LABDIM_PREPEND, StringResources.AutoDetectDAS_SLICE_SerialNumberBelongsToASLICELABDIM); ValidateNotSN(ref errors, ref bValid, TDAS_LABRACK_PREPEND, StringResources.AutoDetectDAS_SerialNumberBelongsToATDASLabRack); ValidateNotSN(ref errors, ref bValid, POWERPRO_PREPEND, StringResources.AutoDetectDAS_SerialNumberBelongsToAPowerPRO); break; } } return bValid; } } }