using SinoChemFC2PosProxy.Communicator; using System; using System.Collections.Generic; using System.Configuration; using System.Data.SqlClient; using System.Linq; using System.Text; using System.Threading; using Wayne.Lib; using Wayne.Lib.Log; namespace SinoChemFC2PosProxy { //public delegate void NozzleLiftedHandler(int sitewiseNozzleId, IPump callingPump); //public delegate void NozzleReplacedHandler(int sitewiseNozzleId); //public delegate void FuelingDoneHandler(int sitewiseNozzleId, int seqNum, decimal fuelAmount, decimal quantity, long authId); //public delegate void AuthOkHandler(int sitewiseNozzleId, long? authId); //public delegate void AuthFailedHandler(int sitewiseNozzleId); public class FdcCommunicator //: IDisposable//, ICommunicator { //public event NozzleLiftedHandler NozzleLifted; //public event NozzleReplacedHandler NozzleReplaced; //public event FuelingDoneHandler FuelingDone; //public event AuthOkHandler AuthOk; //public event AuthFailedHandler AuthFailed; /// /// 0 for not started, 1 for started already. /// private int isStarted = 0; private const string DEFAULT_FDC_SERVER_CONNECT_STRING = "Host=127.0.0.1,Port=4710,ClientId=101,ClientName=PetroChinaProxy,PortB=4710,PortC=4710"; private readonly string concreteFdcServerConnString = string.Empty; //private readonly DebugLogger debugLogger = // new DebugLogger(new IdentifiableEntity(0, "FC2PosProxyMain", "", null)); static NLog.Logger debugLogger = NLog.LogManager.LoadConfiguration("nlog.config").GetLogger("PumpHandler"); //private readonly Wayne.ForecourtControl.IForecourtControl forecourtControl; //private readonly MessageRouterClient msgRouterClient; private bool autoAuthorizePumpWhenCalling = false; /// /// The Fdc communicator works as a FDC client which connected to FC. /// /// somehow, still need to communicate the Message Router public FdcCommunicator() { //if (!String.IsNullOrEmpty( // ConfigurationManager.AppSettings["AutoAuthorizePumpWhenCalling"])) //{ // this.autoAuthorizePumpWhenCalling = // (ConfigurationManager.AppSettings["AutoAuthorizePumpWhenCalling"].ToLower() == // "true" // ? true // : false); //} //var fdcServerIpAddress = ConfigurationManager.AppSettings["FdcServerIpAddress"]; //this.concreteFdcServerConnString = DEFAULT_FDC_SERVER_CONNECT_STRING.Replace("127.0.0.1", fdcServerIpAddress) // .Replace("ClientId=101", "ClientId=" + ConfigurationManager.AppSettings["ClientId"]); //this.forecourtControl = Wayne.ForecourtControl.Fusion.FUSIONFactory.CreateForecourtControl(0); //this.forecourtControl.OnConnectionStateChange += forecourtControl_OnConnectionStateChange; //this.msgRouterClient = msgRouterClient; //this.msgRouterClient.Start(); } //void forecourtControl_OnConnectionStateChange(object sender, ConnectionChangedEventArgs e) //{ // debugLogger.Add("forecourtControl_OnConnectionStateChange(), new state: " + e.ConnectionState, DebugLogLevel.Normal); // if (e.ConnectionState == Wayne.Lib.DeviceConnectionState.Disconnected) // { // foreach (var pump in this.forecourtControl.Pumps) // { // pump.OnFuellingStateChange -= FdcCommunicator_OnFuellingStateChange; // pump.OnNozzleStateChange -= FdcCommunicator_OnNozzleStateChange; // pump.OnEventOccured -= FdcCommunicator_OnEventOccured; // } // } // else if (e.ConnectionState == Wayne.Lib.DeviceConnectionState.Connected) // { // // sometimes could not receive any notification from FDC server even attached the event handler, // // suspect some underlying bug in communication layer, so here try sleep a while to avoid(probably) this. // // // Thread.Sleep(500); // foreach (var pump in this.forecourtControl.Pumps) // { // pump.OnFuellingStateChange += FdcCommunicator_OnFuellingStateChange; // pump.OnNozzleStateChange += FdcCommunicator_OnNozzleStateChange; // pump.OnEventOccured += FdcCommunicator_OnEventOccured; // } // const int maxRetryTimes = 10; // int retriedTimes = 0; // while (!this.msgRouterClient.SendMessage(MsgRouterMessageUtility.RefreshPumpStatus())) // { // if (++retriedTimes > maxRetryTimes) break; // debugLogger.Add("failed to send RefreshPumpStatus() to MsgRouterServer, will keep retrying until max times reached...", DebugLogLevel.Normal); // Thread.Sleep(2000); // } // this.forecourtControl.SetSiteOpenedAsync(true, (_, __) => { }, null); // } //} //void FdcCommunicator_OnEventOccured(object sender, Wayne.ForecourtControl.PumpEventOccuredEventArgs e) //{ // debugLogger.Add("FdcCommunicator_OnEventOccured(), args: " + e, DebugLogLevel.Maximized); //} //void FdcCommunicator_OnNozzleStateChange(object sender, Wayne.ForecourtControl.NozzleStateChangeEventArgs e) //{ // //var callingPump = sender as IPump; // //debugLogger.Debug("FdcCommunicator_OnNozzleStateChange(), args: pumpId: " + callingPump.Id + " nozzleId: " + e.Nozzle.Id + ", newState: " + e.NozzleState); // //int sitewiseNozzleId = SiteConfigUtility.Default.GetSiteLevelNozzleIdByLogicalNozzleId(callingPump.Id, e.Nozzle.Id); // //if (e.NozzleState == NozzleState.In) // //{ // // /* indicate for nozzle if replaced back */ // // var sizeLevelNozzleIdsOnPump = SiteConfigUtility.Default.GetSiteLevelNozzleIdsByPumpId(callingPump.Id); // // if (!sizeLevelNozzleIdsOnPump.Any()) // // { // // debugLogger.Debug("Could not found any site level nozzle ids for pump: " + callingPump.Id); // // return; // // } // // using (var posSqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["PosDatabaseConnStr"].ConnectionString)) // // { // // try // // { // // /* idle would not carry nozzle id, so here reset all nozzles on target pump.*/ // // var setPumpOnIdleCommand // // = new SqlCommand(sizeLevelNozzleIdsOnPump.Select(siteLevelNozzleId => // // { // // var totalizer = SiteConfigUtility.Default.GetTotalizer(siteLevelNozzleId); // // return // // string.Format( // // "Update jy_info set [status] = '{1}', qty=0, amount=0, fzqty='{2}', fzamount={3}" + // // " where jihao = {0}", siteLevelNozzleId, 'F', // // totalizer.Item1, totalizer.Item2); // // }) // // .Aggregate((acc, n) => acc + " " + n), posSqlConnection); // // debugLogger.Add("setPumpOnIdleCommand(via Fdc): " + setPumpOnIdleCommand.CommandText, DebugLogLevel.Maximized); // // posSqlConnection.Open(); // // setPumpOnIdleCommand.ExecuteNonQuery(); // // } // // catch (Exception ex) // // { // // debugLogger.Add("executing setPumpOnIdleCommand(via Fdc) failed, exception detail: " + ex, // // DebugLogLevel.Normal); // // } // // } // // NozzleReplaced?.Invoke(sitewiseNozzleId); // //} // //else if (e.NozzleState == NozzleState.Out) // //{ // // debugLogger.Add("fire nozzle out event"); // // NozzleLifted?.Invoke(sitewiseNozzleId, callingPump); // //} //} //public void AuthorizePumpAsync(IPump callingPump, int sitewiseNozzleId, decimal authAmount) //{ // if (this.autoAuthorizePumpWhenCalling) // { // var authParameter = new AuthorizeParameters() // { // PriceGroup = PriceGroup.FullService, // LockToReleaseClient = false, // PresetType = PresetType.Amount, // PresetValue = authAmount, // Prepay = false, // PayType = "PC", // }; // for (int i = 0; i < callingPump.Nozzles.Count; i++) // { // int idFuelGrade = callingPump.Nozzles[i].FuelGrade; // authParameter.AllowedFuelGrade[idFuelGrade] = true; // } // debugLogger.Add( // "Authorizing for pumpId: " + callingPump.Id + ", authAmount:" + authAmount, // DebugLogLevel.Normal); // callingPump.AuthorizeAsync(authParameter, (_, arg) => // { // var pumpId = (int)(arg.UserToken); // if (arg.Success) // { // debugLogger.Add( // "AuthorizeAsync finished successfully for pumpId: " + pumpId, // DebugLogLevel.Detailed); // AuthOk?.Invoke(sitewiseNozzleId, arg.Result); // } // else // { // debugLogger.Add( // "AuthorizeAsync failed for pumpId: " + pumpId, // DebugLogLevel.Normal); // AuthFailed?.Invoke(sitewiseNozzleId); // } // }, callingPump.Id); // } // else // { // debugLogger.Add( // "No need to auth before fueling for pumpId: " + callingPump.Id, // DebugLogLevel.Normal); // AuthOk?.Invoke(sitewiseNozzleId, null); // } //} //void FdcCommunicator_OnFuellingStateChange(object sender, Wayne.ForecourtControl.FuellingStateChangeEventArgs e) //{ // debugLogger.Add("FdcCommunicator_OnFuellingStateChange(), args: " + e, DebugLogLevel.Detailed); // debugLogger.Add("\r\n PumpID = " + e.Fuelling.Pump.Id + // "\r\n Nozzle = " + e.Fuelling.Nozzle.Id + // "\r\n Amount = $" + e.Fuelling.Amount + // "\r\n State = " + e.State + // "\r\n FuelGrade = " + e.Fuelling.FuelGrade + // "\r\n ReservingDeviceId = " + e.Fuelling.ReservingDeviceId + // "\r\n Quantity = " + e.Fuelling.Quantity + // "\r\n ReservedBy = " + e.Fuelling.ReservedBy + // "\r\n FuelPeriodID = " + e.Fuelling.FuelPeriodId + // "\r\n FuellingSeqNumber = " + e.Fuelling.FuellingSequenceNumber + // "\r\n Price = $" + e.Fuelling.Price); // if (e.State == FuellingState.PayableTransaction) // { // /* in SinoChem project, the pump was set to FullService mode, so the PayableTransaction case here is impossible to happen, but just leave the code here*/ // this.forecourtControl.Pumps[e.Fuelling.Pump.Id - 1].Fuellings.ToList().ForEach(f => // { // var fsn = f.FuellingSequenceNumber; // debugLogger.Add("Sending SetAsPaidAsync for pumpId: " + f.Pump.Id + ", FuellingSequenceNumber: " + fsn, // DebugLogLevel.Detailed); // f.SetAsPaidAsync((_, arg) => // { // var pumpId = (int)(arg.UserToken); // if (arg.Success) // { // debugLogger.Add( // "SetAsPaidAsync finished successfully for pumpId: " + pumpId + ", FuellingSequenceNumber: " + fsn, // DebugLogLevel.Detailed); // } // else // { // debugLogger.Add( // "SetAsPaidAsync failed for pumpId: " + pumpId + ", FuellingSequenceNumber: " + fsn, // DebugLogLevel.Normal); // } // }, f.Pump.Id); // }); // } // else if (e.State == FuellingState.Paid) // { // var posSqlConnection = // new SqlConnection(ConfigurationManager.ConnectionStrings["PosDatabaseConnStr"].ConnectionString); // int sitewiseNozzleId = SiteConfigUtility.Default.GetSiteLevelNozzleIdByLogicalNozzleId(e.Fuelling.Pump.Id, e.Fuelling.Nozzle.Id); // using (posSqlConnection) // { // try // { // var totalizer = SiteConfigUtility.Default.GetTotalizer(e.Fuelling.Pump.Id, e.Fuelling.Nozzle.Id); // var updateFuelingTrxDoneCommand = // new SqlCommand( // string.Format( // "insert xiaofei2 (jihao, youpin, qty, danjia, amount, xf_date, xf_time, liushuino, fzqty, fzamount)" + // " values({0}, N'{1}', {2}, {3}, {4}, '{5}', '{6}', '{7}', '{8}', {9})", // sitewiseNozzleId, // Translator.GetFriendlyGradeName(SiteConfigUtility.Default.GetGradeNameByGradeId(e.Fuelling.FuelGrade)), // e.Fuelling.Quantity, // e.Fuelling.Price, // e.Fuelling.Amount, // DateTime.Now.Date.ToString("yyyy-MM-dd"), // DateTime.Now.ToString("HH:mm:ss"), // e.Fuelling.FuellingSequenceNumber, // totalizer.Item1, // totalizer.Item2), // posSqlConnection); // debugLogger.Add("updateFuelingTrxDoneCommand: " + updateFuelingTrxDoneCommand.CommandText, // DebugLogLevel.Maximized); // posSqlConnection.Open(); // updateFuelingTrxDoneCommand.ExecuteNonQuery(); // } // catch (Exception ex) // { // debugLogger.Add("executing updateFuelingTrxDoneCommand failed, exception detail: " + ex, // DebugLogLevel.Normal); // } // } // FuelingDone?.Invoke // (sitewiseNozzleId, e.Fuelling.FuellingSequenceNumber, e.Fuelling.Amount, e.Fuelling.Quantity, e.Fuelling.AuthorizationId); // } //} //public void Dispose() //{ // this.forecourtControl.Dispose(); // this.debugLogger.Dispose(); //} //public bool Start() //{ // if (0 == Interlocked.CompareExchange(ref this.isStarted, 1, 0)) // { // debugLogger.Add("Connecting to FDC server with connStr: " + this.concreteFdcServerConnString, DebugLogLevel.Normal); // this.forecourtControl.Connect(this.concreteFdcServerConnString); // return true; // } // else // { // throw new InvalidOperationException("Already started."); // } //} public bool IsStarted { get { return this.isStarted == 1; } } } }