using System.IO.Ports; using System.Text; using System.Text.Json; using MoniteurBaie.DataModels; using MoniteurBaie.Utils; using StackExchange.Redis; namespace MoniteurBaie.SerialCom; public class Worker : BackgroundService { private readonly ILogger _logger; private readonly IConfiguration _configuration; public Worker(ILogger logger, IConfiguration configuration) { _logger = logger; _configuration = configuration; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { var config = _configuration.GetSection("MoniteurBaie"); var serialConfig = config.GetSection("Serial"); var redisConfig = config.GetSection("Redis"); using IBatteryController batteryController = config.GetValue("Mock") ? new MockBatteryController() : new BatteryController(_logger, serialPort => { serialPort.PortName = serialConfig.GetValue("Path")!; serialPort.BaudRate = serialConfig.GetValue("BaudRate"); serialPort.Parity = serialConfig.GetValue("Parity"); serialPort.DataBits = serialConfig.GetValue("DataBits"); serialPort.StopBits = serialConfig.GetValue("StopBits"); serialPort.Handshake = serialConfig.GetValue("Handshake"); serialPort.Encoding = Encoding.GetEncoding(serialConfig.GetValue("Encoding")!); serialPort.NewLine = serialConfig.GetValue("NewLine")!; }); await batteryController.Open(stoppingToken); using var redis = await ConnectionMultiplexer.ConnectAsync(redisConfig.GetValue("Endpoint")!, opts => { opts.ClientName = redisConfig.GetValue("ClientName"); }); using var dataApi = new DataApi(_logger, config.GetSection("Api")); var redisChannel = redisConfig.GetValue("Channels:Packets")!; batteryController.AddSerialObserver(Listener.Create((BatteryControllerPacket packet) => { var dataPacket = JsonSerializer.Serialize(packet, BatteryControllerPacketContext.Default.BatteryControllerPacket); redis.GetSubscriber().Publish(redisChannel, dataPacket, CommandFlags.FireAndForget); dataApi.Send(packet); })); var mq = await redis.GetSubscriber().SubscribeAsync(redisConfig.GetValue("Channels:Commands")!); mq.OnMessage(channelMessage => batteryController.SendCommand(channelMessage.Message.ToString(), stoppingToken)); await Task.Delay(Timeout.Infinite, stoppingToken); } }