using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Configuration; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading; using log4net; using Timer = System.Timers.Timer; using Common; using System.Collections; using HengShan_Pump_NonIC.MessageEntity; using DeviceProcessor; using Wayne.FDCPOSLibrary; using Common.Config; using System.Xml; namespace HengShan_Pump_NonIC { /// /// this is kind of HS non IC pump that have a build-in auto auth self function by hardware, so outside(fcc) can't auth it, it's /// a 'lift nozzle, and fueling pump'. /// basically it only have 2 states: /// idle: 不允许加油--加油结束--油枪关--电机关--D30--D20--金额加油 /// fueling: 允许加油--加油过程--油枪打开--电机打开--D30--D20--金额加油 /// public class PumpHandlerForSelfAuthPump : PumpHandler { private object syncObject = new object(); //static ILog fdcLogger = log4net.LogManager.GetLogger("FdcServer"); static ILog logger = log4net.LogManager.GetLogger("PumpHandler"); /// /// 恒山非IC油机 /// /// /// public PumpHandlerForSelfAuthPump(int pumpId, string nozzlesXmlConfiguration) : base(pumpId, nozzlesXmlConfiguration) { } public override void Process(IContext context) { this.context = context; if (context.Incoming.Message is GetNozzleStatusResponse getNozzleStatusResponse) { this.isSafeForSend = true; this.lastLogicalDeviceStateReceivedTime = DateTime.Now; //var getNozzleStatusResponse = context.Incoming.Message as GetNozzleStatusResponse; // put the price by reading the real price. this.nozzles.First().RealPriceOnPhysicalPump = getNozzleStatusResponse.单价; var latestStatus = getNozzleStatusResponse.GetPumpStatus(); if (latestStatus.Any(f => f == GetNozzleStatusResponse.PumpStatus.允许加油) && latestStatus.Any(f => f == GetNozzleStatusResponse.PumpStatus.油枪打开) && latestStatus.Any(f => f == GetNozzleStatusResponse.PumpStatus.加油过程) && latestStatus.Any(f => f == GetNozzleStatusResponse.PumpStatus.电机打开)) { //status code: B1 logger.Debug("正处于加油状态下"); /* 正处于加油状态下 */ if (this.previousUnfinishedFuelingNozzleStatus != null && this.previousUnfinishedFuelingNozzleStatus.流水号 != getNozzleStatusResponse.流水号) { logger.Info("Detected a fast put back and pull out nozzle case(action time < polling time cause nozzle place back not detected)," + "\r\n will fire the trx done event for earlier trx(may have volume/money data loss!!!) with most recoverable data(most likely a bit less than real)->\r\n " + "seqNo: " + this.previousUnfinishedFuelingNozzleStatus.流水号 + ", amount: " + this.previousUnfinishedFuelingNozzleStatus.加油金额 + ", volume: " + this.previousUnfinishedFuelingNozzleStatus.加油金额 + ", price: " + this.previousUnfinishedFuelingNozzleStatus.单价); logger.Info(" State switched to FDC_READY(simulate)"); this.lastLogicalDeviceState = LogicalDeviceState.FDC_READY; this.FireOnStateChangeEvent(LogicalDeviceState.FDC_READY); this.FireOnCurrentFuellingStatusChangeEvent(new FdcTransaction() { // use previousUnfinishedFuelingNozzleStatus could miss reading the last trx correct numbers(less than actual number) //, obviously this is caused by pump hardware design, impossible to recovery it back by our application. Nozzle = this.nozzles.First(), Amount = this.previousUnfinishedFuelingNozzleStatus.加油金额, Volumn = this.previousUnfinishedFuelingNozzleStatus.加油量, Price = this.previousUnfinishedFuelingNozzleStatus.单价, SequenceNumberGeneratedOnPhysicalPump = this.previousUnfinishedFuelingNozzleStatus.流水号, Finished = true, }); } this.previousUnfinishedFuelingNozzleStatus = getNozzleStatusResponse; if (this.lastLogicalDeviceState != LogicalDeviceState.FDC_FUELLING) { logger.Debug(" State switched to FDC_FUELLING"); this.lastLogicalDeviceState = LogicalDeviceState.FDC_FUELLING; base.FireOnStateChangeEvent(LogicalDeviceState.FDC_FUELLING); } //fire fuelling progress. base.FireOnCurrentFuellingStatusChangeEvent(new FdcTransaction() { // 恒山油机只有一把枪 Nozzle = this.nozzles.First(), Amount = getNozzleStatusResponse.加油金额, Volumn = getNozzleStatusResponse.加油量, Price = getNozzleStatusResponse.单价, SequenceNumberGeneratedOnPhysicalPump = getNozzleStatusResponse.流水号, Finished = false, }); } else if (latestStatus.Any(f => f == GetNozzleStatusResponse.PumpStatus.不允许加油) && latestStatus.Any(f => f == GetNozzleStatusResponse.PumpStatus.加油结束)) { /* 油机首次上电也会进入此处,并不断发送上一次的加油记录,这种情况下的交易记录并无法判断其之前是否已经发送至上层系统(比如是否已经存入数据库), 所以此处不判断而是往上层系统里送入,由系统判断重复情况。 而其它正常加油过程中的交易记录仅在油机状态变化时才送入系统。*/ // status code: 40 logger.Debug("收到状态: 加油结束"); this.previousUnfinishedFuelingNozzleStatus = null; if (this.lastLogicalDeviceState != LogicalDeviceState.FDC_READY) { logger.Debug(" State switched to FDC_READY"); lastLogicalDeviceState = LogicalDeviceState.FDC_READY; base.FireOnStateChangeEvent(LogicalDeviceState.FDC_READY); if (getNozzleStatusResponse.加油量 != 0 || getNozzleStatusResponse.加油金额 != 0) { base.FireOnCurrentFuellingStatusChangeEvent(new FdcTransaction() { // 恒山油机 一个加油点只有一把枪 Nozzle = this.nozzles.First(), Amount = getNozzleStatusResponse.加油金额, Volumn = getNozzleStatusResponse.加油量, Price = getNozzleStatusResponse.单价, SequenceNumberGeneratedOnPhysicalPump = getNozzleStatusResponse.流水号, Finished = true, }); } } } } else { base.Process(context); } } /// /// /// /// useless for this type of pump, it always one pump one nozzle /// public override bool Authorize(byte logicalNozzleId) { return false; } /// /// /// /// /// useless for this type of pump, it always one pump one nozzle /// public override bool AuthorizeWithAmount(int moneyAmount, byte logicalNozzleId) { return false; } /// /// /// /// /// useless for this type of pump, it always one pump one nozzle /// public override bool AuthorizeWithVolumn(int volumn, byte logicalNozzleId) { return false; } } }