123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550 |
- using Edge.Core.Database.Models;
- using Edge.Core.Processor;
- using Edge.Core.IndustryStandardInterface.Pump;
- using Edge.Core.UniversalApi;
- using LanTian_Pump_664_Or_886.MessageEntity;
- using LanTian_Pump_664_Or_886.MessageEntity.Incoming;
- using LanTian_Pump_664_Or_886.MessageEntity.Outgoing;
- using Microsoft.Extensions.DependencyInjection;
- using Microsoft.Extensions.Logging;
- using Microsoft.Extensions.Logging.Abstractions;
- using NLog.Fluent;
- using Edge.Core.Parser.BinaryParser.Util;
- using Stateless;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- using System.Xml;
- using Wayne.FDCPOSLibrary;
- using static LanTian_Pump_664_Or_886.PumpGroupParameter;
- namespace LanTian_Pump_664_Or_886
- {
- public class StatePumpHandler : IFdcPumpController
- {
- private IServiceProvider services;
- static ILogger logger = NullLogger.Instance;
- private LogicalDeviceState lastLogicalDeviceState = LogicalDeviceState.FDC_OFFLINE;
- private DateTime lastLogicalDeviceStateReceivedTime;
- // by seconds, change this value need change the correlated deviceOfflineCountdownTimer's interval as well
- public const int lastLogicalDeviceStateExpiredTime = 6;
- private List<LogicalNozzle> nozzles = new List<LogicalNozzle>();
- private System.Timers.Timer deviceOfflineCountdownTimer;
- private IContext<byte[], MessageBase> context;
- private bool isOnFdcServerInitCalled = false;
- private int pumpId;
- /// <summary>
- /// hardware address value of this pump, must be set in physical dispenser side.
- /// </summary>
- private byte address;
- private PumpModelEnum pumpModel;
- private PumpAuthorizeModeEnum pumpAuthorizeMode;
- protected enum Trigger
- {
- //AnyPumpMsgReceived,
- AnyPumpMsgHaveNotReceivedForWhile,
- NozzleLifted_And_开机,
- NozzleLifted_And_停机,
- NozzleReplaced_And_开机,
- NozzleReplaced_And_停机,
- NozzleFuelNumbersIsRunning,
- //PumpAuthorizedByFC,
- }
- StateMachine<LogicalDeviceState, Trigger> stateless
- = new StateMachine<LogicalDeviceState, Trigger>(LogicalDeviceState.FDC_OFFLINE);
- private int amountDecimalDigits;
- private int volumeDecimalDigits;
- private int priceDecimalDigits;
- private int volumeTotalizerDecimalDigits;
- private StateMachine<LogicalDeviceState, Trigger>.TriggerWithParameters<FdcTransaction> nozzleFuelNumbersIsRunningTrigger;
- /// <summary>
- /// for avoid a case that FC may miss a pump status change event(pump side issue? or wire issue?),
- /// we timely actively request the pump state.
- /// </summary>
- //private System.Timers.Timer pollingPumpStatus;
- //private int pollingPumpStatusInterval = 30000;
- #region
- public string Name => "LanTian_Pump_664_Or_886";
- public int PumpId => this.pumpId;
- public IEnumerable<LogicalNozzle> Nozzles => this.nozzles;
- public int AmountDecimalDigits => this.amountDecimalDigits;
- public int VolumeDecimalDigits => this.volumeDecimalDigits;
- public int PriceDecimalDigits => this.priceDecimalDigits;
- public int VolumeTotalizerDecimalDigits => this.volumeDecimalDigits;
- public Guid Id => Guid.NewGuid();
- public int PumpPhysicalId => this.address;
- public event EventHandler<FdcPumpControllerOnStateChangeEventArg> OnStateChange;
- public event EventHandler<FdcTransactionDoneEventArg> OnCurrentFuellingStatusChange;
- public async Task<global::Wayne.FDCPOSLibrary.LogicalDeviceState> QueryStatusAsync()
- {
- return this.lastLogicalDeviceState;
- }
- public async Task<bool> LockNozzleAsync(byte logicalNozzleId)
- {
- return false;
- }
- public async Task<bool> UnlockNozzleAsync(byte logicalNozzleId)
- {
- return false;
- }
- #endregion
- public StatePumpHandler(int pumpId, byte address,
- PumpModelEnum pumpModel, PumpAuthorizeModeEnum pumpAuthorizeMode,
- int amountDecimalDigits, int volumeDecimalDigits,
- int priceDecimalDigits, int volumeTotalizerDecimalDigits,
- IServiceProvider services)
- {
- this.services = services;
- var loggerFactory = services.GetRequiredService<ILoggerFactory>();
- logger = loggerFactory.CreateLogger("PumpHandler");
- try
- {
- this.pumpId = pumpId;
- this.address = address;
- this.pumpModel = pumpModel;
- this.pumpAuthorizeMode = pumpAuthorizeMode;
- this.amountDecimalDigits = amountDecimalDigits;
- this.volumeDecimalDigits = volumeDecimalDigits;
- this.priceDecimalDigits = priceDecimalDigits;
- this.volumeTotalizerDecimalDigits = volumeTotalizerDecimalDigits;
- this.pumpId = pumpId;
- // real nozzle Id put hardcode 1 here since HengShan_pump_nonIC only have 1 nozzle per pump.
- // price is not dectected yet, put Null.
- this.nozzles.Add(new LogicalNozzle(pumpId, this.address, 1, null));
- this.deviceOfflineCountdownTimer = new System.Timers.Timer(2000);
- this.deviceOfflineCountdownTimer.Elapsed += async (_, __) =>
- {
- if (DateTime.Now.Subtract(this.lastLogicalDeviceStateReceivedTime).TotalSeconds
- >= lastLogicalDeviceStateExpiredTime)
- await this.stateless.FireAsync(Trigger.AnyPumpMsgHaveNotReceivedForWhile);
- };
- this.deviceOfflineCountdownTimer.Start();
- this.stateless.OnTransitioned(async (transition) =>
- {
- if (transition.Destination != transition.Source)
- {
- this.lastLogicalDeviceState = transition.Destination;
- logger.LogInformation("Pump: " + this.pumpId + ", " + " State switched from: " + transition.Source + " to " + transition.Destination);
- this.OnStateChange?.Invoke(this, new FdcPumpControllerOnStateChangeEventArg(transition.Destination, this.nozzles.FirstOrDefault()));
- }
- if (transition.Source == LogicalDeviceState.FDC_OFFLINE)
- {
- //always send a query to try to align latest price when switched to Online.
- this.context.Outgoing.Write(new ReadPriceRequest() { Adrs = this.address });
- }
- });
- this.stateless.Configure(LogicalDeviceState.FDC_OFFLINE)
- .OnEntryAsync(async () => { })
- .OnEntryAsync(async () => { })
- //.Ignore(Trigger.AnyPumpMsgReceived)
- .Ignore(Trigger.AnyPumpMsgHaveNotReceivedForWhile)
- .PermitIf(Trigger.NozzleLifted_And_停机, LogicalDeviceState.FDC_CALLING, () => true)
- .PermitIf(Trigger.NozzleLifted_And_开机, LogicalDeviceState.FDC_AUTHORISED, () => true)
- .PermitIf(Trigger.NozzleReplaced_And_停机, LogicalDeviceState.FDC_READY, () => true)
- .PermitIf(Trigger.NozzleReplaced_And_开机, LogicalDeviceState.FDC_AUTHORISED, () => true);
- //once a fule sale is done, a retrieving process is triggered, before the process done, new pump Calling will be blocked.
- bool isOnRetrievingLastFuelSale = false;
- this.stateless.Configure(LogicalDeviceState.FDC_READY)
- .OnEntryFromAsync(Trigger.NozzleReplaced_And_停机, async (transition) =>
- {
- if (transition.Source == LogicalDeviceState.FDC_FUELLING)
- {
- isOnRetrievingLastFuelSale = true;
- ReadFuelDataResponse finalTrxDataReading;
- try
- {
- logger.LogInformation("Pump: " + this.pumpId + ", A fueling just done, Retrieving last fuel sale trx...");
- finalTrxDataReading =
- await this.context.Outgoing.WriteAsync(new ReadFuelDataRequest() { Adrs = this.address },
- (_, testResponse) => testResponse is ReadFuelDataResponse rp && rp.Adrs == this.address, 3000) as ReadFuelDataResponse;
- if (finalTrxDataReading == null)
- {
- finalTrxDataReading =
- await this.context.Outgoing.WriteAsync(new ReadFuelDataRequest() { Adrs = this.address },
- (_, testResponse) => testResponse is ReadFuelDataResponse rp && rp.Adrs == this.address, 2000) as ReadFuelDataResponse;
- if (finalTrxDataReading == null)
- {
- logger.LogWarning("Pump: " + this.pumpId + ", fuel sale trx is missing for final read(auto tried one more time and still failed), trx will lost");
- return;
- }
- }
- }
- finally
- {
- isOnRetrievingLastFuelSale = false;
- }
- // at least within 65 years, exception will not throw here
- int newTrxSeqNumber = (int)(DateTime.Now.Subtract(new DateTime(2020, 6, 5)).TotalSeconds);
- logger.LogDebug("Pump: " + this.pumpId + ", Retrieved fuel sale trx, amt: " + finalTrxDataReading.Amount + ", vol: " + finalTrxDataReading.Volume + ", seqNo.: " + newTrxSeqNumber);
- var newTrx = new FdcTransaction()
- {
- // 只有一把枪
- Nozzle = this.nozzles.First(),
- Amount = finalTrxDataReading.Amount,
- Volumn = finalTrxDataReading.Volume,
- Price = this.nozzles.First().RealPriceOnPhysicalPump ?? -1,
- SequenceNumberGeneratedOnPhysicalPump = newTrxSeqNumber,
- Finished = true,
- };
- this.OnCurrentFuellingStatusChange?.Invoke(this, new FdcTransactionDoneEventArg(newTrx));
- }
- })
- .OnEntryAsync(async () => { })
- //.Ignore(Trigger.AnyPumpMsgReceived)
- .Ignore(Trigger.NozzleReplaced_And_停机)
- .Ignore(Trigger.NozzleFuelNumbersIsRunning)
- .PermitIf(Trigger.NozzleLifted_And_停机, LogicalDeviceState.FDC_CALLING, () => !isOnRetrievingLastFuelSale)
- .PermitIf(Trigger.NozzleLifted_And_开机, LogicalDeviceState.FDC_AUTHORISED, () => true)
- .PermitIf(Trigger.AnyPumpMsgHaveNotReceivedForWhile, LogicalDeviceState.FDC_OFFLINE, () => true);
- this.stateless.Configure(LogicalDeviceState.FDC_CALLING)
- .OnEntryAsync(async () => { })
- .OnEntryAsync(async () => { })
- //.Ignore(Trigger.AnyPumpMsgReceived)
- .Ignore(Trigger.NozzleLifted_And_停机)
- .PermitIf(Trigger.NozzleReplaced_And_停机, LogicalDeviceState.FDC_READY, () => true)
- .PermitIf(Trigger.NozzleLifted_And_开机, LogicalDeviceState.FDC_AUTHORISED, () => true)
- .PermitIf(Trigger.AnyPumpMsgHaveNotReceivedForWhile, LogicalDeviceState.FDC_OFFLINE, () => true);
- this.nozzleFuelNumbersIsRunningTrigger =
- this.stateless.SetTriggerParameters<FdcTransaction>(Trigger.NozzleFuelNumbersIsRunning);
- this.stateless.Configure(LogicalDeviceState.FDC_AUTHORISED)
- .OnEntryAsync(() =>
- Task.Run(() => this.context.Outgoing.Write(new ReadFuelDataRequest() { Adrs = this.address }))
- )
- .OnExitAsync(async () => { })
- //.Ignore(Trigger.AnyPumpMsgReceived)
- .Ignore(Trigger.NozzleLifted_And_开机)
- .PermitIf(Trigger.NozzleFuelNumbersIsRunning, LogicalDeviceState.FDC_FUELLING, () => true)
- .PermitIf(Trigger.AnyPumpMsgHaveNotReceivedForWhile, LogicalDeviceState.FDC_OFFLINE, () => true);
- this.stateless.Configure(LogicalDeviceState.FDC_FUELLING)
- .OnEntryFromAsync(this.nozzleFuelNumbersIsRunningTrigger, async (arg) =>
- {
- this.OnCurrentFuellingStatusChange?.Invoke(this, new FdcTransactionDoneEventArg(arg));
- this.context.Outgoing.Write(new ReadFuelDataRequest() { Adrs = this.address });
- //for detecting nozzle placed back.
- this.context.Outgoing.Write(new ReadPumpStateRequest() { Adrs = this.address });
- })
- .OnEntryAsync(async () => { })
- .OnExitAsync(async () => { })
- .PermitReentry(Trigger.NozzleFuelNumbersIsRunning)
- //.Ignore(Trigger.AnyPumpMsgReceived)
- .Ignore(Trigger.NozzleLifted_And_开机)
- .PermitIf(Trigger.NozzleReplaced_And_停机, LogicalDeviceState.FDC_READY, () => true)
- .PermitIf(Trigger.NozzleReplaced_And_开机, LogicalDeviceState.FDC_AUTHORISED, () => true)
- .PermitIf(Trigger.AnyPumpMsgHaveNotReceivedForWhile, LogicalDeviceState.FDC_OFFLINE, () => true);
- }
- catch (Exception exxx)
- {
- logger.LogError("Constructing LanTian_Pump_664_Or_886.StatePumpHanlder exceptioned: " + exxx);
- }
- }
- public void OnFdcServerInit(Dictionary<string, object> parameters)
- {
- if (parameters.ContainsKey("LastPriceChange"))
- {
- // nozzle logical id:rawPrice
- var lastPriceChanges = parameters["LastPriceChange"] as Dictionary<byte, int>;
- foreach (var priceChange in lastPriceChanges)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + "Pump " + this.pumpId + " OnFdcServerInit, load last price change " +
- "on logical nozzle: " + priceChange.Key + " with price: " + priceChange.Value);
- this.nozzles.First(n => n.LogicalId == priceChange.Key).ExpectingPriceOnFcSide = priceChange.Value;
- }
- }
- /* Load Last sale trx(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 volume Totalizer " +
- "on logical nozzle: " + lastFuelSaleTrx.Key + " with volume value: " + lastFuelSaleTrx.Value.VolumeTotalizer);
- this.nozzles.First(n => n.LogicalId == lastFuelSaleTrx.Key).VolumeTotalizer = lastFuelSaleTrx.Value.VolumeTotalizer;
- }
- }
- this.isOnFdcServerInitCalled = true;
- }
- public void Init(IContext<byte[], MessageBase> context)
- {
- this.context = context;
- var timeWindowWithActivePollingOutgoing =
- this.context.Outgoing as TimeWindowWithActivePollingOutgoing<byte[], MessageBase>;
- timeWindowWithActivePollingOutgoing.PollingMsgProducer = () => new ReadPumpStateRequest();
- }
- public async Task Process(IContext<byte[], MessageBase> context)
- {
- try
- {
- if (!isOnFdcServerInitCalled) return;
- this.lastLogicalDeviceStateReceivedTime = DateTime.Now;
- //await this.stateless.FireAsync(Trigger.AnyPumpMsgReceived);
- if (context.Incoming.Message is ReadPumpStateResponse readPumpStateResponse)
- {
- #region AcquireControl if pump authorize mode is FC_Authorize
- if (readPumpStateResponse.ControlState == ReadPumpStateResponse.ControlStateEnum.自控
- && this.pumpAuthorizeMode == PumpAuthorizeModeEnum.FC_Authorize)
- {
- var acquireControlResponse = await this.context.Outgoing.WriteAsync(
- new AcquireControlRequest() { Adrs = this.address },
- (request, response) => response is AcquireControlResponse rp && rp.Adrs == this.address, 3000).ConfigureAwait(false) as AcquireControlResponse;
- if (acquireControlResponse == null)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + " AcquireControlResponse first time timedout, will send 2nd time...");
- acquireControlResponse = await this.context.Outgoing.WriteAsync(
- new AcquireControlRequest() { Adrs = this.address },
- (request, response) => response is AcquireControlResponse rp && rp.Adrs == this.address, 3000).ConfigureAwait(false) as AcquireControlResponse;
- if (acquireControlResponse == null)
- logger.LogInformation("Pump: " + this.pumpId + ", " + " AcquireControlResponse 2nd time timedout, will ignore this error, then the pump may have wrong authorize mode");
- }
- }
- #endregion
- if (readPumpStateResponse.NozzleState == ReadPumpStateResponse.NozzleStateEnum.提枪)
- {
- if (readPumpStateResponse.StartOrStopState == ReadPumpStateResponse.StartOrStopStateEnum.开机)
- await this.stateless.FireAsync(Trigger.NozzleLifted_And_开机);
- else
- await this.stateless.FireAsync(Trigger.NozzleLifted_And_停机);
- }
- else
- {
- if (readPumpStateResponse.StartOrStopState == ReadPumpStateResponse.StartOrStopStateEnum.开机)
- await this.stateless.FireAsync(Trigger.NozzleReplaced_And_开机);
- else
- await this.stateless.FireAsync(Trigger.NozzleReplaced_And_停机);
- }
- }
- else if (context.Incoming.Message is ReadFuelDataResponse readFuelDataResponse)
- {
- //await this.stateless.FireAsync(Trigger.NozzleFuelNumbersIsRunning);
- await this.stateless.FireAsync(this.nozzleFuelNumbersIsRunningTrigger,
- new FdcTransaction()
- {
- // 只有一把枪
- Nozzle = this.nozzles.First(),
- Amount = readFuelDataResponse.Amount,
- Volumn = readFuelDataResponse.Volume,
- Price = this.nozzles.First().RealPriceOnPhysicalPump ?? -1,
- Finished = false,
- });
- }
- else if (context.Incoming.Message is ReadPriceResponse readPriceResponse)
- {
- if (!this.nozzles.First().RealPriceOnPhysicalPump.HasValue ||
- this.nozzles.First().RealPriceOnPhysicalPump.Value != readPriceResponse.Price)
- logger.LogInformation("Pump " + this.pumpId + ", detected the pump side price changed from: "
- + (this.nozzles.First().RealPriceOnPhysicalPump ?? -1) + " to: " + readPriceResponse.Price + ", will updating to local");
- this.nozzles.First().RealPriceOnPhysicalPump = readPriceResponse.Price;
- }
- }
- catch (Exception eee)
- {
- logger.LogInformation("Process(...) exceptioned: " + eee);
- }
- }
- /// <summary>
- /// no decimal point value.
- /// </summary>
- /// <returns>MoneyTotalizer:VolumnTotalizer</returns>
- public async Task<System.Tuple<int, int>> QueryTotalizerAsync(byte logicalNozzleId)
- {
- var readTotalizerResponse = await this.context.Outgoing.WriteAsync(new ReadTotalizerRequest() { Adrs = this.address },
- (_, testResponse) => testResponse is ReadTotalizerResponse rp && rp.Adrs == this.address, 3000) as ReadTotalizerResponse;
- if (readTotalizerResponse == null) return new System.Tuple<int, int>(-1, -1);
- return new System.Tuple<int, int>((int)readTotalizerResponse.AmountTotalizer, (int)readTotalizerResponse.VolumeTotalizer);
- }
- public async Task<bool> SuspendFuellingAsync()
- {
- logger.LogDebug("Pump " + this.pumpId + ", SuspendFuellingAsync...");
- var suspendFuelResponse = await this.context.Outgoing.WriteAsync(new SuspendFuelRequest() { Adrs = this.address },
- (_, testResponse) => testResponse is SuspendFuelResponse rp && rp.Adrs == this.address, 3000) as SuspendFuelResponse;
- var result = suspendFuelResponse != null;
- logger.LogDebug("Pump " + this.pumpId + ", SuspendFuellingAsync result: " + result);
- return result;
- }
- public async Task<bool> ResumeFuellingAsync()
- {
- logger.LogDebug("Pump " + this.pumpId + ", ResumeFuellingAsync...");
- var resumeFuelResponse = await this.context.Outgoing.WriteAsync(new ResumeFuelRequest() { Adrs = this.address },
- (_, testResponse) => testResponse is ResumeFuelResponse rp && rp.Adrs == this.address, 3000) as ResumeFuelResponse;
- var result = resumeFuelResponse != null;
- logger.LogDebug("Pump " + this.pumpId + ", ResumeFuellingAsync result: " + result);
- return result;
- }
- public async Task<bool> ChangeFuelPriceAsync(int newPriceWithoutDecimalPoint, byte logicalNozzleId)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + " ChangeFuelPriceAsync, new price: " + newPriceWithoutDecimalPoint);
- var readPriceResponse = await this.context.Outgoing.WriteAsync(new ReadPriceRequest() { Adrs = this.address },
- (request, response) => response is ReadPriceResponse rp && rp.Adrs == this.address, 3000).ConfigureAwait(false) as ReadPriceResponse;
- if (readPriceResponse == null)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + " Reading pump side price timedout, will ignore this error and won't send a ChangePriceRequest here but may need a manual Price change if find price discrepancy");
- return false;
- }
- this.nozzles.First().RealPriceOnPhysicalPump = readPriceResponse.Price;
- if (readPriceResponse.Price != newPriceWithoutDecimalPoint)
- {
- //logger.LogInformation("Pump: " + this.pumpId + ", "
- // + " Read the pump side price(without decimal points): " + readPriceResponse.Price + " which NOT Equals with the price as FC expect, will start a change price internally...");
- var changePriceResponse = await this.context.Outgoing.WriteAsync(
- new ChangePriceRequest(newPriceWithoutDecimalPoint, this.pumpModel == PumpModelEnum.Model_664 ? (byte)2 : (byte)3) { Adrs = this.address },
- (request, response) => response is ChangePriceResponse rp && rp.Adrs == this.address, 3000).ConfigureAwait(false) as ChangePriceResponse;
- if (changePriceResponse == null || !changePriceResponse.Succeed)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + " change price timedout or failed, may need a manual price change later if find price discrepancy");
- return false;
- }
- var doubleConfirm_readPriceResponse = await this.context.Outgoing.WriteAsync(new ReadPriceRequest() { Adrs = this.address },
- (request, response) => response is ReadPriceResponse rp && rp.Adrs == this.address, 3000).ConfigureAwait(false) as ReadPriceResponse;
- if (doubleConfirm_readPriceResponse == null)
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + " Double confirm change price timedout, so FC can't sure if the new price applied, or a manual Price change is needed if find price discrepancy");
- return false;
- }
- else if (doubleConfirm_readPriceResponse.Price == newPriceWithoutDecimalPoint)
- {
- this.nozzles.First().RealPriceOnPhysicalPump = doubleConfirm_readPriceResponse.Price;
- logger.LogInformation("Pump: " + this.pumpId + ", " + " Double confirm succeed for new FC price(without decimal points): " + newPriceWithoutDecimalPoint + " have been applied to pump.");
- return true;
- }
- else
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + " Double confirm failed for new FC price(without decimal points): " + newPriceWithoutDecimalPoint + " failed applying to pump as pump side still report its price(without decimal point): " + doubleConfirm_readPriceResponse.Price + ", a manual Change Price is needed");
- return false;
- }
- }
- else
- {
- logger.LogInformation("Pump: " + this.pumpId + ", " + " Read the pump side price(without decimal points): " + readPriceResponse.Price + ", no need to align with FC(FC has no expecting price)");
- return true;
- }
- }
- public async Task<bool> AuthorizeAsync(byte logicalNozzleId)
- {
- logger.LogDebug("Pump " + this.pumpId + ", AuthorizeAsync...");
- var openResponse = await this.context.Outgoing.WriteAsync(new OpenRequest() { Adrs = this.address },
- (_, testResponse) => testResponse is OpenResponse rp && rp.Adrs == this.address, 3000) as OpenResponse;
- if (openResponse == null)
- {
- logger.LogInformation("Pump " + this.pumpId + ", AuthorizeAsync failed due to timedout");
- return false;
- }
- logger.LogInformation("Pump " + this.pumpId + ", AuthorizeAsync result: " + openResponse.Succeed);
- return openResponse.Succeed;
- }
- public async Task<bool> UnAuthorizeAsync(byte logicalNozzleId)
- {
- return false;
- }
- public async Task<bool> AuthorizeWithAmountAsync(int moneyAmountWithoutDecimalPoint, byte logicalNozzleId)
- {
- logger.LogDebug("Pump " + this.pumpId + ", AuthorizeWithAmountAsync(amt: " + moneyAmountWithoutDecimalPoint + ")...");
- var presetAmountResponse = await this.context.Outgoing.WriteAsync(
- new PresetAmountRequest(moneyAmountWithoutDecimalPoint,
- this.pumpModel == PumpModelEnum.Model_664 ? (byte)3 : (byte)4)
- { Adrs = this.address },
- (_, testResponse) => testResponse is PresetAmountResponse rp && rp.Adrs == this.address, 3000) as PresetAmountResponse;
- if (presetAmountResponse == null)
- {
- logger.LogInformation("Pump " + this.pumpId + ", AuthorizeWithAmountAsync failed due to PresetAmountRequest timedout");
- return false;
- }
- logger.LogInformation("Pump " + this.pumpId + ", AuthorizeWithAmountAsync PresetAmountRequest succeed, will AuthorizePump...");
- return await this.AuthorizeAsync(logicalNozzleId);
- }
- public async Task<bool> AuthorizeWithVolumeAsync(int volumnWithoutDecimalPoint, byte logicalNozzleId)
- {
- logger.LogDebug("Pump " + this.pumpId + ", AuthorizeWithVolumeAsync(amt: " + volumnWithoutDecimalPoint + ")...");
- var presetVolumeResponse = await this.context.Outgoing.WriteAsync(
- new PresetVolumeRequest(volumnWithoutDecimalPoint,
- this.pumpModel == PumpModelEnum.Model_664 ? (byte)3 : (byte)4)
- { Adrs = this.address },
- (_, testResponse) => testResponse is PresetVolumeResponse rp && rp.Adrs == this.address, 3000) as PresetVolumeResponse;
- if (presetVolumeResponse == null)
- {
- logger.LogInformation("Pump " + this.pumpId + ", AuthorizeWithVolumeAsync failed due to PresetVolumeRequest timedout");
- return false;
- }
- logger.LogInformation("Pump " + this.pumpId + ", AuthorizeWithVolumeAsync PresetVolumeRequest succeed, will AuthorizePump...");
- return await this.AuthorizeAsync(logicalNozzleId);
- }
- public Task<bool> FuelingRoundUpByAmountAsync(int amount)
- {
- return Task.FromResult(false);
- }
- public Task<bool> FuelingRoundUpByVolumeAsync(int volume)
- {
- return Task.FromResult(false);
- }
- }
- }
|