Add the print Topology
This commit is contained in:
parent
b8b908e7f8
commit
8455bb64e3
|
@ -16,6 +16,7 @@ using InnovEnergy.Lib.Devices.Trumpf.TruConvertDc;
|
||||||
using InnovEnergy.Lib.Protocols.Modbus.Channels;
|
using InnovEnergy.Lib.Protocols.Modbus.Channels;
|
||||||
using InnovEnergy.Lib.Time.Unix;
|
using InnovEnergy.Lib.Time.Unix;
|
||||||
using InnovEnergy.Lib.Units;
|
using InnovEnergy.Lib.Units;
|
||||||
|
using InnovEnergy.Lib.Units.Power;
|
||||||
using InnovEnergy.Lib.Utils;
|
using InnovEnergy.Lib.Utils;
|
||||||
using static InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes.SystemConfig;
|
using static InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes.SystemConfig;
|
||||||
using AcPower = InnovEnergy.Lib.Units.Composite.AcPower;
|
using AcPower = InnovEnergy.Lib.Units.Composite.AcPower;
|
||||||
|
@ -146,83 +147,6 @@ internal static class Program
|
||||||
Config = Config.Load() // load from disk every iteration, so config can be changed while running
|
Config = Config.Load() // load from disk every iteration, so config can be changed while running
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// async Task<StatusRecord> ReadStatus()
|
|
||||||
// {
|
|
||||||
// var acDcTask = Task.Run(() => acDcDevices.Read());
|
|
||||||
// var dcDcTask = Task.Run(() => dcDcDevices.Read());
|
|
||||||
// var batteryTask = Task.Run(() => batteryDevices.Read());
|
|
||||||
// var relaysTask = Task.Run(() => saliMaxRelaysDevice.Read());
|
|
||||||
// var loadOnAcIslandTask = Task.Run(() => acIslandLoadMeter.Read());
|
|
||||||
// var gridMeterTask = Task.Run(() => gridMeterDevice.Read());
|
|
||||||
// var pvOnDcTask = Task.Run(() => amptDevice.Read());
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// var timeout = Task.Delay(TimeSpan.FromSeconds(4));
|
|
||||||
// var whenAll = Task
|
|
||||||
// .WhenAll
|
|
||||||
// (
|
|
||||||
// acDcTask,
|
|
||||||
// dcDcTask,
|
|
||||||
// batteryTask,
|
|
||||||
// relaysTask,
|
|
||||||
// loadOnAcIslandTask,
|
|
||||||
// gridMeterTask,
|
|
||||||
// pvOnDcTask
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// await Task.WhenAny(whenAll, timeout);
|
|
||||||
//
|
|
||||||
// var acDc = await acDcTask.ResultOrNull() ;
|
|
||||||
// var dcDc = await dcDcTask.ResultOrNull();
|
|
||||||
// var battery = await batteryTask.ResultOrNull();
|
|
||||||
// var relays = await relaysTask.ResultOrNull();
|
|
||||||
// var loadOnAcIsland = await loadOnAcIslandTask.ResultOrNull();
|
|
||||||
// var gridMeter = await gridMeterTask.ResultOrNull();
|
|
||||||
// var pvOnDc = await pvOnDcTask.ResultOrNull();
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// var pvOnAcGrid = AcDevicePower.Null;
|
|
||||||
// var pvOnAcIsland = AcDevicePower.Null;
|
|
||||||
// var loadOnAcGrid = pvOnAcGrid.Power +
|
|
||||||
// pvOnAcIsland.Power +
|
|
||||||
// (gridMeter is null ? AcPower.Null : gridMeter.Ac.Power) +
|
|
||||||
// (loadOnAcIsland is null ? AcPower.Null : loadOnAcIsland.Ac.Power);
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// var dcPowers = new[]
|
|
||||||
// {
|
|
||||||
// acDc?.Dc.Power.Value,
|
|
||||||
// pvOnDc?.Dc?.Power.Value,
|
|
||||||
// dcDc?.Dc.Link.Power.Value
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// var loadOnDc = dcPowers.Any(p => p is null)
|
|
||||||
// ? null
|
|
||||||
// : new DcDevicePower { Power = dcPowers.Sum(p => p)!} ;
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// return new StatusRecord
|
|
||||||
// {
|
|
||||||
// AcDc = acDc ?? AcDcDevicesRecord.Null,
|
|
||||||
// DcDc = dcDc ?? DcDcDevicesRecord.Null,
|
|
||||||
// Battery = battery ?? Battery48TlRecords.Null,
|
|
||||||
// Relays = relays,
|
|
||||||
// GridMeter = gridMeter,
|
|
||||||
//
|
|
||||||
// PvOnAcGrid = pvOnAcGrid,
|
|
||||||
// PvOnAcIsland = pvOnAcIsland,
|
|
||||||
// PvOnDc = pvOnDc ?? AmptStatus.Null,
|
|
||||||
//
|
|
||||||
// LoadOnAcGrid = new AcDevicePower { Power = -loadOnAcGrid },
|
|
||||||
// LoadOnAcIsland = loadOnAcIsland,
|
|
||||||
// LoadOnDc = loadOnDc,
|
|
||||||
//
|
|
||||||
// Config = Config.Load() // load from disk every iteration, so config can be changed while running
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
void WriteControl(StatusRecord r)
|
void WriteControl(StatusRecord r)
|
||||||
{
|
{
|
||||||
|
@ -246,28 +170,24 @@ internal static class Program
|
||||||
|
|
||||||
var record = ReadStatus();
|
var record = ReadStatus();
|
||||||
|
|
||||||
var emuMeterRegisters = record.GridMeter;
|
PrintTopology(record);
|
||||||
if (emuMeterRegisters is not null)
|
|
||||||
{
|
|
||||||
emuMeterRegisters.Ac.Power.Active.WriteLine("Grid Active");
|
|
||||||
emuMeterRegisters.Ac.Power.Reactive.WriteLine("Grid Reactive");
|
|
||||||
}
|
|
||||||
|
|
||||||
record.AcDc.ResetAlarms();
|
|
||||||
record.DcDc.ResetAlarms();
|
|
||||||
|
|
||||||
|
if (record.Relays is not null)
|
||||||
|
record.Relays.ToCsv().WriteLine();
|
||||||
|
|
||||||
|
|
||||||
record.ControlConstants();
|
record.ControlConstants();
|
||||||
|
|
||||||
record.ControlSystemState();
|
record.ControlSystemState();
|
||||||
|
|
||||||
Console.WriteLine($"{record.StateMachine.State}: {record.StateMachine.Message}");
|
Console.WriteLine($"{record.StateMachine.State}: {record.StateMachine.Message}");
|
||||||
|
|
||||||
var essControl = record.ControlEss();
|
var essControl = record.ControlEss().WriteLine();
|
||||||
|
|
||||||
record.EssControl = essControl;
|
record.EssControl = essControl;
|
||||||
|
|
||||||
record.AcDc.SystemControl.ApplyDefaultSettings();
|
record.AcDc.SystemControl.ApplyDefaultSettingsAc();
|
||||||
record.DcDc.SystemControl.ApplyDefaultSettings();
|
record.DcDc.SystemControl.ApplyDefaultSettingsDc();
|
||||||
|
|
||||||
DistributePower(record, essControl);
|
DistributePower(record, essControl);
|
||||||
|
|
||||||
|
@ -282,6 +202,88 @@ internal static class Program
|
||||||
// ReSharper disable once FunctionNeverReturns
|
// ReSharper disable once FunctionNeverReturns
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PrintTopology(StatusRecord s)
|
||||||
|
{
|
||||||
|
// Power Measurement Values
|
||||||
|
var gridPower = s.GridMeter!.Ac.Power.Active;
|
||||||
|
var inverterPower = s.AcDc.Ac.Power.Active;
|
||||||
|
var islandLoadPower = s.LoadOnAcIsland is null ? 0 : s.LoadOnAcIsland.Ac.Power.Active;
|
||||||
|
var dcBatteryPower = s.DcDc.Dc.Battery.Power;
|
||||||
|
var dcdcPower = s.DcDc.Dc.Link.Power;
|
||||||
|
var pvOnDcPower = s.PvOnDc.Dc!.Power.Value;
|
||||||
|
|
||||||
|
// Power Calculated Values
|
||||||
|
var islandToGridBusPower = inverterPower + islandLoadPower;
|
||||||
|
var gridLoadPower = gridPower - islandToGridBusPower;
|
||||||
|
|
||||||
|
var gridPowerByPhase = s.GridMeter.Ac.L1.Power.Active.ToString()+ "," + s.GridMeter.Ac.L2.Power.Active + s.GridMeter.Ac.L3.Power.Active;
|
||||||
|
//var inverterPowerByPhase = new ActivePower[(Int32)s.AcDc.Ac.L1.Power.Active, (Int32)s.AcDc.Ac.L2.Power.Active, (Int32)s.AcDc.Ac.L3.Power.Active];
|
||||||
|
|
||||||
|
// Voltage Measurement Values
|
||||||
|
//var inverterVoltage = new Voltage [(Int32)s.AcDc.Ac.L1.Voltage, (Int32)s.AcDc.Ac.L2.Voltage, (Int32)s.AcDc.Ac.L3.Voltage];
|
||||||
|
//var dcLinkVoltage = s.DcDc.Dc.Link.Voltage;
|
||||||
|
var dc48Voltage = s.DcDc.Dc.Battery.Voltage;
|
||||||
|
var batteryVoltage = s.Battery.Dc.Voltage;
|
||||||
|
var batterySoc = s.Battery.Soc;
|
||||||
|
var batteryCurrent = s.Battery.Dc.Current;
|
||||||
|
var batteryTemp = s.Battery.Temperature;
|
||||||
|
|
||||||
|
gridPowerByPhase.Split(",");
|
||||||
|
var gridBusColumn = ColumnBox("Pv", "Grid Bus", "Load" , "Voltage", gridLoadPower);
|
||||||
|
var islandBusColumn = ColumnBox("Pv", "Island Bus", "Load" , "Voltage", islandLoadPower);
|
||||||
|
var dcBusColumn = ColumnBox("Pv", "Dc Bus", "Load" , "DC Link V", 0, pvOnDcPower);
|
||||||
|
var gridBusFlow = Flow.Horizontal(gridPower);
|
||||||
|
var flowGridBusToIslandBus = Flow.Horizontal((ActivePower)islandToGridBusPower);
|
||||||
|
var flowIslandBusToInverter = Flow.Horizontal(inverterPower);
|
||||||
|
var flowInverterToDcBus = Flow.Horizontal(inverterPower);
|
||||||
|
var flowDcBusToDcDc = Flow.Horizontal(-dcdcPower);
|
||||||
|
var flowDcDcToBattery = Flow.Horizontal(-dcBatteryPower);
|
||||||
|
|
||||||
|
var gridBox = TextBlock.AlignLeft("none","none", "none").TitleBox("Grid");
|
||||||
|
var inverterBox = TextBlock.AlignLeft("none","none", "none").TitleBox("Inverter");
|
||||||
|
var dcDcBox = TextBlock.AlignLeft(dc48Voltage).TitleBox("DC/DC");
|
||||||
|
var batteryBox = TextBlock.AlignLeft(batteryVoltage, batterySoc, batteryCurrent, batteryTemp).TitleBox("Battery");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var totalBoxes = TextBlock.CenterVertical(gridBox,
|
||||||
|
gridBusFlow,
|
||||||
|
gridBusColumn,
|
||||||
|
flowGridBusToIslandBus,
|
||||||
|
islandBusColumn,
|
||||||
|
flowIslandBusToInverter,
|
||||||
|
inverterBox,
|
||||||
|
flowInverterToDcBus,
|
||||||
|
dcBusColumn,
|
||||||
|
flowDcBusToDcDc,
|
||||||
|
dcDcBox,
|
||||||
|
flowDcDcToBattery,
|
||||||
|
batteryBox);
|
||||||
|
|
||||||
|
totalBoxes.WriteLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TextBlock ColumnBox(String pvTitle, String busTitle, String loadTitle, String dataBox)
|
||||||
|
{
|
||||||
|
return ColumnBox(pvTitle, busTitle, loadTitle, dataBox, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TextBlock ColumnBox(String pvTitle, String busTitle, String loadTitle, String dataBox, ActivePower loadPower)
|
||||||
|
{
|
||||||
|
return ColumnBox(pvTitle, busTitle, loadTitle, dataBox, loadPower, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TextBlock ColumnBox(String pvTitle, String busTitle, String loadTitle, String dataBox, ActivePower loadPower, ActivePower pvPower)
|
||||||
|
{
|
||||||
|
var pvBox = TextBlock.AlignLeft("").TitleBox(pvTitle);
|
||||||
|
var pvToBus = Flow.Vertical(pvPower);
|
||||||
|
var busBox = TextBlock.AlignLeft(dataBox).TitleBox(busTitle);
|
||||||
|
var busToLoad = Flow.Vertical(loadPower);
|
||||||
|
var loadBox = TextBlock.AlignLeft("").TitleBox(loadTitle);
|
||||||
|
|
||||||
|
return TextBlock.CenterHorizontal(pvBox, pvToBus, busBox, busToLoad, loadBox);
|
||||||
|
}
|
||||||
|
|
||||||
private static async Task<T?> ResultOrNull<T>(this Task<T> task)
|
private static async Task<T?> ResultOrNull<T>(this Task<T> task)
|
||||||
{
|
{
|
||||||
if (task.Status == TaskStatus.RanToCompletion)
|
if (task.Status == TaskStatus.RanToCompletion)
|
||||||
|
@ -294,12 +296,13 @@ internal static class Program
|
||||||
{
|
{
|
||||||
var inverters = r.AcDc.Devices;
|
var inverters = r.AcDc.Devices;
|
||||||
|
|
||||||
inverters.ForEach(d => d.Control.Dc.MaxVoltage = r.Config.MaxDcBusVoltage);
|
inverters.ForEach(d => d.Control.Dc.MaxVoltage = r.Config.MaxDcBusVoltage);
|
||||||
inverters.ForEach(d => d.Control.Dc.MinVoltage = r.Config.MinDcBusVoltage);
|
inverters.ForEach(d => d.Control.Dc.MinVoltage = r.Config.MinDcBusVoltage);
|
||||||
inverters.ForEach(d => d.Control.Dc.ReferenceVoltage = r.Config.ReferenceDcBusVoltage);
|
inverters.ForEach(d => d.Control.Dc.ReferenceVoltage = r.Config.ReferenceDcBusVoltage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// why this is not in Controller?
|
||||||
private static void DistributePower(StatusRecord record, EssControl essControl)
|
private static void DistributePower(StatusRecord record, EssControl essControl)
|
||||||
{
|
{
|
||||||
var nInverters = record.AcDc.Devices.Count;
|
var nInverters = record.AcDc.Devices.Count;
|
||||||
|
|
Loading…
Reference in New Issue