using Edge.Core.Processor;
using Edge.Core.IndustryStandardInterface.Pump;
using LanTian_Pump_664_Or_886.MessageEntity;
using LanTian_Pump_664_Or_886.MessageEntity.Outgoing;
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.Threading.Tasks;
using System.Text.Json;
using System.Text.Json.Serialization;
using Edge.Core.UniversalApi;
using Edge.Core.Processor.Dispatcher.Attributes;
using Edge.Core.Processor.Communicator;
namespace LanTian_Pump_664_Or_886
{
public class PumpGroupParameter
{
public enum PumpModelEnum
{
// for all cases, this type of dispenser, like totalizer, amount, price data fields and etc., has smaller value range
Model_664 = 0,
// for all cases, this type of dispenser, like totalizer, amount, price data fields and etc., has wider value range
Model_886 = 1
}
public enum PumpAuthorizeModeEnum
{
///
/// in this mode, dispenser need get fc authorized then can start fueling.
///
FC_Authorize = 0,
///
/// in this mode, dispenser can start fueling without authorize from fc, so lift nozzle, fueling start.
///
Pump_Self_Authorize = 1,
}
public class PumpParameter
{
public int PumpId { get; set; }
///
/// setup in physical dispenser side.
///
public byte Address { get; set; }
public PumpModelEnum? PumpModel { get; set; } = PumpModelEnum.Model_664;
public PumpAuthorizeModeEnum? PumpAuthorizeMode { get; set; } = PumpAuthorizeModeEnum.FC_Authorize;
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 PumpParameters { get; set; }
}
[MetaPartsRequired(typeof(HalfDuplexActivePollingDeviceProcessor<,>))]
[MetaPartsRequired(typeof(ComPortCommunicator<>))]
[MetaPartsRequired(typeof(TcpClientCommunicator<>))]
[MetaPartsDescriptor(
"lang-zh-cn:蓝天加油机lang-en-us:BlueSky Pump",
"lang-zh-cn:用于驱动蓝天协议的加油机lang-en-us:Used for driven BlueSky Pump which use BlueSky Protocol",
new[] { "lang-zh-cn:加油机lang-en-us:Pump" })]
public class PumpGroupHandler : IEnumerable, IDeviceHandler
{
private IContext context;
private List pumpHandlers;
private IServiceProvider services;
static ILogger logger = NullLogger.Instance;
public PumpGroupHandler(string rawUglyEncodedCommaJsonStr, IServiceProvider services)
{
this.services = services;
var loggerFactory = services.GetRequiredService();
logger = loggerFactory.CreateLogger("PumpHandler");
var jsonSerializerOptions = new JsonSerializerOptions()
{
WriteIndented = true,
};
jsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
var decoded = rawUglyEncodedCommaJsonStr.Replace("____UglyEncodedComma____", ",");
var pumpGroupParameter = System.Text.Json.JsonSerializer.Deserialize(decoded, jsonSerializerOptions);
this.CreatePumpHandlers(pumpGroupParameter);
}
[ParamsJsonSchemas("PumpGroupHandlerCtorParamsJsonSchemas")]
public PumpGroupHandler(PumpGroupParameter pumpGroupParameter, IServiceProvider services)
{
this.services = services;
var loggerFactory = services.GetRequiredService();
logger = loggerFactory.CreateLogger("PumpHandler");
this.CreatePumpHandlers(pumpGroupParameter);
}
private void CreatePumpHandlers(PumpGroupParameter pumpGroupParameter)
{
this.pumpHandlers = new List();
this.pumpHandlers.AddRange(pumpGroupParameter.PumpParameters.Select(p =>
new StatePumpHandler(p.PumpId, p.Address, p.PumpModel.Value, p.PumpAuthorizeMode.Value,
p.AmountDecimalDigits.Value, p.VolumeDecimalDigits.Value, p.PriceDecimalDigits.Value,
p.VolumeTotalizerDecimalDigits.Value,
this.services)));
}
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;
timeWindowWithActivePollingOutgoing.PollingMsgProducer = () =>
{
if (this.pumpHandlers.Count <= previousPolledHandlerIndex)
previousPolledHandlerIndex = 0;
var target = this.pumpHandlers[previousPolledHandlerIndex++];
return new ReadPumpStateRequest() { Adrs = (byte)target.PumpPhysicalId };
};
}
public Task Process(IContext context)
{
this.context = context;
var ph = this.pumpHandlers.FirstOrDefault(p => (byte)(p.PumpPhysicalId) == context.Incoming.Message.Adrs);
if (ph == null)
{
logger.LogInformation("PumpGroupHandler does not contain pumpHandler with physcialId: "
+ context.Incoming.Message.Adrs.ToString("X2"));
return Task.CompletedTask;
}
return ph.Process(context);
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.pumpHandlers.GetEnumerator();
}
[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);
}
}
}