using System; using System.Collections.Generic; using System.Linq; using System.Windows; using DataPROWin7.DataModel.Classes.TestTemplate; using DTS.Common.Base; using DTS.Common.DataModel; using DTS.Common.Interface.DASFactory.Diagnostics; using DTS.Common.Interface.DASFactory.Diagnostics.HardwareList; using DTS.Common.Interface.DataRecorders; using DTS.Common.Storage; namespace DataPROWin7.DataModel.Classes.Hardware { public class DASHardwareList : BasePropertyChanged { private static DASHardwareList _list; private static bool _cache = false; /// /// turns off queries to the db and starts using cached data instead /// this is done when a large number of test setups are validating, since each test setup /// will get a complete list of hardware from the db, which adds time when you have a lot of hardware and test setups /// public static bool Cache { get => _cache; set { _cache = value; if (!value) { _cachedDASHardware = null; } } } public static DASHardwareList GetList() { if (null != _list) return _list; _list = new DASHardwareList(); //_list.PopulateHardware(); return _list; } public void ReloadAll() { //_list = new DASHardwareList(); //_list.PopulateHardware(); } private ICachedContainer _cachedHardware = null; public void SetCache(ICachedContainer container) { _cachedHardware = container; } public void ClearCache() { _cachedHardware = null; } public string GetDASSerialNumberFromId(int id) { //this could probably be improved, but rather than getting ALL HARDWARE and ALL channels //just to get a serial number for a database id //just get the hardware without the channels var hr = DbOperations.DASGet(null, null, out var records); if (0 == hr && null != records && records.Any()) { var match = Array.Find(records, das => das.DASId == id); if (null != match) { return match.SerialNumber; } } return string.Empty; } public DASHardware GetHardware(int id) { var sn = GetDASSerialNumberFromId(id); return GetHardware(sn); } public DASHardware GetHardware(string id, bool bUseCache = true) { return GetHardware(id, true, out var bNotUsed, bUseCache); } public DASHardware[] GetHardware(string[] ids, bool bUseCache = true) { List dasHW = new List(); foreach (string id in ids) { var hw = GetHardware(id, bUseCache); if (null != hw) { dasHW.Add(hw); } } return dasHW.ToArray(); } public DASHardware GetHardware(string id, bool bThrowExceptionIfChanged, out bool changed, bool bUseCache = true) { if (null != _cachedHardware && bUseCache) { var tokens = id.Split('_'); var h = _cachedHardware.GetCachedHardware(tokens[0]); if (null != h) { changed = false; return h; } if (null != _cachedDASHardware) { h = Array.Find(_cachedDASHardware, das => das.SerialNumber == id); if (null != h) { changed = false; return h; } } } var hardware = DTS.Common.ISO.Hardware.GetAllDAS(id, null); changed = false; if (null != hardware && hardware.Any()) { return new DASHardware(hardware[0]); } return null; } public class HardwareTypeChangedException : Exception { } public DASHardware GetHardware(string serialNumber, string ipaddress) { return GetHardware(serialNumber); } public void UpdateMaxMemory(DASHardware h, long newMaxMemory) { h.GetHardware().MaxMemory = newMaxMemory; h.GetHardware().Update(); } public DASHardware GetPrototypeHardware(string serial, int type) { //return new DASHardware(); var key = $"{serial}_{type}"; var das = DTS.Common.ISO.Hardware.GetAllDAS(key, DbOperations.DAS.PROTOTYPE_POSITION); if (null != das && das.Any()) { das[0].CalDate = DateTime.MinValue;//if something is using the prototype, use a blank caldate return new DASHardware(das[0]); } return null; } /// /// holds a cache of all hardware this is done for speed reasons when there are a large number /// of test setups to validate, each one of them grabs all the hardware, which takes time /// private static DASHardware[] _cachedDASHardware = null; public static DASHardware[] GetAllHardware() { if (Cache && null != _cachedDASHardware) { return _cachedDASHardware; } var allHardware = DTS.Common.ISO.Hardware.GetAllDAS(); var ret = allHardware.Select(h => new DASHardware(h)).ToArray(); if (Cache) { _cachedDASHardware = ret; } return ret; } public static List GetEmbeddedModules(IDASHardware[] hardware, int id) { var modules = new List(); foreach (var hw in hardware) { if (hw.Connection.StartsWith(hardware.First(h => h.DASId == id).SerialNumber)) { modules.Add(hw.DASId); } } return modules; } public static Dictionary GetEmbeddedModuleInfo(DASHardware[] hardware, int id) { var info = new Dictionary(); foreach (var hw in hardware) { if (hw.Connection.StartsWith(hardware.First(h => h.DASId == id).SerialNumber)) { info[hw.SerialNumber] = hw.GetMaxSampleRateDouble(); } } return info; } public enum Tags { Hardware } /// /// Unassociate is used to indicate whether children das should be unassociated before commiting or not /// public void Commit(DASHardware hardware, bool bExisting = false, bool bCheckExisting = true, bool Unassociate = true) { //note when you are commiting a group of hardware that contains a SLICE6Db, you should //sort the hardware so that this call happens BEFORE we commit any child slice6 if (hardware.IsPseudoRack() && Unassociate) { UnassociateParentDAS(hardware.SerialNumber); } var iso = hardware.GetHardware(); var h = new DTS.Common.ISO.Hardware { SerialNumber = hardware.SerialNumber, LocalOnly = hardware.LocalOnly, IsModule = hardware.IsModule(), CalDate = hardware.CalDate, DASType = hardware.GetHardwareTypeInt(), FirmwareVersion = hardware.Firmware, IPAddress = hardware.Connection, MaxMemory = hardware.GetMaxMemoryLong(), MaxModules = hardware.MaxModules, MaxSampleRate = hardware.GetMaxSampleRateDouble(), MinSampleRate = hardware.GetMinSampleRateDouble(), ProtocolVersion = hardware.ProtocolVersion, Channels = hardware.Channels.Length, LastModified = DateTime.Now, LastModifiedBy = ApplicationProperties.CurrentUser.UserName, IsReconfigurable = hardware.Reconfigurable, IsProgrammable = hardware.Reprogrammable, ChannelTypes = hardware.ChannelTypes, ParentDAS = hardware.ParentDAS, Port = hardware.PortOnDistributor, PositionOnChain = hardware.PositionOnChain, PositionOnDistributor = hardware.PositionOnDistributor, IsFirstUseValid = hardware.IsFirstUseValid, FirstUseDate = hardware.FirstUseDate, StandIn = iso.StandIn, MaxAAFRate = hardware.GetMaxAAFRateDouble(), TestId = iso.TestId, GroupId = iso.GroupId, LastUsed = iso.LastUsed, LastUsedBy = iso.LastUsedBy }; h.ISOChannels = hardware.Channels.Select(channel => new DTS.Common.ISO.HardwareChannel(channel.GetISOChannel(), h)) .ToArray(); hardware.SetHardware(h); //if (null == _hardware) //{ // PopulateHardware(); //} //10037 TDAS G5 module is detected as a TDAS G5 in a VDS, so if the existing serial number and ip address //already exists in the database if (bCheckExisting) { //22320 Unnecessary hardware retrieval bExisting = DASHardware.GetDataBaseID(hardware.SerialNumber) > 0; } if (!bExisting) { h.Insert(); } else { h.Version = h.Version + 1; //10037 TDAS G5 module is detected as a TDAS G5 in a VDS //the id could change, so if we are doing an update, we should make sure to remove the old instance in the list //_hardware.Remove(existingHardware.GetHardware().GetId()); //_hardware[hardware.GetHardware().GetId()] = hardware; h.Update(); } OnPropertyChanged(Tags.Hardware.ToString()); //no longer need to mark groups incomplete } /// /// deletes the selected IHardware /// public void Delete(IHardware hardware) { if (hardware.Hardware is IISOHardware isoHW) { isoHW.Delete(); } } public void Delete(DASHardware hardware) { var h = hardware?.GetHardware(); if (h == null) { return; } h.Delete(); if (hardware.IsPseudoRack()) { UnassociateParentDAS(hardware.SerialNumber); } OnPropertyChanged(Tags.Hardware.ToString()); } /// /// iteratively deletes the given hardware /// public void Delete(IHardware[] hardware) { foreach (var h in hardware) { Delete(h); } } public void Delete(DASHardware[] hardware) { foreach (DASHardware hw in hardware) { Delete(hw); } } public static void UnassociateParentDAS(string distributorSerialNumber) { using (var sql = DbOperations.GetSQLCommand(true)) { try { sql.CommandType = System.Data.CommandType.StoredProcedure; sql.CommandText = DbOperationsEnum.StoredProcedure.sp_DASChildrenUnAssociate.ToString(); DbOperations.CreateParam(sql, "@ParentSerialNumber", System.Data.SqlDbType.NVarChar, distributorSerialNumber); sql.ExecuteNonQuery(); } finally { sql.Connection.Dispose(); } } } } }