using System; using System.Collections.Generic; using System.Data; using System.Globalization; using System.Linq; using System.Text; using System.Windows.Media; using DataPROWin7.Common; using DTS.Common.SharedResource.Strings; using DTS.Common.Interface.Channels; using DTS.SensorDB; using DTS.Common.ISO; using DTS.Common.Enums.Sensors; using DTS.Common.Classes.TestSetups; using DTS.Common.Interface.Graphs; using DTS.Common; namespace DataPROWin7.DataModel { public class TestGraph : GraphRecord, IGraph { /// /// updates the ChannelsString and ThresholdsString /// using GroupChannels and Thresholds properties /// public void UpdateChannelAndThresholdStrings() { var sb = new StringBuilder(); int index = 0; foreach (var ch in GroupChannels) { if (0 != index++) { sb.Append(","); } sb.Append(ch.Id); } ChannelsString = sb.ToString(); index = 0; sb.Clear(); foreach (var d in Thresholds) { if (0 != index++) { sb.Append(","); } sb.Append(d.ToString(CultureInfo.InvariantCulture)); } ThresholdsString = sb.ToString(); } public void AddChannel(IGroupChannel groupChannel) { _groupChannels.Add(groupChannel); OnPropertyChanged("GroupChannels"); } public void RemoveChannel(IGroupChannel groupChannel) { _groupChannels.Remove(groupChannel); OnPropertyChanged("GroupChannels"); } private readonly List _groupChannels = new List(); public IGroupChannel[] GroupChannels => _groupChannels.ToArray(); private const string SEPARATOR = "§"; public string GetThresholdsSQL() { var sb = new StringBuilder(); sb.Append("{"); int count = 0; foreach (var t in Thresholds) { if (count > 0) { sb.Append(SEPARATOR); } //for now thresholds are only doubles, we'll probably want more complicated ones in the future sb.Append("("); sb.Append(t.ToString(CultureInfo.InvariantCulture)); sb.Append(")"); count++; } sb.Append("}"); return sb.ToString(); } public void SetThresholdsFromSQL(string sThresholds) { //for now we take an easy parse sThresholds = sThresholds.Replace("{", "").Replace("}", ""); var sTokens = sThresholds.Split(new[] { SEPARATOR }, StringSplitOptions.None); foreach (var token in sTokens) { if (double.TryParse(token, out var d)) { _thresholds.Add(d); } } } public void SetChannelsFromSQL(string sChannels) { var lookup = new Dictionary(); if (null == AvailableChannels) { return; } foreach (var channel in AvailableChannels) { lookup[channel.GetGraphId()] = channel; } sChannels = sChannels.Replace("{", "").Replace("}", ""); var tokens = sChannels.Split(new[] { SEPARATOR }, StringSplitOptions.None); foreach (var token in tokens) { var sChannelId = token.Replace("(", "").Replace(")", ""); if (lookup.ContainsKey(sChannelId)) { AddChannel(lookup[sChannelId]); } } } /// /// Generate a key like __ and if the channel is squib "current", "_CU" /// /// /// private string GetTestGraphKey(TestObjectChannel ch) { var key = string.Format("{0}_{1}_{2}", ch.TestObject.SerialNumber, ch.Name, ch.Channel.MMEChannelType); var sd = SensorsCollection.SensorsList.GetSensorBySerialNumber(ch.SensorSerialNumber); if (null == sd || !sd.IsDigitalOutput()) { if ((sd != null) && (sd.Bridge == SensorConstants.BridgeType.SQUIB)) { if (ch.SquibChannelType == TestObjectChannel.SquibChannelTypes.Current) { key += Constants.CURRENT_SUFFIX; } } } return key; } public string GetChannelsForSQL() { var sb = new StringBuilder(); sb.Append("{"); var bNeedSep = false; //we must "refresh" the channels we have as they are a snapshot from when the graph was created and the channels may have new ids //6991 Clicking save removes sensors from graph in test setup. var channelLookup = new Dictionary(); foreach (var ch in _channels) { channelLookup[GetTestGraphKey(ch)] = ch; } foreach (var ch in AvailableChannels) { channelLookup[GetTestGraphKey(ch)] = ch; } var channelsAfterResolve = new List(); foreach (var ch in _channels) { if (channelLookup.ContainsKey(GetTestGraphKey(ch))) { channelsAfterResolve.Add(ch); } } _channels = channelsAfterResolve; foreach (var ch in Channels) { if (bNeedSep) { sb.Append(SEPARATOR); } else { bNeedSep = true; } sb.AppendFormat("({0})", ch.GetGraphId()); } sb.Append("}"); return sb.ToString(); } public static SolidColorBrush[] Brushes = { System.Windows.Media.Brushes.Blue, System.Windows.Media.Brushes.Red, System.Windows.Media.Brushes.Green, System.Windows.Media.Brushes.Orange, System.Windows.Media.Brushes.Brown, System.Windows.Media.Brushes.Purple, System.Windows.Media.Brushes.Pink, System.Windows.Media.Brushes.Lime, System.Windows.Media.Brushes.Magenta }; private List _channels = new List(); private readonly Dictionary _lookup = new Dictionary(); public TestObjectChannel[] Channels { get { var toBeRemoved = new List(); foreach (var ch in _channels) { var found = false; foreach (var group in Groups) { if (group.SerialNumber == ch.TestObject.SerialNumber) { found = true; } } foreach (var addedGroup in AddedGroups) { if (addedGroup.SerialNumber == ch.TestObject.SerialNumber) { found = true; } } if (!found) { toBeRemoved.Add(ch); } } foreach (var ch in toBeRemoved) { _channels.Remove(ch); } return _channels.ToArray(); } } private void AddGroup(TestTestObject group) { Groups.Add(group); } private void AddAddedGroup(TestTestObject addedGroup) { AddedGroups.Add(addedGroup); } private void AddChannel(TestObjectChannel channel) { _channels.Add(channel); _lookup[channel.GetGraphId()] = channel; OnPropertyChanged("Channels"); OnPropertyChanged("AvailableChannels"); } private bool ContainsChannel(TestObjectChannel channel) { return _lookup.ContainsKey(channel.GetGraphId()); } private bool ContainsCurrentChannel(TestObjectChannel channel) { if (channel.SquibChannelType == TestObjectChannel.SquibChannelTypes.Current) { return ContainsChannel(channel); } else { return _lookup.ContainsKey(channel.GetGraphId() + Constants.CURRENT_SUFFIX); } } private bool ContainsVoltageChannel(TestObjectChannel channel) { return ContainsChannel(channel); } private const int MAX_CHANNELS_PER_GRAPH = 8; public TestObjectChannel[] AvailableChannels { get { _lookup.Clear(); var channels = new List(); if (_channels.Count >= MAX_CHANNELS_PER_GRAPH) return channels.ToArray(); foreach (var setChannel in _channels) { _lookup[setChannel.GetGraphId()] = setChannel; } if (Groups.Exists(to => !AddChannels(to, channels))) { return null; } if (AddedGroups.Where(to => to.Hardware.Any()).Any(to => !AddChannels(to, channels))) { return null; } channels.Sort(); return channels.ToArray(); } } private bool AddChannels(TestTestObject to, List channels) { var isoTestObject = to.GetISOTestObject(); if (null == isoTestObject) { return false; } foreach (var channel in isoTestObject.AllChannels) { if (!channel.Required || channel.Disabled) { continue; } if (string.IsNullOrWhiteSpace(channel.SensorSerialNumber)) { continue; } var sd = SensorsCollection.SensorsList.GetSensorBySerialNumber(channel.SensorSerialNumber); if (null == sd || !sd.IsDigitalOutput()) { if ((sd != null) && (sd.Bridge == SensorConstants.BridgeType.SQUIB)) { //Put squib channels (Current and/or Voltage) in the //Available list if and only if they are not in the graph if (!ContainsCurrentChannel(channel)) { var currentChannel = new TestObjectChannel(channel, isoTestObject, new TestObjectTemplate().ToISOTestObjectTemplate()) { SquibChannelType = TestObjectChannel.SquibChannelTypes.Current, NameOfTheChannel = channel.Name + " " + StringResources.Graph_SquibCurrent }; channels.Add(currentChannel); } if (!ContainsVoltageChannel(channel)) { channel.SquibChannelType = TestObjectChannel.SquibChannelTypes.Voltage; channel.NameOfTheChannel = channel.Name + " " + StringResources.Graph_SquibVoltage; channels.Add(channel); } } else { if (ContainsChannel(channel)) { continue; } channels.Add(channel); } } } return true; } private List _thresholds = new List(); public double[] Thresholds { get => _thresholds.ToArray(); set => SetProperty(ref _thresholds, new List(value), "Thresholds"); } private bool _bSelected; public bool Selected { get => _bSelected; set { SetProperty(ref _bSelected, value, "Selected"); OnPropertyChanged("BackgroundColor"); OnPropertyChanged("ForegroundColor"); OnPropertyChanged("Channels"); OnPropertyChanged("AvailableChannels"); } } public Color BackgroundColor => Selected ? DTS.Common.BrushesAndColors.Color_ActionBackground : DTS.Common.BrushesAndColors.Color_ItemBackground; private readonly Color _foregroundColor = DTS.Common.BrushesAndColors.Color_ItemForeground; public Color ForegroundColor => Selected ? DTS.Common.BrushesAndColors.Color_ActionForeground : _foregroundColor; private readonly TestTemplate _template; public List Groups { get; set; } = new List(); public List AddedGroups { get; set; } = new List(); public TestGraph() { } private void CommonInit(IReadOnlyDictionary lookup) { var s = ChannelsString; if (!string.IsNullOrWhiteSpace(s)) { var tokens = s.Split(','); foreach (var token in tokens) { if (long.TryParse(token, NumberStyles.Any, CultureInfo.InvariantCulture, out var l)) { if (lookup.ContainsKey(l)) { AddChannel(lookup[l]); } } } } s = ThresholdsString; if (!string.IsNullOrWhiteSpace(s)) { var list = new List(); var tokens = s.Split(','); foreach (var token in tokens) { if (double.TryParse(token, NumberStyles.Any, CultureInfo.InvariantCulture, out var d)) { list.Add(d); } } Thresholds = list.ToArray(); } } public TestGraph(IGraphRecord record, IReadOnlyDictionary lookup) : base(record) { CommonInit(lookup); } public TestGraph(IDataReader reader, IReadOnlyDictionary lookup) : base(reader) { CommonInit(lookup); } public void ReadXML(System.Xml.XmlElement root, IReadOnlyDictionary channelLookup) { var s = root.GetAttribute("DomainMax"); if (double.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out var d)) { DomainMax = d; } s = root.GetAttribute("DomainMin"); if (double.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out d)) { DomainMin = d; } GraphDescription = root.GetAttribute("GraphDescription"); s = root.GetAttribute("GraphId"); if (int.TryParse(s, out var i)) { GraphId = i; } GraphName = root.GetAttribute("GraphName"); s = root.GetAttribute("RangeMax"); if (double.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out d)) { RangeMax = d; } s = root.GetAttribute("RangeMin"); if (double.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out d)) { RangeMin = d; } s = root.GetAttribute("Thresholds"); if (!string.IsNullOrWhiteSpace(s)) { var tokens = s.Split(','); var list = new List(); foreach (var token in tokens) { if (double.TryParse(token, NumberStyles.Any, CultureInfo.InvariantCulture, out d)) { list.Add(d); } } Thresholds = list.ToArray(); } s = root.GetAttribute("UseDomainMax"); if (bool.TryParse(s, out var b)) { UseDomainMax = b; } s = root.GetAttribute("UseDomainMin"); if (bool.TryParse(s, out b)) { UseDomainMin = b; } s = root.GetAttribute("UseRangeMax"); if (bool.TryParse(s, out b)) { UseRangeMax = b; } s = root.GetAttribute("UseRangeMin"); if (bool.TryParse(s, out b)) { UseRangeMin = b; } s = root.GetAttribute("Channels"); if (!string.IsNullOrWhiteSpace(s)) { var tokens = s.Split(','); foreach (var token in tokens) { if (long.TryParse(token, out var l)) { if (channelLookup.ContainsKey(l)) { AddChannel(channelLookup[l]); } } } } } public void WriteXML(ref System.Xml.XmlWriter writer) { writer.WriteAttributeString("DomainMax", DomainMax.ToString(CultureInfo.InvariantCulture)); writer.WriteAttributeString("DomainMin", DomainMin.ToString(CultureInfo.InvariantCulture)); writer.WriteAttributeString("GraphDescription", GraphDescription ?? ""); writer.WriteAttributeString("GraphId", GraphId.ToString(CultureInfo.InvariantCulture)); writer.WriteAttributeString("GraphName", GraphName); writer.WriteAttributeString("RangeMax", RangeMax.ToString(CultureInfo.InvariantCulture)); writer.WriteAttributeString("RangeMin", RangeMin.ToString(CultureInfo.InvariantCulture)); var sb = new StringBuilder(); var index = 0; foreach (var d in Thresholds) { if (0 != index++) { sb.Append(","); } sb.Append(d.ToString(CultureInfo.InvariantCulture)); } writer.WriteAttributeString("Thresholds", sb.ToString()); writer.WriteAttributeString("UseDomainMax", UseDomainMax.ToString()); writer.WriteAttributeString("UseDomainMin", UseDomainMin.ToString()); writer.WriteAttributeString("UseRangeMax", UseRangeMax.ToString()); writer.WriteAttributeString("UseRangeMin", UseRangeMin.ToString()); sb.Clear(); index = 0; foreach (var ch in GroupChannels) { if (0 != index++) { sb.Append(","); } sb.Append(ch.Id.ToString(CultureInfo.InvariantCulture)); } writer.WriteAttributeString("Channels", sb.ToString()); writer.Flush(); } public TestGraph(TestTemplate template) { _template = template; foreach (var group in _template.TestObjectsWithChannels) { AddGroup(new TestTestObject(group)); } foreach (var addedGroup in _template.AddedGroups) { AddAddedGroup(new TestTestObject(addedGroup)); } } public TestGraph(TestGraph copy) : base(copy) { _thresholds = new List(copy.Thresholds); _groupChannels = new List(copy.GroupChannels); } } }