IFdcPumpController.cs 10 KB

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