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 Timer = System.Timers.Timer; using System.Collections; using Edge.Core.Processor; using Edge.Core.IndustryStandardInterface.Pump; using Wayne.FDCPOSLibrary; using System.Xml; using Edge.Core.Database.Models; using System.Threading.Tasks; using Edge.Core.Processor.Communicator; using Edge.Core.Processor.Dispatcher.Attributes; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Stateless; using Microsoft.Extensions.DependencyInjection; namespace Gilbarco_Pump { public class StatePumpHandler : IFdcPumpController//, IDeviceHandler { private IServiceProvider services; private IContext context; private ILogger logger = NullLogger.Instance; private PumpGroupHandler parent; private LogicalDeviceState currentState = LogicalDeviceState.FDC_OFFLINE; public event EventHandler OnStateChange; /// /// fired on fueling process is on going, the fuel amount should keep changing. /// public event EventHandler OnCurrentFuellingStatusChange; StateMachine stateless = new StateMachine(LogicalDeviceState.FDC_OFFLINE); protected List nozzles; public IEnumerable Nozzles => this.nozzles; protected enum Trigger { //AnyPumpMsgReceived, AnyPumpMsgHaveNotReceivedForWhile, NozzleLifted_And_开机, NozzleLifted_And_停机, NozzleReplaced_And_开机, NozzleReplaced_And_停机, NozzleFuelNumbersIsRunning, //PumpAuthorizedByFC, } public int AmountDecimalDigits => 2; public int VolumeDecimalDigits => 2; public int PriceDecimalDigits => 2; public int VolumeTotalizerDecimalDigits => 2; /// /// public int PumpId { get; private set; } /// /// will set it to 油机端的配置值,枪号为以整个加油站为基础的油枪顺序编号, 就是全站枪号 /// public int PumpPhysicalId { get; private set; } public string Name => "ZhongSheng_NonIC_Pump"; /// /// 每把枪就是一个Pump即一个加油点 /// /// /// 油机端的配置值,枪号为以整个加油站为基础的油枪顺序编号, 就是全站枪号? public StatePumpHandler(PumpGroupHandler parent, byte pumpId, byte dispenserSideNozzleId, IServiceProvider services) { this.parent = parent; this.services = services; var loggerFactory = services.GetRequiredService(); this.logger = loggerFactory.CreateLogger("PumpHandler"); this.PumpId = pumpId; this.PumpPhysicalId = dispenserSideNozzleId; //每把枪就是一个Pump即一个加油点 this.nozzles = new List() { new LogicalNozzle(pumpId, dispenserSideNozzleId, 1, null) }; } internal void TriggerPumpOffline() { if (this.currentState != LogicalDeviceState.FDC_OFFLINE) { this.currentState = LogicalDeviceState.FDC_OFFLINE; this.OnStateChange?.Invoke(this, new FdcPumpControllerOnStateChangeEventArg(LogicalDeviceState.FDC_OFFLINE)); } } public void Init(IContext context) { this.context = context; } public async Task Process(IContext context) { this.context = context; } public virtual async Task QueryStatusAsync() { return this.currentState; } /// /// /// /// MoneyTotalizer:VolumnTotalizer public async Task> QueryTotalizerAsync(byte logicalNozzleId) { var result = new System.Tuple(-1, -1); logger.LogDebug("Pump: " + this.PumpId + ", " + "Start QueryTotalizer pump with logical nozzle: " + logicalNozzleId); return result; } public virtual async Task ChangeFuelPriceAsync(int newPriceWithoutDecimalPoint, byte logicalNozzleId) { logger.LogDebug("Pump: " + this.PumpId + ", " + "start ChangeFuelPriceAsync pump with nozzle: " + logicalNozzleId); return false; } /// /// /// /// useless for this type of pump, it always one pump one nozzle /// public virtual async Task AuthorizeAsync(byte logicalNozzleId) { logger.LogDebug("Pump: " + this.PumpId + ", " + "start AuthorizeAsync pump with nozzle: " + logicalNozzleId); return false; } /// /// /// /// /// useless for this type of pump, it always one pump one nozzle /// public virtual async Task AuthorizeWithAmountAsync(int moneyAmountWithoutDecimalPoint, byte logicalNozzleId) { logger.LogDebug("Pump: " + this.PumpId + ", " + "start AuthorizeWithAmountAsync pump with amount: " + moneyAmountWithoutDecimalPoint + ", nozzle: " + logicalNozzleId); return false; } /// /// /// /// /// useless for this type of pump, it always one pump one nozzle /// public virtual async Task AuthorizeWithVolumeAsync(int volumnWithoutDecimalPoint, byte logicalNozzleId) { logger.LogDebug("Pump: " + this.PumpId + ", " + "start AuthorizeWithVolumeAsync pump with volume: " + volumnWithoutDecimalPoint + ", nozzle: " + logicalNozzleId); return false; } public virtual async Task FuelingRoundUpByAmountAsync(int amount) { throw new NotImplementedException(); } #region not implemented public async Task UnAuthorizeAsync(byte logicalNozzleId) { logger.LogDebug("Pump: " + this.PumpId + ", " + "start UnAuthorizeAsync pump with nozzle: " + logicalNozzleId); return false; } public async Task SuspendFuellingAsync() { throw new NotImplementedException(); } public async Task ResumeFuellingAsync() { throw new NotImplementedException(); } public async Task FuelingRoundUpByVolumeAsync(int volume) { throw new NotImplementedException(); } #endregion /// /// protected Dictionary logicalNozzleIdToLastFuelSaleTrxMapping = new Dictionary(); public void OnFdcServerInit(Dictionary parameters) { if (parameters.ContainsKey("LastPriceChange")) { } /* Load Last sale(from db) for void the case of FC accidently disconnect from Pump in fueling, and may cause a fueling trx gone from FC control */ if (parameters.ContainsKey("LastFuelSaleTrx")) { // nozzle logical id:lastSale //var lastFuelSaleTrxes = parameters["LastFuelSaleTrx"] as Dictionary; //foreach (var lastFuelSaleTrx in lastFuelSaleTrxes) //{ // logger.Info("Pump: " + this.pumpId + ", OnFdcServerInit, load last fuel sale " + // "on logical nozzle: " + lastFuelSaleTrx.Key + " with value: " + lastFuelSaleTrx.Value); // this.logicalNozzleIdToLastFuelSaleTrxMapping.Remove(lastFuelSaleTrx.Key); // this.logicalNozzleIdToLastFuelSaleTrxMapping.Add(lastFuelSaleTrx.Key, lastFuelSaleTrx.Value); //} } } public async Task LockNozzleAsync(byte logicalNozzleId) { return false; } public async Task UnlockNozzleAsync(byte logicalNozzleId) { return false; } } }