Innovenergy_trunk/csharp/App/SaliMax/src/Topology.cs

241 lines
8.6 KiB
C#

#define BatteriesAllowed
using InnovEnergy.App.SaliMax.Controller;
using InnovEnergy.Lib.Utils;
using InnovEnergy.Lib.Units;
namespace InnovEnergy.App.SaliMax;
public static class Topology
{
private static String Separator(Decimal power)
{
const String chargingSeparator = ">>>>>>>>>>";
const String dischargingSeparator = "<<<<<<<<<";
return power > 0 ? chargingSeparator : dischargingSeparator;
}
public static Decimal Round3(this Decimal d)
{
return d.RoundToSignificantDigits(3);
}
public static void Print(StatusRecord s)
{
const Int32 height = 25;
var calculatedActivePwr = - s.InverterStatus!.Ac.ActivePower;
var measuredActivePwr = (s.InverterStatus.SumActivePowerL1 + s.InverterStatus.SumActivePowerL2 +
s.InverterStatus.SumActivePowerL3) * -1;
measuredActivePwr.WriteLine(" : measured Sum of Active Pwr ");
var setValueCosPhi = s.InverterStatus.CosPhiSetValue;
var setValueApparentPower = s.InverterStatus.ApparentPowerSetValue;
#if AmptAvailable
var pvPower = (s.AmptStatus!.Devices[0].Dc.Voltage * s.AmptStatus.Devices[0].Dc.Current + s.AmptStatus!.Devices[1].Dc.Voltage * s.AmptStatus.Devices[1].Dc.Current).Round0(); // TODO using one Ampt
#else
var pvPower = 0;
#endif
var criticalLoadPower = (s.AcInToAcOutMeterStatus!.Ac.ActivePower.Value).Round3();
var dcTotalPower = -s.DcDcStatus!.TotalDcPower;
var gridSeparator = Separator(s.GridMeterStatus!.Ac.ActivePower);
var inverterSeparator = Separator(measuredActivePwr);
var dcSeparator = Separator(dcTotalPower);
var something = measuredActivePwr + criticalLoadPower;
var gridLoadPower = (s.GridMeterStatus!.Ac.ActivePower - something).Value.Round3();
////////////////// Grid //////////////////////
var boxGrid = AsciiArt.CreateBox
(
"Grid",
s.GridMeterStatus.Ac.L1.Voltage.Value.V(),
s.GridMeterStatus.Ac.L2.Voltage.Value.V(),
s.GridMeterStatus.Ac.L3.Voltage.Value.V()
).AlignCenterVertical(height);
var gridAcBusArrow = AsciiArt.CreateHorizontalArrow(s.GridMeterStatus!.Ac.ActivePower, gridSeparator)
.AlignCenterVertical(height);
////////////////// Ac Bus //////////////////////
var boxAcBus = AsciiArt.CreateBox
(
"AC Bus",
s.InverterStatus.Ac.L1.Voltage.Value.V(),
s.InverterStatus.Ac.L2.Voltage.Value.V(),
s.InverterStatus.Ac.L3.Voltage.Value.V()
);
var boxLoad = AsciiArt.CreateBox
(
"",
"LOAD",
""
);
var loadRect = StringUtils.AlignBottom(CreateRect(boxAcBus, boxLoad, gridLoadPower), height);
var acBusInvertArrow = AsciiArt.CreateHorizontalArrow(measuredActivePwr, inverterSeparator)
.AlignCenterVertical(height);
//////////////////// Inverter /////////////////////////
var inverterBox = AsciiArt.CreateBox
(
"",
"Inverter",
""
).AlignCenterVertical(height);
var inverterArrow = AsciiArt.CreateHorizontalArrow(measuredActivePwr, inverterSeparator)
.AlignCenterVertical(height);
//////////////////// DC Bus /////////////////////////
var dcBusBox = AsciiArt.CreateBox
(
"DC Bus",
(s.InverterStatus.ActualDcLinkVoltageLowerHalfExt.Value + s.InverterStatus.ActualDcLinkVoltageUpperHalfExt.Value).V(),
""
);
var pvBox = AsciiArt.CreateBox
(
"MPPT",
((s.AmptStatus!.Devices[0].Strings[0].Voltage.Value + s.AmptStatus!.Devices[0].Strings[1].Voltage.Value) / 2).V(),
""
);
var pvRect = StringUtils.AlignTop(CreateRect(pvBox, dcBusBox, pvPower), height);
var dcBusArrow = AsciiArt.CreateHorizontalArrow(-s.DcDcStatus!.Left.Power, dcSeparator)
.AlignCenterVertical(height);
//////////////////// Dc/Dc /////////////////////////
var dcBox = AsciiArt.CreateBox( "Dc/Dc", s.DcDcStatus.Right.Voltage.Value.V(), "").AlignCenterVertical(height);
var topology = "";
if (s.BatteriesStatus != null)
{
var numBatteries = s.BatteriesStatus.Children.Count;
// Create an array of battery arrows using LINQ
var dcArrows = s
.BatteriesStatus.Children
.Select(b => AsciiArt.CreateHorizontalArrow(b.Dc.Power, Separator(b.Dc.Power)))
.ToArray();
// Create a rectangle from the array of arrows and align it vertically
var dcArrowRect = CreateRect(dcArrows).AlignCenterVertical(height);
//////////////////// Batteries /////////////////////////
var batteryBox = new String[numBatteries];
for (var i = 0; i < numBatteries; i++)
{
if (s.BatteriesStatus.Children[i] != null)
{
batteryBox[i] = AsciiArt.CreateBox
(
"Battery " + (i+1),
s.BatteriesStatus.Children[i].Dc.Voltage .Value.V(),
s.BatteriesStatus.Children[i].Soc .Value.Percent(),
s.BatteriesStatus.Children[i].Temperature .Value.Celsius(),
s.BatteriesStatus.Children[i].Dc.Current .Value.A(),
s.BatteriesStatus.Children[i].TotalCurrent.Value.A()
);
}
else
{
batteryBox[i] = AsciiArt.CreateBox
(
"Battery " + (i+1),
"not detected"
);
}
}
var batteryRect = CreateRect(batteryBox).AlignCenterVertical(height);
var avgBatteryBox = "";
if (s.BatteriesStatus.Combined != null)
{
avgBatteryBox = AsciiArt.CreateBox
(
"Batteries",
s.BatteriesStatus.Combined.CellsVoltage,
s.BatteriesStatus.Combined.Soc,
s.BatteriesStatus.Combined.Temperature,
s.BatteriesStatus.Combined.Dc.Current,
s.BatteriesStatus.Combined.Alarms.Count > 0 ? String.Join(Environment.NewLine, s.BatteriesStatus.Combined.Alarms) : "No Alarm"
).AlignCenterVertical(height);
}
topology = boxGrid.SideBySideWith(gridAcBusArrow, "")
.SideBySideWith(loadRect, "")
.SideBySideWith(acBusInvertArrow, "")
.SideBySideWith(inverterBox, "")
.SideBySideWith(inverterArrow, "")
.SideBySideWith(pvRect, "")
.SideBySideWith(dcBusArrow, "")
.SideBySideWith(dcBox, "")
.SideBySideWith(dcArrowRect, "")
.SideBySideWith(batteryRect, "")
.SideBySideWith(avgBatteryBox, "")+ "\n";
}
else
{
topology = boxGrid.SideBySideWith(gridAcBusArrow, "")
.SideBySideWith(loadRect, "")
.SideBySideWith(acBusInvertArrow, "")
.SideBySideWith(inverterBox, "")
.SideBySideWith(inverterArrow, "")
.SideBySideWith(pvRect, "")
.SideBySideWith(dcBusArrow, "")
.SideBySideWith(dcBox, "") + "\n";
}
Console.WriteLine(topology);
}
private static String CreateRect(String boxTop, String boxBottom, Decimal power)
{
var powerArrow = AsciiArt.CreateVerticalArrow(power);
var boxes = new[] { boxTop, powerArrow, boxBottom };
var maxWidth = boxes.Max(l => l.Width());
var rect = boxes.Select(l => l.AlignCenterHorizontal(maxWidth)).JoinLines();
return rect;
}
private static String CreateRect(String boxTop, String boxBottom)
{
var boxes = new[] { boxTop, boxBottom };
var maxWidth = boxes.Max(l => l.Width());
var rect = boxes.Select(l => l.AlignCenterHorizontal(maxWidth)).JoinLines();
return rect;
}
private static String CreateRect(String[] boxes)
{
var maxWidth = boxes.Max(l => l.Width());
var rect = boxes.Select(l => l.AlignCenterHorizontal(maxWidth)).JoinLines();
return rect;
}
}