Add serial number.

Add second AMPT
This commit is contained in:
atef 2025-06-24 11:48:12 +02:00
parent 5bcb90f0c0
commit eeb949bdfa
5 changed files with 40 additions and 35 deletions

View File

@ -13,24 +13,24 @@ namespace InnovEnergy.App.SodiStoreMax.Ess;
public record StatusRecord public record StatusRecord
{ {
public required AcDcDevicesRecord AcDc { get; init; } public required AcDcDevicesRecord AcDc { get; init; }
public required DcDcDevicesRecord DcDc { get; init; } public required DcDcDevicesRecord DcDc { get; init; }
public required BatteryDeligreenRecords? Battery { get; init; } public required BatteryDeligreenRecords? Battery { get; init; }
public required EmuMeterRegisters? GridMeter { get; init; } public required EmuMeterRegisters? GridMeter { get; init; }
public required EmuMeterRegisters? LoadOnAcIsland { get; init; } public required EmuMeterRegisters? LoadOnAcIsland { get; init; }
public required AcPowerDevice? LoadOnAcGrid { get; init; } public required AcPowerDevice? LoadOnAcGrid { get; init; }
public required AmptStatus? PvOnAcGrid { get; init; } public required AmptStatus? PvOnAcGrid { get; init; }
public required AmptStatus? PvOnAcIsland { get; init; } public required AmptStatus? PvOnAcIsland { get; init; }
public required AcPowerDevice? AcGridToAcIsland { get; init; } public required AcPowerDevice? AcGridToAcIsland { get; init; }
public required DcPowerDevice? AcDcToDcLink { get; init; } public required DcPowerDevice? AcDcToDcLink { get; init; }
public required DcPowerDevice? LoadOnDc { get; init; } public required DcPowerDevice? LoadOnDc { get; init; }
public required IRelaysRecord? Relays { get; init; } public required IRelaysRecord? Relays { get; init; }
public required AmptStatus? PvOnDc { get; init; } public required IReadOnlyList<AmptStatus?> PvOnDc { get; init; }
public required DoepkeRegisters? Doepke { get; init; } public required DoepkeRegisters? Doepke { get; init; }
public required Config Config { get; set; } public required Config Config { get; set; }
public required SystemLog Log { get; init; } // TODO: init only public required SystemLog Log { get; init; } // TODO: init only
public required EssControl EssControl { get; set; } // TODO: init only public required EssControl EssControl { get; set; } // TODO: init only
public required StateMachine StateMachine { get; init; } public required StateMachine StateMachine { get; init; }
} }

View File

@ -57,6 +57,7 @@ internal static class Program
private static readonly Channel GridMeterChannel; private static readonly Channel GridMeterChannel;
private static readonly Channel IslandBusLoadChannel; private static readonly Channel IslandBusLoadChannel;
private static readonly Channel PvOnDc; private static readonly Channel PvOnDc;
private static readonly Channel SecondPvOnDc;
private static readonly Channel PvOnAcGrid; private static readonly Channel PvOnAcGrid;
private static readonly Channel PvOnAcIsland; private static readonly Channel PvOnAcIsland;
private static readonly Channel RelaysChannel; private static readonly Channel RelaysChannel;
@ -65,7 +66,7 @@ internal static class Program
// //
private const String _swVersionNumber =" V1.33.120625"; private const String SwVersionNumber =" V1.33.120625 beta";
private static Boolean _curtailFlag = false; private static Boolean _curtailFlag = false;
private const String VpnServerIp = "10.2.0.11"; private const String VpnServerIp = "10.2.0.11";
private static Boolean _subscribedToQueue = false; private static Boolean _subscribedToQueue = false;
@ -92,6 +93,7 @@ internal static class Program
GridMeterChannel = CreateChannel(d.GridMeterIp); GridMeterChannel = CreateChannel(d.GridMeterIp);
IslandBusLoadChannel = CreateChannel(d.IslandBusLoadMeterIp); IslandBusLoadChannel = CreateChannel(d.IslandBusLoadMeterIp);
PvOnDc = CreateChannel(d.PvOnDc); PvOnDc = CreateChannel(d.PvOnDc);
SecondPvOnDc = CreateChannel(d.SecondPvOnDc);
PvOnAcGrid = CreateChannel(d.PvOnAcGrid); PvOnAcGrid = CreateChannel(d.PvOnAcGrid);
PvOnAcIsland = CreateChannel(d.PvOnAcIsland); PvOnAcIsland = CreateChannel(d.PvOnAcIsland);
RelaysChannel = CreateChannel(d.RelaysIp); RelaysChannel = CreateChannel(d.RelaysIp);
@ -147,6 +149,7 @@ internal static class Program
var gridMeterDevice = new EmuMeterDevice(GridMeterChannel); var gridMeterDevice = new EmuMeterDevice(GridMeterChannel);
var acIslandLoadMeter = new EmuMeterDevice(IslandBusLoadChannel); var acIslandLoadMeter = new EmuMeterDevice(IslandBusLoadChannel);
var pvOnDcDevice = new AmptDevices(PvOnDc); var pvOnDcDevice = new AmptDevices(PvOnDc);
var secondPvOnDcDevice = new AmptDevices(SecondPvOnDc);
var pvOnAcGridDevice = new AmptDevices(PvOnAcGrid); var pvOnAcGridDevice = new AmptDevices(PvOnAcGrid);
var pvOnAcIslandDevice = new AmptDevices(PvOnAcIsland); var pvOnAcIslandDevice = new AmptDevices(PvOnAcIsland);
var doepkeDevice = new DoepkeDevice(DoepkeChannel); var doepkeDevice = new DoepkeDevice(DoepkeChannel);
@ -168,11 +171,14 @@ internal static class Program
var relays = saliMaxRelaysDevice.Read(); var relays = saliMaxRelaysDevice.Read();
var loadOnAcIsland = acIslandLoadMeter.Read(); var loadOnAcIsland = acIslandLoadMeter.Read();
var gridMeter = gridMeterDevice.Read(); var gridMeter = gridMeterDevice.Read();
var pvOnDc = pvOnDcDevice.Read(); var firstPvOnDc = pvOnDcDevice.Read();
var secondPvOnDc = secondPvOnDcDevice.Read();
var battery = batteryDevices.Read(); var battery = batteryDevices.Read();
var pvOnAcGrid = pvOnAcGridDevice.Read(); var pvOnAcGrid = pvOnAcGridDevice.Read();
var pvOnAcIsland = pvOnAcIslandDevice.Read(); var pvOnAcIsland = pvOnAcIslandDevice.Read();
var doepek = doepkeDevice.Read(); var doepek = doepkeDevice.Read();
IReadOnlyList<AmptStatus?> pvOnDc = new List<AmptStatus?> { firstPvOnDc, secondPvOnDc };
var gridBusToIslandBus = Topology.CalculateGridBusToIslandBusPower(pvOnAcIsland, loadOnAcIsland, acDc); var gridBusToIslandBus = Topology.CalculateGridBusToIslandBusPower(pvOnAcIsland, loadOnAcIsland, acDc);
@ -278,7 +284,6 @@ internal static class Program
record.EssControl = essControl; record.EssControl = essControl;
DistributePower(record, essControl); DistributePower(record, essControl);
//record.PerformLed(); //record.PerformLed();
@ -286,7 +291,7 @@ internal static class Program
WriteControl(record); WriteControl(record);
$"{record.StateMachine.State}: {record.StateMachine.Message}".WriteLine(); $"{record.StateMachine.State}: {record.StateMachine.Message}".WriteLine();
$"{DateTime.Now.Round(UpdateInterval).ToUnixTime()} : {DateTime.Now.Round(UpdateInterval):dd/MM/yyyy} : {_swVersionNumber}".WriteLine(); $"{DateTime.Now.Round(UpdateInterval).ToUnixTime()} : {DateTime.Now.Round(UpdateInterval):dd/MM/yyyy HH:mm:ss} : {SwVersionNumber}".WriteLine();
record.CreateTopologyTextBlock().WriteLine(); record.CreateTopologyTextBlock().WriteLine();

View File

@ -112,7 +112,8 @@ public class Config //TODO: let IE choose from config files (Json) and connect t
PvOnAcIsland = new() { Host = "true" , Port = 0 , DeviceState = DeviceState.Measured}, PvOnAcIsland = new() { Host = "true" , Port = 0 , DeviceState = DeviceState.Measured},
IslandBusLoadMeterIp = new() { Host = "localhost", Port = 5004, DeviceState = DeviceState.Measured}, IslandBusLoadMeterIp = new() { Host = "localhost", Port = 5004, DeviceState = DeviceState.Measured},
TruConvertAcIp = new() { Host = "localhost", Port = 5001, DeviceState = DeviceState.Measured}, TruConvertAcIp = new() { Host = "localhost", Port = 5001, DeviceState = DeviceState.Measured},
PvOnDc = new() { Host = "localhost", Port = 5005, DeviceState = DeviceState.Measured}, PvOnDc = new() { Host = "localhost", Port = 5005, DeviceState = DeviceState.Measured},
SecondPvOnDc = new() { Host = "localhost", Port = 5006, DeviceState = DeviceState.Measured},
LoadOnDc = new() { Host = "false" , Port = 0 , DeviceState = DeviceState.Measured}, LoadOnDc = new() { Host = "false" , Port = 0 , DeviceState = DeviceState.Measured},
TruConvertDcIp = new() { Host = "localhost", Port = 5002, DeviceState = DeviceState.Measured}, TruConvertDcIp = new() { Host = "localhost", Port = 5002, DeviceState = DeviceState.Measured},
BatteryIp = new() { Host = "localhost", Port = 5007, DeviceState = DeviceState.Measured}, BatteryIp = new() { Host = "localhost", Port = 5007, DeviceState = DeviceState.Measured},
@ -215,7 +216,8 @@ public class Config //TODO: let IE choose from config files (Json) and connect t
PvOnAcIsland = new() { Host = "false" , Port = 0 , DeviceState = DeviceState.Measured}, PvOnAcIsland = new() { Host = "false" , Port = 0 , DeviceState = DeviceState.Measured},
IslandBusLoadMeterIp = new() { Host = "10.0.4.2", Port = 502, DeviceState = DeviceState.Measured}, IslandBusLoadMeterIp = new() { Host = "10.0.4.2", Port = 502, DeviceState = DeviceState.Measured},
TruConvertAcIp = new() { Host = "10.0.2.1", Port = 502, DeviceState = DeviceState.Measured}, TruConvertAcIp = new() { Host = "10.0.2.1", Port = 502, DeviceState = DeviceState.Measured},
PvOnDc = new() { Host = "10.0.5.1", Port = 502, DeviceState = DeviceState.Measured}, PvOnDc = new() { Host = "10.0.5.1", Port = 502, DeviceState = DeviceState.Measured},
SecondPvOnDc = new() { Host = "10.0.5.2", Port = 502, DeviceState = DeviceState.Measured},
LoadOnDc = new() { Host = "false" , Port = 0 , DeviceState = DeviceState.Measured}, LoadOnDc = new() { Host = "false" , Port = 0 , DeviceState = DeviceState.Measured},
TruConvertDcIp = new() { Host = "10.0.3.1", Port = 502, DeviceState = DeviceState.Measured}, TruConvertDcIp = new() { Host = "10.0.3.1", Port = 502, DeviceState = DeviceState.Measured},
DoepkeIp = new() { Host = "10.0.6.1", Port = 502, DeviceState = DeviceState.Measured}, DoepkeIp = new() { Host = "10.0.6.1", Port = 502, DeviceState = DeviceState.Measured},

View File

@ -14,6 +14,7 @@ public class DeviceConfig
public required SalimaxDevice IslandBusLoadMeterIp { get; init; } public required SalimaxDevice IslandBusLoadMeterIp { get; init; }
public required SalimaxDevice TruConvertAcIp { get; init; } public required SalimaxDevice TruConvertAcIp { get; init; }
public required SalimaxDevice PvOnDc { get; init; } public required SalimaxDevice PvOnDc { get; init; }
public required SalimaxDevice SecondPvOnDc { get; init; }
public required SalimaxDevice LoadOnDc { get; init; } public required SalimaxDevice LoadOnDc { get; init; }
public required SalimaxDevice TruConvertDcIp { get; init; } public required SalimaxDevice TruConvertDcIp { get; init; }
public required SalimaxDevice DoepkeIp { get; init; } public required SalimaxDevice DoepkeIp { get; init; }

View File

@ -72,9 +72,9 @@ public static class Topology
var f = status.LoadOnAcIsland?.Ac.Power.Active; var f = status.LoadOnAcIsland?.Ac.Power.Active;
var g = status.AcDc.Dc.Power.Value; var g = status.AcDc.Dc.Power.Value;
var h = status.AcDcToDcLink?.Power.Value; var h = status.AcDcToDcLink?.Power.Value;
var i = status.PvOnDc?.Dc.Power.Value; var i = status.PvOnDc?.Sum(p => p?.Dc.Power.Value);
var k = status.DcDc.Dc.Link.Power.Value; var k = status.DcDc.Dc.Link.Power.Value;
var l = status.Battery is not null ? status.Battery.Power : 0; var l = status.Battery?.Power ?? 0;
var j = status.LoadOnDc?.Power.Value; var j = status.LoadOnDc?.Power.Value;
var d = status.AcGridToAcIsland?.Power.Active; var d = status.AcGridToAcIsland?.Power.Active;
var c = status.LoadOnAcGrid?.Power.Active; var c = status.LoadOnAcGrid?.Power.Active;
@ -332,10 +332,8 @@ public static class Topology
/////////////////// top /////////////////// /////////////////// top ///////////////////
var mppt = status.PvOnDc; var mppt = status.PvOnDc;
var totalStrings = mppt.Sum(p => p?.Strings.Count ?? 0); // or we can use mppt.Sum(p => p.NbrOfStrings)
var nStrings = mppt is not null var nStrings = "x" + totalStrings;
? "x" + mppt.Strings.Count
: "?";
var pvBox = TextBlock.FromString($"PV {nStrings}").Box(); var pvBox = TextBlock.FromString($"PV {nStrings}").Box();
var pvToBus = Flow.Vertical(i); var pvToBus = Flow.Vertical(i);
@ -482,9 +480,9 @@ public static class Topology
} }
//We are fake using the ampt instead of PvOnAc, We dont have a Pv on Ac at the moment and we don't have it classes :TODO //We are fake using the ampt instead of PvOnAc, We dont have a Pv on Ac at the moment and we don't have it classes :TODO
public static DcPowerDevice? CalculateAcDcToDcLink(AmptStatus? pvOnDc, DcDcDevicesRecord? dcDc, AcDcDevicesRecord acDc) public static DcPowerDevice? CalculateAcDcToDcLink(IReadOnlyList<AmptStatus?> pvOnDc, DcDcDevicesRecord? dcDc, AcDcDevicesRecord acDc)
{ {
var i = pvOnDc?.Dc.Power; var i = pvOnDc?.Sum(p => p?.Dc.Power ?? 0);
var k = dcDc?.Dc.Link.Power; // We don't check on the DcDc because this device is mandatory var k = dcDc?.Dc.Link.Power; // We don't check on the DcDc because this device is mandatory
var g = acDc?.Dc.Power; var g = acDc?.Dc.Power;
@ -513,10 +511,10 @@ public static class Topology
return new AcPowerDevice { Power = d }; return new AcPowerDevice { Power = d };
} }
public static DcPowerDevice? CalculateDcLoad(AcDcDevicesRecord? acDc, AmptStatus? pvOnDc, DcDcDevicesRecord? dcDc) public static DcPowerDevice? CalculateDcLoad(AcDcDevicesRecord? acDc, IReadOnlyList<AmptStatus?> pvOnDc, DcDcDevicesRecord? dcDc)
{ {
var h = acDc?.Dc.Power; // We don't check on the AcDc because this device is mandatory var h = acDc?.Dc.Power; // We don't check on the AcDc because this device is mandatory
var i = pvOnDc is not null? pvOnDc?.Dc.Power: 0; var i = pvOnDc?.Sum(p => p?.Dc.Power ?? 0);
var k = dcDc?.Dc.Link.Power; // We don't check on the DcDc because this device is mandatory var k = dcDc?.Dc.Link.Power; // We don't check on the DcDc because this device is mandatory
if (h is null || i is null || k is null) if (h is null || i is null || k is null)
@ -526,5 +524,4 @@ public static class Topology
return new DcPowerDevice { Power = j}; return new DcPowerDevice { Power = j};
} }
} }