using Edge.Core.Parser.BinaryParser.Attributes; using Edge.Core.Parser.BinaryParser.Util; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ZhongSheng_NonIC_Pump { /// /// 加油实时数据命令格式和错误状态信息格式: /// (实时信息有时会一条枪有时会多条枪,每条枪用一个信息块表示) /// public class PumpInOperationResponse : MessageTemplateBase { private List dataRaw; private IEnumerable fuellingDataBlocks; private IEnumerable pumpStateBlocks; /// /// [EnumerableFormat("%cascade", 1, EncodingType = EncodingType.BIN)] public List DataRaw { get { return this.dataRaw; } set { this.dataRaw = value; this.fuellingDataBlocks = this.ParseFuellingDataBlocks(); this.pumpStateBlocks = this.ParsePumpStateBlocks(); } } private IEnumerable ParseFuellingDataBlocks() { if (this.DataRaw == null || !this.DataRaw.Any()) throw new ArgumentException("DataRaw is null or empty"); List results = null; int elapsedCount = 0; //skip the 信息计数n(1字节) var blocks = this.DataRaw.Skip(1); while (true) { var nxt = blocks.Skip(elapsedCount).ToArray(); if (!nxt.Any()) return results; if (nxt.Length < 12) return results; if (nxt[0] == 0x01) { if (results == null) results = new List(); elapsedCount += 12; var block = new FuellingDataBlock() { NozzleNumber = nxt[1], Amount = nxt.Skip(2).Take(4).ToInt32(), Volume = nxt.Skip(6).Take(3).ToInt32(), Price = nxt.Skip(9).Take(3).ToInt32() }; results.Add(block); } else elapsedCount += 7; } } private IEnumerable ParsePumpStateBlocks() { if (this.DataRaw == null || !this.DataRaw.Any()) throw new ArgumentException("DataRaw is null or empty"); List results = null; int elapsedCount = 0; //skip the 信息计数n(1字节) var blocks = this.DataRaw.Skip(1); while (true) { var nxt = blocks.Skip(elapsedCount).ToArray(); if (!nxt.Any()) return results; if (nxt.Length < 7) return results; //throw new ArgumentException("block data should either have length with times of 12 or 4, please check the full DataRaw: 0x" + this.DataRaw.ToHexLogString()); if (nxt[0] == 0x01) { elapsedCount += 12; } else { if (results == null) results = new List(); elapsedCount += 7; var paymentMode = (PumpAuthModeEnum)Enum.ToObject(typeof(PumpAuthModeEnum), nxt[2]); var pumpState = (NozzleLiftStateEnum)Enum.ToObject(typeof(NozzleLiftStateEnum), nxt[5]); var pumpAuthorizeState = (PumpAuthorizeStateEnum)Enum.ToObject(typeof(PumpAuthorizeStateEnum), nxt[6]); var block = new PumpStateBlock() { NozzleNumber = nxt[1], AuthMode = paymentMode, NozzleLiftState = pumpState, PumpAuthorizeState = pumpAuthorizeState }; results.Add(block); } } } public IEnumerable FuellingDataBlocks => this.fuellingDataBlocks; public IEnumerable PumpStateBlocks => this.pumpStateBlocks; public override string ToLogString() { string innerLog = ""; if (this.PumpStateBlocks?.Any() ?? false) innerLog += "PumpStateBlocks -> " + this.PumpStateBlocks.Select(b => "Pump side nozzle No.: " + b.NozzleNumber + ", authMode: " + b.AuthMode + ", authState: " + b.PumpAuthorizeState + ", nzlState: " + b.NozzleLiftState).Aggregate((acc, n) => acc + " | " + n) + "; "; if (this.FuellingDataBlocks?.Any() ?? false) innerLog += "FuellingDataBlocks -> " + this.FuellingDataBlocks.Select(b => "Pump side nozzle No.: " + b.NozzleNumber + ", amt: " + b.Amount + ", vol: " + b.Volume + ", price: " + b.Price).Aggregate((acc, n) => acc + " | " + n); return base.ToLogString() + Environment.NewLine + innerLog; } } /// /// 状态字为0x01, 枪号为以整个加油站为基础的油枪顺序编号 /// public class FuellingDataBlock { /// /// 枪号为以整个加油站为基础的油枪顺序编号 /// public byte NozzleNumber { get; set; } /// /// 金额(带2位小数)(HEX)高位在前 /// public int Amount { get; set; } /// /// 升数(带2位小数)(HEX)高位在前 /// public int Volume { get; set; } /// /// 价格(带2位小数)(HEX)高位在前 /// public int Price { get; set; } public override string ToString() { return "amt: " + this.Amount + ", vol: " + this.Volume + ", price: " + this.Price; } } public enum NozzleLiftStateEnum { 未提 = 0, /// /// 如果单面双单价模式,第一条枪提起为1,第二条枪提起为2 /// 已提 = 1, 第二条枪提起 = 2, } public enum PumpAuthModeEnum { /// /// 油枪提枪后自动开始加油的模式,此模式下中控无法控制油机授权与否,于油机端设置。 /// 自授权模式 = 0, /// /// 油枪需要中控授权才可以出油的模式,于油机端设置。 /// 在油机被中控授权并完成一笔交易后,将自动解除授权状态,即下一笔提枪还需要中控再次发送授权命令。 /// 需中控授权模式 = 4 } public enum PumpAuthorizeStateEnum { /// /// 如果为中控授权模式,此值一直为'未授权' /// 未授权 = 0, /// /// 如果为中控授权模式,在油机获得授权后,将保持此状态,再完成一笔加油后,油机将自动进入'未授权'状态,从而下一次加油需要中控再次授权。 /// 授权成功 = 1 } public class PumpStateBlock { /// /// 枪号为以整个加油站为基础的油枪顺序编号 /// public byte NozzleNumber { get; set; } /// /// 0表示非授权状态加油模式,4表示授权状态加油模式 /// public PumpAuthModeEnum AuthMode { get; set; } /// /// 枪状态 /// public NozzleLiftStateEnum NozzleLiftState { get; set; } /// /// 授权状态 /// public PumpAuthorizeStateEnum PumpAuthorizeState { get; set; } public override string ToString() { return this.NozzleLiftState + ", " + this.AuthMode + "(" + this.PumpAuthorizeState + ")"; } } }