Delete the intermediate state.

Update the state machine as defined in the excel sheet.

Commment the disable function of Dc/Dc, as we don't need to disable Dc/DC in the grid tie and island transition(I will delete the function in the future).
This commit is contained in:
atef 2023-08-10 13:06:42 +02:00
parent 8b159a6a2c
commit 898ea3fcd8
1 changed files with 148 additions and 164 deletions

View File

@ -10,7 +10,6 @@ namespace InnovEnergy.App.SaliMax.System;
public static class Controller public static class Controller
{ {
private static Boolean _intermediateState;
private static Int32 GetSystemState(this StatusRecord r) private static Int32 GetSystemState(this StatusRecord r)
{ {
var relays = r.Relays; var relays = r.Relays;
@ -19,7 +18,6 @@ public static class Controller
return 101; // Message = "Panic: relay device is not available!", return 101; // Message = "Panic: relay device is not available!",
var acDcs = r.AcDc; var acDcs = r.AcDc;
// var dcDcs = r.DcDc;
if (acDcs.NotAvailable()) if (acDcs.NotAvailable())
return 102; return 102;
@ -34,24 +32,29 @@ public static class Controller
} }
var allDisabled = acDcs.AllDisabled(); var allDisabled = acDcs.AllDisabled();
var allEnabled = acDcs.AllEnabled();
var allGridTied = acDcs.AllGridTied(); var allGridTied = acDcs.AllGridTied();
var allIsland = acDcs.AllIsland(); var allIsland = acDcs.AllIsland();
var k4 = allDisabled ? 0 var k4 = allGridTied ? 0
: allGridTied ? 1 : allIsland ? 1
: allIsland ? 2
: 4; : 4;
var k5 = allDisabled ? 0
: allEnabled ? 1
: 4;
// After testing this, It looks it more messing up the system and get stuck in a cycle of open one inverter and close the other one.
// The solution is always to send the open/close command in every cycle, if one open before the other(s) , the next cycle will open the other inverter(s).
//if (!acDcs.AllTheSame()) //if (!acDcs.AllTheSame())
//{ //{
// k4 = 4; // k4 = 4;
// "Panic: ACDCs have unequal power stage".LogError(); // "Panic: ACDCs have unequal power stage".LogError();
//} //}
// we need to check for dcdc unequal power stage if (k4 == 4 || k5 == 4)
if (k4 == 4)
{ {
return 103; //Message = "Panic: ACDCs have unequal grid types or power stage", return 103; //Message = "Panic: ACDCs have unequal grid types or power stage",
} }
@ -63,31 +66,35 @@ public static class Controller
var k3 = relays.K3InverterIsConnectedToIslandBus.Take(nInverters).Any(c => c) ? 1 : 0; var k3 = relays.K3InverterIsConnectedToIslandBus.Take(nInverters).Any(c => c) ? 1 : 0;
// states as defined in states excel sheet // states as defined in states excel sheet
return 1 return
+ 1*k1 1*k1
+ 2*k2 + 2*k2
+ 4*k3 + 4*k3
+ 8*k4; + 8*k4
+ 16*k5;
} }
public static Boolean ControlSystemState(this StatusRecord s) public static Boolean ControlSystemState(this StatusRecord s)
{ {
s.StateMachine.State = s.GetSystemState(); s.StateMachine.State = s.GetSystemState();
return s.StateMachine.State switch return s.StateMachine.State switch
{ {
0 => State0(s),
1 => State1(s), 1 => State1(s),
2 => State2(s), 3 => State3(s),
4 => State4(s), 4 => State4(s),
6 => State6(s), 6 => State6(s),
8 => State8(s),
9 => State9(s), 9 => State9(s),
12 => State12(s),
13 => State13(s), 13 => State13(s),
15 => State15(s), 19 => State19(s),
16 => State16(s), 22 => State22(s),
17 => State17(s), 23 => State23(s),
18 => State18(s), 24 => State24(s),
21 => State21(s), 28 => State28(s),
29 => State29(s),
101 => State101(s), 101 => State101(s),
102 => State102(s), 102 => State102(s),
@ -102,58 +109,51 @@ public static class Controller
return acDcs.SystemControl == null || acDcs.Devices.Count == 0; return acDcs.SystemControl == null || acDcs.Devices.Count == 0;
} }
private static Boolean State1(StatusRecord s) private static Boolean State0(StatusRecord s)
{ {
s.StateMachine.Message = "Ac/Dc are off. Switching to Island Mode."; s.StateMachine.Message = "Ac/Dc are off. Switching to Island Mode.";
if (!_intermediateState) s.DcDc.Disable();
{ s.AcDc.Disable();
s.DcDc.Disable();
s.AcDc.Disable();
s.AcDc.EnableIslandMode();
s.Relays.DisconnectIslandBusFromGrid();
_intermediateState = true;
}
else
{
_intermediateState = false;
State1Intermediate(s);
}
return false;
// => Intermediate State
}
private static void State1Intermediate(StatusRecord s)
{
s.StateMachine.Message = "Intermediate State 1 ";
s.DcDc.Enable();
s.AcDc.Enable();
s.AcDc.EnableIslandMode(); s.AcDc.EnableIslandMode();
s.Relays.DisconnectIslandBusFromGrid(); s.Relays.DisconnectIslandBusFromGrid();
return false;
// => 17 // => 8
} }
private static Boolean State2(StatusRecord s) private static Boolean State9(StatusRecord s)
{ {
s.StateMachine.Message = "Ac/Dc are disconnected from Island Bus. Switching to GridTie Mode. C"; s.StateMachine.Message = "Ac/Dc are disconnected from Island Bus. Switching to GridTie Mode.";
s.DcDc.Disable();
s.AcDc.Disable();
s.AcDc.EnableGridTieMode();
s.Relays.DisconnectIslandBusFromGrid();
return false;
// => 1
}
private static Boolean State1(StatusRecord s)
{
s.StateMachine.Message = "Grid Tied mode active, closing k2";
s.DcDc.Disable(); s.DcDc.Disable();
s.AcDc.Disable(); s.AcDc.Disable();
s.AcDc.EnableGridTieMode(); s.AcDc.EnableGridTieMode();
s.Relays.ConnectIslandBusToGrid(); s.Relays.ConnectIslandBusToGrid();
return false; return false;
// => 4 // => 3
} }
private static Boolean State4(StatusRecord s) private static Boolean State3(StatusRecord s)
{ {
s.StateMachine.Message = "Turning on Ac/Dc"; s.StateMachine.Message = "K2 closed, Turning on Ac/Dc";
s.DcDc.Enable(); s.DcDc.Enable();
s.AcDc.Enable(); s.AcDc.Enable();
@ -162,11 +162,10 @@ public static class Controller
return false; return false;
// => 12 // => 19
} }
private static Boolean State13(StatusRecord s)
private static Boolean State6(StatusRecord s)
{ {
s.StateMachine.Message = "Ac/Dc are off. Waiting for them to disconnect from Island Bus."; s.StateMachine.Message = "Ac/Dc are off. Waiting for them to disconnect from Island Bus.";
@ -177,43 +176,12 @@ public static class Controller
return true; return true;
// => 2 // => 9
} }
private static Boolean State9(StatusRecord s)
{
s.StateMachine.Message = "Ac/Dc 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) private static Boolean State19(StatusRecord s)
{ {
s.StateMachine.Message = "Waiting for Ac/Dc to connect to Island Bus"; s.StateMachine.Message = "Waiting for Ac/Dc to connect to Island Bus";
@ -224,40 +192,11 @@ public static class Controller
return true; return true;
// => 16 // => 23
} }
private static Boolean State23(StatusRecord s)
private static Boolean State13(StatusRecord s)
{
s.StateMachine.Message = "Disconnected from AcIn (K2), awaiting Ac/Dc 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)
{ {
s.StateMachine.Message = "ESS"; s.StateMachine.Message = "ESS";
@ -269,13 +208,55 @@ public static class Controller
return true; return true;
// => 15 // => 22
}
private static Boolean State22(StatusRecord s)
{
s.StateMachine.Message = "K1 opened, switching inverters off";
s.DcDc.Disable();
s.AcDc.Disable();
s.AcDc.EnableGridTieMode();
s.Relays.ConnectIslandBusToGrid();
return true;
// => 6
} }
private static Boolean State17(StatusRecord s) private static Boolean State6(StatusRecord s)
{ {
s.StateMachine.Message = "Ac/Dc are in Island Mode. Waiting for them to connect to AcIn."; s.StateMachine.Message = "Inverters are off, opening K2";
s.DcDc.Disable();
s.AcDc.Disable();
s.AcDc.EnableGridTieMode();
s.Relays.DisconnectIslandBusFromGrid();
return true;
// => 4
}
private static Boolean State4(StatusRecord s)
{
s.StateMachine.Message = "K2 is open, waiting K3 to open";
s.DcDc.Disable();
s.AcDc.Disable();
s.AcDc.EnableGridTieMode();
s.Relays.DisconnectIslandBusFromGrid();
return true;
// => 0
}
private static Boolean State8(StatusRecord s)
{
s.StateMachine.Message = "Ac/Dc are off and in Island Mode.";
s.DcDc.Enable(); s.DcDc.Enable();
s.AcDc.Enable(); s.AcDc.Enable();
@ -283,32 +264,10 @@ public static class Controller
s.Relays.DisconnectIslandBusFromGrid(); s.Relays.DisconnectIslandBusFromGrid();
return true; return true;
// => 24
// => 21
} }
private static Boolean State28(StatusRecord s)
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.StateMachine.Message = "Island Mode";
@ -320,7 +279,35 @@ public static class Controller
return false; return false;
// => 22 // => 29
}
private static Boolean State29(StatusRecord s)
{
s.StateMachine.Message = "K1 closed, Switching off Inverters and moving to grid tie";
s.DcDc.Disable();
s.AcDc.Disable();
s.AcDc.EnableIslandMode();
s.Relays.DisconnectIslandBusFromGrid();
return false;
// => 13
}
private static Boolean State24(StatusRecord s)
{
s.StateMachine.Message = "Inverter are on waiting for k3 to close";
s.DcDc.Enable();
s.AcDc.Enable();
s.AcDc.EnableIslandMode();
s.Relays.DisconnectIslandBusFromGrid();
return false;
// => 28
} }
private static Boolean State101(StatusRecord s) private static Boolean State101(StatusRecord s)
@ -352,7 +339,6 @@ public static class Controller
private static Boolean UnknownState(StatusRecord s) private static Boolean UnknownState(StatusRecord s)
{ {
// "Unknown System State" // "Unknown System State"
return s.EnableSafeDefaults(); return s.EnableSafeDefaults();
} }
@ -362,6 +348,12 @@ public static class Controller
{ {
return acDcs.Devices.All(d => !d.Control.PowerStageEnable); return acDcs.Devices.All(d => !d.Control.PowerStageEnable);
} }
private static Boolean AllEnabled(this AcDcDevicesRecord acDcs)
{
return acDcs.Devices.All(d => d.Control.PowerStageEnable);
}
private static Boolean AllTheSame(this AcDcDevicesRecord acDcs) private static Boolean AllTheSame(this AcDcDevicesRecord acDcs)
{ {
@ -400,6 +392,9 @@ public static class Controller
private static void Disable(this DcDcDevicesRecord dcDc) private static void Disable(this DcDcDevicesRecord dcDc)
{ {
// For Test purpose, The transition from island mode to grid tier and vis versa , may not need to disable Dc/Dc.
// This will keep the Dc link powered.
// dcDc.Devices // dcDc.Devices
// .Select(d => d.Control) // .Select(d => d.Control)
// .ForAll(c => c.PowerStageEnable = false); // .ForAll(c => c.PowerStageEnable = false);
@ -419,19 +414,6 @@ public static class Controller
.ForAll(c => c.PowerStageEnable = true); .ForAll(c => c.PowerStageEnable = true);
} }
// private static void Enable(this DcDcDevicesRecord dcDc, AcDcDevicesRecord acDc)
// {
// var enableDc = acDc
// .Devices
// .Select(ac => ac.Status.InverterState.Current)
// .All(s => s > InverterState.DcLinkChargeDischargeTest );
//
// dcDc.Devices
// .Select(d => d.Control)
// .ForAll(c => c.PowerStageEnable = enableDc);
// }
private static void EnableGridTieMode(this AcDcDevicesRecord acDc) private static void EnableGridTieMode(this AcDcDevicesRecord acDc)
{ {
@ -463,12 +445,13 @@ public static class Controller
private static void EnableDcLinkGridTie(this StatusRecord s) private static void EnableDcLinkGridTie(this StatusRecord s)
{ {
// Dc Link Windows on DcDc +-55 // Dc Link Windows on DcDc +-30
s.Config.ReferenceDcLinkVoltageFromAcDc = 750; s.Config.ReferenceDcLinkVoltageFromAcDc = 750;
s.Config.MinDcLinkVoltageFromAcDc = 720; s.Config.MinDcLinkVoltageFromAcDc = 720;
s.Config.MaxDcLinkVoltageFromAcDc = 780; s.Config.MaxDcLinkVoltageFromAcDc = 780;
// Dc Link Windows on DcDc +-20
s.Config.ReferenceDcLinkVoltageFromDc = 750; s.Config.ReferenceDcLinkVoltageFromDc = 750;
s.Config.UpperDcLinkVoltageFromDc = 20; s.Config.UpperDcLinkVoltageFromDc = 20;
s.Config.LowerDcLinkVoltageFromDc = 20; s.Config.LowerDcLinkVoltageFromDc = 20;
@ -489,11 +472,12 @@ public static class Controller
private static Boolean EnableSafeDefaults(this StatusRecord s) private static Boolean EnableSafeDefaults(this StatusRecord s)
{ {
// After some tests, the safe state is switch off inverter and keep the last state of K2 , Dc/Dc and Grid type to avoid conflict.
// s.DcDc.Disable(); // s.DcDc.Disable();
s.AcDc.Disable(); s.AcDc.Disable();
// s.AcDc.EnableGridTieMode(); // s.AcDc.EnableGridTieMode();
// s.Relays.DisconnectIslandBusFromGrid(); // s.Relays.DisconnectIslandBusFromGrid();
return false; return false;
} }