PumpGroupHandler.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. using Edge.Core.Processor;
  2. using Edge.Core.IndustryStandardInterface.Pump;
  3. using LanTian_Pump_664_Or_886.MessageEntity;
  4. using LanTian_Pump_664_Or_886.MessageEntity.Outgoing;
  5. using Microsoft.Extensions.DependencyInjection;
  6. using Microsoft.Extensions.Logging;
  7. using Microsoft.Extensions.Logging.Abstractions;
  8. using System;
  9. using System.Collections;
  10. using System.Collections.Generic;
  11. using System.Linq;
  12. using System.Text;
  13. using System.Threading.Tasks;
  14. using System.Text.Json;
  15. using System.Text.Json.Serialization;
  16. using Edge.Core.UniversalApi;
  17. using Edge.Core.Processor.Dispatcher.Attributes;
  18. using Edge.Core.Processor.Communicator;
  19. namespace LanTian_Pump_664_Or_886
  20. {
  21. public class PumpGroupParameter
  22. {
  23. public enum PumpModelEnum
  24. {
  25. // for all cases, this type of dispenser, like totalizer, amount, price data fields and etc., has smaller value range
  26. Model_664 = 0,
  27. // for all cases, this type of dispenser, like totalizer, amount, price data fields and etc., has wider value range
  28. Model_886 = 1
  29. }
  30. public enum PumpAuthorizeModeEnum
  31. {
  32. /// <summary>
  33. /// in this mode, dispenser need get fc authorized then can start fueling.
  34. /// </summary>
  35. FC_Authorize = 0,
  36. /// <summary>
  37. /// in this mode, dispenser can start fueling without authorize from fc, so lift nozzle, fueling start.
  38. /// </summary>
  39. Pump_Self_Authorize = 1,
  40. }
  41. public class PumpParameter
  42. {
  43. public int PumpId { get; set; }
  44. /// <summary>
  45. /// setup in physical dispenser side.
  46. /// </summary>
  47. public byte Address { get; set; }
  48. public PumpModelEnum? PumpModel { get; set; } = PumpModelEnum.Model_664;
  49. public PumpAuthorizeModeEnum? PumpAuthorizeMode { get; set; } = PumpAuthorizeModeEnum.FC_Authorize;
  50. public int? AmountDecimalDigits { get; set; } = 2;
  51. public int? VolumeDecimalDigits { get; set; } = 2;
  52. public int? PriceDecimalDigits { get; set; } = 2;
  53. public int? VolumeTotalizerDecimalDigits { get; set; } = 2;
  54. }
  55. public IEnumerable<PumpParameter> PumpParameters { get; set; }
  56. }
  57. [MetaPartsRequired(typeof(HalfDuplexActivePollingDeviceProcessor<,>))]
  58. [MetaPartsRequired(typeof(ComPortCommunicator<>))]
  59. [MetaPartsRequired(typeof(TcpClientCommunicator<>))]
  60. [MetaPartsDescriptor(
  61. "lang-zh-cn:蓝天加油机lang-en-us:BlueSky Pump",
  62. "lang-zh-cn:用于驱动蓝天协议的加油机lang-en-us:Used for driven BlueSky Pump which use BlueSky Protocol",
  63. new[] { "lang-zh-cn:加油机lang-en-us:Pump" })]
  64. public class PumpGroupHandler : IEnumerable<IFdcPumpController>, IDeviceHandler<byte[], MessageBase>
  65. {
  66. private IContext<byte[], MessageBase> context;
  67. private List<StatePumpHandler> pumpHandlers;
  68. private IServiceProvider services;
  69. static ILogger logger = NullLogger.Instance;
  70. public PumpGroupHandler(string rawUglyEncodedCommaJsonStr, IServiceProvider services)
  71. {
  72. this.services = services;
  73. var loggerFactory = services.GetRequiredService<ILoggerFactory>();
  74. logger = loggerFactory.CreateLogger("PumpHandler");
  75. var jsonSerializerOptions = new JsonSerializerOptions()
  76. {
  77. WriteIndented = true,
  78. };
  79. jsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
  80. var decoded = rawUglyEncodedCommaJsonStr.Replace("____UglyEncodedComma____", ",");
  81. var pumpGroupParameter = System.Text.Json.JsonSerializer.Deserialize<PumpGroupParameter>(decoded, jsonSerializerOptions);
  82. this.CreatePumpHandlers(pumpGroupParameter);
  83. }
  84. [ParamsJsonSchemas("PumpGroupHandlerCtorParamsJsonSchemas")]
  85. public PumpGroupHandler(PumpGroupParameter pumpGroupParameter, IServiceProvider services)
  86. {
  87. this.services = services;
  88. var loggerFactory = services.GetRequiredService<ILoggerFactory>();
  89. logger = loggerFactory.CreateLogger("PumpHandler");
  90. this.CreatePumpHandlers(pumpGroupParameter);
  91. }
  92. private void CreatePumpHandlers(PumpGroupParameter pumpGroupParameter)
  93. {
  94. this.pumpHandlers = new List<StatePumpHandler>();
  95. this.pumpHandlers.AddRange(pumpGroupParameter.PumpParameters.Select(p =>
  96. new StatePumpHandler(p.PumpId, p.Address, p.PumpModel.Value, p.PumpAuthorizeMode.Value,
  97. p.AmountDecimalDigits.Value, p.VolumeDecimalDigits.Value, p.PriceDecimalDigits.Value,
  98. p.VolumeTotalizerDecimalDigits.Value,
  99. this.services)));
  100. }
  101. public IEnumerator<IFdcPumpController> GetEnumerator()
  102. {
  103. return this.pumpHandlers.GetEnumerator();
  104. }
  105. public void Init(IContext<byte[], MessageBase> context)
  106. {
  107. this.context = context;
  108. this.pumpHandlers.ForEach(p => p.Init(this.context));
  109. var timeWindowWithActivePollingOutgoing =
  110. this.context.Outgoing as TimeWindowWithActivePollingOutgoing<byte[], MessageBase>;
  111. int previousPolledHandlerIndex = 0;
  112. timeWindowWithActivePollingOutgoing.PollingMsgProducer = () =>
  113. {
  114. if (this.pumpHandlers.Count <= previousPolledHandlerIndex)
  115. previousPolledHandlerIndex = 0;
  116. var target = this.pumpHandlers[previousPolledHandlerIndex++];
  117. return new ReadPumpStateRequest() { Adrs = (byte)target.PumpPhysicalId };
  118. };
  119. }
  120. public Task Process(IContext<byte[], MessageBase> context)
  121. {
  122. this.context = context;
  123. var ph = this.pumpHandlers.FirstOrDefault(p => (byte)(p.PumpPhysicalId) == context.Incoming.Message.Adrs);
  124. if (ph == null)
  125. {
  126. logger.LogInformation("PumpGroupHandler does not contain pumpHandler with physcialId: "
  127. + context.Incoming.Message.Adrs.ToString("X2"));
  128. return Task.CompletedTask;
  129. }
  130. return ph.Process(context);
  131. }
  132. IEnumerator IEnumerable.GetEnumerator()
  133. {
  134. return this.pumpHandlers.GetEnumerator();
  135. }
  136. [UniversalApi]
  137. public Task<bool> ChangeFuelPriceAsync(int pumpId, int newPriceWithoutDecimalPoint, byte logicalNozzleId)
  138. {
  139. return this.pumpHandlers.FirstOrDefault(ph => ph.PumpId == pumpId)?.ChangeFuelPriceAsync(newPriceWithoutDecimalPoint, logicalNozzleId);
  140. }
  141. [UniversalApi]
  142. public Task<System.Tuple<int, int>> QueryTotalizerAsync(int pumpId, byte logicalNozzleId)
  143. {
  144. return this.pumpHandlers.FirstOrDefault(ph => ph.PumpId == pumpId)?.QueryTotalizerAsync(logicalNozzleId);
  145. }
  146. }
  147. }