Files
DP44/DataPRO/IService/Classes/Channels/OutputSquibChannel.cs
2026-04-17 14:55:32 -04:00

361 lines
17 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using DTS.Common.Enums;
using DTS.Common.Interface.DASFactory.Diagnostics;
using DTS.Common.Utilities.Logging;
namespace DTS.DASLib.Service
{
/// <summary>
/// Base class for SQUIB channels.
/// </summary>
[Serializable]
public class OutputSquibChannel : AnalogOutputDASChannel, IComparable
{
public SquibFireMode[] SupportedSquibFireModes { get; set; } = { SquibFireMode.AC, SquibFireMode.CAP, SquibFireMode.CONSTANT, SquibFireMode.NONE };
public IDiagnosticResult Diagnostics
{
get
{
try
{
IDiagnosticResult[] allChannelDiagnostics;
IEnumerable<IDiagnosticResult> theseChannelDiagnostics;
if (null == (allChannelDiagnostics = OwningModule.OwningDAS.ChannelDiagnosticsResults))
throw new InvalidDataException("No diagnostics available (for any channel)");
if (null == (theseChannelDiagnostics = (allChannelDiagnostics.Where(r => r.DASChannelNumber == Number))))
throw new NullReferenceException("No diagnostics available (for this channel)");
if (theseChannelDiagnostics.Count() > 1)
throw new InvalidDataException("Several diagnostics results were found for the specified channel; only one was expected");
if (theseChannelDiagnostics.Count() < 1)
{
throw new NullReferenceException("No diagnostics available (for this channel)");
}
return theseChannelDiagnostics.First();
}
catch (Exception ex)
{
throw new ApplicationException("encountered problem getting diagnostics for channel ", ex);
}
}
}
public override string ToString()
{
if (!string.IsNullOrEmpty(SquibDescription.Trim()))
return SquibDescription.Trim();
return base.ToString();
}
int IComparable.CompareTo(object o)
{
if (null == o) { return 1; }
if (o is OutputSquibChannel)
{
return SquibDescription.CompareTo((o as OutputSquibChannel).SquibDescription);
}
return SquibDescription.CompareTo(o.ToString());
}
public SquibFireMode FireMode { get; set; } = SquibFireMode.NONE;
public SquibMeasurementType MeasurementType { get; set; } = SquibMeasurementType.NONE;
public bool BypassCurrentFilter { get; set; } = false;
public bool BypassVoltageFilter { get; set; } = false;
public double SquibToleranceLow { get; set; } = 0D;
public double SquibToleranceHigh { get; set; } = 0D;
public double SquibOutputCurrent { get; set; } = 0D;
public double SquibMeasuredOhms { get; set; } = 0D;
public bool SquibFiredValid { get; set; } = false;
public bool SquibFiredPassed { get; set; } = false;
public double DelayMS { get; set; } = 0D;
public double DurationMS { get; set; } = 0D;
public string SquibDescription { get; set; } = "";
public string ISOCode { get; set; } = "";
public string ChannelId { get; set; }
public string ChannelName2 { get; set; }
public string HardwareChannelName { get; set; }
public bool LimitDuration { get; set; }
public short PreTestDataZeroLevelADC { get; set; }
public double ScaleFactorMv { get; set; } = 0D;
public bool LocalOnly { get; set; } = false;
public string LastModifiedBy { get; set; }
public string Sensor { get; set; }
public string SerialNumber { get; set; } = "";
/// <summary>
/// controls the frequency of software filters for squib channels
/// 8747 - TDC by default will filter at 1650hz
/// </summary>
public double SoftwareFilterFrequency { get; set; }
public OutputSquibChannel(XmlReader reader)
{
SupportedSquibFireModes = new[] { SquibFireMode.AC, SquibFireMode.CAP, SquibFireMode.CONSTANT, SquibFireMode.NONE };
IDs = new[] { new EID() };
ReadXml(reader);
}
public OutputSquibChannel(DASModule owner, int channelNumber)
: base(owner, channelNumber)
{
SupportedSquibFireModes = new[] { SquibFireMode.AC, SquibFireMode.CAP, SquibFireMode.CONSTANT, SquibFireMode.NONE };
IDs = new[] { new EID() };
}
public OutputSquibChannel()
{
SupportedSquibFireModes = new[] { SquibFireMode.AC, SquibFireMode.CAP, SquibFireMode.CONSTANT, SquibFireMode.NONE };
IDs = new[] { new EID() };
}
public override void WriteXmlCRC32(XmlWriter writer)
{
base.WriteXmlCRC32(writer);
XMLHelper.PutBool(writer, "BypassCurrentFilter", BypassCurrentFilter);
XMLHelper.PutBool(writer, "BypassVoltageFilter", BypassVoltageFilter);
XMLHelper.PutDouble(writer, "DelayMS", DelayMS);
XMLHelper.PutDouble(writer, "DurationMS", DurationMS);
XMLHelper.PutString(writer, "FireMode", FireMode.ToString());
XMLHelper.PutString(writer, "ISOCode", ISOCode);
XMLHelper.PutString(writer, "MeasurementType", MeasurementType.ToString());
XMLHelper.PutString(writer, "SquibDescription", SquibDescription);
XMLHelper.PutString(writer, "ChannelName2", ChannelName2);
XMLHelper.PutString(writer, "ChannelId", ChannelId);
XMLHelper.PutString(writer, "ChannelGroupName", ChannelGroupName);
XMLHelper.PutString(writer, "HardwareChannelName", HardwareChannelName);
XMLHelper.PutDouble(writer, "SquibOutputCurrent", SquibOutputCurrent);
XMLHelper.PutDouble(writer, "SquibToleranceHigh", SquibToleranceHigh);
XMLHelper.PutDouble(writer, "SquibToleranceLow", SquibToleranceLow);
XMLHelper.PutBool(writer, "LimitDuration", LimitDuration);
XMLHelper.PutString(writer, "ArticleId", "");
XMLHelper.PutString(writer, "SupportedSquibFireModes", GetSerializedSupportedSquibFireModes());
XMLHelper.PutDouble(writer, "SoftwareFilterFrequency", SoftwareFilterFrequency);
XMLHelper.PutString(writer, "Sensor", Sensor);
}
private readonly string _SEPARATOR = "@";
public override void WriteXml(XmlWriter writer)
{
base.WriteXml(writer);
XMLHelper.PutBool(writer, "BypassCurrentFilter", BypassCurrentFilter);
XMLHelper.PutBool(writer, "BypassVoltageFilter", BypassVoltageFilter);
XMLHelper.PutDouble(writer, "DelayMS", DelayMS);
XMLHelper.PutDouble(writer, "DurationMS", DurationMS);
XMLHelper.PutString(writer, "FireMode", FireMode.ToString());
XMLHelper.PutString(writer, "ISOCode", ISOCode);
XMLHelper.PutString(writer, "MeasurementType", MeasurementType.ToString());
XMLHelper.PutString(writer, "SquibDescription", SquibDescription);
XMLHelper.PutString(writer, "ChannelName2", ChannelName2);
XMLHelper.PutString(writer, "ChannelId", ChannelId);
XMLHelper.PutString(writer, "ChannelGroupName", ChannelGroupName);
XMLHelper.PutString(writer, "HardwareChannelName", HardwareChannelName);
XMLHelper.PutBool(writer, "SquibFirePassed", SquibFiredPassed);
XMLHelper.PutBool(writer, "SquibFireValid", SquibFiredValid);
XMLHelper.PutDouble(writer, "SquibOhms", SquibMeasuredOhms);
XMLHelper.PutDouble(writer, "SquibOutputCurrent", SquibOutputCurrent);
XMLHelper.PutDouble(writer, "SquibToleranceHigh", SquibToleranceHigh);
XMLHelper.PutDouble(writer, "SquibToleranceLow", SquibToleranceLow);
XMLHelper.PutBool(writer, "LimitDuration", LimitDuration);
XMLHelper.PutDouble(writer, "ScaleFactorMv", ScaleFactorMv);
XMLHelper.PutInt(writer, "PreTestDataZeroLevelADC", PreTestDataZeroLevelADC);
XMLHelper.PutString(writer, "ArticleId", "");
XMLHelper.PutString(writer, "SupportedSquibFireModes", GetSerializedSupportedSquibFireModes());
XMLHelper.PutDouble(writer, "SoftwareFilterFrequency", SoftwareFilterFrequency);
XMLHelper.PutString(writer, "Sensor", Sensor);
XMLHelper.PutString(writer, "SerialNumber", SerialNumber);
}
public int Version { get; set; }
public DateTime Date { get; set; }
public string GetSerializedSupportedSquibFireModes()
{
var sb = new StringBuilder();
foreach (var s in SupportedSquibFireModes)
{
if (sb.Length > 0) { sb.Append(_SEPARATOR); }
sb.Append(s);
}
return sb.ToString();
}
private SquibFireMode[] DeserializeSquibFireModes(string s)
{
var modes = new List<SquibFireMode>();
var tokens = s.Split(new[] { _SEPARATOR }, StringSplitOptions.None);
foreach (var token in tokens)
{
if (Enum.TryParse(token, out SquibFireMode mode)) { modes.Add(mode); }
}
return modes.ToArray();
}
private const string BYPASSCURRENTFILTER_TAG = "BypassCurrentFilter";
private const string BYPASSVOLTAGEFILTER_TAG = "BypassVoltageFilter";
private const string DELAYMS_TAG = "DelayMS";
private const string DURATIONMS_TAG = "DurationMS";
private const string FIREMODE_TAG = "FireMode";
private const string ISOCODE_TAG = "ISOCode";
private const string MEASUREMENTTYPE_TAG = "MeasurementType";
private const string SQUIBDESCRIPTION_TAG = "SquibDescription";
private const string CHANNELID_TAG = "ChannelId";
private const string CHANNELGROUPNAME_TAG = "ChannelGroupName";
private const string CHANNELNAME2_TAG = "ChannelName2";
private const string HARDWARECHANNELNAME_TAG = "HardwareChannelName";
private const string SQUIBFIREPASSED_TAG = "SquibFirePassed";
private const string SQUIBFIREVALID_TAG = "SquibFireValid";
private const string SQUIBOHMS_TAG = "SquibOhms";
private const string SQUIBOUTPUTCURRENT_TAG = "SquibOutputCurrent";
private const string SQUIBTOLERANCEHIGH_TAG = "SquibToleranceHigh";
private const string SQUIBTOLERANCELOW_TAG = "SquibToleranceLow";
private const string LIMITDURATION_TAG = "LimitDuration";
private const string SCALEFACTORMV_TAG = "ScaleFactorMv";
private const string PRETESTDATAZEROLEVELADC_TAG = "PreTestDataZeroLevelADC";
private const string ARTICLEID_TAG = "ArticleId";
private const string SUPPORTEDSQUIBFIREMODES_TAG = "SupportedSquibFireModes";
private const string SOFTWAREFILTERHZ_TAG = "SoftwareFilterFrequency";
private const string SENSOR_TAG = "Sensor";
private const string SERIALNUMBER_TAG = "SerialNumber";
protected override void HandleElement(XmlReader reader)
{
base.HandleElement(reader);
if (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
case BYPASSCURRENTFILTER_TAG:
BypassCurrentFilter = XMLHelper.GetBool(reader);
break;
case BYPASSVOLTAGEFILTER_TAG:
BypassVoltageFilter = XMLHelper.GetBool(reader);
break;
case DELAYMS_TAG:
DelayMS = XMLHelper.GetDouble(reader);
break;
case DURATIONMS_TAG:
DurationMS = XMLHelper.GetDouble(reader);
break;
case FIREMODE_TAG:
String mode = XMLHelper.GetString(reader);
try
{
FireMode = (SquibFireMode)Enum.Parse(typeof(SquibFireMode), mode);
}
catch (Exception ex) { APILogger.Log("Failed to load firemode ", mode, ex); }
break;
case ISOCODE_TAG:
ISOCode = XMLHelper.GetString(reader);
break;
case MEASUREMENTTYPE_TAG:
string measurementType = XMLHelper.GetString(reader);
try
{
MeasurementType = (SquibMeasurementType)Enum.Parse(typeof(SquibMeasurementType), measurementType);
}
catch (Exception ex) { APILogger.Log("Failed to load MeasurementType ", measurementType, ex); }
break;
case SQUIBDESCRIPTION_TAG:
SquibDescription = XMLHelper.GetString(reader);
break;
case CHANNELID_TAG:
ChannelId = XMLHelper.GetString(reader);
break;
case SENSOR_TAG:
Sensor = XMLHelper.GetString(reader);
break;
case SERIALNUMBER_TAG:
SerialNumber = XMLHelper.GetString(reader);
break;
case CHANNELGROUPNAME_TAG:
ChannelGroupName = XMLHelper.GetString(reader);
break;
case CHANNELNAME2_TAG:
ChannelName2 = XMLHelper.GetString(reader);
break;
case HARDWARECHANNELNAME_TAG:
HardwareChannelName = XMLHelper.GetString(reader);
break;
case SQUIBFIREPASSED_TAG:
SquibFiredPassed = XMLHelper.GetBool(reader);
break;
case SQUIBFIREVALID_TAG:
SquibFiredValid = XMLHelper.GetBool(reader);
break;
case SQUIBOHMS_TAG:
SquibMeasuredOhms = XMLHelper.GetDouble(reader);
break;
case SQUIBOUTPUTCURRENT_TAG:
SquibOutputCurrent = XMLHelper.GetDouble(reader);
break;
case SQUIBTOLERANCEHIGH_TAG:
SquibToleranceHigh = XMLHelper.GetDouble(reader);
break;
case SQUIBTOLERANCELOW_TAG:
SquibToleranceLow = XMLHelper.GetDouble(reader);
break;
case LIMITDURATION_TAG:
LimitDuration = XMLHelper.GetBool(reader);
break;
case SCALEFACTORMV_TAG:
ScaleFactorMv = XMLHelper.GetDouble(reader);
break;
case PRETESTDATAZEROLEVELADC_TAG:
PreTestDataZeroLevelADC = Convert.ToInt16(XMLHelper.GetInt(reader));
break;
case ARTICLEID_TAG:
//2021-05-21 - why aren't we using this id? -DTM
_ = XMLHelper.GetString(reader);
IDs = new EID[] { new EID() };
break;
case SUPPORTEDSQUIBFIREMODES_TAG:
string s = XMLHelper.GetString(reader);
SupportedSquibFireModes = DeserializeSquibFireModes(s);
break;
case SOFTWAREFILTERHZ_TAG:
var freq = XMLHelper.GetOptionalDouble(reader);
if (null != freq) { SoftwareFilterFrequency = (double)freq; }
break;
default:
// let child handle it
break;
}
}
}
public override bool IsConfigured()
{
return FireMode != SquibFireMode.NONE && !string.IsNullOrEmpty(SquibDescription);
}
public const double DEFAULT_MIN_FIRE_DURATION_MS = 0.20; // FB 5439; don't allow user to set below min duration
public const double DEFAULT_MIN_FIRE_DELAY_MS = 0.0D; // FB 5827 Saving squibs with invalid delay settings
public const double DEFAULT_DEFINEINTEST_FIRE_DELAY_FLAG = -1; // FB 14623 A flag which specifies the Delay has to be defined in the test setup, also when updating please update the -1 check for SquibDelay in EditSquibControl
public const double DEFAULT_MAX_FIRE_DURATION_MS = 25.5D; //stole it out of the UI in datapro
public const double DEFAULT_MAX_FIRE_DELAY_MS = 99000D; //also stolen
}
}