/*
Test.Module.AnalogInputChannel.cs
Copyright © 2008
Diversified Technical Systems, Inc.
All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using DTS.Common.Utilities;
using DTS.Common.Utilities.DotNetProgrammingConstructs;
using System.ComponentModel;
using DTS.Common.Utilities.Logging;
using DTS.Common.Utilities.Xml;
namespace DTS.Serialization
{
// *** see Test.cs ***
public partial class Test
{
// *** see Test.Module.cs ***
public partial class Module
{
///
/// Representation of a calculated channel.
///
[XmlSerializationTag("CalculatedChannel")]
public class CalculatedChannel : AnalogInputChannel
{
public CalculatedChannel(Module parentModule)
: base(parentModule)
{
}
///
/// Get/set the Source Channel for this channel.
///
[XmlSerializationTag("SourceChannelNumber")]
public int[] SourceChannelNumber
{
get => _SourceChannelNumber.Value;
set => _SourceChannelNumber.Value = value;
}
private readonly Property _SourceChannelNumber
= new Property(
typeof(CalculatedChannel).Namespace + ".Test.Module.CalculatedChannel.SourceChannelNumber",
null,
false
);
///
/// Get/set the Source Channel for this channel.
///
[XmlSerializationTag("SourceModuleNumber")]
public int[] SourceModuleNumber
{
get => _SourceModuleNumber.Value;
set => _SourceModuleNumber.Value = value;
}
private readonly Property _SourceModuleNumber
= new Property(
typeof(CalculatedChannel).Namespace + ".Test.Module.CalculatedChannel.SourceModuleNumber",
null,
false
);
///
/// Get/set the Source Channel for this channel.
///
[XmlSerializationTag("SourceModuleSerialNumber")]
public string[] SourceModuleSerialNumber
{
get => _SourceModuleSerialNumber.Value;
set => _SourceModuleSerialNumber.Value = value;
}
private readonly Property _SourceModuleSerialNumber
= new Property(
typeof(CalculatedChannel).Namespace + ".Test.Module.CalculatedChannel.SourceModuleSerialNumber",
null,
false
);
///
/// the calculation for the channel(s) involved
///
[XmlSerializationTag("Calculation")]
public string Calculation
{
get => _Calculation.Value;
set => _Calculation.Value = value;
}
private readonly Property _Calculation
= new Property(
typeof(CalculatedChannel).Namespace + ".Test.Module.CalculatedChannel.Calculation",
"NONE",
false
);
[XmlSerializationTag("T1")]
public ulong T1
{
get => _T1.Value;
set => _T1.Value = value;
}
private readonly Property _T1
= new Property(
typeof(CalculatedChannel).Namespace + ".Test.Module.CalculatedChannel.T1",
0,
false);
[XmlSerializationTag("T2")]
public ulong T2
{
get => _T2.Value;
set => _T2.Value = value;
}
private readonly Property _T2
= new Property(
typeof(CalculatedChannel).Namespace + ".Test.Module.CalculatedChannel.T2",
0,
false);
[XmlSerializationTag("HIC")]
public double HIC
{
get => _HIC.Value;
set => _HIC.Value = value;
}
private readonly Property _HIC
= new Property(
typeof(CalculatedChannel).Namespace + ".Test.Module.CalculatedChannel.HIC",
0D,
false);
///
/// Get/set the sample rate for this test module.
///
[XmlSerializationTag("SampleRateHz")]
public double SampleRateHz
{
get => _SampleRateHz.Value;
set => _SampleRateHz.Value = value;
}
private readonly Property _SampleRateHz
= new Property(
typeof(CalculatedChannel).Namespace + ".Test.Module.CalculatedChannel.SampleRateHz",
0,
false
);
private const string BeginTagModifier = "Begin";
private const string EndTagModifier = "End";
///
/// Write XML serialization for this object to the specified writer.
///
///
///
/// The to which this object's XML serialization
/// will be written.
///
///
public override void WriteXml(XmlWriter writer)
{
try
{
APILogger.Log("writing CalculatedChannel::WriteXML");
var cult = new System.Globalization.CultureInfo("");
var attributeExtractor = new AttributeExtractor();
writer.WriteStartElement(attributeExtractor.ExtractAttachedAttributeFromObject(this).Value);
writeXmlAttributes(writer);
writer.WriteAttributeString(attributeExtractor.ExtractAttachedAttributeFromProperty(this,
"SourceChannelNumber").Value, IntArrayToString(SourceChannelNumber));
writer.WriteAttributeString(attributeExtractor.ExtractAttachedAttributeFromProperty(this,
"SourceModuleNumber").Value, IntArrayToString(SourceModuleNumber));
writer.WriteAttributeString(
attributeExtractor.ExtractAttachedAttributeFromProperty(this, "SourceModuleSerialNumber")
.Value, StringArrayToString(SourceModuleSerialNumber));
writer.WriteAttributeString(attributeExtractor.ExtractAttachedAttributeFromProperty(this,
"Calculation").Value, Calculation.ToString(cult));
writer.WriteAttributeString(attributeExtractor.ExtractAttachedAttributeFromProperty(this,
"SampleRateHz").Value, SampleRateHz.ToString(cult));
if (_HIC.IsValueInitialized)
{
writer.WriteAttributeString(attributeExtractor.ExtractAttachedAttributeFromProperty(this,
"HIC").Value, HIC.ToString(System.Globalization.CultureInfo.InvariantCulture));
writer.WriteAttributeString(attributeExtractor.ExtractAttachedAttributeFromProperty(this,
"T1").Value, T1.ToString(System.Globalization.CultureInfo.InvariantCulture));
writer.WriteAttributeString(attributeExtractor.ExtractAttachedAttributeFromProperty(this,
"T2").Value, T2.ToString(System.Globalization.CultureInfo.InvariantCulture));
}
writer.WriteEndElement();
}
catch (System.Exception ex)
{
throw new Exception("encountered problem converting " + GetType().FullName + " object to XML: ", ex);
}
}
///
/// Read XML serialization for this object from the specified reader.
///
///
///
/// The from which this object's XML serialization
/// will be read.
///
///
public override void ReadXml(XmlReader reader)
{
try
{
var cult = new System.Globalization.CultureInfo("");
var attributeExtractor = new AttributeExtractor();
var xmlAttributeDecoder
= new PropertyAttributeDecoder(this);
base.ReadXml(reader);
SourceChannelNumber =
StringToIntArray(xmlAttributeDecoder.ExtractStringProperty("SourceChannelNumber", reader));
SourceModuleNumber =
StringToIntArray(xmlAttributeDecoder.ExtractStringProperty("SourceModuleNumber", reader));
SourceModuleSerialNumber =
StringToStringArray(xmlAttributeDecoder.ExtractStringProperty("SourceModuleSerialNumber",
reader));
Calculation = xmlAttributeDecoder.ExtractStringProperty("Calculation", reader);
SampleRateHz = xmlAttributeDecoder.ExtractDoubleProperty("SampleRateHz", reader);
var s = reader.GetAttribute("HIC");
if (!string.IsNullOrWhiteSpace(s))
{
HIC = Convert.ToDouble(s);
T1 = Convert.ToUInt64(reader.GetAttribute("T1"));
T2 = Convert.ToUInt64(reader.GetAttribute("T2"));
}
}
catch (System.Exception ex)
{
throw new Exception("encountered problem converting XML to " + GetType().FullName + " object", ex);
}
}
private int[] StringToIntArray(string s)
{
var ints = new List();
var tokens = s.Split(new char[] { ',' });
foreach (var token in tokens)
{
if (int.TryParse(token, System.Globalization.NumberStyles.Any,
System.Globalization.CultureInfo.InvariantCulture, out int i))
{
ints.Add(i);
}
}
return ints.ToArray();
}
private string[] StringToStringArray(string s)
{
var tokens = s.Split(new string[] { "_.-._" }, StringSplitOptions.None);
return tokens;
}
private string IntArrayToString(int[] array)
{
var sb = new StringBuilder();
foreach (var i in array)
{
if (sb.Length > 0)
{
sb.Append(",");
}
sb.Append(i.ToString(System.Globalization.CultureInfo.InvariantCulture));
}
return sb.ToString();
}
private string StringArrayToString(string[] array)
{
return string.Join("_.-._", array);
}
///
/// Test the specified object for equality with this object.
///
///
///
/// The to be tested for equality.
///
///
///
/// true if the specified object has memeberwise equality with
/// this object; false otherwise.
///
///
public override bool Equals(object obj)
{
try
{
var that = obj as CalculatedChannel;
return (null != obj)
// Must-be-initialized properties.
&& ChannelId.Equals(that.ChannelId)
&& SourceChannelNumber.Equals(that.SourceChannelNumber)
&& ChannelDescriptionString.Equals(that.ChannelDescriptionString)
&& EngineeringUnits.Equals(that.EngineeringUnits, StringComparison.OrdinalIgnoreCase)
&& Calculation.Equals(that.Calculation)
&& IsoCode.Equals(that.IsoCode);
}
catch (System.Exception ex)
{
throw new Exception("encountered problem equality-testing the object " + (null != obj ? "\"" + obj.ToString() + "\"" : "<>"), ex);
}
}
///
/// Return the hash code for this object.
///
///
///
/// The hash code for this object.
///
///
public override int GetHashCode()
{
return base.GetHashCode();
}
public override string ToString()
{
return ChannelDescriptionString;
}
///
/// creates a new calculated channel, with the modulenumbers, channelnumbers, and moduleserialnumbers composed of all the inputs
///
///
///
///
public static CalculatedChannel CreateInstance(Channel[] channels)
{
var cc = new CalculatedChannel(channels.First().ParentModule);
var maxSampleRAte = channels.Select(ch => ch.ParentModule.SampleRateHz).Max();
//CC only values
var channelNumbers = new List();
var moduleNumbers = new List();
var moduleSerialNumbers = new List();
var sps = channels.First().ParentModule.SampleRateHz;
foreach (var ch in channels)
{
channelNumbers.Add(ch.Number);
moduleSerialNumbers.Add(ch.ParentModule.SerialNumber);
if (0 != maxSampleRAte % ch.ParentModule.SampleRateHz)
{
throw new InvalidOperationException($"sample rate: {maxSampleRAte} is not a multiple of sample rate: {ch.ParentModule.SampleRateHz}");
}
}
cc.SourceChannelNumber = channelNumbers.ToArray();
cc.SourceModuleNumber = moduleNumbers.ToArray();
cc.SourceModuleSerialNumber = moduleSerialNumbers.ToArray();
cc.SampleRateHz = sps;
//Rip a copy. Can't use cloning
foreach (
PropertyDescriptor item in
TypeDescriptor.GetProperties(
channels.First() as AnalogInputChannel))
{
try
{
item.SetValue(cc, item.GetValue(channels.First()));
}
catch (System.Exception ex)
{
APILogger.Log(ex);
}
}
//need a copy not the original for linearization formula...
cc.LinearizationFormula =
new DTS.Common.Classes.Sensors.LinearizationFormula(
(channels.First() as AnalogInputChannel).LinearizationFormula);
return cc;
}
///
/// creates a calculated channel using a single source channel
///
///
///
public static CalculatedChannel CreateInstance(Channel sourceChannel)
{
//Dammit, need to manually clone properties from souce channel
var cc = new CalculatedChannel(sourceChannel.ParentModule);
//CC only values
cc.SourceChannelNumber = new int[] { sourceChannel.Number };
cc.SourceModuleNumber = new int[] { sourceChannel.ParentModule.Number };
cc.SourceModuleSerialNumber = new string[] { sourceChannel.ParentModule.SerialNumber };
cc.SampleRateHz = sourceChannel.ParentModule.SampleRateHz;
//Rip a copy. Can't use cloning
foreach (PropertyDescriptor item in TypeDescriptor.GetProperties(sourceChannel as AnalogInputChannel))
{
try
{
item.SetValue(cc, item.GetValue(sourceChannel));
}
catch { }
}
return cc;
}
}
}
}
}