using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using Timer = System.Timers.Timer;
using System.Collections;
using Edge.Core.Processor;
using Edge.Core.IndustryStandardInterface.Pump;
using Wayne.FDCPOSLibrary;
using System.Xml;
using Edge.Core.Database.Models;
using System.Threading.Tasks;
using Edge.Core.Processor.Communicator;
using Edge.Core.Processor.Dispatcher.Attributes;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Stateless;
using Edge.Core.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace Gilbarco_Pump
{
#region Ctor parameters
public class PumpGroupConfig
{
///
/// 数据发送端的地址编号
/// 一般是指FCC? 则应该是一个全局共享值,放0xE0
///
public byte FccCommAddress { get; set; } = 0xE0;
///
/// 数据接收端的地址编号
/// 指油机端的配置值,应该是每个通讯链路都不一样,一个链路上可能有1个或者多个加油点
///
public byte DispenserCommBoardAddress { get; set; }
public List PumpConfigs { get; set; }
}
public class PumpConfig
{
///
/// used by Fcc inside, the classic pump id concept.
///
public byte PumpId { get; set; }
///
/// 枪号为以整个加油站为基础的油枪顺序编号
/// 就是全站枪号?
///
public byte DispenserSideNozzleId { get; set; }
}
#endregion
///
/// 协议支持5787bps,8 位数据位,1 位起始位,1 位停止位,Even校验位
///
[MetaPartsRequired(typeof(HalfDuplexActivePollingDeviceProcessor<,>))]
[MetaPartsRequired(typeof(ComPortCommunicator<>))]
[MetaPartsRequired(typeof(TcpClientCommunicator<>))]
[MetaPartsDescriptor(
"lang-zh-cn:吉尔巴克加油机lang-en-us:Gilbarco dispenser",
"用于驱动 吉尔巴克 加油机",
new[] { "lang-zh-cn:加油机lang-en-us:Pump" })]
public class PumpGroupHandler : IEnumerable, IDeviceHandler
{
private IServiceProvider services;
private ILogger logger = NullLogger.Instance;
public PumpGroupConfig pumpGroupConfig;
protected IEnumerable nozzleExtraInfos;
protected IContext context;
protected IEnumerable pumpHandlers;
private object rotateFrameNo_Guard = new object();
///
///
private byte rotateFrameNo = 0;
///
/// get a valid FrameNo which from >=1 and <= 0x3F.
///
///
public byte GenerateNewFrameNo()
{
lock (this.rotateFrameNo_Guard)
{
//return 0;
if (this.rotateFrameNo > 0x3E)
this.rotateFrameNo = 0;
return (byte)(++this.rotateFrameNo);
}
}
[ParamsJsonSchemas("PumpGroupHandlerCtorParamsJsonSchemas")]
public PumpGroupHandler(PumpGroupConfig pumpGroupConfig, IServiceProvider services)
{
this.pumpGroupConfig = pumpGroupConfig;
this.services = services;
var loggerFactory = services.GetRequiredService();
this.logger = loggerFactory.CreateLogger("PumpHandler");
this.pumpHandlers =
pumpGroupConfig.PumpConfigs.Select(pc =>
new StatePumpHandler(this, pc.PumpId, pc.DispenserSideNozzleId, services)).ToList();
}
public void OnFdcServerInit(Dictionary parameters)
{
if (parameters != null && parameters.TryGetValue("NozzleProductMapping", out object param))
{
this.nozzleExtraInfos = param as IEnumerable;
}
}
public void Init(IContext context)
{
this.context = context;
var timeWindowWithActivePollingOutgoing =
this.context.Outgoing as TimeWindowWithActivePollingOutgoing;
//this.pollingInterval = timeWindowWithActivePollingOutgoing.PollingInterval;
timeWindowWithActivePollingOutgoing.PollingMsgProducer =
() =>
{
return null;
};
this.pumpHandlers.ToList().ForEach(p => p.Init(this.context));
this.context.Incoming.OnLongTimeNoSeeMessage += (_, __) =>
{
this.pumpHandlers.ToList().ForEach(p => p.TriggerPumpOffline());
};
this.context.Incoming.LongTimeNoSeeMessageTimeout = 6000;
}
public async Task Process(IContext context)
{
this.context = context;
foreach (var ph in this.pumpHandlers)
await ph.Process(context);
}
public IEnumerator GetEnumerator()
{
return this.pumpHandlers.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.pumpHandlers.GetEnumerator();
}
}
}