| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using HengShan_Pump_NonIC_Plus.MessageEntity;
- using Edge.Core.Processor;
- using Edge.Core.IndustryStandardInterface.Pump;
- using Wayne.FDCPOSLibrary;
- using Edge.Core.Database.Models;
- using System.Threading.Tasks;
- using Edge.Core.Parser.BinaryParser.MessageEntity;
- using static HengShan_Pump_NonIC_Plus.MessageEntity.GetNozzleStatusResponse;
- using static HengShan_Pump_NonIC_Plus.MessageEntity.NonICMessageTemplateResponseBase;
- using System.Xml;
- using Microsoft.Extensions.Logging;
- namespace HengShan_Pump_NonIC_Plus
- {
- public class PumpHandler : IFdcPumpController, IDisposable
- {
- public event EventHandler<FdcPumpControllerOnStateChangeEventArg> OnStateChange;
- /// <summary>
- /// fired on fueling process is on going, the fuel amount should keep changing.
- /// </summary>
- public event EventHandler<FdcTransactionDoneEventArg> OnCurrentFuellingStatusChange;
- protected IContext<byte[], MessageTemplateBase> context;
- private ILogger logger = null;
- /// <summary>
- /// when first time connected with physical pump , in some case, the pump will not report any status actively,
- /// so need send a status query from FC.
- /// From then on, pump will actively notify FC when state changes, no need to send query anymore from FC.
- /// </summary>
- private bool initialPumpStatueEverRetrieved = false;
- private PumpStatus lastLogicalDeviceState = PumpStatus.未运行;
- /// <summary>
- /// Indicator for OnFdcServiceInit function called, the Process() will be called eariler that this function,
- /// </summary>
- protected bool isOnFdcServerInitCalled = false;
- private Guid uniqueId = Guid.NewGuid();
- private PumpGroupHandler parent;
- private int pumpId = -1;
- protected List<LogicalNozzle> nozzles = new List<LogicalNozzle>();
- private byte liftNozzleId = 0;
- private int amountDecimalDigits;
- private int volumeDecimalDigits;
- private int priceDecimalDigits;
- private int volumeTotalizerDecimalDigits;
- private int previousPolledHandlerIndex = 0;
- /// <summary>
- /// this type of pump state change is detected by FC actively polling, then state is always delay reported, so there's a corner case that in a fueling process,
- /// the attendants put back and pull out nozzle very quickly and it happened exactly in the middle of a polling, meanwhile,
- /// an auth request was done to auth the pump again(most likely the autoAuthCallingPump set with True),
- /// then the pump state returned from physical pump will still be read as a fueling state, but actually the
- /// 2nd fueling process is started, so detect the pump state is not enough, need detect if the fueling seq number reset to null(if place back nozzle detected) or not.
- /// </summary>
- protected GetNozzleStatusResponse previousUnfinishedFuelingNozzleStatus;
- public IEnumerable<LogicalNozzle> Nozzles => this.nozzles;
- protected void FireOnStateChangeEvent(LogicalDeviceState state)
- {
- var safe = this.OnStateChange;
- safe?.Invoke(this, new FdcPumpControllerOnStateChangeEventArg(state, this.nozzles.First()));
- }
- protected void FireOnCurrentFuellingStatusChangeEvent(FdcTransaction trx)
- {
- var safe = this.OnCurrentFuellingStatusChange;
- safe?.Invoke(this, new FdcTransactionDoneEventArg(trx));
- }
- public PumpHandler(PumpGroupHandler parent, int pumpId,
- int amountDecimalDigits, int volumeDecimalDigits,
- int priceDecimalDigits, int volumeTotalizerDecimalDigits,
- string pumpXmlConfiguration, ILogger logger)
- {
- this.parent = parent;
- this.pumpId = pumpId;
- this.amountDecimalDigits = amountDecimalDigits;
- this.volumeDecimalDigits = volumeDecimalDigits;
- this.priceDecimalDigits = priceDecimalDigits;
- this.volumeTotalizerDecimalDigits = volumeTotalizerDecimalDigits;
- this.logger = logger;
- // sample of pumpXmlConfiguration
- // <Pump pumpId='1' physicalId='1'>
- // <Nozzles>
- // <Nozzle logicalId='1' physicalId='1' defaultNoDecimalPointPriceIfNoHistoryPriceReadFromDb='2345'/>
- // <Nozzle logicalId='2' physicalId='2' defaultNoDecimalPointPriceIfNoHistoryPriceReadFromDb='2345'/>
- // <Nozzle logicalId='3' physicalId='3' defaultNoDecimalPointPriceIfNoHistoryPriceReadFromDb='2345'/>
- // </Nozzles>
- // </Pump>
- var xmlDocument = new XmlDocument();
- xmlDocument.LoadXml(pumpXmlConfiguration);
- //var physicalPumpAddressConfiguratedInPump =
- // byte.Parse(xmlDocument.SelectSingleNode("/Pump").Attributes["physicalId"].Value);
- //if (physicalPumpAddressConfiguratedInPump > 0x20)
- // throw new ArgumentOutOfRangeException("HSC+ pump only accept pump address range from 1 to 32, make sure this value is correctly configurated in physical pump mother board");
- foreach (var nozzleElement in xmlDocument.GetElementsByTagName("Nozzle").Cast<XmlNode>())
- {
- var nozzlePhysicalId = byte.Parse(nozzleElement.Attributes["physicalId"].Value);
- var nozzleLogicalId = byte.Parse(nozzleElement.Attributes["logicalId"].Value);
- var nozzleRawDefaultPriceWithoutDecimal = nozzleElement.Attributes["defaultNoDecimalPointPriceIfNoHistoryPriceReadFromDb"].Value;
- //if (nozzlePhysicalId < 1 || nozzlePhysicalId > 8) throw new ArgumentOutOfRangeException("HSC+ pump only accept nozzle physical id range in config from 1 to 8");
- this.nozzles.Add(new LogicalNozzle(pumpId, nozzlePhysicalId, nozzleLogicalId, null) { ExpectingPriceOnFcSide = int.Parse(nozzleRawDefaultPriceWithoutDecimal) });
- logger.LogInformation("Pump: " + this.pumpId
- + ", created a nozzle with logicalId: " + nozzleLogicalId + ", physicalId: " + nozzlePhysicalId
- + ", default raw price without decimal points: " + nozzleRawDefaultPriceWithoutDecimal);
- }
- }
- public NonICMessageTemplateBase GetRequest()
- {
- if (this.liftNozzleId != 0)
- return new GetNozzleStatusRequest(this.liftNozzleId);
- if (this.nozzles.Count <= previousPolledHandlerIndex)
- previousPolledHandlerIndex = 0;
- var target = this.nozzles[previousPolledHandlerIndex++];
- return new GetNozzleStatusRequest(target.PhysicalId);
- }
- public void Init(IContext<byte[], MessageTemplateBase> context)
- {
- this.context = context;
- this.context.Incoming.OnLongTimeNoSeeMessage += (_, __) =>
- {
- if (this.lastLogicalDeviceState != PumpStatus.未运行)
- {
- this.lastLogicalDeviceState = PumpStatus.未运行;
- logger.LogInformation("Pump: " + this.pumpId + ", " + " State switched to FDC_OFFLINE due to long time no see pump data incoming");
- var safe0 = this.OnStateChange;
- safe0?.Invoke(this, new FdcPumpControllerOnStateChangeEventArg(LogicalDeviceState.FDC_OFFLINE));
- logger.LogTrace("Pump: " + this.pumpId + ", " + " OnStateChange event fired and back");
- }
- };
- this.context.Incoming.LongTimeNoSeeMessageTimeout = 3000;
- }
- public async Task Process(IContext<byte[], MessageTemplateBase> context)
- {
- if (!isOnFdcServerInitCalled)
- return;
- this.context = context;
- if (context.Incoming.Message is GetNozzleStatusResponse getNozzleStatusResponse)
- {
- var latestStatus = (PumpStatus)getNozzleStatusResponse.Status;
- var safe = this.OnStateChange;
- string prefix = "Pump: " + this.pumpId + ", " + "Nozzle: " + getNozzleStatusResponse.Nozzle + ", ";
- if (this.lastLogicalDeviceState == PumpStatus.未运行 && latestStatus != PumpStatus.未运行)
- {
- logger.LogInformation(prefix + "Recevied an Pump Msg in FDC_OFFLINE state, " +
- "indicates the underlying connection is established, switch to FDC_READY");
- if (latestStatus == PumpStatus.空闲态)
- this.lastLogicalDeviceState = latestStatus;
- safe?.Invoke(this, new FdcPumpControllerOnStateChangeEventArg(LogicalDeviceState.FDC_READY));
- logger.LogTrace(prefix + " OnStateChange event fired and back");
- }
- // put the price by reading the real price.
- if (0 != getNozzleStatusResponse.Nozzle)
- this.nozzles.First(n => n.PhysicalId == getNozzleStatusResponse.Nozzle).RealPriceOnPhysicalPump = getNozzleStatusResponse.单价;
- if (latestStatus == PumpStatus.空闲态)
- {
- //在加油结束后,交易信息跟随加油状态主动上报给后台
- //if (this.lastLogicalDeviceState == PumpStatus.正在加油 || this.lastLogicalDeviceState == PumpStatus.暂停加油 ||
- // latestStatus == PumpStatus.暂停开始 || latestStatus == PumpStatus.暂停加油)
- //{
- //}
- this.liftNozzleId = 0;
- this.lastLogicalDeviceState = PumpStatus.空闲态;
- safe?.Invoke(this, new FdcPumpControllerOnStateChangeEventArg(LogicalDeviceState.FDC_READY, this.nozzles.First(n => n.PhysicalId == getNozzleStatusResponse.Nozzle)));
- }
- else if (latestStatus == PumpStatus.提枪)
- {
- this.liftNozzleId = getNozzleStatusResponse.Nozzle;
- logger.LogDebug(prefix + "收到状态: " + latestStatus.ToString() + ", switch to FDC_CALLING");
- this.lastLogicalDeviceState = PumpStatus.提枪;
- safe?.Invoke(this, new FdcPumpControllerOnStateChangeEventArg(LogicalDeviceState.FDC_CALLING, this.nozzles.First(n => n.PhysicalId == liftNozzleId)));
- }
- else if (latestStatus == PumpStatus.授权)
- {
- this.liftNozzleId = getNozzleStatusResponse.Nozzle;
- logger.LogDebug(prefix + "收到状态: " + latestStatus.ToString() + ", switch to FDC_AUTHORISED");
- lastLogicalDeviceState = PumpStatus.授权;
- safe?.Invoke(this, new FdcPumpControllerOnStateChangeEventArg(LogicalDeviceState.FDC_AUTHORISED, this.nozzles.First(n => n.PhysicalId == liftNozzleId)));
- }
- else if (latestStatus == PumpStatus.开始加油 || latestStatus == PumpStatus.正在加油)
- {
- this.liftNozzleId = getNozzleStatusResponse.Nozzle;
- logger.LogDebug(prefix + "收到状态: " + latestStatus.ToString() + ", switch to FDC_FUELLING");
- lastLogicalDeviceState = latestStatus;
- safe?.Invoke(this, new FdcPumpControllerOnStateChangeEventArg(LogicalDeviceState.FDC_FUELLING, this.nozzles.First(n => n.PhysicalId == liftNozzleId)));
- }
- else if (latestStatus == PumpStatus.暂停开始 || latestStatus == PumpStatus.暂停加油)
- {
- this.liftNozzleId = getNozzleStatusResponse.Nozzle;
- logger.LogDebug(prefix + "收到状态: " + latestStatus.ToString() + ", switch to FDC_SUSPENDED_FUELLING");
- lastLogicalDeviceState = latestStatus;
- safe?.Invoke(this, new FdcPumpControllerOnStateChangeEventArg(LogicalDeviceState.FDC_SUSPENDED_FUELLING, this.nozzles.First(n => n.PhysicalId == liftNozzleId)));
- }
- else if (latestStatus == PumpStatus.未运行 || latestStatus == PumpStatus.关闭)
- {
- this.lastLogicalDeviceState = latestStatus;
- }
- else
- {
- this.lastLogicalDeviceState = PumpStatus.未运行;
- logger.LogDebug(prefix + "收到未知状态: " + getNozzleStatusResponse.ToLogString() + ", \r\n switch to FDC_ERRORSTATE");
- }
- }
- else if (context.Incoming.Message is ActivePushTransactionResponse trx)
- {
- logger.LogDebug($"Pump: {this.pumpId}, Nozzle: {trx.Nozzle}, {trx.ToLogString()}");
- byte targetNozzlePhysicalId = trx.Nozzle;
- var lastFillTrx = new FdcTransaction()
- {
- Nozzle = this.nozzles.First(n => n.PhysicalId == targetNozzlePhysicalId),
- Amount = trx.加油金额,
- Volumn = trx.加油量,
- Price = this.nozzles.First(n => n.PhysicalId == targetNozzlePhysicalId).RealPriceOnPhysicalPump ?? 0,
- SequenceNumberGeneratedOnPhysicalPump = trx.SequenceNo,
- VolumeTotalizer = (int)trx.升累计,
- Finished = true,
- };
- FireOnCurrentFuellingStatusChangeEvent(lastFillTrx);
- byte result = (byte)EnumResult.成功;
- await this.context.Outgoing.WriteAsync(new AckActivePushTransactionRequest(targetNozzlePhysicalId) { HandleResult = result }, null, 1);
- }
- else
- {
- logger.LogDebug("Pump: " + this.pumpId + ", " + "收到: " + context.Incoming.Message.ToLogString());
- }
- }
- public virtual async Task<LogicalDeviceState> QueryStatusAsync()
- {
- switch (this.lastLogicalDeviceState)
- {
- case PumpStatus.空闲态:
- return LogicalDeviceState.FDC_OFFLINE;
- default:
- return LogicalDeviceState.FDC_OFFLINE;
- }
- }
- public string Name => this.GetType().FullName;
- public Guid Id => this.uniqueId;
- /// <summary>
- /// Gets the Identification of the pump for the system. Is the logical number of the pump
- /// </summary>
- public int PumpId => this.pumpId;
- /// <summary>
- /// this pump have no way to share same comport since this HengShan protocol content does not contains
- /// any id info, so always static 0 here.
- /// 地址面地址
- /// </summary>
- public int PumpPhysicalId => 0;
- public int AmountDecimalDigits => this.amountDecimalDigits;
- public int VolumeDecimalDigits => this.volumeDecimalDigits;
- public int PriceDecimalDigits => this.priceDecimalDigits;
- public int VolumeTotalizerDecimalDigits => this.volumeTotalizerDecimalDigits;
- /// <summary>
- ///
- /// </summary>
- /// <returns>MoneyTotalizer:VolumnTotalizer</returns>
- public async Task<Tuple<int, int>> QueryTotalizerAsync(byte logicalNozzleId)
- {
- var result = new Tuple<int, int>(-1, -1);
- logger.LogInformation("Pump: " + this.pumpId + ", " + " Start QueryTotalizer for logicalNozzle: " + logicalNozzleId);
- if (this.lastLogicalDeviceState == PumpStatus.未运行)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + " Pump is in state FDC_CLOSED or FDC_OFFLINE, will return -1, -1");
- return result;
- }
- byte nozzleId = this.nozzles.First(n => n.LogicalId == logicalNozzleId).PhysicalId;
- var response = await this.context.Outgoing.WriteAsync(new GetAccumulateRequest(nozzleId),
- (request, testResponse) => testResponse is GetAccumulateResponse, 3000);
- if (response == null)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "QueryTotalizer timed out");
- return result;
- }
- else
- {
- var accumResponse = response as GetAccumulateResponse;
- logger.LogDebug($"Pump: {this.pumpId}, {accumResponse.ToLogString()}");
- result = new Tuple<int, int>((int)accumResponse.金额累计, (int)accumResponse.升累计);
- }
- return result;
- }
- public virtual async Task<bool> ChangeFuelPriceAsync(int newPriceWithoutDecimalPoint, byte logicalNozzleId)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + " Start ChangeFuelPrice for logicalNozzle: " + logicalNozzleId + " with new price(without decimalPoints): " + newPriceWithoutDecimalPoint);
- if (this.lastLogicalDeviceState == PumpStatus.未运行)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + " Pump is in state FDC_CLOSED or FDC_OFFLINE, ChangeFuelPrice will return false");
- return false;
- }
- byte nozzleId = this.nozzles.First(n => n.LogicalId == logicalNozzleId).PhysicalId;
- var response = await this.context.Outgoing.WriteAsync(new SetFuelPriceRequest(nozzleId) { FuelPrice = newPriceWithoutDecimalPoint },
- (request, testResponse) => testResponse is SetFuelPriceResponse, 3000);
- if (response == null)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "ChangeFuelPrice timed out");
- return false;
- }
- else
- {
- var priceChangeResponse = response as SetFuelPriceResponse;
- if (priceChangeResponse.Result != EnumResult.成功)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "ChangeFuelPriceResponse is NOT Result.成功");
- return false;
- }
- else
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "ChangeFuelPriceResponse succeed");
- return true;
- }
- }
- }
- public virtual async Task<bool> ChangePumpClockAsync(DateTime datetime, byte logicalNozzleId)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + " Start ChangePumpClockAsync");
- if (this.lastLogicalDeviceState == PumpStatus.未运行)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + " Pump is in state FDC_CLOSED or FDC_OFFLINE, ChangePumpClockAsync will return false");
- return false;
- }
- var response = await this.context.Outgoing.WriteAsync(new SetClockRequest(logicalNozzleId, datetime),
- (request, testResponse) => testResponse is SetClockResponse, 3000);
- if (response == null)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "ChangePumpClock timed out");
- return false;
- }
- else
- {
- var setClockResponse = response as SetClockResponse;
- if (setClockResponse.Result != EnumResult.成功)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "SetClockResponse is NOT Result.成功");
- return false;
- }
- else
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "SetClockResponse succeed");
- return true;
- }
- }
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="logicalNozzleId">useless for this type of pump, it always one pump one nozzle</param>
- /// <returns></returns>
- public virtual async Task<bool> AuthorizeAsync(byte logicalNozzleId)
- {
- logger.LogDebug("Pump: " + this.pumpId + ", " + "Start Authorize for logicalNozzle: " + this.liftNozzleId);
- var response = await this.context.Outgoing.WriteAsync(new StartRequest(this.liftNozzleId),
- (request, testResponse) => testResponse is StartResponse, 3000);
- if (response == null)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "Authorize timed out");
- return false;
- }
- else
- {
- var startResponse = response as StartResponse;
- string prefix = "Pump: " + this.pumpId + ", " + "Nozzle: " + startResponse.Nozzle + ", ";
- if (startResponse.Result != EnumResult.成功)
- {
- logger.LogInformation(prefix + "Authorize (StartResponse) is NOT Result.成功");
- return false;
- }
- else
- {
- logger.LogDebug(prefix + "Authorize (StartResponse) succeed");
- return true;
- }
- }
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="moneyAmount"></param>
- /// <param name="logicalNozzleId">useless for this type of pump, it always one pump one nozzle</param>
- /// <returns></returns>
- public virtual async Task<bool> AuthorizeWithAmountAsync(int moneyAmountWithoutDecimalPoint, byte logicalNozzleId)
- {
- //return await AuthorizeWithVolumeAsync(moneyAmountWithoutDecimalPoint, logicalNozzleId);
- logger.LogDebug("Pump: " + this.pumpId + ", " + "Start AuthorizeWithAmount for logicalNozzle: " + this.liftNozzleId + " with money(without decimalPoint): " + moneyAmountWithoutDecimalPoint);
- var response = await this.context.Outgoing.WriteAsync(new AuthPumpWithAmountRequest(this.liftNozzleId) { Amount = moneyAmountWithoutDecimalPoint },
- (request, testResponse) => testResponse is AuthPumpWithAmountResponse, 3000);
- if (response == null)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "AuthorizeWithAmount timed out");
- return false;
- }
- else
- {
- var presetResponse = response as AuthPumpWithAmountResponse;
- if (presetResponse.Result != EnumResult.成功)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "AuthPumpWithAmountResponse is NOT Result.成功");
- return false;
- }
- else
- {
- logger.LogDebug("Pump: " + this.pumpId + ", " + "Authorize (StartResponse) succeed");
- return true;
- }
- }
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="volumn"></param>
- /// <param name="logicalNozzleId">useless for this type of pump, it always one pump one nozzle</param>
- /// <returns></returns>
- public virtual async Task<bool> AuthorizeWithVolumeAsync(int volumnWithoutDecimalPoint, byte logicalNozzleId)
- {
- logger.LogDebug("Pump: " + this.pumpId + ", " + "Start AuthorizeWithVolumn for logicalNozzle: " + this.liftNozzleId + " with vol(without decimalPoint): " + volumnWithoutDecimalPoint);
- var response = await this.context.Outgoing.WriteAsync(new AuthPumpWithGallonRequest(this.liftNozzleId) { Gallon = volumnWithoutDecimalPoint },
- (request, testResponse) => testResponse is AuthPumpWithGallonResponse, 3000);
- if (response == null)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "AuthPumpWithGallonRequest timed out");
- return false;
- }
- else
- {
- var presetResponse = (AuthPumpWithGallonResponse)response;
- if (presetResponse.Result != EnumResult.成功)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "AuthorizeWithVolumnResponse is NOT Result.成功");
- return false;
- }
- else
- {
- logger.LogDebug("Pump: " + this.pumpId + ", " + "Authorize (StartResponse) succeed");
- return true;
- }
- }
- }
- public virtual async Task<bool> GetTransactionAsync(int sequenceNo, byte logicalNozzleId)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "Start Get transaction for sequenceNo: " + sequenceNo);
- var response = await this.context.Outgoing.WriteAsync(new GetTransactionRequest(logicalNozzleId) { SequenceNo = sequenceNo },
- (request, testResponse) => (testResponse is GetTransactionResponse || testResponse is GetTransactionFailureResponse), 3000);
- if (response == null)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "GetTransactionRequest timed out");
- return false;
- }
- else
- {
- if (response is GetTransactionFailureResponse)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "不存在该流水");
- return false;
- }
- else
- {
- var trxResponse = response as GetTransactionResponse;
- logger.LogInformation($"Pump: {this.pumpId}, {trxResponse.ToLogString()}");
- return true;
- }
- }
- }
- public virtual async Task<bool> GetVersionAsync(byte logicalNozzleId)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "Start Get version");
- var response = await this.context.Outgoing.WriteAsync(new GetVersionRequest(logicalNozzleId),
- (request, testResponse) => (testResponse is GetVersionResponse), 3000);
- if (response == null)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "GetVersionRequest timed out");
- return false;
- }
- else
- {
- var versionResponse = response as GetVersionResponse;
- logger.LogInformation($"Pump: {this.pumpId}, {versionResponse.ToLogString()}");
- return true;
- }
- }
- public virtual async Task<bool> ErrorPromptAsync(string errorMessage, byte logicalNozzleId)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "Start Error message prompt.");
- var response = await this.context.Outgoing.WriteAsync(new ErrorPromptRequest(logicalNozzleId, errorMessage),
- (request, testResponse) => testResponse is ErrorPromptResponse, 3000);
- if (response == null)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "Error message prompt timed out");
- return false;
- }
- else
- {
- var errorResponse = response as ErrorPromptResponse;
- if (errorResponse.Result != EnumResult.成功)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "ErrorPromptResponse is NOT Result.成功");
- return false;
- }
- else
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "Error message prompt succeed");
- return true;
- }
- }
- }
- public virtual async Task<bool> CancelRationAsync(byte logicalNozzleId)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "Start Cancel ration.");
- var response = await this.context.Outgoing.WriteAsync(new CancelRationRequest(logicalNozzleId),
- (request, testResponse) => testResponse is CancelRationResponse, 3000);
- if (response == null)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "Cancel ration timed out");
- return false;
- }
- else
- {
- var rationResponse = response as CancelRationResponse;
- if (rationResponse.Result != EnumResult.成功)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "CancelRationResponse is NOT Result.成功");
- return false;
- }
- else
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "Cancel ration succeed");
- return true;
- }
- }
- }
- public virtual async Task<bool> FuelingRoundUpByAmountAsync(int amount)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + " Start FuelingRoundUpByAmount, amount: " + amount + " will be ignored due to hardware limit");
- return await Task.FromResult(false);
- }
- #region not implemented
- public async Task<bool> UnAuthorizeAsync(byte logicalNozzleId)
- {
- throw new NotImplementedException();
- }
- public async Task<bool> SuspendFuellingAsync()
- {
- throw new NotImplementedException();
- }
- public async Task<bool> ResumeFuellingAsync()
- {
- throw new NotImplementedException();
- }
- public async Task<bool> FuelingRoundUpByVolumeAsync(int volume)
- { throw new NotImplementedException(); }
- #endregion
- /// <summary>
- /// </summary>
- protected Dictionary<byte, FuelSaleTransaction> logicalNozzleIdToLastFuelSaleTrxMapping = new Dictionary<byte, FuelSaleTransaction>();
- public void OnFdcServerInit(Dictionary<string, object> 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<byte, FuelSaleTransaction>;
- foreach (var lastFuelSaleTrx in lastFuelSaleTrxes)
- {
- logger.LogInformation("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);
- }
- }
- this.isOnFdcServerInitCalled = true;
- }
- public async Task<bool> LockNozzleAsync(byte logicalNozzleId)
- {
- return false;
- }
- public async Task<bool> UnlockNozzleAsync(byte logicalNozzleId)
- {
- return false;
- }
- public void Dispose()
- {
- //this.retryReadLastFillTimer?.Stop();
- //this.retryReadLastFillTimer?.Dispose();
- }
- }
- }
|