using Censtar_31064V105OrV106_Pump.MessageEntity; using Censtar_31064V105OrV106_Pump.MessageEntity.Outgoing; using Edge.Core.IndustryStandardInterface.Pump; using Edge.Core.Parser.BinaryParser.MessageEntity; using Edge.Core.Processor; using Edge.Core.UniversalApi; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using System.Threading.Tasks; namespace Censtar_31064V105OrV106_Pump { public class PumpGroupHandler : IEnumerable, IDeviceHandler { public enum DispenserModelEnum { Model_31064V105 = 0, Model_31064V106 = 1 } /// /// 加油后是否加锁标志 /// //public enum DispenserPostFuelingLockModeEnum //{ // 加油后加锁_不可解锁, // 加油后加锁_可解锁, // 加油后不加锁, // 室外解锁密码_3位长度密码, //} /// /// 控制加油枪授权出油的方式 /// public enum DispenserAuthorizeModeEnum { /// /// 感觉像是提枪就出油??? /// 开放 = 0, /// /// 加油机需要获得 “开机信号” 才可以出油。 /// 监控 = 1, } /// /// seems one dispenser is a basic comm unit?? /// public class DispenserParameter { public DispenserModelEnum? DispenserModel { get; set; } = DispenserModelEnum.Model_31064V105; public SetPostFuelingLockTypeRequest.LockTypeEnum? DispenserPostFuelingLockMode { get; set; } = SetPostFuelingLockTypeRequest.LockTypeEnum.加油后不加锁; public DispenserAuthorizeModeEnum? DispenserAuthorizeMode { get; set; } = DispenserAuthorizeModeEnum.监控; public class PumpParameter { /// /// seems the dispendser side has no this concept?? /// public int PumpId { get; set; } public int? AmountDecimalDigits { get; set; } = 2; public int? VolumeDecimalDigits { get; set; } = 2; public int? PriceDecimalDigits { get; set; } = 2; public int? VolumeTotalizerDecimalDigits { get; set; } = 2; public IEnumerable NozzleParameters { get; set; } } public class NozzleParameter { public byte NozzleNumber { get; set; } } public IEnumerable PumpParameters { get; set; } } private IContext context; private List pumpHandlers; private IServiceProvider services; static ILogger logger = NullLogger.Instance; public PumpGroupHandler(DispenserParameter dispenserParameter, IServiceProvider services) { this.CreatePumpHanlders(dispenserParameter); } public PumpGroupHandler(string rawUglyEncodedCommaJsonStr_Of_DispenserParameter, IServiceProvider services) { var loggerFactory = services.GetRequiredService(); logger = loggerFactory.CreateLogger("PumpHandler"); this.services = services; var jsonSerializerOptions = new JsonSerializerOptions() { WriteIndented = true, }; jsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); var decoded = rawUglyEncodedCommaJsonStr_Of_DispenserParameter.Replace("____UglyEncodedComma____", ","); var dispenserParameter = JsonSerializer.Deserialize(decoded, jsonSerializerOptions); this.CreatePumpHanlders(dispenserParameter); } private void CreatePumpHanlders(DispenserParameter dispenserParameter) { this.pumpHandlers = new List(); this.pumpHandlers.AddRange( dispenserParameter.PumpParameters.Select(pp => new StatePumpHandler(pp, services) { DispenserModel = dispenserParameter.DispenserModel.Value, DispenserAuthorizeMode = dispenserParameter.DispenserAuthorizeMode.Value, DispenserPostFuelingLockMode = dispenserParameter.DispenserPostFuelingLockMode.Value, AmountDecimalDigits = pp.AmountDecimalDigits.Value, PriceDecimalDigits = pp.PriceDecimalDigits.Value, VolumeDecimalDigits = pp.VolumeDecimalDigits.Value, VolumeTotalizerDecimalDigits = pp.VolumeTotalizerDecimalDigits.Value })); } public IEnumerator GetEnumerator() { return this.pumpHandlers.GetEnumerator(); } public void Init(IContext context) { this.context = context; this.pumpHandlers.ForEach(p => p.Init(this.context)); var timeWindowWithActivePollingOutgoing = this.context.Outgoing as TimeWindowWithActivePollingOutgoing; int previousPolledHandlerIndex = 0; var nozzlePhysicalIds = this.pumpHandlers.SelectMany(ph => ph.Nozzles.Select(n => n.PhysicalId)).ToList(); timeWindowWithActivePollingOutgoing.PollingMsgProducer = () => { if (this.pumpHandlers.Count <= previousPolledHandlerIndex) previousPolledHandlerIndex = 0; var nextNozzlePhysicalId = nozzlePhysicalIds[previousPolledHandlerIndex++]; return new ReadRealTimeData() { NozzleNumber = nextNozzlePhysicalId }; }; } public Task Process(IContext context) { this.context = context; var msg = ((MessageBase)(context.Incoming.Message)); var ph = this.pumpHandlers.FirstOrDefault(ph => ph.Nozzles.Select(n => n.PhysicalId).Contains(msg.NozzleNumber)); if (ph == null) { logger.LogInformation("PumpGroupHandler does not contain pumpHandler with NozzlePhyscialId: 0x" + msg.NozzleNumber.ToString("X2")); return Task.CompletedTask; } return ph.Process(context); } [UniversalApi] public Task ChangeFuelPriceAsync(int pumpId, int newPriceWithoutDecimalPoint, byte logicalNozzleId) { return this.pumpHandlers.FirstOrDefault(ph => ph.PumpId == pumpId)?.ChangeFuelPriceAsync(newPriceWithoutDecimalPoint, logicalNozzleId); } [UniversalApi] public Task> QueryTotalizerAsync(int pumpId, byte logicalNozzleId) { return this.pumpHandlers.FirstOrDefault(ph => ph.PumpId == pumpId)?.QueryTotalizerAsync(logicalNozzleId); } IEnumerator IEnumerable.GetEnumerator() { return this.pumpHandlers.GetEnumerator(); } } }