StatePumpHandler.cs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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 Timer = System.Timers.Timer;
  10. using System.Collections;
  11. using Edge.Core.Processor;
  12. using Edge.Core.IndustryStandardInterface.Pump;
  13. using Wayne.FDCPOSLibrary;
  14. using System.Xml;
  15. using Edge.Core.Database.Models;
  16. using System.Threading.Tasks;
  17. using Edge.Core.Processor.Communicator;
  18. using Edge.Core.Processor.Dispatcher.Attributes;
  19. using Microsoft.Extensions.Logging;
  20. using Microsoft.Extensions.Logging.Abstractions;
  21. using Stateless;
  22. using Microsoft.Extensions.DependencyInjection;
  23. namespace Gilbarco_Pump
  24. {
  25. public class StatePumpHandler : IFdcPumpController//, IDeviceHandler<byte[], MessageTemplateBase>
  26. {
  27. private IServiceProvider services;
  28. private IContext<byte[], MessageTemplateBase> context;
  29. private ILogger logger = NullLogger.Instance;
  30. private PumpGroupHandler parent;
  31. private LogicalDeviceState currentState = LogicalDeviceState.FDC_OFFLINE;
  32. public event EventHandler<FdcPumpControllerOnStateChangeEventArg> OnStateChange;
  33. /// <summary>
  34. /// fired on fueling process is on going, the fuel amount should keep changing.
  35. /// </summary>
  36. public event EventHandler<FdcTransactionDoneEventArg> OnCurrentFuellingStatusChange;
  37. StateMachine<LogicalDeviceState, Trigger> stateless
  38. = new StateMachine<LogicalDeviceState, Trigger>(LogicalDeviceState.FDC_OFFLINE);
  39. protected List<LogicalNozzle> nozzles;
  40. public IEnumerable<LogicalNozzle> Nozzles => this.nozzles;
  41. protected enum Trigger
  42. {
  43. //AnyPumpMsgReceived,
  44. AnyPumpMsgHaveNotReceivedForWhile,
  45. NozzleLifted_And_开机,
  46. NozzleLifted_And_停机,
  47. NozzleReplaced_And_开机,
  48. NozzleReplaced_And_停机,
  49. NozzleFuelNumbersIsRunning,
  50. //PumpAuthorizedByFC,
  51. }
  52. public int AmountDecimalDigits => 2;
  53. public int VolumeDecimalDigits => 2;
  54. public int PriceDecimalDigits => 2;
  55. public int VolumeTotalizerDecimalDigits => 2;
  56. /// <summary>
  57. /// </summary>
  58. public int PumpId { get; private set; }
  59. /// <summary>
  60. /// will set it to 油机端的配置值,枪号为以整个加油站为基础的油枪顺序编号, 就是全站枪号
  61. /// </summary>
  62. public int PumpPhysicalId { get; private set; }
  63. public string Name => "ZhongSheng_NonIC_Pump";
  64. /// <summary>
  65. /// 每把枪就是一个Pump即一个加油点
  66. /// </summary>
  67. /// <param name="pumpId"></param>
  68. /// <param name="dispenserSideNozzleId">油机端的配置值,枪号为以整个加油站为基础的油枪顺序编号, 就是全站枪号?</param>
  69. public StatePumpHandler(PumpGroupHandler parent, byte pumpId,
  70. byte dispenserSideNozzleId, IServiceProvider services)
  71. {
  72. this.parent = parent;
  73. this.services = services;
  74. var loggerFactory = services.GetRequiredService<ILoggerFactory>();
  75. this.logger = loggerFactory.CreateLogger("PumpHandler");
  76. this.PumpId = pumpId;
  77. this.PumpPhysicalId = dispenserSideNozzleId;
  78. //每把枪就是一个Pump即一个加油点
  79. this.nozzles = new List<LogicalNozzle>() { new LogicalNozzle(pumpId, dispenserSideNozzleId, 1, null) };
  80. }
  81. internal void TriggerPumpOffline()
  82. {
  83. if (this.currentState != LogicalDeviceState.FDC_OFFLINE)
  84. {
  85. this.currentState = LogicalDeviceState.FDC_OFFLINE;
  86. this.OnStateChange?.Invoke(this, new FdcPumpControllerOnStateChangeEventArg(LogicalDeviceState.FDC_OFFLINE));
  87. }
  88. }
  89. public void Init(IContext<byte[], MessageTemplateBase> context)
  90. {
  91. this.context = context;
  92. }
  93. public async Task Process(IContext<byte[], MessageTemplateBase> context)
  94. {
  95. this.context = context;
  96. }
  97. public virtual async Task<LogicalDeviceState> QueryStatusAsync()
  98. {
  99. return this.currentState;
  100. }
  101. /// <summary>
  102. ///
  103. /// </summary>
  104. /// <returns>MoneyTotalizer:VolumnTotalizer</returns>
  105. public async Task<Tuple<int, int>> QueryTotalizerAsync(byte logicalNozzleId)
  106. {
  107. var result = new System.Tuple<int, int>(-1, -1);
  108. logger.LogDebug("Pump: " + this.PumpId + ", " + "Start QueryTotalizer pump with logical nozzle: " + logicalNozzleId);
  109. return result;
  110. }
  111. public virtual async Task<bool> ChangeFuelPriceAsync(int newPriceWithoutDecimalPoint, byte logicalNozzleId)
  112. {
  113. logger.LogDebug("Pump: " + this.PumpId + ", " + "start ChangeFuelPriceAsync pump with nozzle: " + logicalNozzleId);
  114. return false;
  115. }
  116. /// <summary>
  117. ///
  118. /// </summary>
  119. /// <param name="logicalNozzleId">useless for this type of pump, it always one pump one nozzle</param>
  120. /// <returns></returns>
  121. public virtual async Task<bool> AuthorizeAsync(byte logicalNozzleId)
  122. {
  123. logger.LogDebug("Pump: " + this.PumpId + ", " + "start AuthorizeAsync pump with nozzle: " + logicalNozzleId);
  124. return false;
  125. }
  126. /// <summary>
  127. ///
  128. /// </summary>
  129. /// <param name="moneyAmount"></param>
  130. /// <param name="logicalNozzleId">useless for this type of pump, it always one pump one nozzle</param>
  131. /// <returns></returns>
  132. public virtual async Task<bool> AuthorizeWithAmountAsync(int moneyAmountWithoutDecimalPoint, byte logicalNozzleId)
  133. {
  134. logger.LogDebug("Pump: " + this.PumpId + ", " + "start AuthorizeWithAmountAsync pump with amount: " + moneyAmountWithoutDecimalPoint + ", nozzle: " + logicalNozzleId);
  135. return false;
  136. }
  137. /// <summary>
  138. ///
  139. /// </summary>
  140. /// <param name="volumnWithoutDecimalPoint"></param>
  141. /// <param name="logicalNozzleId">useless for this type of pump, it always one pump one nozzle</param>
  142. /// <returns></returns>
  143. public virtual async Task<bool> AuthorizeWithVolumeAsync(int volumnWithoutDecimalPoint, byte logicalNozzleId)
  144. {
  145. logger.LogDebug("Pump: " + this.PumpId + ", " + "start AuthorizeWithVolumeAsync pump with volume: " + volumnWithoutDecimalPoint + ", nozzle: " + logicalNozzleId);
  146. return false;
  147. }
  148. public virtual async Task<bool> FuelingRoundUpByAmountAsync(int amount)
  149. {
  150. throw new NotImplementedException();
  151. }
  152. #region not implemented
  153. public async Task<bool> UnAuthorizeAsync(byte logicalNozzleId)
  154. {
  155. logger.LogDebug("Pump: " + this.PumpId + ", " + "start UnAuthorizeAsync pump with nozzle: " + logicalNozzleId);
  156. return false;
  157. }
  158. public async Task<bool> SuspendFuellingAsync()
  159. {
  160. throw new NotImplementedException();
  161. }
  162. public async Task<bool> ResumeFuellingAsync()
  163. {
  164. throw new NotImplementedException();
  165. }
  166. public async Task<bool> FuelingRoundUpByVolumeAsync(int volume)
  167. { throw new NotImplementedException(); }
  168. #endregion
  169. /// <summary>
  170. /// </summary>
  171. protected Dictionary<byte, FuelSaleTransaction> logicalNozzleIdToLastFuelSaleTrxMapping = new Dictionary<byte, FuelSaleTransaction>();
  172. public void OnFdcServerInit(Dictionary<string, object> parameters)
  173. {
  174. if (parameters.ContainsKey("LastPriceChange"))
  175. {
  176. }
  177. /* Load Last sale(from db) for void the case of FC accidently disconnect from Pump in fueling,
  178. and may cause a fueling trx gone from FC control */
  179. if (parameters.ContainsKey("LastFuelSaleTrx"))
  180. {
  181. // nozzle logical id:lastSale
  182. //var lastFuelSaleTrxes = parameters["LastFuelSaleTrx"] as Dictionary<byte, FuelSaleTransaction>;
  183. //foreach (var lastFuelSaleTrx in lastFuelSaleTrxes)
  184. //{
  185. // logger.Info("Pump: " + this.pumpId + ", OnFdcServerInit, load last fuel sale " +
  186. // "on logical nozzle: " + lastFuelSaleTrx.Key + " with value: " + lastFuelSaleTrx.Value);
  187. // this.logicalNozzleIdToLastFuelSaleTrxMapping.Remove(lastFuelSaleTrx.Key);
  188. // this.logicalNozzleIdToLastFuelSaleTrxMapping.Add(lastFuelSaleTrx.Key, lastFuelSaleTrx.Value);
  189. //}
  190. }
  191. }
  192. public async Task<bool> LockNozzleAsync(byte logicalNozzleId)
  193. {
  194. return false;
  195. }
  196. public async Task<bool> UnlockNozzleAsync(byte logicalNozzleId)
  197. {
  198. return false;
  199. }
  200. }
  201. }