using InnovEnergy.Lib.Protocols.Modbus.Clients; using InnovEnergy.Lib.Protocols.Modbus.Slaves; using InnovEnergy.Lib.Units.Composite; using InnovEnergy.Lib.Utils; namespace InnovEnergy.Lib.Devices.AMPT; public class AmptDevice { private readonly ModbusDevice _CommunicationUnit; private readonly IEnumerable> _StringOptimizers; public AmptDevice(ModbusClient modbusClient) { _CommunicationUnit = new ModbusDevice(modbusClient); _StringOptimizers = StringOptimizers(modbusClient); } public AmptStatus? Read() { var cuStatus = _CommunicationUnit.Read(); if (cuStatus.NumberOfStrings == 0) return default; var rs = _StringOptimizers .Take(cuStatus.NumberOfStrings) .Select(so => so.Read()) .ToArray(cuStatus.NumberOfStrings); var busVoltage = rs.Average(r => r.Voltage); var busCurrent = rs.Sum(r => r.Current); var strings = rs.SelectMany(GetStrings).ToArray(rs.Length * 2); return new AmptStatus ( Dc : DcBus.FromVoltageCurrent(busVoltage, busCurrent), Strings: strings ); } private static IEnumerable GetStrings(StringOptimizerRegisters r) { yield return DcBus.FromVoltageCurrent(r.String1Voltage, r.String1Current); yield return DcBus.FromVoltageCurrent(r.String2Voltage, r.String2Current); } private static IEnumerable> StringOptimizers(ModbusClient modbusClient) { var cache = new List>(); ModbusDevice GetOptimizer(Int32 i) { if (i < cache.Count) return cache[i]; var modbusDevice = new ModbusDevice(modbusClient, i * 16); return modbusDevice.Apply(cache.Add); } return Enumerable .Range(0, Byte.MaxValue) .Select(GetOptimizer); } }