123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- using Edge.Core.Parser.BinaryParser.Util;
- using System;
- using System.Collections.Generic;
- using System.Globalization;
- using System.Linq;
- using System.Text;
- namespace VeederRoot_ATG_Console.MessageEntity.Incoming
- {
- /// <summary>
- /// i|I201
- /// </summary>
- public class QueryInTankInventoryReportResponse : IncomingMessageBase
- {
- 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);
- }
- }
- public int? TankNumberInFunctionCode
- {
- get
- {
- if (base.FunctionCode.Item1 == MessageFormat.Display)
- return null;
- var r = int.Parse(base.FunctionCode.Item3);
- return r;
- }
- }
- public List<InventoryData> InventoryDatas
- {
- 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
- * p - Product Code (one ASCII character [20h-7Eh]) - 1 bytes
- * ssss - Tank Status Bits - 4 bytes
- * NN - Number of eight character Data Fields to follow (Hex) - 2 bytes
- *
- * ABOVE TOTAL LEN IS 9
- */
- var datas = new List<InventoryData>();
- int previousTotalDataCount = 0;
- while (true)
- {
- var buffer = rawDataBody.Skip(previousTotalDataCount);
- if (buffer.Count() < 7)
- throw new ArgumentException("Min bytes count for describe an i201 tank report is 7, but now is " + buffer.Count());
- var numberOfEightCharDataFieldsValue
- = int.Parse(Encoding.ASCII.GetString(buffer.Skip(7).Take(2).ToArray()));
- if (numberOfEightCharDataFieldsValue < 1 || numberOfEightCharDataFieldsValue > 99)
- throw new ArgumentException("number Of Eight Char DataFields to follow must range from 1 to 99, but now is: " + numberOfEightCharDataFieldsValue);
- datas.Add(new InventoryData(
- buffer.Take(7 + 2 + 8 * numberOfEightCharDataFieldsValue).ToArray()));
- previousTotalDataCount += 7 + 2 + 8 * numberOfEightCharDataFieldsValue;
- if (previousTotalDataCount == rawDataBody.Count()) break;
- }
- return datas;
- }
- }
- public override string ToLogString()
- {
- if (base.FunctionCode.Item1 == MessageFormat.Display)
- return Encoding.ASCII.GetString(base.DataFieldAndOptionalCheckSumAndETX.ToArray());
- return this.GetType().Name + " Current DateTime: " + this.CurrentDateAndTime.Value.ToString("yyyy-MM-dd HH:mm")
- + ", TankNumber_InFunctionCode: " + this.TankNumberInFunctionCode
- + ", data: " + this.InventoryDatas.Select(d => d.ToFullLogString())
- .Aggregate((acc, n) => acc + " || " + n);
- }
- public class InventoryData
- {
- private byte[] bytes;
- public enum TankState
- {
- DeliveryInProgress_LSB,
- LeakTestInProgress,
- InvalidFuelHeighAlarm_MagProbesOnly,
- Unknown,
- }
- public enum TankReadingDataName
- {
- Volume = 1,
- TC_Volume = 2,
- Ullage = 3,
- Height = 4,
- Water = 5,
- Temperature = 6,
- WaterVolume = 7,
- }
- public InventoryData(byte[] bytes)
- {
- this.bytes = bytes;
- }
- public int? TankNumber
- {
- get
- {
- var r = int.Parse(Encoding.ASCII.GetString(this.bytes.Take(2).ToArray()));
- return r;
- }
- }
- public char? ProductCode
- {
- get
- {
- return
- Encoding.ASCII.GetString(
- this.bytes.Skip(2).Take(1).ToArray())[0];
- }
- }
- public List<TankState> States
- {
- get
- {
- /* 4 ascii encoded bytes,
- * check 16 bits to get the states
- * say now the raw data here is: 0x30,0x30,0x30,0x39
- * then target byte here is the last byte of value 9 which binary format is 0000 1001.
- * so is bit 0 is 1, indicates the TankState.DeliveryInProgress_LSB
- */
- var states = new List<TankState>();
- var tankStateBit = Util.ConvertHexBcdStrToBytes(this.bytes.Skip(3).Take(4).ToArray());
- if (tankStateBit.Last().GetBit(0) == 1)
- states.Add(TankState.DeliveryInProgress_LSB);
- if (tankStateBit.Last().GetBit(1) == 1)
- states.Add(TankState.LeakTestInProgress);
- if (tankStateBit.Last().GetBit(2) == 1)
- states.Add(TankState.InvalidFuelHeighAlarm_MagProbesOnly);
- return states;
- }
- }
- public int? NumberOfEightCharDataFieldsToFollow
- {
- get
- {
- var nn = int.Parse(Encoding.ASCII.GetString(this.bytes.Skip(7).Take(2).ToArray()));
- //this.QueryInTankInventoryReportDatas = new List<QueryInTankInventoryReportDataField>(nn);
- return nn;
- }
- }
- public Dictionary<TankReadingDataName, double> TankReadingDatas
- {
- get
- {
- var datas = new Dictionary<TankReadingDataName, double>();
- for (int i = 0; i < this.NumberOfEightCharDataFieldsToFollow.Value; i++)
- {
- var asciiEncodedBytes = Util.ConvertHexBcdStrToBytes(this.bytes.Skip(9 + 8 * i).Take(8).ToArray());
- var dataValue =
- Util.ConvertIEEEWith4BytesToDouble(asciiEncodedBytes.ToArray());
- switch (i + 1)
- {
- case 1: // VOLUME
- datas.Add(TankReadingDataName.Volume, dataValue);
- break;
- case 2: // TC VOLUME
- datas.Add(TankReadingDataName.TC_Volume, dataValue);
- break;
- case 3: // ULLAGE
- datas.Add(TankReadingDataName.Ullage, dataValue);
- break;
- case 4: // HEIGHT
- datas.Add(TankReadingDataName.Height, dataValue);
- break;
- case 5: // WATER HEIGHT
- datas.Add(TankReadingDataName.Water, dataValue);
- break;
- case 6: // TEMPERATURE
- datas.Add(TankReadingDataName.Temperature, dataValue);
- break;
- case 7: // WATER VOLUME
- datas.Add(TankReadingDataName.WaterVolume, dataValue);
- break;
- }
- }
- return datas;
- }
- }
- public string ToFullLogString()
- {
- return "Tank with Number: " + (this.TankNumber ?? -1) + " with ProductCode: " + (this.ProductCode ?? ' ')
- + " with States: " +
- (this.States != null && this.States.Any() ? this.States.Select(s => s.ToString()).Aggregate((acc, n) => acc + "-" + n) : "")
- + ", data read: "
- + this.TankReadingDatas.Select(s => s.Key.ToString() + "-" + s.Value).Aggregate((acc, n) => acc + " | " + n);
- }
- public string ToSimpleLogString()
- {
- return "Tank with Number: " + (this.TankNumber ?? -1) + " has ProductCode: " + (this.ProductCode ?? ' ');
- }
- }
- }
- }
|