using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using log4net;
using Timer = System.Timers.Timer;
using Common;
using System.Collections;
using HengShan_Pump_NonIC.MessageEntity;
using DeviceProcessor;
using Wayne.FDCPOSLibrary;
using Common.Config;
using System.Xml;
namespace HengShan_Pump_NonIC
{
///
/// this is kind of HS non IC pump that have a build-in auto auth self function by hardware, so outside(fcc) can't auth it, it's
/// a 'lift nozzle, and fueling pump'.
/// basically it only have 2 states:
/// idle: 不允许加油--加油结束--油枪关--电机关--D30--D20--金额加油
/// fueling: 允许加油--加油过程--油枪打开--电机打开--D30--D20--金额加油
///
public class PumpHandlerForSelfAuthPump : PumpHandler
{
private object syncObject = new object();
//static ILog fdcLogger = log4net.LogManager.GetLogger("FdcServer");
static ILog logger = log4net.LogManager.GetLogger("PumpHandler");
///
/// 恒山非IC油机
///
///
///
public PumpHandlerForSelfAuthPump(int pumpId, string nozzlesXmlConfiguration) : base(pumpId, nozzlesXmlConfiguration)
{
}
public override void Process(IContext context)
{
this.context = context;
if (context.Incoming.Message is GetNozzleStatusResponse getNozzleStatusResponse)
{
this.isSafeForSend = true;
this.lastLogicalDeviceStateReceivedTime = DateTime.Now;
//var getNozzleStatusResponse = context.Incoming.Message as GetNozzleStatusResponse;
// put the price by reading the real price.
this.nozzles.First().RealPriceOnPhysicalPump = getNozzleStatusResponse.单价;
var latestStatus = getNozzleStatusResponse.GetPumpStatus();
if (latestStatus.Any(f => f == GetNozzleStatusResponse.PumpStatus.允许加油)
&& latestStatus.Any(f => f == GetNozzleStatusResponse.PumpStatus.油枪打开)
&& latestStatus.Any(f => f == GetNozzleStatusResponse.PumpStatus.加油过程)
&& latestStatus.Any(f => f == GetNozzleStatusResponse.PumpStatus.电机打开))
{
//status code: B1
logger.Debug("正处于加油状态下");
/* 正处于加油状态下 */
if (this.previousUnfinishedFuelingNozzleStatus != null && this.previousUnfinishedFuelingNozzleStatus.流水号 != getNozzleStatusResponse.流水号)
{
logger.Info("Detected a fast put back and pull out nozzle case(action time < polling time cause nozzle place back not detected)," +
"\r\n will fire the trx done event for earlier trx(may have volume/money data loss!!!) with most recoverable data(most likely a bit less than real)->\r\n "
+ "seqNo: " + this.previousUnfinishedFuelingNozzleStatus.流水号
+ ", amount: " + this.previousUnfinishedFuelingNozzleStatus.加油金额
+ ", volume: " + this.previousUnfinishedFuelingNozzleStatus.加油金额
+ ", price: " + this.previousUnfinishedFuelingNozzleStatus.单价);
logger.Info(" State switched to FDC_READY(simulate)");
this.lastLogicalDeviceState = LogicalDeviceState.FDC_READY;
this.FireOnStateChangeEvent(LogicalDeviceState.FDC_READY);
this.FireOnCurrentFuellingStatusChangeEvent(new FdcTransaction()
{
// use previousUnfinishedFuelingNozzleStatus could miss reading the last trx correct numbers(less than actual number)
//, obviously this is caused by pump hardware design, impossible to recovery it back by our application.
Nozzle = this.nozzles.First(),
Amount = this.previousUnfinishedFuelingNozzleStatus.加油金额,
Volumn = this.previousUnfinishedFuelingNozzleStatus.加油量,
Price = this.previousUnfinishedFuelingNozzleStatus.单价,
SequenceNumberGeneratedOnPhysicalPump = this.previousUnfinishedFuelingNozzleStatus.流水号,
Finished = true,
});
}
this.previousUnfinishedFuelingNozzleStatus = getNozzleStatusResponse;
if (this.lastLogicalDeviceState != LogicalDeviceState.FDC_FUELLING)
{
logger.Debug(" State switched to FDC_FUELLING");
this.lastLogicalDeviceState = LogicalDeviceState.FDC_FUELLING;
base.FireOnStateChangeEvent(LogicalDeviceState.FDC_FUELLING);
}
//fire fuelling progress.
base.FireOnCurrentFuellingStatusChangeEvent(new FdcTransaction()
{
// 恒山油机只有一把枪
Nozzle = this.nozzles.First(),
Amount = getNozzleStatusResponse.加油金额,
Volumn = getNozzleStatusResponse.加油量,
Price = getNozzleStatusResponse.单价,
SequenceNumberGeneratedOnPhysicalPump = getNozzleStatusResponse.流水号,
Finished = false,
});
}
else if (latestStatus.Any(f => f == GetNozzleStatusResponse.PumpStatus.不允许加油)
&& latestStatus.Any(f => f == GetNozzleStatusResponse.PumpStatus.加油结束))
{
/* 油机首次上电也会进入此处,并不断发送上一次的加油记录,这种情况下的交易记录并无法判断其之前是否已经发送至上层系统(比如是否已经存入数据库),
所以此处不判断而是往上层系统里送入,由系统判断重复情况。 而其它正常加油过程中的交易记录仅在油机状态变化时才送入系统。*/
// status code: 40
logger.Debug("收到状态: 加油结束");
this.previousUnfinishedFuelingNozzleStatus = null;
if (this.lastLogicalDeviceState != LogicalDeviceState.FDC_READY)
{
logger.Debug(" State switched to FDC_READY");
lastLogicalDeviceState = LogicalDeviceState.FDC_READY;
base.FireOnStateChangeEvent(LogicalDeviceState.FDC_READY);
if (getNozzleStatusResponse.加油量 != 0 || getNozzleStatusResponse.加油金额 != 0)
{
base.FireOnCurrentFuellingStatusChangeEvent(new FdcTransaction()
{
// 恒山油机 一个加油点只有一把枪
Nozzle = this.nozzles.First(),
Amount = getNozzleStatusResponse.加油金额,
Volumn = getNozzleStatusResponse.加油量,
Price = getNozzleStatusResponse.单价,
SequenceNumberGeneratedOnPhysicalPump = getNozzleStatusResponse.流水号,
Finished = true,
});
}
}
}
}
else
{
base.Process(context);
}
}
///
///
///
/// useless for this type of pump, it always one pump one nozzle
///
public override bool Authorize(byte logicalNozzleId)
{
return false;
}
///
///
///
///
/// useless for this type of pump, it always one pump one nozzle
///
public override bool AuthorizeWithAmount(int moneyAmount, byte logicalNozzleId)
{
return false;
}
///
///
///
///
/// useless for this type of pump, it always one pump one nozzle
///
public override bool AuthorizeWithVolumn(int volumn, byte logicalNozzleId)
{
return false;
}
}
}