using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; namespace DatabaseExport { public class TestGraph //: BindableBase { private const string SEPARATOR = "§"; private const string CURRENT_SUFFIX = "_CU"; 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) { double d; if (double.TryParse(token, out 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 == Test.Module.Channel.Sensor.BridgeType.SQUIB)) { if (ch.SquibChannelType == TestObjectChannel.SquibChannelTypes.Current) { key += 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 snapshotted 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(); } 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() + CURRENT_SUFFIX); } } private bool ContainsVoltageChannel(TestObjectChannel channel) { return ContainsChannel(channel); } public TestObjectChannel[] AvailableChannels { get { _lookup.Clear(); foreach (var setChannel in _channels) { _lookup[setChannel.GetGraphID()] = setChannel; } var channels = new List(); 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) { continue; } if (string.IsNullOrWhiteSpace(channel.SensorSerialNumber)) { continue; } var sd = SensorsCollection.SensorsList.GetSensorBySerialNumber(channel.SensorSerialNumber); if (null == sd || !sd.IsDigitalOutput()) { if ((sd != null) && (sd.Bridge == Test.Module.Channel.Sensor.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 + " " + "(Current)" //Strings.StringResources.Graph_SquibCurrent }; channels.Add(currentChannel); } if (!ContainsVoltageChannel(channel)) { channel.SquibChannelType = TestObjectChannel.SquibChannelTypes.Voltage; channel.NameOfTheChannel = channel.Name + " " + "(Voltage)"; //Strings.StringResources.Graph_SquibVoltage; channels.Add(channel); } } else { if (ContainsChannel(channel)) { continue; } channels.Add(channel); } } } return true; } public string GraphName { get; set; } = ""; public string GraphDescription { get; set; } = ""; public bool UseDomainMin { get; set; } public double DomainMin { get; set; } = double.MinValue; public bool UseDomainMax { get; set; } public double DomainMax { get; set; } = double.MaxValue; public bool UseRangeMin { get; set; } public double RangeMin { get; set; } = double.MinValue; public bool UseRangeMax { get; set; } public double RangeMax { get; set; } = double.MaxValue; private List _thresholds = new List(); public double[] Thresholds { get => _thresholds.ToArray(); set => _thresholds = new List(value); } private readonly TestTemplate _template; private List _groups = new List(); private List _addedGroups = new List(); 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)); } } } }