Innovenergy_trunk/csharp/App/SaliMax/src/System/Controller.cs

470 lines
12 KiB
C#

using InnovEnergy.App.SaliMax.Ess;
using InnovEnergy.App.SaliMax.SaliMaxRelays;
using InnovEnergy.Lib.Devices.Battery48TL;
using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc;
using InnovEnergy.Lib.Devices.Trumpf.TruConvertDc;
using static InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes.GridType;
namespace InnovEnergy.App.SaliMax.System;
public static class Controller
{
private static Int32 GetSystemState(this StatusRecord r)
{
var relays = r.Relays;
if (relays is null)
return 101; // Message = "Panic: relay device is not available!",
var acDcs = r.AcDc;
if (acDcs.NotAvailable())
return 102;
var k4 = acDcs.AllDisabled() ? 0
: acDcs.AllGridTied() ? 1
: acDcs.AllIsland() ? 2
: 4;
if (k4 == 4)
return 103; //Message = "Panic: ACDCs have unequal grid types",
var nInverters = r.AcDc.Devices.Count;
var k1 = relays.K1GridBusIsConnectedToGrid ? 1 : 0;
var k2 = relays.K2IslandBusIsConnectedToGridBus ? 1 : 0;
var k3 = relays.K3InverterIsConnectedToIslandBus.Take(nInverters).Any(c => c) ? 1 : 0;
// states as defined in states excel sheet
return 1
+ 1*k1
+ 2*k2
+ 4*k3
+ 8*k4;
}
public static Boolean ControlSystemState(this StatusRecord s)
{
s.StateMachine.State = s.GetSystemState();
return s.StateMachine.State switch
{
1 => State1(s),
2 => State2(s),
4 => State4(s),
6 => State6(s),
9 => State9(s),
//10 => State10(s),
12 => State12(s),
13 => State13(s),
15 => State15(s),
16 => State16(s),
17 => State17(s),
18 => State18(s),
21 => State21(s),
101 => State101(s),
102 => State102(s),
103 => State103(s),
_ => UnknownState(s)
};
}
private static Boolean NotAvailable(this AcDcDevicesRecord acDcs)
{
return acDcs.SystemControl == null || acDcs.Devices.Count == 0;
}
private static Boolean NotAvailable(this DcDcDevicesRecord dcDcs)
{
return dcDcs.SystemControl == null || dcDcs.Devices.Count == 0;
}
private static Boolean NotAvailable(this Battery48TlRecords batteries)
{
return batteries.Devices.Count <= 0;
}
private static Boolean State1(StatusRecord s)
{
s.StateMachine.Message = "Inverters are off. Switching to Island Mode.";
s.DcDc.Enable();
s.AcDc.Enable();
s.AcDc.EnableIslandMode();
s.Relays.DisconnectIslandBusFromGrid();
return false;
// => 17
}
private static Boolean State2(StatusRecord s)
{
s.StateMachine.Message = "Inverters are disconnected from Island Bus. Switching to GridTie Mode. C";
s.DcDc.Disable();
s.AcDc.Disable();
s.AcDc.EnableGridTieMode();
s.Relays.ConnectIslandBusToGrid();
return false;
// => 10
}
private static Boolean State4(StatusRecord s)
{
s.StateMachine.Message = "Turning on Inverters";
s.DcDc.Enable();
s.AcDc.Enable();
s.AcDc.EnableGridTieMode();
s.Relays.ConnectIslandBusToGrid();
return false;
// => 12
}
private static Boolean State6(StatusRecord s)
{
s.StateMachine.Message = "Inverters are off. Waiting for them to disconnect from Island Bus.";
s.DcDc.Disable();
s.AcDc.Disable();
s.AcDc.EnableIslandMode();
s.Relays.DisconnectIslandBusFromGrid();
return true;
// => 2
}
private static Boolean State9(StatusRecord s)
{
s.StateMachine.Message = "Inverters have disconnected from Island Bus. Turning them off.";
s.DcDc.Disable(); // TODO: leave enabled?
s.AcDc.Disable();
s.AcDc.EnableGridTieMode();
s.Relays.DisconnectIslandBusFromGrid();
return true;
// => 1
}
//
// private static Boolean State10(StatusRecord s)
// {
//
// s.SystemState.Message = "Inverters have disconnected from AcOut. Turning them off.";
//
// s.DcDc.Disable(); // TODO: leave enabled?
// s.AcDc.Disable();
// s.AcDc.EnableGridTieMode();
// s.Relays.DisconnectIslandBusFromGrid();
//
// return true;
//
// // => 12
// }
private static Boolean State12(StatusRecord s)
{
s.StateMachine.Message = "Waiting for Inverters to connect to Island Bus";
s.DcDc.Enable();
s.AcDc.Enable();
s.AcDc.EnableGridTieMode();
s.Relays.ConnectIslandBusToGrid();
return true;
// => 16
}
private static Boolean State13(StatusRecord s)
{
s.StateMachine.Message = "Disconnected from AcIn (K2), awaiting inverters to disconnect from AcOut (K3)";
s.DcDc.Enable();
s.AcDc.Enable();
s.AcDc.EnableGridTieMode();
s.Relays.DisconnectIslandBusFromGrid();
return true;
// => 9
}
private static Boolean State15(StatusRecord s)
{
s.StateMachine.Message = "Grid has been lost, disconnecting AcIn from AcOut (K2)";
s.DcDc.Enable();
s.AcDc.Enable();
s.AcDc.EnableGridTieMode();
s.Relays.DisconnectIslandBusFromGrid();
return true;
// => 13
}
private static Boolean State16(StatusRecord s)
{
// return new
// (
// " Inverter is in grid-tie\n Waiting for K1AcInIsConnectedToGrid to open to leave it",
// AcPowerStageEnable: true,
// DcPowerStageEnable: true,
// GridType.GridTied400V50Hz,
// HighActivePinState.Closed
// );
s.StateMachine.Message = "ESS";
s.DcDc.Enable();
s.AcDc.Enable();
s.AcDc.EnableGridTieMode();
s.Relays.ConnectIslandBusToGrid();
return true;
// => 15
}
private static Boolean State17(StatusRecord s)
{
s.StateMachine.Message = "Inverters are in Island Mode. Waiting for them to connect to AcIn.";
s.DcDc.Enable();
s.AcDc.Enable();
s.AcDc.EnableIslandMode();
s.Relays.DisconnectIslandBusFromGrid();
return true;
// => 21
}
private static Boolean State18(StatusRecord s)
{
// return new
// (
// " Didn't succeed to go to Island mode and K1AcInIsConnectedToGrid close\n Turning off power stage of inverter\n Moving to Grid Tie",
// AcPowerStageEnable: false,
// DcPowerStageEnable: false,
// GridType.GridTied400V50Hz,
// HighActivePinState.Open
// );
s.DcDc.Disable();
s.AcDc.Disable();
s.AcDc.EnableIslandMode();
s.Relays.DisconnectIslandBusFromGrid();
return true;
}
private static Boolean State21(StatusRecord s)
{
s.StateMachine.Message = "Island Mode";
s.DcDc.Enable();
s.AcDc.Enable();
s.AcDc.EnableIslandMode();
s.Relays.DisconnectIslandBusFromGrid();
return false;
// => 22
}
private static Boolean State22(StatusRecord s)
{
s.StateMachine.Message = "Grid became available (K1). Turning off inverters.";
s.DcDc.Disable();
s.AcDc.Disable();
s.AcDc.EnableIslandMode();
s.Relays.DisconnectIslandBusFromGrid();
return false;
// => 6
}
private static Boolean State101(StatusRecord s)
{
s.StateMachine.Message = "Relay device is not available";
return s.EnableSafeDefaults();
}
private static Boolean State102(StatusRecord s)
{
s.StateMachine.Message = "ACDCs not available";
return s.EnableSafeDefaults();
}
private static Boolean State103(StatusRecord s)
{
s.StateMachine.Message = "Panic: ACDCs have unequal grid types";
return s.EnableSafeDefaults();
}
private static Boolean State104(StatusRecord s)
{
s.StateMachine.Message = "Panic: DCDCs not available";
return s.EnableSafeDefaults();
}
private static Boolean UnknownState(StatusRecord s)
{
// "Unknown System State"
return s.EnableSafeDefaults();
}
private static Boolean AllDisabled(this AcDcDevicesRecord acDcs)
{
return acDcs.Devices.All(d => !d.Control.PowerStageEnable);
}
private static Boolean AllGridTied(this AcDcDevicesRecord acDcs)
{
return acDcs.Devices.All(d => d.Status.ActiveGridType is GridTied380V60Hz)
|| acDcs.Devices.All(d => d.Status.ActiveGridType is GridTied400V50Hz)
|| acDcs.Devices.All(d => d.Status.ActiveGridType is GridTied480V60Hz);
}
private static Boolean AllIsland(this AcDcDevicesRecord acDcs)
{
return acDcs.Devices.All(d => d.Status.ActiveGridType is Island400V50Hz)
|| acDcs.Devices.All(d => d.Status.ActiveGridType is Island480V60Hz);
}
private static void ForAll<T>(this IEnumerable<T> ts, Action<T> action)
{
foreach (var t in ts)
action(t);
}
private static void Disable(this AcDcDevicesRecord acDc)
{
acDc.Devices
.Select(d => d.Control)
.ForAll(c => c.PowerStageEnable = false);
}
private static void Disable(this DcDcDevicesRecord dcDc)
{
dcDc.Devices
.Select(d => d.Control)
.ForAll(c => c.PowerStageEnable = false);
}
private static void Enable(this AcDcDevicesRecord acDc)
{
acDc.Devices
.Select(d => d.Control)
.ForAll(c => c.PowerStageEnable = true);
}
private static void Enable(this DcDcDevicesRecord dcDc)
{
dcDc.Devices
.Select(d => d.Control)
.ForAll(c => c.PowerStageEnable = true);
}
private static void EnableGridTieMode(this AcDcDevicesRecord acDc)
{
acDc.Devices
.Select(d => d.Control)
.ForAll(c => c.Ac.GridType = GridTied400V50Hz); // TODO: config grid type
}
private static void EnableIslandMode(this AcDcDevicesRecord acDc)
{
acDc.Devices
.Select(d => d.Control)
.ForAll(c => c.Ac.GridType = Island400V50Hz); // TODO: config grid type
}
private static void DisconnectIslandBusFromGrid(this RelaysRecord? relays)
{
if (relays is not null)
relays.K2ConnectIslandBusToGridBus = false;
}
private static void ConnectIslandBusToGrid(this RelaysRecord? relays)
{
if (relays is not null)
relays.K2ConnectIslandBusToGridBus = true;
}
private static Boolean EnableSafeDefaults(this StatusRecord s)
{
s.DcDc.Disable();
s.AcDc.Disable();
s.AcDc.EnableGridTieMode();
s.Relays.DisconnectIslandBusFromGrid();
return false;
}
private static DcDcDevicesRecord ResetAlarms(this DcDcDevicesRecord dcDcStatus)
{
var sc = dcDcStatus.SystemControl;
if (sc is not null)
sc.ResetAlarmsAndWarnings = sc.Alarms.Any();
foreach (var d in dcDcStatus.Devices)
d.Control.ResetAlarmsAndWarnings = d.Status.Alarms.Any() || d.Status.Warnings.Any();
return dcDcStatus;
}
private static AcDcDevicesRecord ResetAlarms(this AcDcDevicesRecord acDcStatus)
{
var sc = acDcStatus.SystemControl;
if (sc is not null)
sc.ResetAlarmsAndWarnings = sc.Alarms.Any() || sc.Warnings.Any();
foreach (var d in acDcStatus.Devices)
d.Control.ResetAlarmsAndWarnings = d.Status.Alarms.Any() || d.Status.Warnings.Any();
return acDcStatus;
}
}