using Edge.Core.IndustryStandardInterface.ATG; using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; namespace VeederRoot_ATG_Console.MessageEntity.Incoming { /// /// i|I205, checking any active alarms from device. /// public class QueryInTankStatusReportResponse : IncomingMessageBase { public int? TankNumberInFunctionCode { get { if (base.FunctionCode.Item1 == MessageFormat.Display) return null; var r = int.Parse(base.FunctionCode.Item3); return r; } } public DateTime? CurrentDateAndTime { get { if (base.FunctionCode.Item1 == MessageFormat.Display) return null; return DateTime.ParseExact( Encoding.ASCII.GetString(base.DataFieldAndOptionalCheckSumAndETX.Take(10).ToArray()), "yyMMddHHmm", CultureInfo.InvariantCulture); } } /// /// Gets the all active OR unacknowledged alarms and warnings up to the limit of 25 alarms in display format, /// and 150 alarms in computer format. /// public List TanksOfAlarms { get { // skip 10 bytes of current date and time var rawDataBody = base.DataFieldAndOptionalCheckSumAndETX.Skip(10) //and exclude tail of -> && + 4 bytes check sum + ETX <- which is total 7 bytes. .Take(base.DataFieldAndOptionalCheckSumAndETX.Count - 10 - 7); /* * TT - Tank Number (Decimal, 00=all) - 2 bytes * nn - Number of alarms active for tank (Hex, 00=none) - 2 bytes * * ABOVE TOTAL LEN IS 4 */ var datas = new List(); int previousTotalDataCount = 0; while (true) { var buffer = rawDataBody.Skip(previousTotalDataCount); var tankNumber = int.Parse(Encoding.ASCII.GetString(buffer.Take(2).ToArray())); var alarmBodyLen = int.Parse(Encoding.ASCII.GetString(buffer.Skip(2).Take(2).ToArray())); datas.Add(new TankAlarms(tankNumber, buffer.Skip(2 + 2).Take(alarmBodyLen * 2).ToArray())); previousTotalDataCount += 2 + 2 + alarmBodyLen * 2; if (previousTotalDataCount == rawDataBody.Count()) break; } return datas; } } public override string ToLogString() { return this.GetType().Name + " Current DateTime: " + this.CurrentDateAndTime.Value.ToString("yyyy-MM-dd HH:mm") + ", TankNumber_InFunctionCode: " + this.TankNumberInFunctionCode + ", data-> " + this.TanksOfAlarms.Select(d => d.ToFullLogString()) .Aggregate((acc, n) => acc + " | " + n); ; } /// /// Gets the all active OR unacknowledged alarms and warnings up to the limit of 25 alarms in display format, /// and 150 alarms in computer format. /// public class TankAlarms { /// /// without length bytes header. /// so each 2 bytes constructs an alarm code. /// private byte[] alarmsBodyBytes; /// /// /// /// /// without length bytes header. public TankAlarms(int tankNumber, byte[] alarmsBodyBytes) { this.TankNumber = tankNumber; this.alarmsBodyBytes = alarmsBodyBytes; } public int TankNumber { get; } public int NumberOfAlarmsActiveForThisTank { get { var nn = this.alarmsBodyBytes.Length / 2; return nn; } } public IEnumerable Alarms { get { var result = new List(); for (int i = 0; i < this.alarmsBodyBytes.Length; i += 2) { var _ = Enum.Parse(typeof(AlarmType), Encoding.ASCII.GetString(new byte[] { this.alarmsBodyBytes[i], this.alarmsBodyBytes[i + 1] })); result.Add((AlarmType)_); } return result; } } public string ToFullLogString() { return "Tank with Number: " + this.TankNumber + " has " + this.NumberOfAlarmsActiveForThisTank + " AlarmsActive, " + "Active Alarms: " + (this.Alarms != null && this.Alarms.Any() ? this.Alarms.Select(a => a.ToString()).Aggregate((acc, n) => acc + "," + n) : ""); } //public string ToSimpleLogString() //{ // return "Tank with Number: " + (this.TankNumber ?? -1) + " has ProductCode: " + (this.ProductCode ?? ' '); //} } } }