diff --git a/csharp/App/SaliMax/src/System/Controller.cs b/csharp/App/SaliMax/src/System/Controller.cs index 4768e225f..43b09b7c3 100644 --- a/csharp/App/SaliMax/src/System/Controller.cs +++ b/csharp/App/SaliMax/src/System/Controller.cs @@ -10,7 +10,6 @@ namespace InnovEnergy.App.SaliMax.System; public static class Controller { - private static Boolean _intermediateState; private static Int32 GetSystemState(this StatusRecord r) { var relays = r.Relays; @@ -19,7 +18,6 @@ public static class Controller return 101; // Message = "Panic: relay device is not available!", var acDcs = r.AcDc; - // var dcDcs = r.DcDc; if (acDcs.NotAvailable()) return 102; @@ -34,24 +32,29 @@ public static class Controller } var allDisabled = acDcs.AllDisabled(); + var allEnabled = acDcs.AllEnabled(); var allGridTied = acDcs.AllGridTied(); - var allIsland = acDcs.AllIsland(); + var allIsland = acDcs.AllIsland(); - var k4 = allDisabled ? 0 - : allGridTied ? 1 - : allIsland ? 2 + var k4 = allGridTied ? 0 + : allIsland ? 1 : 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()) //{ // k4 = 4; // "Panic: ACDCs have unequal power stage".LogError(); //} - // we need to check for dcdc unequal power stage - - if (k4 == 4) + if (k4 == 4 || k5 == 4) { 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; // states as defined in states excel sheet - return 1 - + 1*k1 + return + 1*k1 + 2*k2 + 4*k3 - + 8*k4; + + 8*k4 + + 16*k5; } public static Boolean ControlSystemState(this StatusRecord s) { s.StateMachine.State = s.GetSystemState(); - + return s.StateMachine.State switch { + 0 => State0(s), 1 => State1(s), - 2 => State2(s), + 3 => State3(s), 4 => State4(s), 6 => State6(s), + 8 => State8(s), 9 => State9(s), - 12 => State12(s), 13 => State13(s), - 15 => State15(s), - 16 => State16(s), - 17 => State17(s), - 18 => State18(s), - 21 => State21(s), + 19 => State19(s), + 22 => State22(s), + 23 => State23(s), + 24 => State24(s), + 28 => State28(s), + 29 => State29(s), + 101 => State101(s), 102 => State102(s), @@ -102,58 +109,51 @@ public static class Controller 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."; - if (!_intermediateState) - { - 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.DcDc.Disable(); + s.AcDc.Disable(); s.AcDc.EnableIslandMode(); 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.AcDc.Disable(); s.AcDc.EnableGridTieMode(); s.Relays.ConnectIslandBusToGrid(); - + 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.AcDc.Enable(); @@ -162,11 +162,10 @@ public static class Controller return false; - // => 12 + // => 19 } - - private static Boolean State6(StatusRecord s) + private static Boolean State13(StatusRecord s) { 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; - // => 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"; @@ -224,40 +192,11 @@ public static class Controller return true; - // => 16 + // => 23 } - - 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) + private static Boolean State23(StatusRecord s) { s.StateMachine.Message = "ESS"; @@ -269,13 +208,55 @@ public static class Controller 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.AcDc.Enable(); @@ -283,32 +264,10 @@ public static class Controller s.Relays.DisconnectIslandBusFromGrid(); return true; - - // => 21 + // => 24 } - - - 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) + private static Boolean State28(StatusRecord s) { s.StateMachine.Message = "Island Mode"; @@ -320,7 +279,35 @@ public static class Controller 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) @@ -352,7 +339,6 @@ public static class Controller private static Boolean UnknownState(StatusRecord s) { // "Unknown System State" - return s.EnableSafeDefaults(); } @@ -362,6 +348,12 @@ public static class Controller { 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) { @@ -400,6 +392,9 @@ public static class Controller 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 // .Select(d => d.Control) // .ForAll(c => c.PowerStageEnable = false); @@ -419,19 +414,6 @@ public static class Controller .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) { @@ -463,12 +445,13 @@ public static class Controller 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.MinDcLinkVoltageFromAcDc = 720; s.Config.MaxDcLinkVoltageFromAcDc = 780; + // Dc Link Windows on DcDc +-20 s.Config.ReferenceDcLinkVoltageFromDc = 750; s.Config.UpperDcLinkVoltageFromDc = 20; s.Config.LowerDcLinkVoltageFromDc = 20; @@ -489,11 +472,12 @@ public static class Controller 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.AcDc.Disable(); // s.AcDc.EnableGridTieMode(); // s.Relays.DisconnectIslandBusFromGrid(); - return false; }