PumpHandlerForSelfAuthPump.cs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.Configuration;
  5. using System.IO.Ports;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading;
  9. using log4net;
  10. using Timer = System.Timers.Timer;
  11. using Common;
  12. using System.Collections;
  13. using HengShan_Pump_NonIC.MessageEntity;
  14. using DeviceProcessor;
  15. using Wayne.FDCPOSLibrary;
  16. using Common.Config;
  17. using System.Xml;
  18. namespace HengShan_Pump_NonIC
  19. {
  20. /// <summary>
  21. /// 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
  22. /// a 'lift nozzle, and fueling pump'.
  23. /// basically it only have 2 states:
  24. /// idle: 不允许加油--加油结束--油枪关--电机关--D30--D20--金额加油
  25. /// fueling: 允许加油--加油过程--油枪打开--电机打开--D30--D20--金额加油
  26. /// </summary>
  27. public class PumpHandlerForSelfAuthPump : PumpHandler
  28. {
  29. private object syncObject = new object();
  30. //static ILog fdcLogger = log4net.LogManager.GetLogger("FdcServer");
  31. static ILog logger = log4net.LogManager.GetLogger("PumpHandler");
  32. /// <summary>
  33. /// 恒山非IC油机
  34. /// </summary>
  35. /// <param name="pumpId"></param>
  36. /// <param name="nozzlesXmlConfiguration"></param>
  37. public PumpHandlerForSelfAuthPump(int pumpId, string nozzlesXmlConfiguration) : base(pumpId, nozzlesXmlConfiguration)
  38. {
  39. }
  40. public override void Process(IContext<byte[], NonICMessageTemplateBase> context)
  41. {
  42. this.context = context;
  43. if (context.Incoming.Message is GetNozzleStatusResponse getNozzleStatusResponse)
  44. {
  45. this.isSafeForSend = true;
  46. this.lastLogicalDeviceStateReceivedTime = DateTime.Now;
  47. //var getNozzleStatusResponse = context.Incoming.Message as GetNozzleStatusResponse;
  48. // put the price by reading the real price.
  49. this.nozzles.First().RealPriceOnPhysicalPump = getNozzleStatusResponse.单价;
  50. var latestStatus = getNozzleStatusResponse.GetPumpStatus();
  51. if (latestStatus.Any(f => f == GetNozzleStatusResponse.PumpStatus.允许加油)
  52. && latestStatus.Any(f => f == GetNozzleStatusResponse.PumpStatus.油枪打开)
  53. && latestStatus.Any(f => f == GetNozzleStatusResponse.PumpStatus.加油过程)
  54. && latestStatus.Any(f => f == GetNozzleStatusResponse.PumpStatus.电机打开))
  55. {
  56. //status code: B1
  57. logger.Debug("正处于加油状态下");
  58. /* 正处于加油状态下 */
  59. if (this.previousUnfinishedFuelingNozzleStatus != null && this.previousUnfinishedFuelingNozzleStatus.流水号 != getNozzleStatusResponse.流水号)
  60. {
  61. logger.Info("Detected a fast put back and pull out nozzle case(action time < polling time cause nozzle place back not detected)," +
  62. "\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 "
  63. + "seqNo: " + this.previousUnfinishedFuelingNozzleStatus.流水号
  64. + ", amount: " + this.previousUnfinishedFuelingNozzleStatus.加油金额
  65. + ", volume: " + this.previousUnfinishedFuelingNozzleStatus.加油金额
  66. + ", price: " + this.previousUnfinishedFuelingNozzleStatus.单价);
  67. logger.Info(" State switched to FDC_READY(simulate)");
  68. this.lastLogicalDeviceState = LogicalDeviceState.FDC_READY;
  69. this.FireOnStateChangeEvent(LogicalDeviceState.FDC_READY);
  70. this.FireOnCurrentFuellingStatusChangeEvent(new FdcTransaction()
  71. {
  72. // use previousUnfinishedFuelingNozzleStatus could miss reading the last trx correct numbers(less than actual number)
  73. //, obviously this is caused by pump hardware design, impossible to recovery it back by our application.
  74. Nozzle = this.nozzles.First(),
  75. Amount = this.previousUnfinishedFuelingNozzleStatus.加油金额,
  76. Volumn = this.previousUnfinishedFuelingNozzleStatus.加油量,
  77. Price = this.previousUnfinishedFuelingNozzleStatus.单价,
  78. SequenceNumberGeneratedOnPhysicalPump = this.previousUnfinishedFuelingNozzleStatus.流水号,
  79. Finished = true,
  80. });
  81. }
  82. this.previousUnfinishedFuelingNozzleStatus = getNozzleStatusResponse;
  83. if (this.lastLogicalDeviceState != LogicalDeviceState.FDC_FUELLING)
  84. {
  85. logger.Debug(" State switched to FDC_FUELLING");
  86. this.lastLogicalDeviceState = LogicalDeviceState.FDC_FUELLING;
  87. base.FireOnStateChangeEvent(LogicalDeviceState.FDC_FUELLING);
  88. }
  89. //fire fuelling progress.
  90. base.FireOnCurrentFuellingStatusChangeEvent(new FdcTransaction()
  91. {
  92. // 恒山油机只有一把枪
  93. Nozzle = this.nozzles.First(),
  94. Amount = getNozzleStatusResponse.加油金额,
  95. Volumn = getNozzleStatusResponse.加油量,
  96. Price = getNozzleStatusResponse.单价,
  97. SequenceNumberGeneratedOnPhysicalPump = getNozzleStatusResponse.流水号,
  98. Finished = false,
  99. });
  100. }
  101. else if (latestStatus.Any(f => f == GetNozzleStatusResponse.PumpStatus.不允许加油)
  102. && latestStatus.Any(f => f == GetNozzleStatusResponse.PumpStatus.加油结束))
  103. {
  104. /* 油机首次上电也会进入此处,并不断发送上一次的加油记录,这种情况下的交易记录并无法判断其之前是否已经发送至上层系统(比如是否已经存入数据库),
  105. 所以此处不判断而是往上层系统里送入,由系统判断重复情况。 而其它正常加油过程中的交易记录仅在油机状态变化时才送入系统。*/
  106. // status code: 40
  107. logger.Debug("收到状态: 加油结束");
  108. this.previousUnfinishedFuelingNozzleStatus = null;
  109. if (this.lastLogicalDeviceState != LogicalDeviceState.FDC_READY)
  110. {
  111. logger.Debug(" State switched to FDC_READY");
  112. lastLogicalDeviceState = LogicalDeviceState.FDC_READY;
  113. base.FireOnStateChangeEvent(LogicalDeviceState.FDC_READY);
  114. if (getNozzleStatusResponse.加油量 != 0 || getNozzleStatusResponse.加油金额 != 0)
  115. {
  116. base.FireOnCurrentFuellingStatusChangeEvent(new FdcTransaction()
  117. {
  118. // 恒山油机 一个加油点只有一把枪
  119. Nozzle = this.nozzles.First(),
  120. Amount = getNozzleStatusResponse.加油金额,
  121. Volumn = getNozzleStatusResponse.加油量,
  122. Price = getNozzleStatusResponse.单价,
  123. SequenceNumberGeneratedOnPhysicalPump = getNozzleStatusResponse.流水号,
  124. Finished = true,
  125. });
  126. }
  127. }
  128. }
  129. }
  130. else
  131. {
  132. base.Process(context);
  133. }
  134. }
  135. /// <summary>
  136. ///
  137. /// </summary>
  138. /// <param name="logicalNozzleId">useless for this type of pump, it always one pump one nozzle</param>
  139. /// <returns></returns>
  140. public override bool Authorize(byte logicalNozzleId)
  141. {
  142. return false;
  143. }
  144. /// <summary>
  145. ///
  146. /// </summary>
  147. /// <param name="moneyAmount"></param>
  148. /// <param name="logicalNozzleId">useless for this type of pump, it always one pump one nozzle</param>
  149. /// <returns></returns>
  150. public override bool AuthorizeWithAmount(int moneyAmount, byte logicalNozzleId)
  151. {
  152. return false;
  153. }
  154. /// <summary>
  155. ///
  156. /// </summary>
  157. /// <param name="volumn"></param>
  158. /// <param name="logicalNozzleId">useless for this type of pump, it always one pump one nozzle</param>
  159. /// <returns></returns>
  160. public override bool AuthorizeWithVolumn(int volumn, byte logicalNozzleId)
  161. {
  162. return false;
  163. }
  164. }
  165. }