151 lines
4.4 KiB
C#
151 lines
4.4 KiB
C#
using System;
|
|
using System.Globalization;
|
|
|
|
namespace TBF.BenchControl.WaterMeters.iPerl
|
|
{
|
|
public class OptoTelegram
|
|
{
|
|
public static readonly int Length = 42;
|
|
|
|
public double EMF;
|
|
public Int16 MagneticField;
|
|
public double Flow;
|
|
public double Volume;
|
|
public Int16 Impedance;
|
|
public UInt32 Timestamp;
|
|
public byte GG;
|
|
|
|
string sourceStr;
|
|
|
|
|
|
public OptoTelegram()
|
|
{
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return sourceStr;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create a configuration structure from a complete byte array
|
|
///
|
|
/// Telegram description:
|
|
///
|
|
/// AAAAAA[tab]BBBB[tab]CCCC[tab]DDDDDD[tab]EEEE[tab]FFFFFFFF[tab]GG[cr][lf] (42 bytes)
|
|
///
|
|
/// Data Comment Type Calculate to decimal
|
|
/// ----------------------------------------------------------------
|
|
/// AAAAAA EMF Int24 Value * 0.000000333
|
|
/// BBBB Magnetic field Int16 Value
|
|
/// CCCC Flow Int16 Value * 0.225 * Scalig factor
|
|
/// DDDDDD Volume Int24 Value / 16000 * Scaling factor
|
|
/// EEEE Impedance Int16 Value
|
|
/// FFFFFFFF Timestamp Uint32 Value / 8192
|
|
/// GG
|
|
/// ----------------------------------------------------------------
|
|
///
|
|
/// Example:
|
|
/// FFFFFE 51EA 0000 65324E 0087 F6319DFF 86
|
|
/// FFDD3A 51F9 0000 65324E 0088 F631A60B 45
|
|
/// ...
|
|
/// </summary>
|
|
/// <param name="data">A complete byte array data</param>
|
|
/// <returns>ConfigStruct or null when byte array was not complete</returns>
|
|
public static OptoTelegram FromString(string telegram, MeterType meterType)
|
|
{
|
|
if ((telegram == null) || (telegram.Length < Length) ||
|
|
(telegram[6] != '\t') || (telegram[11] != '\t') ||
|
|
(telegram[16] != '\t') || (telegram[23] != '\t') ||
|
|
(telegram[28] != '\t') || (telegram[37] != '\t') ||
|
|
(telegram[40] != '\r') || (telegram[41] != '\n'))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
OptoTelegram opto = new OptoTelegram();
|
|
|
|
Int32 value;
|
|
if (Int32.TryParse(telegram.Substring(0, 6), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out value))
|
|
{
|
|
Int32 svalue = (value >= 0x00800000) ? (value - 0x01000000) : value;
|
|
opto.EMF = 0.000000333 * (double)svalue;
|
|
}
|
|
else return null;
|
|
|
|
if (Int32.TryParse(telegram.Substring(7, 4), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out value))
|
|
{
|
|
Int32 svalue = (value >= 0x00008000) ? (value - 0x00010000) : value;
|
|
opto.MagneticField = (Int16)svalue;
|
|
}
|
|
else return null;
|
|
|
|
double factor = ScalingFactor(meterType);
|
|
|
|
if (Int32.TryParse(telegram.Substring(12, 4), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out value))
|
|
{
|
|
Int32 svalue = (value >= 0x00008000) ? (value - 0x00010000) : value;
|
|
opto.Flow = 0.225 * (double)svalue * factor;
|
|
}
|
|
else return null;
|
|
|
|
if (Int32.TryParse(telegram.Substring(17, 6), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out value))
|
|
{
|
|
Int32 svalue = (value >= 0x00800000) ? (value - 0x01000000) : value;
|
|
opto.Volume = (double)svalue / 16000.0 * factor;
|
|
}
|
|
else return null;
|
|
|
|
if (Int32.TryParse(telegram.Substring(24, 4), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out value))
|
|
{
|
|
Int32 svalue = (value >= 0x00008000) ? (value - 0x00010000) : value;
|
|
opto.Impedance = (Int16)svalue;
|
|
}
|
|
else return null;
|
|
|
|
UInt32 uvalue;
|
|
if (UInt32.TryParse(telegram.Substring(29, 8), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out uvalue))
|
|
{
|
|
opto.Timestamp = uvalue;
|
|
}
|
|
else return null;
|
|
|
|
if (UInt32.TryParse(telegram.Substring(38, 2), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out uvalue))
|
|
{
|
|
opto.GG = (byte)uvalue;
|
|
}
|
|
else return null;
|
|
|
|
opto.sourceStr = telegram.Substring(0, Length - 2);
|
|
|
|
return opto;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Scaling factor:
|
|
/// 0, 1 (DN15, Coax) . . . . 1
|
|
/// 2 (DN20) . . . . . . . . 2
|
|
/// 3 (DN25) . . . . . . . . 4
|
|
/// 4, 5 (DN26, DN32) . . . . 8
|
|
/// 6 (DN40) . . . . . . . . 16
|
|
/// </summary>
|
|
/// <param name="meterType">MeterType (0..6)</param>
|
|
/// <returns>Scaling factor</returns>
|
|
public static double ScalingFactor(MeterType meterType)
|
|
{
|
|
switch (meterType)
|
|
{
|
|
default:
|
|
case MeterType.DN15:
|
|
case MeterType.CoaxManifold: return 1.0;
|
|
case MeterType.DN20: return 2.0;
|
|
case MeterType.DN25: return 4.0;
|
|
case MeterType.DN26:
|
|
case MeterType.DN32: return 8.0;
|
|
case MeterType.DN40: return 16.0;
|
|
}
|
|
}
|
|
}
|
|
}
|