1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456 |
- using System;
- using System.Collections.Generic;
- using System.Globalization;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- using System.Xml;
- using System.Xml.Serialization;
- using Applications.FDC;
- using Edge.Core.Configuration;
- using Edge.Core.IndustryStandardInterface.Pump;
- using Edge.Core.Processor;
- using FdcServerHost;
- using GenericDisplayCommand.Controls;
- using GenericDisplayCommand.Controls.V1;
- using HKCarPlateRecognize_App;
- using Microsoft.Extensions.DependencyInjection;
- using Microsoft.Extensions.Logging;
- using ShellChina_EPS_Project_CarPlatePay_EpsClient_App.MessageEntity.Base;
- using ShellChina_EPS_Project_CarPlatePay_EpsClient_App.MessageEntity.Incoming;
- using ShellChina_EPS_Project_CarPlatePay_EpsClient_App.MessageEntity.Outgoing;
- using Wayne.FDCPOSLibrary;
- using Timer = System.Timers.Timer;
- namespace ShellChina_EPS_Project_CarPlatePay_EpsClient_App
- {
- public class CarPlatePayEpsClientApp : IAppProcessor, IFdcCommunicableController
- {
- private FdcServerHostApp fdcServerApp;
- private IEnumerable<IFdcPumpController> fdcPumpControllers;
- public string MetaConfigName { get; set; }
- public ShellChinaEPSClientHandler EpsClientHandler;
- public HkCarPlateRecognizeApp HkCarPlateRecognizeapp;
- private string terminalId;
- private int epsTimeOut;
- private int carPlateTimeOut;
- private string videoSource;
- public Dictionary<string, CarPlateStatusInfo> CarPlateStatusInfos = new Dictionary<string, CarPlateStatusInfo>();
- //private static NLog.Logger logger = NLog.LogManager.LoadConfiguration("NLog.config").GetLogger("ShellChinaEPSClientApp");
- private static ILogger logger;
- private Dictionary<string, string> BackGroundColors = new Dictionary<string, string>();
- private const string ErrorTransTextColor = "#ffffff";
- private const string TextColor = "#000000";
- private Dictionary<(int, int), int> nozzles = new Dictionary<(int, int), int>();
- private DateTime lastUpdateOutdoorScreenTime = DateTime.Now;
- private readonly System.Timers.Timer UpdateOutdoorScreenTimer = null;
- private int _updateOutdoorScreenInterval = 0;
- private int delayToSendPayment = 5;
- ///// <summary>
- /////
- ///// </summary>
- ///// <param name="terminalId">此终端号由EPS分配,需要配置到终端内</param>
- ///// <param name="epsTimeOut">how long to wait for response from EPS</param>
- ///// <param name="carPlateTimeOut">how long to keep the car plate if the sale finished</param>
- public CarPlatePayEpsClientApp(string terminalId, int epsTimeOut, int carPlateTimeOut, int updateScreenInterval, int delay, string videoSrc, IServiceProvider services)
- {
- this.terminalId = terminalId;
- this.epsTimeOut = epsTimeOut;
- this.carPlateTimeOut = carPlateTimeOut;
- if (delay != 0) this.delayToSendPayment = delay;
- videoSource = videoSrc;
- var loggerFactory = services.GetRequiredService<ILoggerFactory>();
- logger = loggerFactory.CreateLogger("DynamicPrivate_ShellChinaEPSClientApp");
- BuildDefaultBackGroundColors();
- OnMessageReceivedViaFdc += ProcessMessageReceivedViaFdc;
- if (updateScreenInterval > 0)
- {
- _updateOutdoorScreenInterval = updateScreenInterval;
- UpdateOutdoorScreenTimer = new Timer();
- UpdateOutdoorScreenTimer.Interval = updateScreenInterval * 60 * 1000;
- }
- }
- private void BuildDefaultBackGroundColors()
- {
- BackGroundColors.Add("车牌付", "#bababa");
- BackGroundColors.Add("普通用户", "#ffd700");
- BackGroundColors.Add("车牌付加油中", "#ffff00");
- BackGroundColors.Add("车牌付待支付", "#1e90ff");
- BackGroundColors.Add("车牌付已支付", "#32cd32");
- BackGroundColors.Add("交易异常", "#ff0000");
- BackGroundColors.Add("车牌付待加油", "#bababa");
- }
- public CarPlatePayEpsClientApp()
- {
- logger.LogDebug("Do nothing");
- }
- public Task<bool> Start()
- {
- //OnMessageReceivedViaFdc += ProcessMessageReceivedViaFdc;
- HkCarPlateRecognizeapp.NewCarPlateCatched += HKCarPlateRecognizeapp_OnNewCarPlateCatched;
- foreach (var fdcPumpController in fdcPumpControllers)
- {
- fdcPumpController.OnStateChange += FdcPumpController_OnStateChange;
- }
- if (fdcServerApp != null)
- {
- fdcServerApp.OnCurrentFuellingStatusChange += FdcServer_OnCurrentFuellingStatusChange;
- fdcServerApp.OnStateChange += fdcServer_OnStateChange;
- }
- SetupSiteNozzles(fdcPumpControllers);
- //Send pump info to outdoor screen
- GenerateAndBrodcastMessageToOutdoorScreen();
- //GenerateAndBrodcastMessageToOutdoorScreenViaFuellingPoint();
- if (UpdateOutdoorScreenTimer != null)
- {
- UpdateOutdoorScreenTimer.Elapsed += (o, e) =>
- {
- logger.LogDebug("update screen timer elapsed");
- if (DateTime.Now.Subtract(lastUpdateOutdoorScreenTime).TotalMinutes > _updateOutdoorScreenInterval)
- {
- logger.LogDebug("update outdoor screen due to IDLE timer");
- GenerateAndBrodcastMessageToOutdoorScreen();
- // GenerateAndBrodcastMessageToOutdoorScreenViaFuellingPoint();
- }
- };
- UpdateOutdoorScreenTimer.Start();
- }
- return Task.FromResult(true);
- }
- private void fdcServer_OnStateChange(object sender, FdcPumpControllerOnStateChangeEventArg e)
- {
- bool needUpdateScreen = false;
- try
- {
- logger.LogDebug("FdcPumpController_OnStateChange state:{0}", e.NewPumpState);
- if (e.StateChangedNozzles != null)
- {
- //check plate list to see if any plate binded to the nozzle
- var stateChangedNozzle = e.StateChangedNozzles.First();
- string tempBindstr = "Pump" + stateChangedNozzle.PumpId + "_Nozzle" + stateChangedNozzle.LogicalId;
- logger.LogInformation("FdcPumpController_OnStateChange {0},state:{1}", tempBindstr, e.NewPumpState.ToString());
- lock (CarPlateStatusInfos)
- {
- foreach (var carPlateStatusInfo in CarPlateStatusInfos)
- {
- if (carPlateStatusInfo.Value.BindingInfo != null &&
- carPlateStatusInfo.Value.MemberShipId != "0" &&
- carPlateStatusInfo.Value.BindingInfo.BindedNozzle.Equals(tempBindstr) &&
- (carPlateStatusInfo.Value.PaymentState != CarPlateStatusInfo.PaymentStatus.车牌付已支付 &&
- carPlateStatusInfo.Value.PaymentState != CarPlateStatusInfo.PaymentStatus.交易异常 &&
- carPlateStatusInfo.Value.PaymentState != CarPlateStatusInfo.PaymentStatus.车牌付待支付))
- {
- logger.LogDebug("Nozzle:{0} bind with plate {1}", stateChangedNozzle.LogicalId,
- carPlateStatusInfo.Key);
- switch (e.NewPumpState)
- {
- case LogicalDeviceState.FDC_AUTHORISED:
- case LogicalDeviceState.FDC_CALLING:
- if (carPlateStatusInfo.Value.PaymentState !=
- CarPlateStatusInfo.PaymentStatus.车牌付待加油)
- {
- carPlateStatusInfo.Value.PaymentState =
- CarPlateStatusInfo.PaymentStatus.车牌付待加油;
- needUpdateScreen = true;
- }
- break;
- case LogicalDeviceState.FDC_FUELLING:
- if (carPlateStatusInfo.Value.PaymentState !=
- CarPlateStatusInfo.PaymentStatus.车牌付加油中)
- {
- carPlateStatusInfo.Value.PaymentState =
- CarPlateStatusInfo.PaymentStatus.车牌付加油中;
- needUpdateScreen = true;
- }
- break;
- default:
- logger.LogDebug(
- "FdcPumpController_OnStateChange, current state is {0}, CarPlateStatusInfo PaymentStatus:{1}",
- e.NewPumpState,
- Enum.GetName(typeof(CarPlateStatusInfo.PaymentStatus),
- carPlateStatusInfo.Value.PaymentState));
- break;
- }
- break;
- }
- }
- }
- }
- }
- catch (Exception ex)
- {
- logger.LogError("exception happened in FdcPumpController_OnStateChange:{0}", ex.Message);
- }
- if (needUpdateScreen) GenerateAndBrodcastMessageToOutdoorScreen();//GenerateAndBrodcastMessageToOutdoorScreenViaFuellingPoint();
- }
- private void FdcServer_OnCurrentFuellingStatusChange(object sender, FdcServerTransactionDoneEventArg e)
- {
- try
- {
- logger.LogDebug("Fuelling state changed");
- CarPlateStatusInfo bindedCarPlateStatusInfo = null;
- //when the fuel transaction finished, update the binded plate state to waiting for payment
- if (e.Transaction.Finished)
- {
- var tempBindStr = "Pump" + e.Transaction.Nozzle.PumpId + "_Nozzle" + e.Transaction.Nozzle.LogicalId;
- //var tempBindStr = "Pump" + e.Transaction.Nozzle.PumpId;
- logger.LogDebug("Fuelling state change on: {0}, Amount{1}", tempBindStr, e.Transaction.Amount);
- lock (CarPlateStatusInfos)
- {
- foreach (var carPlateStatusInfo in CarPlateStatusInfos)
- {
- //logger.Debug("carPlateStatusInfo MemberShipId:{0},plate:{1},paymentState:{2},count:{3}", carPlateStatusInfo.Value.MemberShipId, carPlateStatusInfo.Key, carPlateStatusInfo.Value.PaymentState, CarPlateStatusInfos.Count);
- if (carPlateStatusInfo.Value.MemberShipId != "0" &&
- carPlateStatusInfo.Value.BindingInfo != null &&
- carPlateStatusInfo.Value.BindingInfo.BindedNozzle.Equals(tempBindStr) &&
- carPlateStatusInfo.Value.PaymentState == CarPlateStatusInfo.PaymentStatus.车牌付加油中)
- {
- //logger.Debug("in the if");
- carPlateStatusInfo.Value.PaymentState = CarPlateStatusInfo.PaymentStatus.车牌付待支付;
- //logger.Debug("after payment state was set");
- bindedCarPlateStatusInfo = carPlateStatusInfo.Value;
- //logger.Debug("binded statusInfo");
- break;
- }
- //logger.Debug("exit for");
- }
- }
- }
- if (bindedCarPlateStatusInfo != null)
- {
- GenerateAndBrodcastMessageToOutdoorScreen();
- //GenerateAndBrodcastMessageToOutdoorScreenViaFuellingPoint();
- var logicalNozzleId = nozzles[(e.Transaction.Nozzle.PumpId, e.Transaction.Nozzle.LogicalId)];
- logger.LogInformation("send payment request to EPS amount:{0},transNum:{1},nozzle:{2},membership:{3},plate:{4},sitelevelNozzleId:{5}", e.Transaction.Amount, bindedCarPlateStatusInfo.TransactionNumber, e.Transaction.Nozzle.LogicalId, bindedCarPlateStatusInfo.MemberShipId, bindedCarPlateStatusInfo.PlateLicense, logicalNozzleId);
- //System.Timers.Timer timer = new Timer(5000);
- var paymentRequest =
- new PaymentRequest((decimal)e.Transaction.Amount / 100, bindedCarPlateStatusInfo.TransactionNumber, logicalNozzleId, bindedCarPlateStatusInfo.MemberShipId, bindedCarPlateStatusInfo.PlateLicense,
- terminalId)
- { TPDU = "6000300000" };
- //timer.Elapsed += (o, te) =>
- //{
- // StartLicensePayment((decimal)e.Transaction.Amount / 100, bindedCarPlateStatusInfo.TransactionNumber, logicalNozzleId, bindedCarPlateStatusInfo.MemberShipId, bindedCarPlateStatusInfo.PlateLicense);
- //};
- //timer.Start();
- ThreadPool.QueueUserWorkItem(new WaitCallback(StartLicensePayment), paymentRequest);
- //StartLicensePayment((decimal)e.Transaction.Amount / 100, bindedCarPlateStatusInfo.TransactionNumber, logicalNozzleId, bindedCarPlateStatusInfo.MemberShipId, bindedCarPlateStatusInfo.PlateLicense);
- }
- }
- catch (Exception exception)
- {
- logger.LogError("exception happened on currentFuelling state change:{0}", exception.Message);
- }
- }
- private void FdcPumpController_OnStateChange(object sender, FdcPumpControllerOnStateChangeEventArg e)
- {
- bool needUpdateScreen = false;
- try
- {
- logger.LogDebug("FdcPumpController_OnStateChange state:{0}", e.NewPumpState);
- if (e.StateChangedNozzles != null)
- {
- //check plate list to see if any plate binded to the nozzle
- var stateChangedNozzle = e.StateChangedNozzles.First();
- //For the shell site, treat one fuelling point as a nozzle
- string tempBindstr = "Pump" + stateChangedNozzle.PumpId + "_Nozzle" + stateChangedNozzle.LogicalId;
- //string tempBindstr = "Pump" + stateChangedNozzle.PumpId;
- logger.LogInformation("FdcPumpController_OnStateChange {0},state:{1}", tempBindstr, e.NewPumpState.ToString());
- lock (CarPlateStatusInfos)
- {
- foreach (var carPlateStatusInfo in CarPlateStatusInfos)
- {
- if (carPlateStatusInfo.Value.BindingInfo != null &&
- carPlateStatusInfo.Value.MemberShipId != "0" &&
- carPlateStatusInfo.Value.BindingInfo.BindedNozzle.Equals(tempBindstr) &&
- (carPlateStatusInfo.Value.PaymentState != CarPlateStatusInfo.PaymentStatus.车牌付已支付 &&
- carPlateStatusInfo.Value.PaymentState != CarPlateStatusInfo.PaymentStatus.交易异常 &&
- carPlateStatusInfo.Value.PaymentState != CarPlateStatusInfo.PaymentStatus.车牌付待支付))
- {
- logger.LogInformation("Nozzle:{0} bind with plate {1}", stateChangedNozzle.LogicalId,
- carPlateStatusInfo.Key);
- switch (e.NewPumpState)
- {
- case LogicalDeviceState.FDC_AUTHORISED:
- case LogicalDeviceState.FDC_CALLING:
- if (carPlateStatusInfo.Value.PaymentState !=
- CarPlateStatusInfo.PaymentStatus.车牌付待加油)
- {
- carPlateStatusInfo.Value.PaymentState =
- CarPlateStatusInfo.PaymentStatus.车牌付待加油;
- needUpdateScreen = true;
- }
- break;
- case LogicalDeviceState.FDC_FUELLING:
- if (carPlateStatusInfo.Value.PaymentState !=
- CarPlateStatusInfo.PaymentStatus.车牌付加油中)
- {
- carPlateStatusInfo.Value.PaymentState =
- CarPlateStatusInfo.PaymentStatus.车牌付加油中;
- needUpdateScreen = true;
- }
- break;
- default:
- logger.LogInformation(
- "FdcPumpController_OnStateChange, current state is {0}, CarPlateStatusInfo PaymentStatus:{1}",
- e.NewPumpState,
- Enum.GetName(typeof(CarPlateStatusInfo.PaymentStatus),
- carPlateStatusInfo.Value.PaymentState));
- break;
- }
- break;
- }
- }
- }
- }
- }
- catch (Exception ex)
- {
- logger.LogError("exception happened in FdcPumpController_OnStateChange:{0}", ex.Message);
- }
- if (needUpdateScreen) GenerateAndBrodcastMessageToOutdoorScreen();//GenerateAndBrodcastMessageToOutdoorScreenViaFuellingPoint();
- }
- public Task<bool> Stop()
- {
- if (OnMessageReceivedViaFdc != null)
- {
- OnMessageReceivedViaFdc -= ProcessMessageReceivedViaFdc;
- }
- if (UpdateOutdoorScreenTimer.Enabled)
- UpdateOutdoorScreenTimer.Stop();
- return Task.FromResult(true);
- }
- public void Init(IEnumerable<IProcessor> processors)
- {
- var pumpControllers = new List<IFdcPumpController>();
- foreach (dynamic processor in processors)
- {
- //get the car plate recognize processor
- if (processor is IAppProcessor)
- {
- var HKCarPlateRecognize = processor as HkCarPlateRecognizeApp;
- if (HKCarPlateRecognize != null)
- HkCarPlateRecognizeapp = HKCarPlateRecognize;
- FdcServerHostApp fdcServer = processor as FdcServerHostApp;
- if (fdcServer != null)
- {
- logger.LogInformation("FdcServerHostApp retrieved as an IApplication instance!");
- fdcServerApp = processor;
- }
- continue;
- }
- var handler = processor.Context.Handler;
- if (handler is IFdcPumpController)
- pumpControllers.Add(handler);
- else if (handler is IEnumerable<IFdcPumpController>)
- pumpControllers.AddRange(handler);
- else if (handler is IDeviceHandler<byte[], MessageBase>)
- EpsClientHandler = handler as ShellChinaEPSClientHandler;
- }
- fdcPumpControllers = pumpControllers;
- }
- /// <summary>
- /// Called when new car plate catched from HK car plate recognize
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="plateCatchedEventArgs"></param>
- public void HKCarPlateRecognizeapp_OnNewCarPlateCatched(object sender, PlateCatchedEventArgs plateCatchedEventArgs)
- {
- logger.LogDebug("HKCarPlateRecognizeapp_OnNewCarPlateCatched, plate license:{0}", plateCatchedEventArgs.PlateLicense);
- bool quiryMemberInfo = false;
- //1.send the car plate to shell EPS to get the member information
- //2.save it
- lock (CarPlateStatusInfos)
- {
- if (CarPlateStatusInfos.ContainsKey(plateCatchedEventArgs.PlateLicense))
- {
- var carPlateStatusInfo = CarPlateStatusInfos[plateCatchedEventArgs.PlateLicense];
- TimeSpan timeSpan = DateTime.Now - carPlateStatusInfo.Time;
- //remove the plate it haven't started fuelling or has finished the sale in carPlateTimeOut
- if (timeSpan.TotalMinutes > carPlateTimeOut && (carPlateStatusInfo.BindingInfo == null ||
- (carPlateStatusInfo.BindingInfo != null && carPlateStatusInfo.PaymentState == CarPlateStatusInfo.PaymentStatus.车牌付已支付)))
- {
- CarPlateStatusInfos.Remove(plateCatchedEventArgs.PlateLicense);
- quiryMemberInfo = true;
- //CarPlateStatusInfos.Add(plateCatchedEventArgs.PlateLicense, new CarPlateStatusInfo() { Time = plateCatchedEventArgs.Time, PlateLicense = plateCatchedEventArgs.PlateLicense });
- //QuiryMemberShipInfo(plateCatchedEventArgs.PlateLicense);
- }
- }
- else
- {
- quiryMemberInfo = true;
- //CarPlateStatusInfos.Add(plateCatchedEventArgs.PlateLicense, new CarPlateStatusInfo() { Time = plateCatchedEventArgs.Time, PlateLicense = plateCatchedEventArgs.PlateLicense });
- //QuiryMemberShipInfo(plateCatchedEventArgs.PlateLicense);
- }
- }
- //System.Timers.Timer timer = new Timer(5000);
- //var paymentRequest =
- // new PaymentRequest((decimal)230 / 100, "1212", 25, "12222", plateCatchedEventArgs.PlateLicense,
- // terminalId)
- // { TPDU = "6000300000" };
- //timer.Elapsed += (o, te) =>
- //{
- // StartLicensePayment(paymentRequest);
- //};
- // ////timer.Start();
- ////ThreadPool.QueueUserWorkItem(new WaitCallback(StartLicensePayment), paymentRequest);
- //logger.LogDebug("after thread pool");
- if (quiryMemberInfo)
- QuiryMemberShipInfo(plateCatchedEventArgs.PlateLicense);
- }
- /// <summary>
- /// send MembershipInquiryRequest to EPS and handle the response
- /// </summary>
- /// <param name="plateLicense">car plate</param>
- public void QuiryMemberShipInfo(string plateLicense)
- {
- logger.LogDebug("QuiryMemberShipInfo plate license:{0}", plateLicense);
- //this.EpsClientHandler.WriteAsync(new MessageBase(), );
- //plateLicense = "京A12" + plateLicense; //Joy need this one to test with EPS
- this.EpsClientHandler.EPSClientContext.Outgoing.WriteAsync(new MembershipInquiryRequest(plateLicense, terminalId) { TPDU = "6000300000" }, (request, response) => request is MembershipInquiryRequest && response is MembershipInquiryResponse,
- (request, response) =>
- {
- if (response != null)
- {
- var membershipResponse = response as MembershipInquiryResponse;
- var membershipInquiryRequest = request as MembershipInquiryRequest;
- if (membershipResponse != null && membershipResponse.P_39_交易响应码.Equals("00000"))//success
- {
- //int count = membershipResponse.P_24_会员ID.Length;
- //string a = membershipResponse.P_24_会员ID;
- //var b = a.Trim().Replace("\0", "");
- ////string s = @"0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\";
- //if (b.Equals("))
- //{
- // logger.Info("00");
- //}
- if (membershipResponse.P_24_会员ID.Replace("\0", "").Equals("0"))
- {
- logger.LogInformation("The plate:{0} is not a member", membershipResponse.P_34_车牌号码);
- }
- else
- {
- //save the message and brodcast to outdoor screen
- lock (CarPlateStatusInfos)
- {
- if (!CarPlateStatusInfos.ContainsKey(membershipInquiryRequest.P_34_车牌号码))
- {
- CarPlateStatusInfos.Add(membershipInquiryRequest.P_34_车牌号码,
- new CarPlateStatusInfo()
- {
- Time = DateTime.Now,
- PlateLicense = membershipInquiryRequest.P_34_车牌号码,
- MemberShipId = membershipResponse.P_24_会员ID.Replace("\0", ""),
- TransactionNumber = membershipResponse.P_12_交易流水号
- });
- }
- }
- }
- GenerateAndBrodcastMessageToOutdoorScreen();
- //GenerateAndBrodcastMessageToOutdoorScreenViaFuellingPoint();
- //StartLicensePayment((decimal)1.20, membershipResponse.P_12_交易流水号, 5, membershipResponse.P_24_会员ID,
- //membershipInquiryRequest.P_34_车牌号码);//joy this was added for testing
- }
- else//failed, log the error info
- {
- var membershipInquiryRequest1 = request as MembershipInquiryRequest;
- if (membershipInquiryRequest1 != null)
- logger.LogInformation(
- "Failed to get member ship info for carPlate:{0}, error message:{1}",
- membershipInquiryRequest1.P_34_车牌号码, membershipResponse.P_40_错误信息);
- //save the message and brodcast to outdoor screen
- //lock (CarPlateStatusInfos)
- //{
- // //var statusInfo = CarPlateStatusInfos[membershipInquiryRequest.P_34_车牌号码];
- // //statusInfo.MemberShipId = membershipInquiryRequest.P_34_车牌号码;
- // //statusInfo.TransactionNumber = membershipInquiryRequest.P_12_交易流水号;
- // try
- // {
- // CarPlateStatusInfos.Add(membershipInquiryRequest1.P_34_车牌号码,
- // new CarPlateStatusInfo()
- // {
- // Time = DateTime.Now,
- // PlateLicense = membershipInquiryRequest1.P_34_车牌号码,
- // MemberShipId = "0",
- // TransactionNumber = "123"
- // });
- // logger.LogInformation("member ship added to list in quiry:{0}", CarPlateStatusInfos.Last().Value.MemberShipId);
- // }
- // catch (Exception exc)
- // {
- // logger.LogError("Exception happened in QuiryMemberShipInfo:" + exc.Message);
- // }
- //}
- GenerateAndBrodcastMessageToOutdoorScreen();
- //GenerateAndBrodcastMessageToOutdoorScreenViaFuellingPoint();
- }
- }
- else
- {
- var membershipInquiryRequest = request as MembershipInquiryRequest;
- if (membershipInquiryRequest != null)
- logger.LogInformation("Failed to QuiryMemberShipInfo for:{0},timeout,response is null", membershipInquiryRequest.P_34_车牌号码);
- //According to the request from Site, the car which is not a member will not displayed on outdoor screen
- //save the message and brodcast to outdoor screen
- //lock (CarPlateStatusInfos)
- //{
- // //var statusInfo = CarPlateStatusInfos[membershipInquiryRequest.P_34_车牌号码];
- // //statusInfo.MemberShipId = membershipInquiryRequest.P_34_车牌号码;
- // //statusInfo.TransactionNumber = membershipInquiryRequest.P_12_交易流水号;
- // try
- // {
- // CarPlateStatusInfos.Add(membershipInquiryRequest.P_34_车牌号码,
- // new CarPlateStatusInfo()
- // {
- // Time = DateTime.Now,
- // PlateLicense = membershipInquiryRequest.P_34_车牌号码,
- // MemberShipId = "0",
- // TransactionNumber = "123"
- // });
- // logger.LogDebug("member ship added to list in quiry:{0}", CarPlateStatusInfos.Last().Value.MemberShipId);
- // }
- // catch (Exception exc)
- // {
- // logger.LogInformation("Exception happened in QuiryMemberShipInfo:" + exc.Message);
- // }
- //}
- GenerateAndBrodcastMessageToOutdoorScreen();
- //GenerateAndBrodcastMessageToOutdoorScreenViaFuellingPoint();
- }
- }, epsTimeOut);
- }
- /// <summary>
- /// Send payment request to EPS and handle the response
- /// </summary>
- //public void StartLicensePayment(decimal amount, string epsSequenceNo, int siteLevelNozzleId, string membershipId, string plateLicense)
- public void StartLicensePayment(object requestObject)
- {
- try
- {
- logger.LogInformation("StartLicensePayment");
- //var paymentRequest =
- // new PaymentRequest(amount, epsSequenceNo, siteLevelNozzleId, membershipId, plateLicense,
- // terminalId)
- // { TPDU = "6000300000" };
- Thread.Sleep(delayToSendPayment * 1000);
- var paymentRequest = requestObject as PaymentRequest;
- if (paymentRequest != null)
- {
- logger.LogDebug("StartLicensePayment after,amount:{0}", paymentRequest.P_4_交易金额);
- this.EpsClientHandler.EPSClientContext.Outgoing.WriteAsync(paymentRequest,
- (request, response) => request is PaymentRequest && response is PaymentResponse,
- (request, response) =>
- {
- if (response != null)
- {
- var paymentResponse = response as PaymentResponse;
- if (paymentResponse.P_39_交易响应码.Equals("00000"))
- {
- lock (CarPlateStatusInfos)
- {
- CarPlateStatusInfos[(request as PaymentRequest)?.P_34_车牌号码].PaymentState =
- CarPlateStatusInfo.PaymentStatus.车牌付已支付;
- }
- }
- else
- {
- logger.LogInformation("License payment failed, the error message is:{0}",
- paymentResponse.P_40_错误信息);
- lock (CarPlateStatusInfos)
- {
- CarPlateStatusInfos[(request as PaymentRequest)?.P_34_车牌号码].PaymentState =
- CarPlateStatusInfo.PaymentStatus.交易异常;
- }
- }
- }
- else
- {
- logger.LogInformation("License payment failed, response is null");
- lock (CarPlateStatusInfos)
- {
- CarPlateStatusInfos[(request as PaymentRequest)?.P_34_车牌号码].PaymentState =
- CarPlateStatusInfo.PaymentStatus.交易异常;
- }
- }
- logger.LogDebug("StartLicensePayment send to out door screen");
- GenerateAndBrodcastMessageToOutdoorScreen();
- //GenerateAndBrodcastMessageToOutdoorScreenViaFuellingPoint();
- }, epsTimeOut);
- }
- }
- catch (Exception exception)
- {
- logger.LogError("Exception happend in StartLicensePayment:{0}", exception.Message);
- }
- }
- /// <summary>
- /// Gnerate the layout for each out door screen and check the car plate info dic to see if anything need to remove
- /// </summary>
- public void GenerateAndBrodcastMessageToOutdoorScreen()
- {
- logger.LogDebug("GenerateAndBrodcastMessageToOutdoorScreen");
- List<string> platesToRemove = new List<string>();
- string match_parent = "match_parent";
- //video LinearLayout
- var videoLinearLayout = new LinearLayout();
- videoLinearLayout.Width = match_parent;
- videoLinearLayout.Orientation = "vertical";//chuizhi
- var videoview = new VideoView() { Src = videoSource };
- videoLinearLayout.Id = "VideoList";
- //plate info for each pump LinearLayout
- var pumpLinearLayout = new LinearLayout();
- pumpLinearLayout.Id = "NozzleList";
- videoLinearLayout.Width = match_parent;
- if (fdcPumpControllers != null)
- {
- foreach (var fdcPumpController in this.fdcPumpControllers.OrderBy(pc => pc.PumpId))
- {
- foreach (var nozzle in fdcPumpController.Nozzles.OrderBy(n => n.LogicalId))
- {
- var nozzleLinearLayout = new LinearLayout();
- nozzleLinearLayout.Id = "Pump" + fdcPumpController.PumpId + "_Nozzle" + nozzle.LogicalId;
- nozzleLinearLayout.Height = match_parent;
- nozzleLinearLayout.AllowActions = new List<AllowAction>() { AllowAction.Drop };
- nozzleLinearLayout.Views.Add(new NozzleView() { PumpId = fdcPumpController.PumpId, NozzleId = nozzles[(fdcPumpController.PumpId, nozzle.LogicalId)] });
- pumpLinearLayout.Views.Add(nozzleLinearLayout);
- }
- }
- }
- //public car plate LinearLayout
- var commonCarPlateLinearLayout = new LinearLayout();
- commonCarPlateLinearLayout.Width = match_parent;
- var unusedCarPlateLinearLayout = new LinearLayout();
- unusedCarPlateLinearLayout.Id = "IdleList";
- unusedCarPlateLinearLayout.Height = match_parent;
- unusedCarPlateLinearLayout.Orientation = "vertical";
- var errorTransLinearLayout = new LinearLayout();
- errorTransLinearLayout.Id = "ErrorList";
- errorTransLinearLayout.Height = match_parent;
- errorTransLinearLayout.Orientation = "vertical";
- commonCarPlateLinearLayout.Orientation = "horizontal";
- commonCarPlateLinearLayout.Views.Add(unusedCarPlateLinearLayout);
- commonCarPlateLinearLayout.Views.Add(errorTransLinearLayout);
- lock (CarPlateStatusInfos)
- {
- //assign each plate to proper place
- foreach (var carPlateStatusInfo in CarPlateStatusInfos.OrderBy(o => o.Value.Time).ToDictionary(p => p.Key, o => o.Value))
- {
- if ((DateTime.Now - carPlateStatusInfo.Value.Time).TotalMinutes > this.carPlateTimeOut && (carPlateStatusInfo.Value.PaymentState != CarPlateStatusInfo.PaymentStatus.车牌付待支付 &&
- carPlateStatusInfo.Value.PaymentState != CarPlateStatusInfo.PaymentStatus.车牌付加油中 && carPlateStatusInfo.Value.PaymentState != CarPlateStatusInfo.PaymentStatus.交易异常))
- {
- platesToRemove.Add(carPlateStatusInfo.Key);
- logger.LogDebug("Add car plate to the remove list:{0},count:{1}", carPlateStatusInfo.Key, platesToRemove.Count);
- continue;
- }
- var carplateLinearLayout = new LinearLayout();
- carplateLinearLayout.Id = carPlateStatusInfo.Key;
- //plate view
- var plateLicenseView = new TextView();
- plateLicenseView.Text = carPlateStatusInfo.Key;
- //plateLicenseView.Background = "White";
- carplateLinearLayout.Views.Add(plateLicenseView);
- carplateLinearLayout.Orientation = "horizontal";
- //status view
- var plateStatusView = new TextView();
- plateStatusView.TextColor = TextColor;
- //plate was binded with nozzle, will add the linearlayout to associated nozzleLinearLayout
- if (carPlateStatusInfo.Value.BindingInfo != null)
- {
- carplateLinearLayout.AllowActions = new List<AllowAction>() { AllowAction.Submit };
- plateStatusView.Text = Enum.GetName(typeof(CarPlateStatusInfo.PaymentStatus), carPlateStatusInfo.Value.PaymentState);
- plateStatusView.Background = BackGroundColors[plateStatusView.Text];
- carplateLinearLayout.Views.Add(plateStatusView);
- if (carPlateStatusInfo.Value.PaymentState == CarPlateStatusInfo.PaymentStatus.交易异常)
- {
- plateStatusView.TextColor = ErrorTransTextColor;
- errorTransLinearLayout.Views.Insert(0, carplateLinearLayout);
- }
- else
- {
- foreach (var nl in pumpLinearLayout.Views)
- {
- if (nl.Id == carPlateStatusInfo.Value.BindingInfo.BindedNozzle)
- {
- var tmp = new List<CarPlateStatusInfo>();
- foreach (var view in (nl as LinearLayout).Views)
- {
- if (view.Id != null && CarPlateStatusInfos.ContainsKey(view.Id))
- tmp.Add(CarPlateStatusInfos[view.Id]);
- }
- tmp.Add(carPlateStatusInfo.Value);
- tmp = new List<CarPlateStatusInfo>(tmp.OrderByDescending(c => c.BindingInfo.BingTime));
- int index = tmp.FindIndex(c => c.PlateLicense == carPlateStatusInfo.Key);
- (nl as LinearLayout)?.Views.Insert(index + 1, carplateLinearLayout);
- break;
- }
- }
- }
- }
- else if (!string.IsNullOrEmpty(carPlateStatusInfo.Value.MemberShipId))//plate is not binding to any nozzles
- {
- plateStatusView.Text = carPlateStatusInfo.Value.MemberShipId.Equals("0") ? "普通用户" : "车牌付";
- plateStatusView.Background = BackGroundColors[plateStatusView.Text];
- carplateLinearLayout.Views.Add(plateStatusView);
- carplateLinearLayout.AllowActions = new List<AllowAction>() { AllowAction.Drag, AllowAction.Drop };
- unusedCarPlateLinearLayout.Views.Insert(0, carplateLinearLayout);
- }
- }
- logger.LogInformation("plate count need to remove1:{0}", platesToRemove.Count);
- }
- logger.LogDebug("plate count need to remove2:{0}", platesToRemove.Count);
- //root linearLayout
- var rootLinearLayout = new LinearLayout();
- rootLinearLayout.Id = "root";
- rootLinearLayout.Orientation = "vertical";
- rootLinearLayout.Width = rootLinearLayout.Height = match_parent;
- rootLinearLayout.Views.Add(videoLinearLayout);
- rootLinearLayout.Views.Add(commonCarPlateLinearLayout);
- rootLinearLayout.Views.Add(pumpLinearLayout);
- var genericDisplayCommand = new GenericDisplayCommandV1Wrapper() { Control = rootLinearLayout, Version = 1 };
- //broadcaset message to outdoor screen
- logger.LogDebug("broadcaset message to outdoor screen");
- if (BroadcastMessageViaFdc != null)
- {
- logger.LogDebug("BroadcastMessageViaFdc not null");
- XmlSerializer xmlSerializer = new XmlSerializer(typeof(GenericDisplayCommandV1Wrapper),
- new Type[] { typeof(LinearLayout), typeof(VideoView), typeof(TextView), typeof(NozzleView) });
- //using (var sww = new StringWriter())
- using (var ms = new MemoryStream())
- {
- XmlWriterSettings settings = new XmlWriterSettings();
- settings.Encoding = new UTF8Encoding(false);
- settings.Indent = false;
- using (XmlWriter writer = XmlWriter.Create(ms, settings))
- {
- //writer.Settings.Encoding = Encoding.UTF8;
- xmlSerializer.Serialize(writer, genericDisplayCommand);
- //var xml = sww.ToString();
- var xml = Encoding.UTF8.GetString(ms.ToArray());
- BroadcastMessageViaFdc(xml);
- logger.LogDebug("Message broadcast to outdoor:{0}", xml);
- }
- }
- }
- logger.LogDebug("PlateToRemove Count:{0}", platesToRemove.Count);
- //remove the plates
- if (platesToRemove.Count > 0)
- {
- logger.LogDebug("{0} plates will be removed", platesToRemove.Count);
- lock (CarPlateStatusInfos)
- {
- foreach (var plate in platesToRemove)
- if (CarPlateStatusInfos.ContainsKey(plate)) CarPlateStatusInfos.Remove(plate);
- }
- }
- }
- /// <summary>
- /// For the Shell project, the site treat the whole fuelling point as a nozzle, in order to match the configuration as site, need treat the fuelling
- /// point as the same with site.
- /// </summary>
- public void GenerateAndBrodcastMessageToOutdoorScreenViaFuellingPoint()
- {
- logger.LogDebug("GenerateAndBrodcastMessageToOutdoorScreen");
- List<string> platesToRemove = new List<string>();
- string match_parent = "match_parent";
- //video LinearLayout
- var videoLinearLayout = new LinearLayout();
- videoLinearLayout.Width = match_parent;
- videoLinearLayout.Orientation = "vertical";//chuizhi
- var videoview = new VideoView() { Src = videoSource };
- videoLinearLayout.Id = "VideoList";
- //plate info for each pump LinearLayout
- var pumpLinearLayout = new LinearLayout();
- pumpLinearLayout.Id = "NozzleList";
- videoLinearLayout.Width = match_parent;
- if (fdcPumpControllers != null)
- {
- foreach (var fdcPumpController in this.fdcPumpControllers.OrderBy(pc => pc.PumpId))
- {
- var nozzleLinearLayout = new LinearLayout();
- nozzleLinearLayout.Id = "Pump" + fdcPumpController.PumpId;// + "_Nozzle" + fdcPumpController.PumpId;
- nozzleLinearLayout.Height = match_parent;
- nozzleLinearLayout.AllowActions = new List<AllowAction>() { AllowAction.Drop };
- nozzleLinearLayout.Views.Add(new NozzleView() { PumpId = fdcPumpController.PumpId, NozzleId = fdcPumpController.PumpId });
- pumpLinearLayout.Views.Add(nozzleLinearLayout);
- }
- }
- //public car plate LinearLayout
- var commonCarPlateLinearLayout = new LinearLayout();
- commonCarPlateLinearLayout.Width = match_parent;
- var unusedCarPlateLinearLayout = new LinearLayout();
- unusedCarPlateLinearLayout.Id = "IdleList";
- unusedCarPlateLinearLayout.Height = match_parent;
- unusedCarPlateLinearLayout.Orientation = "vertical";
- var errorTransLinearLayout = new LinearLayout();
- errorTransLinearLayout.Id = "ErrorList";
- errorTransLinearLayout.Height = match_parent;
- errorTransLinearLayout.Orientation = "vertical";
- commonCarPlateLinearLayout.Orientation = "horizontal";
- commonCarPlateLinearLayout.Views.Add(unusedCarPlateLinearLayout);
- commonCarPlateLinearLayout.Views.Add(errorTransLinearLayout);
- lock (CarPlateStatusInfos)
- {
- lastUpdateOutdoorScreenTime = DateTime.Now;
- //assign each plate to proper place
- foreach (var carPlateStatusInfo in CarPlateStatusInfos.OrderBy(o => o.Value.Time).ToDictionary(p => p.Key, o => o.Value))
- {
- if ((DateTime.Now - carPlateStatusInfo.Value.Time).TotalMinutes > this.carPlateTimeOut && (carPlateStatusInfo.Value.PaymentState != CarPlateStatusInfo.PaymentStatus.车牌付待支付 &&
- carPlateStatusInfo.Value.PaymentState != CarPlateStatusInfo.PaymentStatus.车牌付加油中 && carPlateStatusInfo.Value.PaymentState != CarPlateStatusInfo.PaymentStatus.交易异常))
- {
- platesToRemove.Add(carPlateStatusInfo.Key);
- logger.LogDebug("Add car plate to the remove list:{0},count:{1}", carPlateStatusInfo.Key, platesToRemove.Count);
- continue;
- }
- var carplateLinearLayout = new LinearLayout();
- carplateLinearLayout.Id = carPlateStatusInfo.Key;
- //plate view
- var plateLicenseView = new TextView();
- plateLicenseView.Text = carPlateStatusInfo.Key;
- //plateLicenseView.Background = "White";
- carplateLinearLayout.Views.Add(plateLicenseView);
- carplateLinearLayout.Orientation = "horizontal";
- //status view
- var plateStatusView = new TextView();
- plateStatusView.TextColor = TextColor;
- //plate was binded with nozzle, will add the linearlayout to associated nozzleLinearLayout
- if (carPlateStatusInfo.Value.BindingInfo != null)
- {
- carplateLinearLayout.AllowActions = new List<AllowAction>() { AllowAction.Submit };
- plateStatusView.Text = Enum.GetName(typeof(CarPlateStatusInfo.PaymentStatus), carPlateStatusInfo.Value.PaymentState);
- plateStatusView.Background = BackGroundColors[plateStatusView.Text];
- carplateLinearLayout.Views.Add(plateStatusView);
- if (carPlateStatusInfo.Value.PaymentState == CarPlateStatusInfo.PaymentStatus.交易异常)
- {
- plateStatusView.TextColor = ErrorTransTextColor;
- errorTransLinearLayout.Views.Insert(0, carplateLinearLayout);
- }
- else
- {
- foreach (var nl in pumpLinearLayout.Views)
- {
- if (nl.Id == carPlateStatusInfo.Value.BindingInfo.BindedNozzle)
- {
- var tmp = new List<CarPlateStatusInfo>();
- foreach (var view in (nl as LinearLayout).Views)
- {
- if (view.Id != null && CarPlateStatusInfos.ContainsKey(view.Id))
- tmp.Add(CarPlateStatusInfos[view.Id]);
- }
- tmp.Add(carPlateStatusInfo.Value);
- tmp = new List<CarPlateStatusInfo>(tmp.OrderByDescending(c => c.BindingInfo.BingTime));
- int index = tmp.FindIndex(c => c.PlateLicense == carPlateStatusInfo.Key);
- (nl as LinearLayout)?.Views.Insert(index + 1, carplateLinearLayout);
- break;
- }
- }
- }
- }
- else if (!string.IsNullOrEmpty(carPlateStatusInfo.Value.MemberShipId))//plate is not binding to any nozzles
- {
- plateStatusView.Text = carPlateStatusInfo.Value.MemberShipId.Equals("0") ? "普通用户" : "车牌付";
- plateStatusView.Background = BackGroundColors[plateStatusView.Text];
- carplateLinearLayout.Views.Add(plateStatusView);
- carplateLinearLayout.AllowActions = new List<AllowAction>() { AllowAction.Drag, AllowAction.Drop };
- unusedCarPlateLinearLayout.Views.Insert(0, carplateLinearLayout);
- }
- }
- logger.LogInformation("plate count need to remove1:{0}", platesToRemove.Count);
- }
- logger.LogDebug("plate count need to remove2:{0}", platesToRemove.Count);
- //root linearLayout
- var rootLinearLayout = new LinearLayout();
- rootLinearLayout.Id = "root";
- rootLinearLayout.Orientation = "vertical";
- rootLinearLayout.Width = rootLinearLayout.Height = match_parent;
- rootLinearLayout.Views.Add(videoLinearLayout);
- rootLinearLayout.Views.Add(commonCarPlateLinearLayout);
- rootLinearLayout.Views.Add(pumpLinearLayout);
- var genericDisplayCommand = new GenericDisplayCommandV1Wrapper() { Control = rootLinearLayout, Version = 1 };
- //broadcaset message to outdoor screen
- logger.LogDebug("broadcaset message to outdoor screen");
- if (BroadcastMessageViaFdc != null)
- {
- logger.LogDebug("BroadcastMessageViaFdc not null");
- XmlSerializer xmlSerializer = new XmlSerializer(typeof(GenericDisplayCommandV1Wrapper),
- new Type[] { typeof(LinearLayout), typeof(VideoView), typeof(TextView), typeof(NozzleView) });
- //using (var sww = new StringWriter())
- using (var ms = new MemoryStream())
- {
- XmlWriterSettings settings = new XmlWriterSettings();
- settings.Encoding = new UTF8Encoding(false);
- settings.Indent = false;
- using (XmlWriter writer = XmlWriter.Create(ms, settings))
- {
- //writer.Settings.Encoding = Encoding.UTF8;
- xmlSerializer.Serialize(writer, genericDisplayCommand);
- //var xml = sww.ToString();
- var xml = Encoding.UTF8.GetString(ms.ToArray());
- BroadcastMessageViaFdc(xml);
- logger.LogDebug("Message broadcast to outdoor:{0}", xml);
- }
- }
- }
- logger.LogDebug("PlateToRemove Count:{0}", platesToRemove.Count);
- //remove the plates
- if (platesToRemove.Count > 0)
- {
- logger.LogDebug("{0} plates will be removed", platesToRemove.Count);
- lock (CarPlateStatusInfos)
- {
- foreach (var plate in platesToRemove)
- if (CarPlateStatusInfos.ContainsKey(plate)) CarPlateStatusInfos.Remove(plate);
- }
- }
- }
- public Func<string, bool> BroadcastMessageViaFdc { get; set; }
- public Func<string, string, string, bool> SendMessageViaFdc { get; set; }
- public Func<string, Tuple<string, OverallResult>> OnMessageReceivedViaFdc { get; set; }
- /// <summary>
- /// Process message from screen
- /// </summary>
- /// <param name="message"></param>
- /// <returns></returns>
- public Tuple<string, OverallResult> ProcessMessageReceivedViaFdc(string message)
- {
- logger.LogDebug("Message recevied via FDC:{0}", message);
- ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessFDCMessage), message);
- //if (message.Contains("GenericDisplayCommand"))
- //{
- // GenericDisplayCommandV1Wrapper genericDiaplayCommand = null;
- // XmlSerializer xmldeSerializer = new XmlSerializer(typeof(GenericDisplayCommandV1Wrapper),
- // new Type[] { typeof(LinearLayout), typeof(VideoView), typeof(TextView), typeof(NozzleView) });
- // using (var sr = new StringReader(message))
- // {
- // genericDiaplayCommand = (GenericDisplayCommandV1Wrapper)xmldeSerializer.Deserialize(sr);
- // }
- // if (genericDiaplayCommand != null)
- // {
- // var rootLinearLayount = genericDiaplayCommand.Control as LinearLayout;
- // if (rootLinearLayount != null && rootLinearLayount.Views.Count == 2)
- // {
- // BindCarplateWithNozzle(rootLinearLayount);
- // }
- // else if (rootLinearLayount != null && rootLinearLayount.Views.Count == 0)
- // {
- // ResetCarPlatePosition(rootLinearLayount);
- // }
- // else
- // {
- // logger.LogError("Invalid message received from outdoor screen");
- // }
- // }
- // else
- // {
- // logger.LogError("Invalid message received from outdoor screen");
- // }
- // //XmlDocument doc = new XmlDocument();
- // //doc.LoadXml(message);
- // //XmlNodeList layoutItems = doc.SelectNodes(@"GenericDisplayCommand/LinearLayout/LinearLayout");
- // //if (layoutItems.Count == 0) layoutItems = doc.SelectNodes(@"GenericDisplayCommand/LinearLayout");
- // //if (layoutItems.Count == 2)
- // //{
- // // BindCarplateWithNozzle(layoutItems);
- // //}
- // //else if (layoutItems.Count == 1)
- // //{
- // // ResetCarPlatePosition(layoutItems[0]);
- // //}
- // //else
- // //{
- // // logger.LogInformation("Invalid message received");
- // //}
- //}
- return new Tuple<string, OverallResult>("", OverallResult.Success);
- }
- private void ProcessFDCMessage(object messageStr)
- {
- try
- {
- var message = messageStr as string;
- if (message != null && message.Contains("GenericDisplayCommand"))
- {
- GenericDisplayCommandV1Wrapper genericDiaplayCommand = null;
- XmlSerializer xmldeSerializer = new XmlSerializer(typeof(GenericDisplayCommandV1Wrapper),
- new Type[] { typeof(LinearLayout), typeof(VideoView), typeof(TextView), typeof(NozzleView) });
- using (var sr = new StringReader(message))
- {
- genericDiaplayCommand = (GenericDisplayCommandV1Wrapper)xmldeSerializer.Deserialize(sr);
- }
- if (genericDiaplayCommand != null)
- {
- var rootLinearLayount = genericDiaplayCommand.Control as LinearLayout;
- if (rootLinearLayount != null && rootLinearLayount.Views.Count == 2)
- {
- BindCarplateWithNozzle(rootLinearLayount);
- }
- else if (rootLinearLayount != null && rootLinearLayount.Views.Count == 0)
- {
- ResetCarPlatePosition(rootLinearLayount);
- }
- else
- {
- logger.LogError("Invalid message received from outdoor screen");
- }
- }
- else
- {
- logger.LogError("Invalid message received from outdoor screen");
- }
- //XmlDocument doc = new XmlDocument();
- //doc.LoadXml(message);
- //XmlNodeList layoutItems = doc.SelectNodes(@"GenericDisplayCommand/LinearLayout/LinearLayout");
- //if (layoutItems.Count == 0) layoutItems = doc.SelectNodes(@"GenericDisplayCommand/LinearLayout");
- //if (layoutItems.Count == 2)
- //{
- // BindCarplateWithNozzle(layoutItems);
- //}
- //else if (layoutItems.Count == 1)
- //{
- // ResetCarPlatePosition(layoutItems[0]);
- //}
- //else
- //{
- // logger.LogInformation("Invalid message received");
- //}
- }
- }
- catch (Exception e)
- {
- logger.LogError("Exception in ProcessFDCMessage:" + e.Message);
- }
- }
- private void BindCarplateWithNozzle(LinearLayout rootlayout)
- {
- logger.LogInformation("Bind car plate to nozzle,layoutItems count:{0}", rootlayout.Views.Count);
- string carPlateLicense = String.Empty;
- string bindingInfo = String.Empty;
- string plateAction = string.Empty;
- string nozzleAction = string.Empty;
- string errorMessage = string.Empty;
- foreach (var layoutItem in rootlayout.Views)
- {
- lock (CarPlateStatusInfos)
- {
- plateAction = "Drag";
- if (layoutItem.AllowActions[0] == AllowAction.Drag /*&& CarPlateStatusInfos.ContainsKey(layoutItem.Id)*/)
- {
- if (CarPlateStatusInfos.ContainsKey(layoutItem.Id))
- {
- plateAction = Enum.GetName(typeof(AllowAction), layoutItem.AllowActions[0]);
- carPlateLicense = layoutItem.Id;
- }
- else
- {
- errorMessage = "车牌" + layoutItem.Id + "已失效";
- logger.LogInformation(errorMessage);
- }
- }
- else if (nozzles.ContainsValue(Convert.ToInt32(layoutItem.Id)))
- {
- bindingInfo = layoutItem.Id;
- nozzleAction = Enum.GetName(typeof(AllowAction), layoutItem.AllowActions[0]);
- }
- }
- }
- if (!string.IsNullOrEmpty(errorMessage))
- {
- SendPromptToOutdoorScreen(bindingInfo, errorMessage);
- return;
- }
- logger.LogInformation("carPlateLicense{0},bindingInfo:{1},plateAction{2},nozzleAction{3}", carPlateLicense, bindingInfo, plateAction, nozzleAction);
- if (!string.IsNullOrEmpty(plateAction) && !string.IsNullOrEmpty(carPlateLicense) &&
- !string.IsNullOrEmpty(nozzleAction) && !string.IsNullOrEmpty(bindingInfo))
- {
- bool updated = false;
- var originalPumpInfo = nozzles.FirstOrDefault(q =>
- q.Value.ToString(CultureInfo.InvariantCulture) == bindingInfo).Key;
- int pumpId = originalPumpInfo.Item1;
- int nozzleId = originalPumpInfo.Item2;
- //string bindingStr = "Pump" + pumpId;//for Shell, the site treat the fuelling point as one nozzle
- string bindingStr = "Pump" + pumpId.ToString(CultureInfo.InvariantCulture) + "_Nozzle" +
- nozzleId.ToString(CultureInfo.InvariantCulture);
- if (!HasBindedPalte(bindingStr))
- {
- lock (CarPlateStatusInfos)
- {
- if (plateAction.Equals(Enum.GetName(typeof(AllowAction), AllowAction.Drag)) &&
- nozzleAction.Equals(Enum.GetName(typeof(AllowAction), AllowAction.Drop)))
- {
- if (CarPlateStatusInfos.ContainsKey(carPlateLicense) &&
- CarPlateStatusInfos[carPlateLicense].BindingInfo == null &&
- !CarPlateStatusInfos[carPlateLicense].MemberShipId.Equals("0"))
- {
- CarPlateStatusInfos[carPlateLicense].BindingInfo = new BindingInfo()
- {
- BindedNozzle = bindingStr,
- BingTime = DateTime.Now
- };
- LogicalDeviceState state = LogicalDeviceState.FDC_UNDEFINED;
- foreach (var pump in fdcPumpControllers)
- {
- if (pump.PumpId == pumpId)
- {
- state = pump.QueryStatusAsync().Result;
- break;
- }
- }
- CarPlateStatusInfos[carPlateLicense].PaymentState =
- state == LogicalDeviceState.FDC_FUELLING
- ? CarPlateStatusInfo.PaymentStatus.车牌付加油中
- : CarPlateStatusInfo.PaymentStatus.车牌付待加油;
- updated = true;
- }
- else
- {
- logger.LogInformation("ignore the message, it's not a car plate member, membershipId is null");
- SendPromptToOutdoorScreen(bindingInfo, "非车牌付用户");
- }
- }
- }
- }
- else
- {
- logger.LogInformation("{0} has already binded with plate", bindingStr);
- SendPromptToOutdoorScreen(bindingInfo, "已有绑定的车牌");
- }
- if (updated)
- //GenerateAndBrodcastMessageToOutdoorScreenViaFuellingPoint();
- GenerateAndBrodcastMessageToOutdoorScreen();
- }
- }
- /// <summary>
- /// This method called when trying to clear the error transaction or unbind the plate
- /// </summary>
- /// <param name="layoutItem"></param>
- private void ResetCarPlatePosition(LinearLayout layoutItem)
- {
- logger.LogInformation("Reset car plate position");
- bool updated = false;
- string carLicense = string.Empty;
- var action = layoutItem.AllowActions[0];
- carLicense = layoutItem.Id;
- if (!string.IsNullOrEmpty(carLicense) && action.Equals(AllowAction.Submit))
- {
- lock (CarPlateStatusInfos)
- {
- if (CarPlateStatusInfos.ContainsKey(carLicense) &&
- CarPlateStatusInfos[carLicense].BindingInfo != null)
- {
- if (CarPlateStatusInfos[carLicense].PaymentState == CarPlateStatusInfo.PaymentStatus.交易异常)
- CarPlateStatusInfos.Remove(carLicense);
- else
- CarPlateStatusInfos[carLicense].BindingInfo = null;
- updated = true;
- }
- }
- if (updated) GenerateAndBrodcastMessageToOutdoorScreen();//GenerateAndBrodcastMessageToOutdoorScreenViaFuellingPoint();
- }
- }
- private void BindCarplateWithNozzle(XmlNodeList layoutItems)
- {
- logger.LogInformation("Bind car plate to nozzle,layoutItems count:{0}", layoutItems.Count);
- string carPlateLicense = String.Empty;
- string bindingInfo = String.Empty;
- string plateAction = string.Empty;
- string nozzleAction = string.Empty;
- for (int i = 0; i < layoutItems.Count; i++)
- {
- lock (CarPlateStatusInfos)
- {
- //carPlateLicense = CarPlateStatusInfos.FirstOrDefault(a => a.Key != string.Empty).Key;
- plateAction = "Drag";
- //var IdNode = layoutItems[i].SelectSingleNode(@"Id");
- if (CarPlateStatusInfos.ContainsKey(layoutItems[i].SelectSingleNode(@"Id")
- ?.InnerText))
- {
- plateAction = layoutItems[i].SelectSingleNode(@"AllowActions/AllowAction")?.InnerText;
- carPlateLicense = layoutItems[i].SelectSingleNode(@"Id")?.InnerText;
- }
- else if (nozzles.ContainsValue(Convert.ToInt32(layoutItems[i].SelectSingleNode(@"Id")?.InnerText.Trim())))
- {
- bindingInfo = layoutItems[i].SelectSingleNode(@"Id")?.InnerText;
- nozzleAction = layoutItems[i].SelectSingleNode(@"AllowActions/AllowAction")?.InnerText;
- }
- }
- }
- logger.LogInformation("carPlateLicense{0},bindingInfo:{1},plateAction{2},nozzleAction{3}", carPlateLicense, bindingInfo, plateAction, nozzleAction);
- if (!string.IsNullOrEmpty(plateAction) && !string.IsNullOrEmpty(carPlateLicense) &&
- !string.IsNullOrEmpty(nozzleAction) && !string.IsNullOrEmpty(bindingInfo))
- {
- bool updated = false;
- var originalPumpInfo = nozzles.FirstOrDefault(q =>
- q.Value.ToString(CultureInfo.InvariantCulture) == bindingInfo).Key;
- int pumpId = originalPumpInfo.Item1;
- int nozzleId = originalPumpInfo.Item2;
- string bindingStr = "Pump" + pumpId.ToString(CultureInfo.InvariantCulture) + "_Nozzle" +
- nozzleId.ToString(CultureInfo.InvariantCulture);
- //string bindingStr = "Pump" + pumpId;//for Shell, the site treat the fuelling po
- if (!HasBindedPalte(bindingStr))
- {
- lock (CarPlateStatusInfos)
- {
- if (plateAction.Equals(Enum.GetName(typeof(AllowAction), AllowAction.Drag)) &&
- nozzleAction.Equals(Enum.GetName(typeof(AllowAction), AllowAction.Drop)))
- {
- if (CarPlateStatusInfos.ContainsKey(carPlateLicense) &&
- CarPlateStatusInfos[carPlateLicense].BindingInfo == null &&
- !CarPlateStatusInfos[carPlateLicense].MemberShipId.Equals("0"))
- {
- //var originalPumpInfo = nozzles.FirstOrDefault(q =>
- // q.Value.ToString(CultureInfo.InvariantCulture) == bindingInfo).Key;
- //int pumpId = originalPumpInfo.Item1;
- //int nozzleId = originalPumpInfo.Item2;
- CarPlateStatusInfos[carPlateLicense].BindingInfo = new BindingInfo()
- {
- //BindedNozzle =
- // "Pump" + pumpId.ToString(CultureInfo.InvariantCulture) + "_Nozzle" +
- // nozzleId.ToString(CultureInfo.InvariantCulture),
- BindedNozzle = bindingStr,
- BingTime = DateTime.Now
- };
- LogicalDeviceState state = LogicalDeviceState.FDC_UNDEFINED;
- foreach (var pump in fdcPumpControllers)
- {
- if (pump.PumpId == pumpId)
- {
- state = pump.QueryStatusAsync().Result;
- break;
- }
- }
- CarPlateStatusInfos[carPlateLicense].PaymentState =
- state == LogicalDeviceState.FDC_FUELLING
- ? CarPlateStatusInfo.PaymentStatus.车牌付加油中
- : CarPlateStatusInfo.PaymentStatus.车牌付待加油;
- updated = true;
- }
- else
- {
- logger.LogInformation("ignore the message, it's not a car plate member, membershipId is null");
- SendPromptToOutdoorScreen(bindingInfo, "非车牌付用户");
- }
- }
- }
- }
- else
- {
- logger.LogInformation("{0} has already binded with plate", bindingStr);
- SendPromptToOutdoorScreen(bindingInfo, "已有绑定的车牌");
- }
- if (updated)
- GenerateAndBrodcastMessageToOutdoorScreen();
- //GenerateAndBrodcastMessageToOutdoorScreenViaFuellingPoint();
- }
- }
- /// <summary>
- /// This method called when trying to clear the error transaction or unbind the plate
- /// </summary>
- /// <param name="layoutItem"></param>
- private void ResetCarPlatePosition(XmlNode layoutItem)
- {
- logger.LogInformation("Reset car plate position");
- bool updated = false;
- string carLicense = string.Empty;
- var actionNode = layoutItem.SelectSingleNode(@"AllowActions/AllowAction");
- carLicense = layoutItem.SelectSingleNode(@"Id")?.InnerText;
- if (!string.IsNullOrEmpty(carLicense) && actionNode != null && actionNode.InnerText
- .Equals(Enum.GetName(typeof(AllowAction), AllowAction.Submit)))
- {
- lock (CarPlateStatusInfos)
- {
- if (CarPlateStatusInfos.ContainsKey(carLicense) &&
- CarPlateStatusInfos[carLicense].BindingInfo != null)
- {
- if (CarPlateStatusInfos[carLicense].PaymentState == CarPlateStatusInfo.PaymentStatus.交易异常)
- CarPlateStatusInfos.Remove(carLicense);
- else
- CarPlateStatusInfos[carLicense].BindingInfo = null;
- updated = true;
- }
- }
- if (updated) GenerateAndBrodcastMessageToOutdoorScreen(); //GenerateAndBrodcastMessageToOutdoorScreenViaFuellingPoint();
- }
- }
- private bool HasBindedPalte(string bindString)
- {
- bool alreadyBind = false;
- lock (CarPlateStatusInfos)
- {
- foreach (var carplateStatusInfo in CarPlateStatusInfos)
- {
- if (carplateStatusInfo.Value.BindingInfo != null &&
- carplateStatusInfo.Value.BindingInfo.BindedNozzle.Equals(bindString) && (carplateStatusInfo.Value.PaymentState == CarPlateStatusInfo.PaymentStatus.车牌付待加油 ||
- carplateStatusInfo.Value.PaymentState == CarPlateStatusInfo.PaymentStatus.车牌付加油中))
- {
- logger.LogInformation("HasbindPlate: {0},plate:{1},plateState:{2}", bindString, carplateStatusInfo.Value.PlateLicense, carplateStatusInfo.Value.PaymentState);
- alreadyBind = true;
- break;
- }
- }
- }
- return alreadyBind;
- }
- private void SendPromptToOutdoorScreen(string nozzleId, string prompt)
- {
- var genericDisplayCommand = new GenericDisplayCommandV1Wrapper() { Version = 1, NozzleId = nozzleId.ToString(CultureInfo.InvariantCulture), Prompt = prompt };
- if (BroadcastMessageViaFdc != null)
- {
- logger.LogDebug("BroadcastMessageViaFdc not null");
- XmlSerializer xmlSerializer = new XmlSerializer(typeof(GenericDisplayCommandV1Wrapper),
- new Type[] { typeof(LinearLayout), typeof(VideoView), typeof(TextView), typeof(NozzleView) });
- //using (var sww = new StringWriter())
- using (var ms = new MemoryStream())
- {
- XmlWriterSettings settings = new XmlWriterSettings();
- settings.Encoding = new UTF8Encoding(false);
- settings.Indent = false;
- using (XmlWriter writer = XmlWriter.Create(ms, settings))
- {
- //writer.Settings.Encoding = Encoding.UTF8;
- xmlSerializer.Serialize(writer, genericDisplayCommand);
- //var xml = sww.ToString();
- var xml = Encoding.UTF8.GetString(ms.ToArray());
- BroadcastMessageViaFdc(xml);
- logger.LogDebug("Message broadcast to outdoor:{0}", xml);
- }
- }
- }
- }
- #region Site nozzles setup
- /// <summary>
- /// Set up the site nozzles, in particular the nozzle number
- /// Strategy:
- /// 1. Sort the Pumps by id
- /// 2. Sort the nozzles by logical id
- /// 3. The site nozzle number then will be (Pump id, Logical nozzle id) => site nozzle number
- /// e.g. (1, 1) => 1, (1, 2) => 2, (2, 1) => 3, (3, 1) => 4, (3, 2) => 5, (4, 1) => 6 ...
- /// </summary>
- /// <param name="fdcPumpControllers">The Fdc pump instance collection.</param>
- private void SetupSiteNozzles(IEnumerable<IFdcPumpController> fdcPumpControllers)
- {
- nozzles.Clear();
- var nozzleProductConfig = Configurator.Default.NozzleExtraInfoConfiguration.Mapping;
- foreach (NozzleExtraInfo np in nozzleProductConfig)
- {
- logger.LogDebug($"({np.PumpId}, {np.NozzleLogicalId}) => {np.SiteLevelNozzleId}");
- nozzles.Add((np.PumpId, np.NozzleLogicalId), np.SiteLevelNozzleId ?? 0);
- }
- }
- #endregion
- }
- }
|