102 lines
3.7 KiB
C#
102 lines
3.7 KiB
C#
///
|
|
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
|
///
|
|
using System;
|
|
using System.Globalization;
|
|
using System.Text;
|
|
|
|
namespace Workplace.CheckItems.S640
|
|
{
|
|
public class DatastreamFrame
|
|
{
|
|
public const int FrameLength = 49; /// Including CR,LF
|
|
public const double VolumeScaleFactor = 1000.0; /// Raw volume is in ml
|
|
public const double TimeScaleFactor = 1000.0; /// Raw time is in ms
|
|
|
|
/// Stored values
|
|
public DateTime DateTime; /// From PC
|
|
public char[] Data = new char[FrameLength - 2];
|
|
public Int32 VolumeRaw;
|
|
public Int64 VolumeRawExt;
|
|
public Int64 Timestamp;
|
|
public Int64 TimestampExt;
|
|
|
|
/// Calculated values
|
|
public double Volume() { return (double)VolumeRawExt / VolumeScaleFactor; }
|
|
public double TimestampDbl() { return (double)TimestampExt / TimeScaleFactor; }
|
|
|
|
public DatastreamFrame() { }
|
|
|
|
/// <summary>
|
|
/// Parses optical telegram and returns OptoTelegramRaw object
|
|
/// </summary>
|
|
/// <description>
|
|
/// Create a configuration structure from a complete byte array
|
|
///
|
|
/// Telegram description:
|
|
///
|
|
/// AAAAAAAAAAAA[tab]BBBBBBBBBB[tab]CCCCCCCCC[tab]DDDDDDDDDD[tab]EE[cr][lf] (49 bytes)
|
|
///
|
|
/// Data Comment Type Calculate to decimal
|
|
/// ----------------------------------------------------------------
|
|
/// AAAAAAAAAAAA PCB number Decimal
|
|
/// BBBBBBBBBB Radio address Decimal
|
|
/// CCCCCCCCC Meter reading Decimal Volume in ml
|
|
/// DDDDDDDDDD Timestamp Decimal Time in ms
|
|
/// EE Checksum Hexadecimal
|
|
/// ----------------------------------------------------------------
|
|
///
|
|
/// Example:
|
|
/// 540210730770 4291524429 000250215 0433411626 4F
|
|
/// 540210730770 4291524429 000250215 0433411876 56
|
|
/// ...
|
|
/// </description>
|
|
/// <param name="data">A complete byte array data</param>
|
|
/// <returns>true = telegram OK, false = telegram NOK</returns>
|
|
public bool UpdateFromString(string frame, ref Int64 volumeRawExtLast, ref Int64 timestampExtLast)
|
|
{
|
|
DateTime = DateTime.Now;
|
|
|
|
if (frame == null || frame.Length < FrameLength ||
|
|
frame[FrameLength - 2] != '\r' || frame[FrameLength - 1] != '\n' ||
|
|
frame[12] != '\t' || frame[23] != '\t' || frame[33] != '\t' || frame[44] != '\t')
|
|
{
|
|
return false;
|
|
}
|
|
|
|
/// Copy data into the fixed size buffer
|
|
int sum = 0;
|
|
for (int i = 0; i < FrameLength - 4; i++)
|
|
{
|
|
Data[i] = frame[i];
|
|
sum += (int)frame[i];
|
|
}
|
|
Data[FrameLength - 4] = frame[FrameLength - 4];
|
|
Data[FrameLength - 3] = frame[FrameLength - 3];
|
|
|
|
byte checkSum;
|
|
bool chksumOk = byte.TryParse(frame.Substring(FrameLength - 4, 2), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out checkSum)
|
|
&& checkSum == (sum & 0xFF);
|
|
|
|
bool volumeOk = Int32.TryParse(frame.Substring(24, 9), out VolumeRaw);
|
|
volumeRawExtLast = VolumeRawExt = VolumeRaw;
|
|
|
|
bool timeOk = Int64.TryParse(frame.Substring(34, 10), out Timestamp);
|
|
timestampExtLast = TimestampExt = Timestamp;
|
|
|
|
bool allOk = volumeOk && timeOk && chksumOk;
|
|
|
|
return allOk;
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
StringBuilder sb = new StringBuilder(FrameLength - 2);
|
|
for (int i = 0; i < FrameLength - 2; i++)
|
|
sb.Append(Data[i]);
|
|
|
|
return string.Format("{0:HH:mm:ss.fff} {1} T={2} V={3}", DateTime, sb.ToString().Replace("\t","~"), TimestampDbl(), Volume());
|
|
}
|
|
}
|
|
}
|