1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261 |
- using Edge.Core.Processor;using Edge.Core.IndustryStandardInterface.Pump;
- using NozzleLockConfiguration;
- using SinochemCarplateService.Models;
- using SinochemCloudClient.Models;
- using SinochemInternetPlusApp.EpsTrxCleanup;
- using SinochemPosClient.Models;
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Threading;
- using System.Xml.Serialization;
- using Wayne.FDCPOSLibrary;
- using Wayne.Lib.Log;
- using WayneChina_IcCardReader_SinoChem.MessageEntity;
- using WayneChina_IcCardReader_SinoChem.MessageEntity.Incoming;
- using Global_Pump_Fdc;
- using System.Threading.Tasks;
- using Wayne.Lib;
- namespace SinochemInternetPlusApp
- {
- public class Eps : IDisposable
- {
- private List<FuelingPoint> fuelingPoints;
- private Dictionary<int, IEnumerable<int>> fuelingPointNozzlesDict = new Dictionary<int, IEnumerable<int>>();
- private Dictionary<int, Dictionary<int, string>> openTrxNozzleDict = new Dictionary<int, Dictionary<int, string>>();
- private EpsTrxCleanupManager epsTrxCleanupManager;
- protected DebugLogger debugLogger;
- private int requestId;
- private object requestSyncObj = new object();
- #region devices and services
- private Sinochem_CarPlateRecognizeCamera_HuLianWangJia.Handler carPlateServer;
- private IEnumerable<WayneChina_IcCardReader_SinoChem.Handler> cardReaderHandlers;
- private PumpGroupHandler globalPumpGroup;
- //private FdcCommunicator fccClient;
- private CloudManager cloudManager;
- private PosManager posManger;
- private object openTrxSyncObj = new object();
- private Dictionary<int, byte> fpSqNoDict = new Dictionary<int, byte>();
- private IEnumerable<IProcessor> processors;
- private IEnumerable<IFdcPumpController> pumpControllers;
- #endregion
- static NLog.Logger logger = NLog.LogManager.LoadConfiguration("nlog.config").GetLogger("SinochemEpsApp");
- #region constants
- public int InvalidNozzleId { get { return 9999; } }
- #endregion
- ForecourtTrxManager forecourtTrxManager;
- private Dictionary<int, string> nozzleMappingGradeName { get; set; } = new Dictionary<int, string>();
- #region Constructor
- public Eps(IEnumerable<int> fpIds, Dictionary<int, IEnumerable<int>> fpNozzlesDict, IEnumerable<IProcessor> processors)
- {
- var identifiableEntity = new IdentifiableEntity(0, "EpsMain", "", null);
- debugLogger = new DebugLogger(identifiableEntity);
- fuelingPoints = new List<FuelingPoint>(fpIds.Count());
- foreach (int fpId in fpIds)
- {
- fuelingPoints.Add(new FuelingPoint(fpId, fpNozzlesDict[fpId], this));
- }
- fuelingPointNozzlesDict = fpNozzlesDict;
- epsTrxCleanupManager = new EpsTrxCleanupManager(this);
- cloudManager = new CloudManager();
- posManger = new PosManager();
- NozzleLockAccessor.FillinNozzles(fpNozzlesDict);
- this.processors = processors;
- var pumpControllerList = new List<IFdcPumpController>();
- foreach (dynamic processor in processors)
- {
- if (processor is IAppProcessor)
- continue;
- var handler = processor.Context.Handler;
- if (handler is IEnumerable<IFdcPumpController>)
- {
- pumpControllerList.AddRange(handler);
- }
- }
- pumpControllers = pumpControllerList;
- debugLogger.Add("Eps has been constructed");
- //logger.Info("Eps has been constructed");
- logger.Info(string.Format($"{this.processors.Count()} processors were loaded."));
- foreach (var proc in this.processors)
- {
- logger.Info(proc.GetType().ToString());
- }
- forecourtTrxManager = new ForecourtTrxManager(pumpControllers, GenericSinochemEpsApp.PumpSideMapping,
- GenericSinochemEpsApp.ForceMappingFusionHoseToHuiTianHoseStr,GenericSinochemEpsApp.PosDatabaseConnString,
- GenericSinochemEpsApp.RawProductNameToPosProductNameStr);
- forecourtTrxManager.Init();
- nozzleMappingGradeName = forecourtTrxManager.GetNozzleFuelMapping();
- }
- internal TrxNotificationResponse NotifySuccessfulTrxToPos(EpsTransactionModel model, DebugLogger debugLogger)
- {
- return posManger.NotifyPosSuccessfulTrx(model, debugLogger);
- }
- internal PaymentResponse SendPaymentToCloud(EpsTransactionModel currentEpsTrxModel, DebugLogger debugLogger)
- {
- return cloudManager.Payment(currentEpsTrxModel, debugLogger);
- }
- internal BalanceInquiryResponse SendBalanceInquiryToCloud(string cardNo, string encryptedPin, string tid, int nozzleId, DebugLogger debugLogger)
- {
- return cloudManager.BalanceInquiry(cardNo, encryptedPin, tid, nozzleId, debugLogger);
- }
- #endregion
- public void Run()
- {
- fpSqNoDict.Clear();
- SetupICCardReaderHandler();
- if (fuelingPoints != null)
- {
- foreach (var fp in fuelingPoints)
- {
- if (!fpSqNoDict.ContainsKey(fp.FuelingPointId))
- {
- fpSqNoDict.Add(fp.FuelingPointId, 0);
- }
- fp.Start();
- }
- }
- epsTrxCleanupManager.Start();
- SetupFccClient();
- SetupCarplateServer();
- }
- private void SetupFccClient()
- {
- foreach (var pumpController in pumpControllers)
- {
- pumpController.OnStateChange += (s, a) =>
- {
- var pump = s as IFdcPumpController;
- if (a.NewPumpState == LogicalDeviceState.FDC_CALLING)
- {
- logger.Info($"Pump {pump.PumpId} at state CALLING");
- int sitewiseNozzleId =
- SiteConfigUtility.Default.GetSiteLevelNozzleIdByLogicalNozzleId(pump.PumpId, a.StateChangedNozzles.FirstOrDefault()?.LogicalId ?? 0);
- FccClient_NozzleLifted(sitewiseNozzleId, pump);
- }
- else if (a.NewPumpState == LogicalDeviceState.FDC_READY)
- {
- int sitewiseNozzleId = 0;
- if (a.StateChangedNozzles != null)
- {
- SiteConfigUtility.Default.GetSiteLevelNozzleIdByLogicalNozzleId(pump.PumpId, a.StateChangedNozzles.FirstOrDefault()?.LogicalId ?? 0);
- }
- else
- {
- logger.Info("StateChangeNozzles null, use sitewiseNozzleId 0");
- }
- logger.Info($"Pump {pump.PumpId} at state: FDC_READY, siteWiseNozzleId: {sitewiseNozzleId}");
- FccClient_NozzleReplaced(sitewiseNozzleId, pump.PumpId);
- }
- else if (a.NewPumpState == LogicalDeviceState.FDC_AUTHORISED)
- {
- int sitewiseNozzleId =
- SiteConfigUtility.Default.GetSiteLevelNozzleIdByLogicalNozzleId(pump.PumpId,
- a.StateChangedNozzles.FirstOrDefault()?.LogicalId ?? 0);
- logger.Info($"Pump {pump.PumpId} at state FDC_AUTHORISED, siteWiseNozzleId: {sitewiseNozzleId}");
- FccClient_AuthOk(sitewiseNozzleId, 1999);
- }
- else if (a.NewPumpState == LogicalDeviceState.FDC_FUELLING)
- {
- logger.Info($"Pump {pump.PumpId} is fueling");
- }
- };
- pumpController.OnCurrentFuellingStatusChange += (s, a) =>
- {
- var pump = s as IFdcPumpController;
- if (a.Transaction.Finished)
- {
- int sitewiseNozzleId =
- SiteConfigUtility.Default.GetSiteLevelNozzleIdByLogicalNozzleId(pump.PumpId, a.Transaction.Nozzle.LogicalId);
- logger.Info($"Pump {pump.PumpId} fueling finished, siteWiseNozzleId: {sitewiseNozzleId}, amount: {a.Transaction.Amount}");
- FccClient_NozzleReplaced(sitewiseNozzleId, pump.PumpId);
- FccClient_FuelingDone(sitewiseNozzleId, a.Transaction.SequenceNumberGeneratedOnPhysicalPump,
- Convert.ToDecimal(a.Transaction.Amount / Math.Pow(10, pump.VolumeDecimalDigits)),
- Convert.ToDecimal(a.Transaction.Volumn / Math.Pow(10, pump.VolumeDecimalDigits)),
- 1999);
- }
- };
- Console.WriteLine($"setup fcc client pump done for {pumpController.PumpId}");
- }
- }
- private void Pump_OnStateChange(object sender, FdcPumpControllerOnStateChangeEventArg e)
- {
- throw new NotImplementedException();
- }
- private void Pump_OnCurrentFuellingStatusChange(object sender, FdcTransactionDoneEventArg e)
- {
- throw new NotImplementedException();
- }
- // find car plate handler and listen to the new car plate event
- private void SetupCarplateServer()
- {
- var carPlateProcessors =
- processors.OfType<Edge.Core.Processor.GenericDeviceProcessor<System.String, Edge.Core.Parser.HttpMessageParser.BaseHttpMessage<System.String>>>();
- carPlateServer = carPlateProcessors.Select(proc => (Sinochem_CarPlateRecognizeCamera_HuLianWangJia.Handler)proc.Context.Handler)
- .FirstOrDefault();
- if (carPlateServer != null)
- {
- carPlateServer.NewCarPlateScanned += CarPlateServer_NewCarPlateScanned;
- carPlateServer.QRCodePaid += CarPlateServer_QRCodePaid;
- carPlateServer.IndoorPaid += CarPlateServer_IndoorPaid;
- carPlateServer.OnMessageReceivedViaFdc += (msg) =>
- {
- logger.Info($"fdc message:\n {msg}");
- if (msg.Length > 10 && msg.StartsWith("<Tran"))
- {
- var serializer = new XmlSerializer(typeof(TransactionOperation));
- using (var reader = new StringReader(msg))
- {
- var trxOpRequest = (TransactionOperation)serializer.Deserialize(reader);
- if (trxOpRequest != null)
- {
- //trxOpRequest.NozzleNo
- //FuelingPoint fp = GetFp(trxOpRequest.NozzleNo ?? default(int));
- if (!string.IsNullOrEmpty(trxOpRequest.NozzleNo))
- {
- int nozzleNo = int.Parse(trxOpRequest.NozzleNo);
- FuelingPoint fp = GetFp(nozzleNo);
- if (fp != null)
- fp.SignalTrxOpRequest(trxOpRequest);
- }
- else
- {
- foreach (FuelingPoint fp in fuelingPoints)
- {
- if (fp.SignalTrxOpRequest(trxOpRequest))
- break;
- }
- }
- }
- }
- }
- else
- {
- var serializer = new XmlSerializer(typeof(DisplayResponse));
- using (var reader = new StringReader(msg))
- {
- var displayResp = (DisplayResponse)serializer.Deserialize(reader);
- logger.Info($"Display Response, id = {displayResp.RequestId}");
- if (displayResp != null && displayResp.OverallResult == ResultType.Success)
- {
- foreach (var fp in fuelingPoints)
- {
- if (fp.ContainsRequestId(displayResp.RequestId))
- fp.SignalDisplayResponseReceived(displayResp);
- }
- }
- }
- }
- return new Tuple<string, OverallResult>("DisplayResponse ACK", OverallResult.Success);
- };
- }
- else
- {
- Console.WriteLine("carPlateServer not found!!!");
- debugLogger.Add("carPlateServer not found!!!");
- }
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="request"></param>
- private void CarPlateServer_NewCarPlateScanned(CarPlateTrxRequest request)
- {
- int sitewiseNozzleId = InvalidNozzleId;
- try
- {
- sitewiseNozzleId = int.Parse(request.gun);
- }
- catch(Exception ex)
- {
- logger.Error(ex.ToString());
- }
- if (IsNozzleConfiguredOpen(sitewiseNozzleId))
- {
- var fp = GetFp(sitewiseNozzleId);
- fp?.SignalNewCarplate(request);
- }
- else
- {
- debugLogger.Add
- (string.Format($"Physical nozzle# {sitewiseNozzleId} is closed, so we ignore the car plate event!!!"));
- }
- }
- private void CarPlateServer_QRCodePaid(QRCodePayResultRequest request)
- {
- logger.Info("CarPlateServer_QRCodePaid");
- ThreadPool.QueueUserWorkItem(o =>
- {
- if (request != null)
- {
- logger.Info($"CarPlateServer_QRCodePaid, ttc:{request.ttc}, nozzleId:{request.nozzleId}, status: {request.status}, openId:{request.openId}");
- EpsTransactionModel epsTrxModel = EpsTransactionQuery.GetEpsTrxByTTC(request.ttc, request.nozzleId);
- if (epsTrxModel != null && epsTrxModel.trx_status != EpsTrxStatus.PaymentOk)
- {
- EpsTransaction epsTrx = EpsTransaction.RestroeEpsTrxFrom(epsTrxModel);
- if (request.status == "1")
- {
- EpsTransactionQuery.UpdateEpsTrxByttc(request.ttc, request.nozzleId, request.amount, request.openId, "07_pos", EpsTrxStatus.PaymentOk);
- //delete xiaofei2
- EpsTransactionQuery.DeleteXiaoFei2(epsTrxModel.liushuino, request.nozzleId);
- MultiFusionsSupport.DeleteXiaofei2FromTargetFusion(request.nozzleId, epsTrxModel.liushuino, debugLogger);
- //notify POS
- TrxNotificationResponse response = NotifySuccessfulTrxToPos(EpsTransactionQuery.RefreshEpsTrx(epsTrx.Model.id), debugLogger);
- if (response != null && response.IsSuccessful())
- {
- epsTrx.UpdateNotifyPosFlagToDb(NotifyPosFlag.NotifyOk);
- }
- }
- else
- {
- epsTrx.UpdateTrxStatusToDb(EpsTrxStatus.PaymentFailed);
- }
- //broadcast the trx to big screen
- BroadCastTrxCompleteToBigScreen(request.nozzleId);
- }
- }
- });
- }
- private void CarPlateServer_IndoorPaid(IndoorPayResultRequest request)
- {
- logger.Info("CarPlateServer_IndoorPaid");
- ThreadPool.QueueUserWorkItem(o =>
- {
- if (request != null)
- {
- logger.Info($"CarPlateServer_IndoorPaid, ttc:{request.liushuino}, nozzleId:{request.nozzleId}");
- EpsTransactionModel epsTrxModel = EpsTransactionQuery.GetEpsTrxByLiuShuiNO(request.liushuino, request.nozzleId);
- if (epsTrxModel != null)
- {
- EpsTransactionQuery.UpdateEpsTrxByliushuino(request.liushuino, request.nozzleId, request.amount, EpsTrxStatus.PaymentOk);
- BroadCastTrxCompleteToBigScreen(request.nozzleId);
- }
- }
- });
- }
- private void BroadCastTrxCompleteToBigScreen(int nozzleId)
- {
- //broadcast to big screen
- var fp = GetFp(nozzleId);
- var validTrx = EpsTransactionQuery.GetValidCarPlateEpsTrxModels(
- fp.GetAllNozzlesOnThisSide(),
- ConfigurationValues.AlreadyDoneEpsTrxCountPerDisplay,
- fp.DebugLogger);
- var availableNozzleInfo = fp.GetAvailableNozzleInfo();
- if (availableNozzleInfo != null)
- {
- foreach (var trx in validTrx)
- {
- if (trx.trx_status == EpsTrxStatus.BeforeFueling || trx.trx_status == EpsTrxStatus.Fueling)
- {
- trx.AvailableNozzleGrade = availableNozzleInfo;
- }
- }
- }
- var text = fp.Eps.CreateDisplayTrxCommand(validTrx, out requestId, 0);
- if (fp.Eps.CarPlateHandler != null)
- {
- fp.Eps.CarPlateHandler.BroadcastMessageViaFdc(text);
- }
- }
- /// <summary>
- /// Get the pairs "nozzleId, gradeName" for the available FP on this side
- /// </summary>
- public Dictionary<int, string> NozzleMappingGradeName()
- {
- return nozzleMappingGradeName; //Mapping grade name & nozzleId
- }
- public PumpState GetFPState(int fpId)
- {
- foreach (var pump in pumpControllers)
- {
- if (pump.PumpId == fpId)
- {
- var state = pump.QueryStatusAsync().Result;
- if (state == LogicalDeviceState.FDC_CALLING)
- return PumpState.Calling;
- else if (state == LogicalDeviceState.FDC_AUTHORISED)
- return PumpState.Authorized;
- else if (state == LogicalDeviceState.FDC_FUELLING)
- return PumpState.Fuelling;
- else if (state == LogicalDeviceState.FDC_READY)
- return PumpState.Idle;
- else if (state == LogicalDeviceState.FDC_CLOSED)
- return PumpState.Closed;
- }
- }
- return PumpState.Unknown;
- }
- private void SetupICCardReaderHandler()
- {
- var icCardReaderProcessors =
- processors.OfType<GenericDeviceProcessor<System.Byte[], WayneChina_IcCardReader_SinoChem.MessageEntity.IcCardReaderMessageBase>>();
- cardReaderHandlers = icCardReaderProcessors.Select(proc => (WayneChina_IcCardReader_SinoChem.Handler)proc.Context.Handler);
- if (cardReaderHandlers != null && cardReaderHandlers.Count() > 0)
- {
- Console.WriteLine($"Card reader handlers count: {cardReaderHandlers.Count()} ");
- foreach (var handler in cardReaderHandlers)
- {
- handler.OnCardReaderMessageReceived += Handler_OnCardReaderMessageReceived;
- }
- }
- else
- {
- Console.WriteLine("card reader handlers not found!!");
- logger.Info("card reader handlers not found!!");
- }
- }
- private void Handler_OnCardReaderMessageReceived(object sender, WayneChina_IcCardReader_SinoChem.CardReaderMessageEventArgs e)
- {
- //debugLogger.AddIfActive($"Receiving Card Reader message {e.CardReaderMessage.GetType().ToString()} for FP id = {e.FuelingPointId}");
- var latestSqNo = GetCurrentSqNoForFp(e.FuelingPointId);
- //debugLogger.AddIfActive($"latestSqNo {latestSqNo}");
- if (latestSqNo.HasValue)
- {
- var currentSqNo = e.CardReaderMessage.MessageSeqNumber;
- if (latestSqNo.Value != currentSqNo || currentSqNo == 0)
- {
- //Update the current sequence number for the designated fueling point.
- fpSqNoDict[e.FuelingPointId] = currentSqNo;
- var targetFP = fuelingPoints.First(_ => _.FuelingPointId == e.FuelingPointId);//GetFp(e.NozzleId);
- if (e.CardReaderMessage is ACK)
- {
- targetFP?.SingalAckReceived((ACK)e.CardReaderMessage);
- }
- else if (e.CardReaderMessage is SignDataResponse)
- {
- targetFP?.SignalSignedDataArrived((SignDataResponse)e.CardReaderMessage);
- }
- else if (e.CardReaderMessage is CardReaderStateEvent)
- {
- targetFP?.SingalCardReaderStateEvent((CardReaderStateEvent)e.CardReaderMessage);
- }
- else if (e.CardReaderMessage is CardExternalCheckErrorRequest)
- {
- targetFP?.SignalCardExternalCheckFailure((CardExternalCheckErrorRequest)e.CardReaderMessage);
- }
- else if (e.CardReaderMessage is CardOnlineVerificationRequest)
- {
- targetFP?.SignalCardOnlineVerification((CardOnlineVerificationRequest)e.CardReaderMessage);
- }
- else if (e.CardReaderMessage is HeartBeat)
- {
- targetFP?.SignalCardReaderHeartbeat((HeartBeat)e.CardReaderMessage);
- }
- }
- //If the sequence number of the received message is the same as the latest stored sequence number,
- //it's probably a re-send from the terminal.
- else
- {
- //2019-06-25, Card reader side updated SqNo as error code in Heartbeat.
- if (e.CardReaderMessage is HeartBeat)
- {
- var targetFP = fuelingPoints.First(_ => _.FuelingPointId == e.FuelingPointId);//GetFp(e.NozzleId);
- targetFP?.SignalCardReaderHeartbeat((HeartBeat)e.CardReaderMessage);
- }
- else
- {
- logger.Info($"A repeated message from terminal: {e}");
- var targetFP = fuelingPoints.First(_ => _.FuelingPointId == e.FuelingPointId);//GetFp(e.NozzleId);
- targetFP?.SignalRepeatedMessageRecieved(e.CardReaderMessage);
- return;
- }
- }
- }
- }
- private byte? GetCurrentSqNoForFp(int fpId)
- {
- if (fpSqNoDict.ContainsKey(fpId))
- {
- return fpSqNoDict[fpId];
- }
- else
- {
- return null;
- }
- }
- #region Cloud interactions
- internal RefundResponse SendRefundToCloud(EpsTransactionModel trxModel, DebugLogger debugLogger)
- {
- return cloudManager.Refund(trxModel, debugLogger);
- }
- internal TrxStatusInquiryResponse SendTrxQueryToCloud(EpsTransactionModel trxModel, DebugLogger debugLogger)
- {
- return cloudManager.TrxStatusInquiry(trxModel, debugLogger);
- }
- #endregion
- #region FDC client interactions
- private void FccClient_NozzleReplaced(int sitewiseNozzleId, int pumpId)
- {
- if (sitewiseNozzleId != 0)
- {
- var fp = GetFp(sitewiseNozzleId);
- fp?.SignalNozzleReplaced(sitewiseNozzleId, pumpId);
- }
- else
- {
- var fp = GetFuelingPoint(pumpId);
- fp?.SignalNozzleReplaced(sitewiseNozzleId, pumpId);
- }
- }
- private void FccClient_AuthFailed(int sitewiseNozzleId)
- {
- var fp = GetFp(sitewiseNozzleId);
- fp?.SignalAuthFailed();
- }
- private void FccClient_AuthOk(int sitewiseNozzleId, long? authId)
- {
- var fp = GetFp(sitewiseNozzleId);
- fp?.SignalAuthOk(authId);
- }
- private void FccClient_NozzleLifted(int sitewiseNozzleId, IFdcPumpController callingPump)
- {
- logger.Info($"SiteNozzle number: {sitewiseNozzleId}, from Pump {callingPump.PumpId} lifted");
- if (IsNozzleConfiguredOpen(sitewiseNozzleId))
- {
- var fp = GetFp(sitewiseNozzleId);
- fp?.SignalNozzleLifted(callingPump, sitewiseNozzleId);
- }
- else
- {
- logger.Info(string.Format($"Physical nozzle# {sitewiseNozzleId} is closed, so we ignore the nozzle lift event!!!"));
- }
- }
- private bool IsNozzleConfiguredOpen(int sitewiseNozzleId)
- {
- return !NozzleLockAccessor.IsNozzleClosedInTermsOfSale(sitewiseNozzleId);
- }
- private void FccClient_FuelingDone(int sitewiseNozzleId, int seqNum, decimal fuelAmount, decimal fuelingQty, long authId)
- {
- var fp = GetFp(sitewiseNozzleId);
- fp?.SignalFuelingDone(sitewiseNozzleId, seqNum, fuelAmount, fuelingQty, authId);
- }
- public void AuthorizePumpAsync(IFdcPumpController callingPump, int sitewiseNozzleId, decimal authAmount)
- {
- //Have to put pump auth in a different thread due to FC reasons, 2019/06/19
- Task.Run(() =>
- {
- LogicalNozzle logicalNozzle = callingPump.Nozzles.First();
- foreach (var nozzle in callingPump.Nozzles)
- {
- if (SiteConfigUtility.Default.GetSiteLevelNozzleIdByLogicalNozzleId(callingPump.PumpId, Convert.ToInt32(nozzle.LogicalId)) == sitewiseNozzleId)
- {
- logicalNozzle = nozzle;
- }
- }
- callingPump.AuthorizeWithAmountAsync((int)((double)authAmount * Math.Pow(10, callingPump.AmountDecimalDigits)), logicalNozzle.LogicalId);
- });
- }
- #endregion
- private void TeardownFccClient()
- {
- //if (fccClient != null)
- //{
- // fccClient.NozzleLifted -= FccClient_NozzleLifted;
- // fccClient.NozzleReplaced -= FccClient_NozzleReplaced;
- // fccClient.AuthOk -= FccClient_AuthOk;
- // fccClient.AuthFailed -= FccClient_AuthFailed;
- // fccClient.FuelingDone -= FccClient_FuelingDone;
- //}
- }
- public void Shutdown()
- {
- TeardownCarplateServer();
- TeardownCardReaderHandler();
- if (fuelingPoints != null)
- {
- foreach (var fp in fuelingPoints)
- {
- fp.SignalShutdown();
- }
- }
- }
- public WayneChina_IcCardReader_SinoChem.Handler GetHandler(int fuelingPointId)
- {
- //debugLogger.AddIfActive($"Trying to get card reader handler for fueling point: {fuelingPointId}");
- foreach (var handler in cardReaderHandlers)
- {
- if (handler.SupportedNozzles.Contains(fuelingPointId))
- return handler;
- }
- return null;
- }
- private void TeardownCarplateServer()
- {
- if (carPlateServer != null)
- {
- carPlateServer.NewCarPlateScanned -= CarPlateServer_NewCarPlateScanned;
- carPlateServer.QRCodePaid -= CarPlateServer_QRCodePaid;
- carPlateServer.IndoorPaid -= CarPlateServer_IndoorPaid;
- }
- }
- private void TeardownCardReaderHandler()
- {
- if (cardReaderHandlers != null)
- {
- foreach (var handler in cardReaderHandlers)
- {
- handler.OnCardReaderMessageReceived -= Handler_OnCardReaderMessageReceived;
- }
- }
- }
- public Sinochem_CarPlateRecognizeCamera_HuLianWangJia.Handler CarPlateHandler => carPlateServer;
- public WayneChina_IcCardReader_SinoChem.Handler GetCardReader(int nozzleId)
- {
- return cardReaderHandlers.FirstOrDefault(h => h.SupportedNozzles.Contains(nozzleId));
- }
- public FuelingPoint GetFp(int nozzleId)
- {
- foreach (var fp in fuelingPoints)
- {
- if (fp.AssociatedNozzles != null && fp.AssociatedNozzles.Contains(nozzleId))
- return fp;
- }
- return null;
- }
- public FuelingPoint GetFuelingPoint(int fpId)
- {
- return fuelingPoints?.FirstOrDefault(_ => fpId == _.FuelingPointId);
- }
- public int GetNextRequestId()
- {
- lock (requestSyncObj)
- {
- if (requestId == int.MaxValue)
- {
- requestId = 0;
- }
- return requestId++;
- }
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="epsTrxList"></param>
- /// <param name="requestId"></param>
- /// <param name="i"></param>
- /// <returns></returns>
- public string CreateDisplayTrxCommand(IEnumerable<EpsTransactionModel> epsTrxList, out int requestId, int i)
- {
- Display display;
- string cmdText = "";
- XmlSerializer serializer = new XmlSerializer(typeof(Display));
- MemoryStream ms;
- StreamReader sr;
- display = new Display();
- display.ScreenType = ScreenType.ShowTrxList;
- display.RequestId = GetNextRequestId();
- display.TimeoutSpecified = true;
- display.Timeout = 300;
- requestId = display.RequestId;
- display.PumpInfo = new DisplayPumpInfo
- {
- Id = 1,
- NozzleId = 1
- };
- int count = epsTrxList.Count();
- display.TrxList = new DisplayTrx[epsTrxList.Count()];
- for (int index = 0; index < count; index++)
- {
- display.TrxList[index] = ConvertEpsTrxModelToDisplayTrx(epsTrxList.ToArray()[index]);
- }
- ms = new MemoryStream();
- serializer.Serialize(ms, display);
- ms.Position = 0;
- sr = new StreamReader(ms, true);
- cmdText = sr.ReadToEnd();
- ms.Close();
- sr.Close();
- return cmdText;
- }
-
- public DisplayTrx ConvertEpsTrxModelToDisplayTrx(EpsTransactionModel epsTrxModel)
- {
- TrxStatus state = TrxStatus.ReadyForFillingStart;
- if (epsTrxModel.trx_status == EpsTrxStatus.BeforeFueling)
- state = TrxStatus.ReadyForFillingStart;
- else if (epsTrxModel.trx_status == EpsTrxStatus.BeforePayment)
- state = TrxStatus.PendingForPayment;
- else if (epsTrxModel.trx_status == EpsTrxStatus.Fueling)
- state = TrxStatus.FillingOngoing;
- else if (epsTrxModel.trx_status == EpsTrxStatus.FuelingDone)
- state = TrxStatus.PendingForPayment;
- else if (epsTrxModel.trx_status == EpsTrxStatus.PaymentOk)
- state = TrxStatus.Success;
- else if (epsTrxModel.trx_status == EpsTrxStatus.PaymentFailed)
- state = TrxStatus.Failed;
- else if (epsTrxModel.trx_status == EpsTrxStatus.PaymentNeedConfirm)
- state = TrxStatus.Failed;
- else if (epsTrxModel.trx_status == EpsTrxStatus.PaymentOkButNeedRefund)
- state = TrxStatus.Failed;
- else if (epsTrxModel.trx_status == EpsTrxStatus.PaymentRefunded)
- state = TrxStatus.Failed;
- var displayTrx = new DisplayTrx
- {
- Id = epsTrxModel.id.ToString(),
- State = state,
- TimeStamp = new DisplayTrxTimeStamp
- {
- StartTime = epsTrxModel.created_time,
- FinishTime = string.IsNullOrEmpty(epsTrxModel.xf_time) ?
- epsTrxModel.created_time :
- Utilities.CombineDateAndTime(epsTrxModel.xf_date, epsTrxModel.xf_time)
- },
- MemberInfo = new DisplayTrxMemberInfo
- {
- Id = epsTrxModel.cardNo_masked,
- LicensePlateNo = epsTrxModel.car_number
- },
- FillingInfo = new DisplayTrxFillingInfo
- {
- PumpId = 1,
- NozzleId = epsTrxModel.jihao,
- ProductNo = 1,
- UnitPrice = (decimal)epsTrxModel.danjia,
- ProductType = epsTrxModel.youpin,
- ProductDiscription = "汽油",
- Amount = (decimal)epsTrxModel.amount,
- AmountPaid = (decimal)epsTrxModel.real_pay_amount,
- Volume = (decimal)epsTrxModel.qty,
- NozzleSelected = epsTrxModel.nozzleSelected,
- }
- };
- if (epsTrxModel.AvailableNozzleGrade != null)
- {
- displayTrx.NozzleList = new DisplayTrxNozzle[epsTrxModel.AvailableNozzleGrade.Count];
- int index = 0;
- foreach (var pair in epsTrxModel.AvailableNozzleGrade)
- {
- displayTrx.NozzleList[index] = new DisplayTrxNozzle
- {
- NozzleId = pair.Key,
- Prompt = pair.Key.ToString() + "号枪" +pair.Value,
- };
- index++;
- }
- }
- return displayTrx;
- }
- public string CreateDisplayCommand(ScreenType screenType)
- {
- Display display;
- string cmdText = "";
- XmlSerializer serializer = new XmlSerializer(typeof(Display));
- MemoryStream ms;
- StreamReader sr;
- switch (screenType)
- {
- case ScreenType.Idle:
-
- display = new Display();
- display.ScreenType = screenType;
- display.CompanyContactInfo = new DisplayCompanyContactInfo
- {
- Tel = "010-59569575",
- Address = "世界500强企业\n中国第四大国家石油公司"
- };
- display.StationInfo = new DisplayStationInfo
- {
- StationNo = "000001",
- StationName = "沈阳望花中街加油加气站"
- };
- display.PumpInfo = new DisplayPumpInfo
- {
- Id = 1,
- NozzleId = 1
- };
- ms = new MemoryStream();
- serializer.Serialize(ms, display);
- ms.Position = 0;
- sr = new StreamReader(ms, true);
- cmdText = sr.ReadToEnd();
- break;
- case ScreenType.Welcome:
- display = new Display();
- display.ScreenType = screenType;
- display.CompanyContactInfo = new DisplayCompanyContactInfo
- {
- Tel = "010-59569575",
- Address = "世界500强企业\n中国第四大国家石油公司"
- };
- display.MemberInfo = new DisplayMemberInfo
- {
- LicensePlateNo = "京A88888",
- Id = "1234567"
- };
- display.PumpInfo = new DisplayPumpInfo
- {
- Id = 1,
- NozzleId = 1
- };
-
- ms = new MemoryStream();
- serializer.Serialize(ms, display);
- ms.Position = 0;
- sr = new StreamReader(ms, true);
- cmdText = sr.ReadToEnd();
- break;
- case ScreenType.ShowTrxList:
- display = new Display();
- display.ScreenType = screenType;
- display.PumpInfo = new DisplayPumpInfo
- {
- Id = 1,
- NozzleId = 1
- };
- display.TrxList = new DisplayTrx[]
- {
- new DisplayTrx
- {
- Id = "100",
- FillingInfo = new DisplayTrxFillingInfo
- {
- Amount = 200,
- NozzleId = 1,
- ProductType = "95#",
- UnitPrice = 6.78m,
- Volume = 35,
- ProductDiscription = "汽油"
- },
- MemberInfo = new DisplayTrxMemberInfo
- {
- LicensePlateNo = "京A88888",
- Id = "1234567"
- },
- State = TrxStatus.Success,
- TimeStamp = new DisplayTrxTimeStamp
- {
- StartTime = DateTime.Now,
- FinishTime =DateTime.Now
- }
- },
- new DisplayTrx
- {
- Id = "101",
- FillingInfo = new DisplayTrxFillingInfo
- {
- Amount = 211,
- NozzleId = 1,
- ProductType = "95#",
- UnitPrice = 6.78m,
- Volume = 35,
- ProductDiscription = "汽油"
- },
- MemberInfo = new DisplayTrxMemberInfo
- {
- LicensePlateNo = "京A88888",
- Id = "1234567"
- },
- State = TrxStatus.Success,
- TimeStamp = new DisplayTrxTimeStamp
- {
- StartTime = DateTime.Now,
- FinishTime =DateTime.Now
- }
- },
- new DisplayTrx
- {
- Id = "102",
- FillingInfo = new DisplayTrxFillingInfo
- {
- Amount = 222,
- NozzleId = 1,
- ProductType = "95#",
- UnitPrice = 6.78m,
- Volume = 35,
- ProductDiscription = "汽油"
- },
- MemberInfo = new DisplayTrxMemberInfo
- {
- LicensePlateNo = "京A88888",
- Id = "1234567"
- },
- State = TrxStatus.Success,
- TimeStamp = new DisplayTrxTimeStamp
- {
- StartTime = DateTime.Now,
- FinishTime =DateTime.Now
- }
- },
- new DisplayTrx
- {
- Id = "103",
- FillingInfo = new DisplayTrxFillingInfo
- {
- Amount = 233,
- NozzleId = 1,
- ProductType = "95#",
- UnitPrice = 6.78m,
- Volume = 35,
- ProductDiscription = "汽油"
- },
- MemberInfo = new DisplayTrxMemberInfo
- {
- LicensePlateNo = "京A88888",
- Id = "1234567"
- },
- State = TrxStatus.Success,
- TimeStamp = new DisplayTrxTimeStamp
- {
- StartTime = DateTime.Now,
- FinishTime =DateTime.Now
- }
- },
- new DisplayTrx
- {
- Id = "104",
- FillingInfo = new DisplayTrxFillingInfo
- {
- Amount = 244,
- NozzleId = 1,
- ProductType = "95#",
- UnitPrice = 6.78m,
- Volume = 35,
- ProductDiscription = "汽油"
- },
- MemberInfo = new DisplayTrxMemberInfo
- {
- LicensePlateNo = "京A88888",
- Id = "1234567"
- },
- State = TrxStatus.Success,
- TimeStamp = new DisplayTrxTimeStamp
- {
- StartTime = DateTime.Now,
- FinishTime =DateTime.Now
- }
- }
- };
- ms = new MemoryStream();
- serializer.Serialize(ms, display);
- ms.Position = 0;
- sr = new StreamReader(ms, true);
- cmdText = sr.ReadToEnd();
- break;
- case ScreenType.TrxResult:
- display = new Display();
- display.ScreenType = screenType;
- display.PumpInfo = new DisplayPumpInfo
- {
- Id = 1,
- NozzleId = 1
- };
- display.TrxList = new DisplayTrx[]
- {
- new DisplayTrx
- {
- Id = "100",
- FillingInfo = new DisplayTrxFillingInfo
- {
- Amount = 200,
- NozzleId = 1,
- ProductType = "95#",
- UnitPrice = 6.78m,
- Volume = 35,
- ProductDiscription = "汽油"
- },
- MemberInfo = new DisplayTrxMemberInfo
- {
- LicensePlateNo = "京A88888",
- Id = "1234567"
- },
- State = TrxStatus.Success,
- TimeStamp = new DisplayTrxTimeStamp
- {
- StartTime = DateTime.Now,
- FinishTime =DateTime.Now
- }
- }
- };
- ms = new MemoryStream();
- serializer.Serialize(ms, display);
- ms.Position = 0;
- sr = new StreamReader(ms, true);
- cmdText = sr.ReadToEnd();
- break;
- default:
- throw new Exception("Unsupported screen type");
- }
- return cmdText;
- }
- #region IDisposable Support
- private bool disposedValue = false; // To detect redundant calls
- protected virtual void Dispose(bool disposing)
- {
- if (!disposedValue)
- {
- if (disposing)
- {
- // TODO: dispose managed state (managed objects).
- if (fuelingPoints != null)
- {
- foreach (var fp in fuelingPoints)
- {
- fp.Dispose();
- }
- }
- if(epsTrxCleanupManager != null)
- {
- epsTrxCleanupManager.Dispose();
- }
- if(debugLogger != null)
- {
- debugLogger.Dispose();
- }
- }
- // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
- // TODO: set large fields to null.
- disposedValue = true;
- }
- }
- // TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
- // ~Eps() {
- // // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
- // Dispose(false);
- // }
- // This code added to correctly implement the disposable pattern.
- public void Dispose()
- {
- // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
- Dispose(true);
- // TODO: uncomment the following line if the finalizer is overridden above.
- // GC.SuppressFinalize(this);
- }
- #endregion
- }
- public enum PumpState
- {
- /// <summary>
- /// Pump is closed.
- /// </summary>
- Closed,
- /// <summary>
- /// Pump is inoperative
- /// </summary>
- Inoperative,
- /// <summary>
- /// Pump is Idle
- /// </summary>
- Idle,
- /// <summary>
- /// Pump is Calling for authorization
- /// </summary>
- Calling,
- /// <summary>
- /// Pump is authorised and ready to begin fuelling.
- /// </summary>
- Authorized,
- /// <summary>
- /// Pump is fuelling
- /// </summary>
- Fuelling,
- /// <summary>
- /// pump is Suspended
- /// </summary>
- Suspended,
- /// <summary>
- /// Unknown state
- /// </summary>
- Unknown,
- /// <summary>
- /// Error state
- /// </summary>
- Error,
- /// <summary>
- /// Offline state
- /// </summary>
- Offline,
- /// <summary>
- /// Starting state
- /// </summary>
- Starting,
- /// <summary>
- /// Stopped state
- /// </summary>
- Stopped,
- }
- }
|