IFdcPumpController.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. using Edge.Core.Parser;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using Wayne.FDCPOSLibrary;
  8. namespace Edge.Core.IndustryStandardInterface.Pump
  9. {
  10. /// <summary>
  11. /// Implements this interface indicates the class have the ability to control the physical
  12. /// pump and expose the controller interface by following Fdc pattern.
  13. /// </summary>
  14. public interface IFdcPumpController //: IDeviceController
  15. {
  16. event EventHandler<FdcPumpControllerOnStateChangeEventArg> OnStateChange;
  17. event EventHandler<FdcTransactionDoneEventArg> OnCurrentFuellingStatusChange;
  18. /// <summary>
  19. /// will be called once Fdc server starting.
  20. /// Fdc server will pass in necessary parameters via this function to each FdcPumpController.
  21. /// </summary>
  22. /// <param name="parameters"></param>
  23. void OnFdcServerInit(Dictionary<string, object> parameters);
  24. string Name { get; }
  25. /// <summary>
  26. /// Gets the Identification of the pump for the system. Is the logical number of the pump.
  27. /// e.g.: A site may have 4 physical pumps, each physical pump have 2 sides(fuelling point), then it's the
  28. /// pump id from 1 to 8.
  29. /// Then may have the model of physical pump with 6 nozzels, 3 for each side, but each side may grouped into 2 fuelling points,
  30. /// the first fuelling point in one side contains 1 nozzel, while the second contains 2 nozzels, so in this case,
  31. /// this physical pump actually have 4 fuelling points, also means this physical pump should have 4 pump ids.
  32. /// </summary>
  33. int PumpId { get; }
  34. /// <summary>
  35. /// Gets the internal identification of the fuelling position.
  36. /// Most likely it'll be only used in binary protocol parsing level.
  37. /// At least for Wayne pump, it can configed an internal address for each fuelling position via physical pump main board,
  38. /// this Id is critical for the case of multiple Pumps connected into one ComPort.
  39. /// If a device didn't have to check binary message with this id, then put any value for it.
  40. /// </summary>
  41. int PumpPhysicalId { get; }
  42. IEnumerable<LogicalNozzle> Nozzles { get; }
  43. /// <summary>
  44. /// Gets the money/amount digits.
  45. /// the Money/amount value read from pump is always an int value, need convert with this digits settings to readable format.
  46. /// </summary>
  47. int AmountDecimalDigits { get; }
  48. /// <summary>
  49. /// Gets the volume digits
  50. /// </summary>
  51. int VolumeDecimalDigits { get; }
  52. /// <summary>
  53. /// price digits typically not the same with Amount digits
  54. /// </summary>
  55. int PriceDecimalDigits { get; }
  56. int VolumeTotalizerDecimalDigits { get; }
  57. Task<LogicalDeviceState> QueryStatusAsync();
  58. /// <summary>
  59. ///
  60. /// </summary>
  61. /// <returns>MoneyTotalizer:VolumnTotalizer</returns>
  62. Task<Tuple<int, int>> QueryTotalizerAsync(byte logicalNozzleId);
  63. //string QueryConfiguration();
  64. Task<bool> SuspendFuellingAsync();
  65. Task<bool> ResumeFuellingAsync();
  66. Task<bool> ChangeFuelPriceAsync(int newPriceWithoutDecimalPoint, byte logicalNozzleId);
  67. Task<bool> AuthorizeAsync(byte logicalNozzleId);
  68. Task<bool> UnAuthorizeAsync(byte logicalNozzleId);
  69. Task<bool> AuthorizeWithAmountAsync(int moneyAmountWithoutDecimalPoint, byte logicalNozzleId);
  70. Task<bool> AuthorizeWithVolumeAsync(int volumnWithoutDecimalPoint, byte logicalNozzleId);
  71. /// <summary>
  72. /// 凑整
  73. /// </summary>
  74. /// <param name="amount">expecting fueling to this amount, value is without decimal point</param>
  75. /// <returns></returns>
  76. Task<bool> FuelingRoundUpByAmountAsync(int amount);
  77. /// <summary>
  78. /// 凑整
  79. /// </summary>
  80. /// <param name="amount">expecting fueling to this volum, value is without decimal point</param>
  81. /// <returns></returns>
  82. Task<bool> FuelingRoundUpByVolumeAsync(int volume);
  83. /// <summary>
  84. /// lock a nozzle for not allow it for fueling
  85. /// </summary>
  86. /// <param name="logicalNozzleId"></param>
  87. /// <returns></returns>
  88. Task<bool> LockNozzleAsync(byte logicalNozzleId);
  89. /// <summary>
  90. /// unlock a locked nozzle
  91. /// </summary>
  92. /// <param name="logicalNozzleId"></param>
  93. /// <returns></returns>
  94. Task<bool> UnlockNozzleAsync(byte logicalNozzleId);
  95. }
  96. /// <summary>
  97. /// 每把逻辑枪代表着能加出某个油品的虚拟枪。
  98. /// 大多数情况下逻辑枪数==物理枪数。
  99. /// 存在一把物理枪可以加出三种油的情况,这种情况下,即为三把逻辑枪,但共用一个Physical Id.
  100. /// </summary>
  101. public class LogicalNozzle
  102. {
  103. private LogicalNozzle() { }
  104. /// <summary>
  105. ///
  106. /// </summary>
  107. /// <param name="pumpId">the pump(FuelPoint) id of this nozzle is hosted</param>
  108. /// <param name="physicalId"></param>
  109. /// <param name="logicalId">must >=1</param>
  110. /// <param name="realPriceOnPhysicalPump"></param>
  111. public LogicalNozzle(int pumpId, byte physicalId, byte logicalId, int? realPriceOnPhysicalPump)
  112. {
  113. if (logicalId < 1) throw new ArgumentException("Nozzle logical id must be >=1");
  114. this.PumpId = pumpId;
  115. this.RealPriceOnPhysicalPump = realPriceOnPhysicalPump;
  116. this.PhysicalId = physicalId;
  117. this.LogicalId = logicalId;
  118. }
  119. public int PumpId { get; }
  120. /// <summary>
  121. /// nozzle PhysicalId should be assgined at hardware level for a physical pump.
  122. /// so it's device dependent, can be confirmed in Pump comm protocol doc.
  123. /// like in Ifsf protocol, physical id for a nozzle is from 0x11 - 0x18.
  124. /// like in Wayne dart protocol, physical id for na nozzle is from 1 - 8.
  125. /// a physical nozzle may have multiple fuel products assgined(blending).
  126. /// most likely it will repeat in each individual pump.
  127. /// </summary>
  128. public byte PhysicalId { get; }
  129. /// <summary>
  130. /// Gets or sets the logical id for a nozzle, value must range from 1 to N.
  131. /// in LiteFcc, we follow the rule of, that you face to a FuelPoint,
  132. /// the most left side nozzle is always logicalId 1,
  133. /// and the nozzle right to it, it's 2, and then 3...
  134. /// </summary>
  135. public byte LogicalId { get; }
  136. /// <summary>
  137. /// Gets or sets the real price which read from physical pump, without decimal points.
  138. /// some pumps can get price when first time FC connected to it, but some are not.
  139. /// So it may null though the physical pump side price is set (have not read by FC).
  140. /// So it may diff from the FC side value(by a failure in price change request, and that value will be saved into db)
  141. ///
  142. /// </summary>
  143. public int? RealPriceOnPhysicalPump { get; set; }
  144. /// <summary>
  145. /// Gets or sets the expecting price which set from FC side, without decimal points.
  146. /// FC side could change the pump price (via price change request), this value will send to physical
  147. /// pump and finally saved into FC db.
  148. /// but this does NOT gurantee the consistent since the comm between the FC and pump may fail.
  149. /// </summary>
  150. public int? ExpectingPriceOnFcSide { get; set; }
  151. /// <summary>
  152. /// Gets or sets the vol totalizer value for this nozzle, without decimal points.
  153. /// </summary>
  154. public int? VolumeTotalizer { get; set; }
  155. public LogicalDeviceState? LogicalState { get; set; }
  156. }
  157. public class FdcTransactionDoneEventArg : System.EventArgs
  158. {
  159. public FdcTransactionDoneEventArg(FdcTransaction transaction)
  160. {
  161. this.Transaction = transaction;
  162. }
  163. public FdcTransaction Transaction { get; private set; }
  164. }
  165. public class FdcTransaction
  166. {
  167. public LogicalNozzle Nozzle { get; set; }
  168. /// <summary>
  169. /// without decimal points
  170. /// </summary>
  171. public int Amount { get; set; }
  172. /// <summary>
  173. /// without decimal points
  174. /// </summary>
  175. public int Volumn { get; set; }
  176. /// <summary>
  177. /// without decimal points
  178. /// </summary>
  179. public int Price { get; set; }
  180. public int Barcode { get; set; }
  181. /// <summary>
  182. /// Gets or set the seq number which typically generated on phsyical pump side for
  183. /// unique a trx, for most pumps, the number will be rotate and reused after a period of time,
  184. /// this is fine since FDC server side check the duplication only by a short time period range,
  185. /// not the full range scan.
  186. /// for some pumps, it didn't have this value at all, then need generate one in FC pump handler side,
  187. /// an unique value is requried.
  188. /// </summary>
  189. public int SequenceNumberGeneratedOnPhysicalPump { get; set; }
  190. /// <summary>
  191. /// the money amount totalizer value after this new trx done, without decimal points.
  192. /// the trx from a pump may not carry on amount totalizer value, it device dependent.
  193. /// </summary>
  194. public int? AmountTotalizer { get; set; }
  195. /// <summary>
  196. /// the volume amount totalizer value after this new trx done, without decimal points.
  197. /// the trx from a pump may not carry on volume totalizer value, it device dependent.
  198. /// </summary>
  199. public int? VolumeTotalizer { get; set; }
  200. /// <summary>
  201. /// Gets or sets if the fueling transaction still on going.
  202. /// True for transaction is done, False for on going.
  203. /// </summary>
  204. public bool Finished { get; set; }
  205. /// <summary>
  206. /// Gets or sets the start time of this fuel trx.
  207. /// leave it null will set it to: (SaleEndTime - x minutues), the default x is 3 and could be changed in future in FdcServerApp.
  208. /// </summary>
  209. public DateTime? SaleStartTime { get; set; }
  210. /// <summary>
  211. /// Gets or sets the end time of this fuel trx.
  212. /// leave it null will set it to DateTime.Now in FdcServerApp.
  213. /// </summary>
  214. public DateTime? SaleEndTime { get; set; }
  215. }
  216. }