2023-04-20 11:21:41 +00:00
#define BatteriesAllowed
2023-02-23 16:59:55 +00:00
2023-02-25 14:53:58 +00:00
using InnovEnergy.App.SaliMax.Controller ;
2023-02-23 16:58:33 +00:00
using InnovEnergy.Lib.Utils ;
2023-04-18 08:04:08 +00:00
using InnovEnergy.Lib.Units ;
2023-02-23 16:58:33 +00:00
2023-02-25 14:53:58 +00:00
namespace InnovEnergy.App.SaliMax ;
2023-02-23 16:58:33 +00:00
public static class Topology
{
2023-04-20 11:21:41 +00:00
private static String Separator ( Decimal power )
2023-02-23 16:58:33 +00:00
{
const String chargingSeparator = ">>>>>>>>>>" ;
const String dischargingSeparator = "<<<<<<<<<" ;
2023-04-20 11:21:41 +00:00
return power > 0 ? chargingSeparator : dischargingSeparator ;
}
public static Decimal Round3 ( this Decimal d )
{
return d . RoundToSignificantDigits ( 3 ) ;
}
public static void Print ( StatusRecord s )
{
2023-02-23 16:58:33 +00:00
const Int32 height = 25 ;
2023-04-20 11:21:41 +00:00
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 ;
2023-02-23 16:58:33 +00:00
#endif
2023-04-20 11:21:41 +00:00
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 ( ) ;
2023-02-23 16:58:33 +00:00
////////////////// Grid //////////////////////
var boxGrid = AsciiArt . CreateBox
(
"Grid" ,
2023-04-20 11:21:41 +00:00
s . GridMeterStatus . Ac . L1 . Voltage . Value . V ( ) ,
s . GridMeterStatus . Ac . L2 . Voltage . Value . V ( ) ,
s . GridMeterStatus . Ac . L3 . Voltage . Value . V ( )
2023-02-23 16:58:33 +00:00
) . AlignCenterVertical ( height ) ;
2023-04-18 08:04:08 +00:00
var gridAcBusArrow = AsciiArt . CreateHorizontalArrow ( s . GridMeterStatus ! . Ac . ActivePower , gridSeparator )
2023-02-23 16:58:33 +00:00
. AlignCenterVertical ( height ) ;
////////////////// Ac Bus //////////////////////
var boxAcBus = AsciiArt . CreateBox
(
"AC Bus" ,
2023-04-20 11:21:41 +00:00
s . InverterStatus . Ac . L1 . Voltage . Value . V ( ) ,
s . InverterStatus . Ac . L2 . Voltage . Value . V ( ) ,
s . InverterStatus . Ac . L3 . Voltage . Value . V ( )
2023-02-23 16:58:33 +00:00
) ;
var boxLoad = AsciiArt . CreateBox
(
"" ,
"LOAD" ,
""
) ;
2023-04-20 11:21:41 +00:00
var loadRect = StringUtils . AlignBottom ( CreateRect ( boxAcBus , boxLoad , gridLoadPower ) , height ) ;
2023-02-23 16:58:33 +00:00
2023-04-20 11:21:41 +00:00
var acBusInvertArrow = AsciiArt . CreateHorizontalArrow ( measuredActivePwr , inverterSeparator )
2023-02-23 16:58:33 +00:00
. AlignCenterVertical ( height ) ;
//////////////////// Inverter /////////////////////////
var inverterBox = AsciiArt . CreateBox
(
"" ,
"Inverter" ,
""
) . AlignCenterVertical ( height ) ;
2023-04-20 11:21:41 +00:00
var inverterArrow = AsciiArt . CreateHorizontalArrow ( measuredActivePwr , inverterSeparator )
2023-02-23 16:58:33 +00:00
. AlignCenterVertical ( height ) ;
//////////////////// DC Bus /////////////////////////
var dcBusBox = AsciiArt . CreateBox
(
"DC Bus" ,
2023-04-20 11:21:41 +00:00
( s . InverterStatus . ActualDcLinkVoltageLowerHalfExt . Value + s . InverterStatus . ActualDcLinkVoltageUpperHalfExt . Value ) . V ( ) ,
2023-02-23 16:58:33 +00:00
""
) ;
var pvBox = AsciiArt . CreateBox
(
"MPPT" ,
2023-04-20 11:21:41 +00:00
( ( s . AmptStatus ! . Devices [ 0 ] . Strings [ 0 ] . Voltage . Value + s . AmptStatus ! . Devices [ 0 ] . Strings [ 1 ] . Voltage . Value ) / 2 ) . V ( ) ,
2023-02-23 16:58:33 +00:00
""
) ;
var pvRect = StringUtils . AlignTop ( CreateRect ( pvBox , dcBusBox , pvPower ) , height ) ;
2023-04-20 11:21:41 +00:00
var dcBusArrow = AsciiArt . CreateHorizontalArrow ( - s . DcDcStatus ! . Left . Power , dcSeparator )
2023-02-23 16:58:33 +00:00
. AlignCenterVertical ( height ) ;
2023-04-20 11:21:41 +00:00
//////////////////// Dc/Dc /////////////////////////
2023-02-23 16:58:33 +00:00
2023-04-20 11:21:41 +00:00
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 ) ;
}
2023-02-23 16:58:33 +00:00
2023-04-20 11:21:41 +00:00
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" ;
}
2023-02-23 16:58:33 +00:00
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 ;
}
2023-04-20 11:21:41 +00:00
private static String CreateRect ( String [ ] boxes )
{
var maxWidth = boxes . Max ( l = > l . Width ( ) ) ;
var rect = boxes . Select ( l = > l . AlignCenterHorizontal ( maxWidth ) ) . JoinLines ( ) ;
return rect ;
}
2023-02-23 16:58:33 +00:00
}