Merge remote-tracking branch 'origin/main'

This commit is contained in:
Kim 2023-08-23 14:06:58 +02:00
commit 4435fb9774
2 changed files with 99 additions and 90 deletions

View File

@ -205,7 +205,7 @@ internal static class Program
WriteControl(record);
Topology.From(record).WriteLine();
record.CreateTopology().WriteLine();
//record.ToCsv().WriteLine();

View File

@ -1,6 +1,8 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using InnovEnergy.App.SaliMax.Ess;
using InnovEnergy.Lib.Devices.Battery48TL;
using InnovEnergy.Lib.StatusApi.Connections;
using InnovEnergy.Lib.Units;
using InnovEnergy.Lib.Units.Power;
using InnovEnergy.Lib.Utils;
@ -10,61 +12,68 @@ namespace InnovEnergy.App.SaliMax;
public static class Topology
{
public static TextBlock From(this StatusRecord s)
public static TextBlock CreateTopology(this StatusRecord status)
{
// Topology is built up from right to left
// Power Measurement Values
var islandTopology = status.CreateIslandTopology();
var inverterPower = s.AcDc.Ac.Power.Active;
var islandLoadPower = s.LoadOnAcIsland is not null
? s.LoadOnAcIsland.Ac.Power.Active
: 0; // TODO
// TODO: check ACDCs if AC is available and synced to find out if grid meter OR grid is unavailable
var islandTopology = CreateIslandTopology(s, islandLoadPower, inverterPower);
if (s.GridMeter is null) // no grid meter?
if (status.GridMeter is null) // no grid meter?
return islandTopology; // we're done
var gridBusColumn = GridBusColumn(s);
var gridBox = CreateGridBox(s);
var gridTopology = status.CreateGridTopology();
return status.ConnectGridToIslandTopology(gridTopology, islandTopology);
}
private static TextBlock ConnectGridToIslandTopology(this StatusRecord status, TextBlock gridTopology, TextBlock islandTopology)
{
var inverterPower = status.AcDc.Ac.Power.Active;
var islandLoadPower = status.LoadOnAcIsland is not null
? status.LoadOnAcIsland.Ac.Power.Active
: 0; // TODO
ActivePower islandToGridBusPower = inverterPower + islandLoadPower;
// return TextBlock
// .AlignCenterVertical
// (
// gridBox , Flow.Horizontal(s.GridMeter.Ac.Power.Active),
// gridBusColumn, Flow.Horizontal(islandToGridBusPower),
// islandTopology
// );
var gridTopology = TextBlock
.AlignCenterVertical
(
gridBox,
Flow.Horizontal(s.GridMeter.Ac.Power.Active),
gridBusColumn
);
return TextBlock.AlignCenterVertical
(
gridTopology,
Flow.Horizontal(islandToGridBusPower),
islandTopology
);
);
}
private static TextBlock CreateIslandTopology(StatusRecord s, ActivePower islandLoadPower, ActivePower inverterPower)
private static TextBlock CreateGridTopology(this StatusRecord status)
{
var dcBatteryPower = s.DcDc.Dc.Battery.Power;
var dcdcPower = s.DcDc.Dc.Link.Power;
Debug.Assert(status.GridMeter is not null);
var gridBusColumn = status.CreateGridBusColumn();
var gridBox = status.GridMeter.CreateGridBox();
var batteries = CreateBatteryColumn(s);
var dcBusColumn = CreateDcBusColumn(s);
var islandBusColumn = CreateIslandBusColumn(s, islandLoadPower);
var inverterBox = CreateInverterBox(s);
var dcDcBox = CreateDcDcBox(s);
return TextBlock
.AlignCenterVertical
(
gridBox,
Flow.Horizontal(status.GridMeter.Ac.Power.Active),
gridBusColumn
);
}
private static TextBlock CreateIslandTopology(this StatusRecord status)
{
var dcBatteryPower = status.DcDc.Dc.Battery.Power;
var dcdcPower = status.DcDc.Dc.Link.Power;
var inverterPower = status.AcDc.Ac.Power.Active;
var islandLoadPower = status.LoadOnAcIsland is not null
? status.LoadOnAcIsland.Ac.Power.Active
: 0; // TODO
var batteries = status.CreateBatteryColumn();
var dcBusColumn = status.CreateDcBusColumn();
var islandBusColumn = status.CreateIslandBusColumn(islandLoadPower);
var inverterBox = status.CreateInverterBox();
var dcDcBox = status.CreateDcDcBox();
return TextBlock
.AlignCenterVertical
@ -77,27 +86,26 @@ public static class Topology
);
}
private static TextBlock CreateGridBox(StatusRecord statusRecord)
private static TextBlock CreateGridBox(this IAc3Connection gridMeter)
{
return statusRecord
.GridMeter!
return gridMeter
.Ac
.PhasePowersActive()
.TitleBox("Grid");
}
private static TextBlock CreateDcDcBox(StatusRecord s)
private static TextBlock CreateDcDcBox(this StatusRecord status)
{
var dc48Voltage = s.DcDc.Dc.Battery.Voltage.ToDisplayString();
var dc48Voltage = status.DcDc.Dc.Battery.Voltage.ToDisplayString();
return TextBlock
.AlignLeft(dc48Voltage)
.TitleBox("DC/DC");
}
private static TextBlock CreateInverterBox(StatusRecord s)
private static TextBlock CreateInverterBox(this StatusRecord status)
{
var inverterAcPhases = s
var inverterAcPhases = status
.AcDc
.Devices
.Select(d => d.Status.Ac.Power)
@ -107,41 +115,57 @@ public static class Topology
.AlignLeft(inverterAcPhases)
.TitleBox("AC/DC");
}
private static TextBlock CreateGridBusColumn(this StatusRecord status)
{
Debug.Assert(status.GridMeter is not null);
private static TextBlock CreateIslandBusColumn(StatusRecord s, ActivePower islandLoadPower)
var gridLoadPower = status.LoadOnAcGrid is not null
? status.LoadOnAcGrid.Power.Active
: 0; // TODO: show that LoadOnAcGrid is actually not available and not 0
return CreateTopologyColumn
(
"PV" , 0,
"Grid Bus", status.GridMeter.Ac.PhaseVoltages(),
"Load" , gridLoadPower
);
}
private static TextBlock CreateIslandBusColumn(this StatusRecord status, ActivePower islandLoadPower)
{
var islandBusPv = 0.W(); // TODO
return ColumnBox
return CreateTopologyColumn
(
"Pv", islandBusPv,
"Island Bus", s.AcDc.Ac.PhasePowersActive(),
"Load", islandLoadPower
"PV" , islandBusPv,
"Island Bus", status.AcDc.Ac.PhaseVoltages(),
"Load" , islandLoadPower
);
}
private static TextBlock CreateDcBusColumn(StatusRecord s)
private static TextBlock CreateDcBusColumn(this StatusRecord status)
{
var dcBusLoad = 0.W(); // TODO
var pvOnDcPower = s.PvOnDc.Dc!.Power; // TODO !
var dcLinkVoltage = s.DcDc.Dc.Link.Voltage.ToDisplayString();
var pvOnDcPower = status.PvOnDc.Dc!.Power; // TODO !
var dcLinkVoltage = status.DcDc.Dc.Link.Voltage.ToDisplayString();
return ColumnBox
return CreateTopologyColumn
(
"Pv" , pvOnDcPower,
"Dc Bus", dcLinkVoltage,
"Load" , dcBusLoad
"PV" , pvOnDcPower,
"DC Bus" , dcLinkVoltage,
"DC Load", dcBusLoad
);
}
private static TextBlock CreateBatteryColumn(StatusRecord s)
private static TextBlock CreateBatteryColumn(this StatusRecord status)
{
var bat = s.Battery;
var bat = status.Battery;
var batteryAvgBox = CreateAveragedBatteryBox(bat);
var batteryBoxes = bat
.Devices
.Select(CreateIndividualBattery)
.Select(CreateBatteryBox)
.ToReadOnlyList();
var individualBatteries = batteryBoxes.Any()
@ -158,42 +182,28 @@ public static class Topology
private static TextBlock CreateAveragedBatteryBox(Battery48TlRecords bat)
{
var batteryVoltage = bat.Dc.Voltage.ToDisplayString();
var batterySoc = bat.Devices.Any() ? bat.Devices.Average(b => b.Soc).Percent().ToDisplayString() : "0";
var batteryCurrent = bat.Dc.Current.ToDisplayString();
var batteryTemp = bat.Temperature.ToDisplayString();
var batteryHeatingCurrent = bat.HeatingCurrent.ToDisplayString();
var voltage = bat.Dc.Voltage.ToDisplayString();
var soc = bat.Devices.Any() ? bat.Devices.Average(b => b.Soc).Percent().ToDisplayString() : "0";
var current = bat.Dc.Current.ToDisplayString();
var temp = bat.Temperature.ToDisplayString();
var heatingCurrent = bat.HeatingCurrent.ToDisplayString();
var alarms = bat.Alarms.Count + " Alarms";
var warnings = bat.Warnings.Count + " Warnings";
return TextBlock
.AlignLeft
(
batteryVoltage,
batterySoc,
batteryCurrent,
batteryTemp,
batteryHeatingCurrent,
voltage,
soc,
current,
temp,
heatingCurrent,
warnings,
alarms
)
.TitleBox("Battery");
}
private static TextBlock GridBusColumn(StatusRecord s)
{
var gridLoadPower = s.LoadOnAcGrid is not null
? s.LoadOnAcGrid.Power.Active
: 0; // TODO: show that LoadOnAcGrid is actually not available and not 0
return ColumnBox
(
"Pv", 0,
"Grid Bus", s.GridMeter!.Ac.PhaseVoltages(),
"Load", gridLoadPower
);
}
private static TextBlock PhaseVoltages(this Ac3Bus ac)
{
return TextBlock.AlignLeft
@ -214,7 +224,7 @@ public static class Topology
);
}
private static TextBlock CreateIndividualBattery(Battery48TlRecord battery, Int32 i)
private static TextBlock CreateBatteryBox(Battery48TlRecord battery, Int32 i)
{
var batteryWarnings = battery.Warnings.Any();
var batteryAlarms = battery.Alarms.Any();
@ -238,10 +248,9 @@ public static class Topology
}
[SuppressMessage("ReSharper", "SuggestBaseTypeForParameter")]
private static TextBlock ColumnBox(String pvTitle , ActivePower pvPower,
String busTitle , Object busData,
String loadTitle, ActivePower loadPower)
private static TextBlock CreateTopologyColumn(String pvTitle , ActivePower pvPower,
String busTitle , Object busData,
String loadTitle, ActivePower loadPower)
{
var pvBox = TextBlock.FromString(pvTitle).Box();
var pvToBus = Flow.Vertical(pvPower);
@ -251,4 +260,4 @@ public static class Topology
return TextBlock.AlignCenterHorizontal(pvBox, pvToBus, busBox, busToLoad, loadBox);
}
}
}