using System.Globalization; using InnovEnergy.App.KacoCommunication.Devices; using InnovEnergy.App.KacoCommunication.ESS; using InnovEnergy.Lib.Devices.BatteryDeligreen; using InnovEnergy.Lib.Units.Power; using InnovEnergy.Lib.Utils; namespace InnovEnergy.App.KacoCommunication; // // ┌────┐ // │ Pv │ // └────┘ // V // V // (i) 13.2 kW ┌────────────┐ ┌────────────┐ ┌────────────┐ // V │ Battery K1│ │ Battery K2│ │ Battery K3│ // ┌─────────┐ ┌─────────┐ V ├────────────┤ ├────────────┤ ├────────────┤ // │ Grid │ │ AC/DC │ ┌────────┐ ┌───────┐ │ 52.3 V │ │ 52.3 V │ │ 52.3 V │ // ├─────────┤ -10.3 kW├─────────┤ -11.7 kW │ Dc Bus │ 1008 W │ DC/DC │ 1008 W │ 99.1 % │ │ 99.1 % │ │ 99.1 % │ // │ -3205 W │<<<<<<<<<│ -6646 W │<<<<<<<<<<├────────┤>>>>>>>>>>├───────┤>>>>>>>>>>│ 490 mA │ │ 490 mA │ │ 490 mA │ // │ -3507 W │ (a) │ -5071 W │ (h) │ 776 V │ (k) │ 56 V │ (l) │ 250 °C │ │ 250 °C │ │ 250 °C │ // │ -3605 W │ └─────────┘ └────────┘ └───────┘ │ 445 A │ │ 445 A │ │ 445 A │ // └─────────┘ V │ │ │ │ │ │ // V │ │ │ │ │ │ // (j) 0 W └────────────┘ └────────────┘ └────────────┘ // V // V // ┌──────┐ // │ Load │ // └──────┘ // // New (simplified) topology: // // ┌────┐ // │ PV │ // └────┘ // V // V // (i) 13.2 kW // V // V // ┌─────────┐ ┌─────────┐ (h) ┌────────┐ (k) ┌───────┐ (l) ┌────────────┐ ┌────────────┐ ┌────────────┐ // │ Grid │<<<│ AC/DC │<<<<<<<<<<<<<│ Dc Bus │>>>>>>>>│ DC/DC │>>>>>>>>│ Battery K1 │ │ Battery K2 │ │ Battery K3 │ // ├─────────┤ ├─────────┤ ├────────┤ ├───────┤ ├────────────┤ ├────────────┤ ├────────────┤ // │ -3205 W │ │ -6646 W │ │ 776 V │ │ 56 V │ │ 52.3 V ... │ │ 52.3 V ... │ │ 52.3 V ... │ // │ -3507 W │ │ -5071 W │ └────────┘ └───────┘ └────────────┘ └────────────┘ └────────────┘ // │ -3605 W │ // └─────────┘ // // V // V // (j) 0 W // V // V // ┌──────┐ // │ Load │ // └──────┘ // // Notes: // - (a) is grid power (to/from grid) // - (h) is AC/DC -> DC link power (or your chosen link variable) // - (i) PV -> DC bus // - (j) DC load // - (k) DC bus -> DC/DC link // - (l) DC/DC -> battery power (or total battery power) public static class SimpleTopology { public static TextBlock CreateSimpleTopologyTextBlock(this StatusRecord status) { // Keep the same variable letters as your diagrams (where possible) var a = status.GridMeterRecord?.ActivePowerTotal; // In your existing code, "AC/DC column" shows per-device AC power; // and "h" is a separate link (AcDcToDcLink?.Power.Value). var h = 0; var i = 0; var j = 0; var k = 0; // You mentioned this changed: l is now equal total battery power var l = status.BatteryKabinet1.Power; var grid = status.CreateGridColumn(a); var acdc = status.CreateAcDcColumn(h); var dcBus = status.CreateDcBusColumn(i, j, k); var dcdc = status.CreateDcDcColumn(l); var batteries = status.CreateBatteriesRow(); return TextBlock.AlignCenterVertical( grid, acdc, dcBus, dcdc, batteries ); } private static TextBlock CreateGridColumn(this StatusRecord status, ActivePower? a) { // ┌─────────┐ // │ Grid │ // ├─────────┤ // │ L1 P │ // │ L2 P │ // │ L3 P │ // └─────────┘ (a) flow to AC/DC var gridMeterAc = status.GridMeterRecord; var gridBox = TextBlock .AlignLeft( gridMeterAc?.ActivePowerL1.Value.ToString(CultureInfo.InvariantCulture) ?? "???", gridMeterAc?.ActivePowerL2.Value.ToString(CultureInfo.InvariantCulture) ?? "???", gridMeterAc?.ActivePowerL3.Value.ToString(CultureInfo.InvariantCulture) ?? "???" ) .TitleBox("Grid"); // Flow from Grid to AC/DC in the picture is horizontal (left -> right), using <<<<<< for export/import. // Your Flow.Horizontal(power) already handles arrow direction by sign (based on your existing outputs). var flow = Flow.Horizontal(a); return TextBlock.AlignCenterVertical(gridBox, flow); } private static TextBlock CreateAcDcColumn(this StatusRecord status, ActivePower? h) { // ┌─────────┐ // │ AC/DC │ // ├─────────┤ // │ dev1 P │ // │ dev2 P │ // └─────────┘ (h) flow to DC Bus var acdcBox = TextBlock .AlignLeft(status.InverterRecord?.ActivePowerSetPercent.ToString() ?? "???") .TitleBox("AC/DC"); var flowToDcBus = Flow.Horizontal(h); return TextBlock.AlignCenterVertical(acdcBox, flowToDcBus); } private static TextBlock CreateDcBusColumn( this StatusRecord status, ActivePower? i, ActivePower? j, ActivePower? k) { // ┌────┐ // │ PV │ // └────┘ // V // (i) 13.2 kW // V // ┌────────┐ (k) >>>>>>>>> to DC/DC // │ Dc Bus │>>>>>>>>>>>>>>>>>>> // ├────────┤ // │ 776 V │ // └────────┘ // V // (j) 0 W // V // ┌──────┐ // │ Load │ // └──────┘ // PV box + vertical flow var pvBox = TextBlock.FromString("PV").Box(); var pvToBus = Flow.Vertical(i); // DC bus box (voltage from your DcDc record matches your existing code) var dcBusVoltage = 0.0; var dcBusBox = dcBusVoltage .ToString(CultureInfo.InvariantCulture) .Apply(TextBlock.FromString) .TitleBox("Dc Bus"); // Horizontal flow from DC Bus to DC/DC var busToDcDc = Flow.Horizontal(k); // Load box + vertical flow var busToLoad = Flow.Vertical(j); var loadBox = TextBlock.FromString("Load").Box(); // Assemble: put PV above DC Bus, Load below DC Bus, and the (k) flow beside the bus. return TextBlock.AlignCenterVertical( TextBlock.AlignCenterHorizontal(pvBox, pvToBus, dcBusBox, busToLoad, loadBox), busToDcDc ); } private static TextBlock CreateDcDcColumn(this StatusRecord status, ActivePower? l) { // ┌───────┐ // │ DC/DC │ // ├───────┤ // │ 56 V │ // └───────┘ (l) flow to batteries var dc48Voltage =0.0; var dcdcBox = TextBlock .AlignLeft(dc48Voltage) .TitleBox("DC/DC"); var flowToBattery = Flow.Horizontal(l); return TextBlock.AlignCenterVertical(dcdcBox, flowToBattery); } private static TextBlock CreateBatteriesRow(this StatusRecord status) { // Battery K1 | Battery K2 | Battery K3 (side-by-side) // Each box: voltage, soc, current, temp, etc. (you can tailor) var bat = status.BatteryKabinet1; if (bat is null) return TextBlock.AlignLeft("no battery").Box(); // If you actually have relay names K1/K2/K3 per battery, wire them here. // For now we label by index as "Battery K{n}" to match your picture. var boxes = bat.Devices .Select((b, idx) => CreateBatteryKBox(b, idx)) .ToReadOnlyList(); // Align horizontally to match the diagram return boxes.Any() ? TextBlock.AlignTop(boxes) : TextBlock.AlignLeft("no battery devices").Box(); } private static TextBlock CreateBatteryKBox(BatteryDeligreenRecord battery, int idx) { // Minimal “K-style” battery box matching your diagram fields var data = battery.BatteryDeligreenDataRecord; // Some of your sample screen values look like: // 52.3 V, 99.1 %, 490 mA, 250 °C, 445 A // Map these to whatever fields you trust in your record. var voltage = data.BusVoltage.ToDisplayString(); var soc = data.Soc.ToDisplayString(); var current = data.BusCurrent.ToDisplayString(); var temp = data.TemperaturesList.PowerTemperature.ToDisplayString(); // If you have a better “pack current” field, replace this line. // Keeping it as a separate line to mimic the picture’s extra current-like line. var extraCurrent = data.BusCurrent.ToDisplayString(); return TextBlock .AlignLeft( voltage, soc, current, temp, extraCurrent ) .TitleBox($"Battery K{idx + 1}"); } }