diff --git a/TestApp/Configuration/ConfigurationManager.cs b/TestApp/Configuration/ConfigurationManager.cs index ac671f7..28ac229 100644 --- a/TestApp/Configuration/ConfigurationManager.cs +++ b/TestApp/Configuration/ConfigurationManager.cs @@ -101,41 +101,9 @@ namespace TestApp.Configuration ChargerDriver = Settings.DEFAULT_CHARGER_DRIVER, ChargerAddress = Settings.DEFAULT_CHARGER_ADDRESS, ChargerPort = Settings.DEFAULT_CHARGER_PORT, + MaxCurrent = Settings.DEFAULT_MAX_CURRENT, + MinNegativePower = Settings.DEFAULT_MIN_NEGATIVE_POWER, Mode = 1, - ModeSettings = new ModeSettings[] { - new ModeSettings - { - ProcessVariable = ProcessVariable.ActivePowerPositive, - SetPoint = 32, - NegativePid = new PidSetting() { - KP = 0, - KI = 1, - KD = 0, - }, - PositivePid = new PidSetting() - { - KP = 0, - KI = 1, - KD = 0, - } - }, - new ModeSettings - { - ProcessVariable = ProcessVariable.ActivePowerNegative, - SetPoint = 100, - NegativePid = new PidSetting() { - KP = 0, - KI = 1, - KD = 0, - }, - PositivePid = new PidSetting() - { - KP = 0, - KI = 1, - KD = 0, - } - }, - } }; } diff --git a/TestApp/Configuration/Settings.cs b/TestApp/Configuration/Settings.cs index e70542c..8dcb4f8 100644 --- a/TestApp/Configuration/Settings.cs +++ b/TestApp/Configuration/Settings.cs @@ -5,207 +5,16 @@ internal const string DEFAULT_CHARGER_DRIVER = "VestelEvc04"; internal const string DEFAULT_CHARGER_ADDRESS = "192.168.178.100"; internal const int DEFAULT_CHARGER_PORT = 512; + internal const double DEFAULT_MAX_CURRENT = 32; + internal const double DEFAULT_MIN_NEGATIVE_POWER = 100; public string? ChargerDriver { get; set; } public string? ChargerAddress { get; set; } public int? ChargerPort { get; set; } + public double? MaxCurrent { get; set; } + public double? MinNegativePower { get; set; } + public int Mode { get; set; } - - public ModeSettings[]? ModeSettings { get; set; } - } - - - public class PidSetting { - public double KP { get; set; } - public double KI { get; set; } - public double KD { get; set; } - } - - public class ModeSettings { - public ProcessVariable ProcessVariable { get; set; } - public double SetPoint { get; set; } - public PidSetting? PositivePid { get; set; } - public PidSetting? NegativePid { get; set; } - } - - public enum ProcessVariable - { - /// in W - ActivePowerPositive, - - /// in Wh - ActiveEnergyPositive, - - /// in W - ActivePowerNegative, - - /// in Wh - ActiveEnergyNegative, - - /// in var - ReactivePowerPositive, - - /// in varh - ReactiveEnergyPositive, - - /// in var - ReactivePowerNegative, - - /// in varh - ReactiveEnergyNegative, - - /// in VA - ApparentPowerPositive, - - /// in VAh - ApparentEnergyPositive, - - /// in VA - ApparentPowerNegative, - - /// in VAh - ApparentEnergyNegative, - - /// in - - PowerFactor, - - /// in Hz - SupplyFrequency, - - /// in W - ActivePowerPositiveL1, - - /// in Wh - ActiveEnergyPositiveL1, - - /// in W - ActivePowerNegativeL1, - - /// in Wh - ActiveEnergyNegativeL1, - - /// in var - ReactivePowerPositiveL1, - - /// in varh - ReactiveEnergyPositiveL1, - - /// in var - ReactivePowerNegativeL1, - - /// in varh - ReactiveEnergyNegativeL1, - - /// in VA - ApparentPowerPositiveL1, - - /// in VAh - ApparentEnergyPositiveL1, - - /// in VA - ApparentPowerNegativeL1, - - /// in VAh - ApparentEnergyNegativeL1, - - /// in A - CurrentL1, - - /// in V - VoltageL1, - - /// in - - PowerFactorL1, - - /// in W - ActivePowerPositiveL2, - - /// in Wh - ActiveEnergyPositiveL2, - - /// in W - ActivePowerNegativeL2, - - /// in Wh - ActiveEnergyNegativeL2, - - /// in var - ReactivePowerPositiveL2, - - /// in varh - ReactiveEnergyPositiveL2, - - /// in var - ReactivePowerNegativeL2, - - /// in varh - ReactiveEnergyNegativeL2, - - /// in VA - ApparentPowerPositiveL2, - - /// in VAh - ApparentEnergyPositiveL2, - - /// in VA - ApparentPowerNegativeL2, - - /// in VAh - ApparentEnergyNegativeL2, - - /// in A - CurrentL2, - - /// in V - VoltageL2, - - /// in - - PowerFactorL2, - - /// in W - ActivePowerPositiveL3, - - /// in Wh - ActiveEnergyPositiveL3, - - /// in W - ActivePowerNegativeL3, - - /// in Wh - ActiveEnergyNegativeL3, - - /// in var - ReactivePowerPositiveL3, - - /// in varh - ReactiveEnergyPositiveL3, - - /// in var - ReactivePowerNegativeL3, - - /// in varh - ReactiveEnergyNegativeL3, - - /// in VA - ApparentPowerPositiveL3, - - /// in VAh - ApparentEnergyPositiveL3, - - /// in VA - ApparentPowerNegativeL3, - - /// in VAh - ApparentEnergyNegativeL3, - - /// in A - CurrentL3, - - /// in V - VoltageL3, - - /// in - - PowerFactorL3, } } diff --git a/TestApp/CurrentLimitter.cs b/TestApp/CurrentLimitter.cs new file mode 100644 index 0000000..d9af22d --- /dev/null +++ b/TestApp/CurrentLimitter.cs @@ -0,0 +1,67 @@ +using TestApp.Configuration; +using TestApp.Driver; + +namespace TestApp +{ + internal class CurrentLimitter + { + private readonly ConfigurationManager _ConfigurationManager; + private readonly EnergyManager _EnergyManager; + + public CurrentLimitter(ConfigurationManager configurationManager, EnergyManager energyManager) + { + _ConfigurationManager = configurationManager; + _EnergyManager = energyManager; + } + + public double GetLimitedCurrent(IChargerDriver chargerDriver, double current) { + var maxCurrent = _ConfigurationManager.Settings.MaxCurrent ?? Settings.DEFAULT_MAX_CURRENT; + + var wallBoxCurrents = chargerDriver.GetCurrents(); + var measuredCurrents = _EnergyManager.GetCurrents(); + + var maxWithoutCharger = GetMaximumCurrentWithoutWallBox(measuredCurrents, wallBoxCurrents); + var freeCurrent = maxCurrent - maxWithoutCharger; + + if (freeCurrent < current) { + return freeCurrent; + } else + { + return current; + } + } + + private static double GetMaximumCurrentWithoutWallBox((double I1, double I2, double I3) measuredCurrent, (double I1, double I2, double I3) wallBoxCurrent) + { + return GetPermutations(wallBoxCurrent) + .Where(wbc => IsValidCombinition(measuredCurrent, wbc)) + .Select(wbc => GetDifference(measuredCurrent, wbc)) + .Select(c => GetMax(c)) + .Max(); + } + + private static IEnumerable<(double I1, double I2, double I3)> GetPermutations((double I1, double I2, double I3) current) { + yield return (current.I1, current.I2, current.I3); + yield return (current.I1, current.I3, current.I2); + yield return (current.I2, current.I3, current.I1); + yield return (current.I2, current.I1, current.I3); + yield return (current.I3, current.I1, current.I2); + yield return (current.I3, current.I2, current.I1); + } + + private static bool IsValidCombinition((double I1, double I2, double I3) measuredCurrent, (double I1, double I2, double I3) wallBoxCurrent) { + if (measuredCurrent.I1 < wallBoxCurrent.I1) { return false; } // even this is not correct if a PV is generating power ! + if (measuredCurrent.I2 < wallBoxCurrent.I2) { return false; } + if (measuredCurrent.I3 < wallBoxCurrent.I3) { return false; } + return true; + } + + private static (double I1, double I2, double I3) GetDifference((double I1, double I2, double I3) x, (double I1, double I2, double I3) y) { + return (x.I1 - y.I1, x.I2 - y.I2, x.I3 - y.I3); + } + + private static double GetMax((double I1, double I2, double I3) currents) { + return Math.Max(Math.Max(currents.I1, currents.I2), currents.I3); + } + } +} diff --git a/TestApp/Driver/IChargerDriver.cs b/TestApp/Driver/IChargerDriver.cs index 2269cca..f0d0fe4 100644 --- a/TestApp/Driver/IChargerDriver.cs +++ b/TestApp/Driver/IChargerDriver.cs @@ -5,6 +5,8 @@ string HostAddress { get; set; } int Port { get; set; } + (double I1, double I2, double I3) GetCurrents(); + void SetLoadingCurrent(double value); } } diff --git a/TestApp/Driver/VestelEvc04.cs b/TestApp/Driver/VestelEvc04.cs index 1bfce1b..29a2a76 100644 --- a/TestApp/Driver/VestelEvc04.cs +++ b/TestApp/Driver/VestelEvc04.cs @@ -1,4 +1,5 @@ using NModbus; +using System.ComponentModel.Design.Serialization; using System.Net.Sockets; namespace TestApp.Driver @@ -83,6 +84,21 @@ namespace TestApp.Driver } } + public (double I1, double I2, double I3) GetCurrents() + { + if (_Modbus is null) + { + Connect(); + } + if (_Modbus is null) { return (double.NaN, double.NaN, double.NaN); } + + var i1 = _Modbus.ReadHoldingRegisters(255, 1008, 1)[0]; + var i2 = _Modbus.ReadHoldingRegisters(255, 1010, 1)[0]; + var i3 = _Modbus.ReadHoldingRegisters(255, 1012, 1)[0]; + + return (0.001 * i1, 0.001 * i2, 0.001 * i3); + } + public void SetLoadingCurrent(double value) { if (!_Running) { return; } diff --git a/TestApp/EMVariable.cs b/TestApp/EMVariable.cs new file mode 100644 index 0000000..46376d5 --- /dev/null +++ b/TestApp/EMVariable.cs @@ -0,0 +1,182 @@ +namespace TestApp +{ + public enum EMVariable + { + /// in W + ActivePowerPositive, + + /// in Wh + ActiveEnergyPositive, + + /// in W + ActivePowerNegative, + + /// in Wh + ActiveEnergyNegative, + + /// in var + ReactivePowerPositive, + + /// in varh + ReactiveEnergyPositive, + + /// in var + ReactivePowerNegative, + + /// in varh + ReactiveEnergyNegative, + + /// in VA + ApparentPowerPositive, + + /// in VAh + ApparentEnergyPositive, + + /// in VA + ApparentPowerNegative, + + /// in VAh + ApparentEnergyNegative, + + /// in - + PowerFactor, + + /// in Hz + SupplyFrequency, + + /// in W + ActivePowerPositiveL1, + + /// in Wh + ActiveEnergyPositiveL1, + + /// in W + ActivePowerNegativeL1, + + /// in Wh + ActiveEnergyNegativeL1, + + /// in var + ReactivePowerPositiveL1, + + /// in varh + ReactiveEnergyPositiveL1, + + /// in var + ReactivePowerNegativeL1, + + /// in varh + ReactiveEnergyNegativeL1, + + /// in VA + ApparentPowerPositiveL1, + + /// in VAh + ApparentEnergyPositiveL1, + + /// in VA + ApparentPowerNegativeL1, + + /// in VAh + ApparentEnergyNegativeL1, + + /// in A + CurrentL1, + + /// in V + VoltageL1, + + /// in - + PowerFactorL1, + + /// in W + ActivePowerPositiveL2, + + /// in Wh + ActiveEnergyPositiveL2, + + /// in W + ActivePowerNegativeL2, + + /// in Wh + ActiveEnergyNegativeL2, + + /// in var + ReactivePowerPositiveL2, + + /// in varh + ReactiveEnergyPositiveL2, + + /// in var + ReactivePowerNegativeL2, + + /// in varh + ReactiveEnergyNegativeL2, + + /// in VA + ApparentPowerPositiveL2, + + /// in VAh + ApparentEnergyPositiveL2, + + /// in VA + ApparentPowerNegativeL2, + + /// in VAh + ApparentEnergyNegativeL2, + + /// in A + CurrentL2, + + /// in V + VoltageL2, + + /// in - + PowerFactorL2, + + /// in W + ActivePowerPositiveL3, + + /// in Wh + ActiveEnergyPositiveL3, + + /// in W + ActivePowerNegativeL3, + + /// in Wh + ActiveEnergyNegativeL3, + + /// in var + ReactivePowerPositiveL3, + + /// in varh + ReactiveEnergyPositiveL3, + + /// in var + ReactivePowerNegativeL3, + + /// in varh + ReactiveEnergyNegativeL3, + + /// in VA + ApparentPowerPositiveL3, + + /// in VAh + ApparentEnergyPositiveL3, + + /// in VA + ApparentPowerNegativeL3, + + /// in VAh + ApparentEnergyNegativeL3, + + /// in A + CurrentL3, + + /// in V + VoltageL3, + + /// in - + PowerFactorL3, + } +} diff --git a/TestApp/EnergyManager.cs b/TestApp/EnergyManager.cs index 970c8e3..9db99ab 100644 --- a/TestApp/EnergyManager.cs +++ b/TestApp/EnergyManager.cs @@ -1,7 +1,6 @@ using MQTTnet; using MQTTnet.Client; using System.Collections.Immutable; -using TestApp.Configuration; namespace TestApp { @@ -79,67 +78,75 @@ namespace TestApp return factor * value; } - public double GetValue(ProcessVariable processVariable) { - return processVariable switch { - ProcessVariable.ActivePowerPositive => GetValue(1099528667391UL, 0.001), - ProcessVariable.ActiveEnergyPositive => GetValue(1099528929535UL, 0.001), - ProcessVariable.ActivePowerNegative => GetValue(1099545444607UL, 0.001), - ProcessVariable.ActiveEnergyNegative => GetValue(1099545706751UL, 0.001), - ProcessVariable.ReactivePowerPositive => GetValue(1099562221823UL, 0.001), - ProcessVariable.ReactiveEnergyPositive => GetValue(1099562483967UL, 0.001), - ProcessVariable.ReactivePowerNegative => GetValue(1099578999039UL, 0.001), - ProcessVariable.ReactiveEnergyNegative => GetValue(1099579261183UL, 0.001), - ProcessVariable.ApparentPowerPositive => GetValue(1099662885119UL, 0.001), - ProcessVariable.ApparentEnergyPositive => GetValue(1099663147263UL, 0.001), - ProcessVariable.ApparentPowerNegative => GetValue(1099679662335UL, 0.001), - ProcessVariable.ApparentEnergyNegative => GetValue(1099679924479UL, 0.001), - ProcessVariable.PowerFactor => GetValue(1099729993983UL, 0.001), - ProcessVariable.SupplyFrequency => GetValue(1099746771199UL, 0.001), - ProcessVariable.ActivePowerPositiveL1 => GetValue(1099864211711UL, 0.001), - ProcessVariable.ActiveEnergyPositiveL1 => GetValue(1099864473855UL, 0.001), - ProcessVariable.ActivePowerNegativeL1 => GetValue(1099880988927UL, 0.001), - ProcessVariable.ActiveEnergyNegativeL1 => GetValue(1099881251071UL, 0.001), - ProcessVariable.ReactivePowerPositiveL1 => GetValue(1099897766143UL, 0.001), - ProcessVariable.ReactiveEnergyPositiveL1 => GetValue(1099898028287UL, 0.001), - ProcessVariable.ReactivePowerNegativeL1 => GetValue(1099914543359UL, 0.001), - ProcessVariable.ReactiveEnergyNegativeL1 => GetValue(1099914805503UL, 0.001), - ProcessVariable.ApparentPowerPositiveL1 => GetValue(1099998429439UL, 0.001), - ProcessVariable.ApparentEnergyPositiveL1 => GetValue(1099998691583UL, 0.001), - ProcessVariable.ApparentPowerNegativeL1 => GetValue(1100015206655UL, 0.001), - ProcessVariable.ApparentEnergyNegativeL1 => GetValue(1100015468799UL, 0.001), - ProcessVariable.CurrentL1 => GetValue(1100031983871UL, 0.001), - ProcessVariable.VoltageL1 => GetValue(1100048761087UL, 0.001), - ProcessVariable.PowerFactorL1 => GetValue(1100065538303UL, 0.001), - ProcessVariable.ActivePowerPositiveL2 => GetValue(1100199756031UL, 0.001), - ProcessVariable.ActiveEnergyPositiveL2 => GetValue(1100200018175UL, 0.001), - ProcessVariable.ActivePowerNegativeL2 => GetValue(1100216533247UL, 0.001), - ProcessVariable.ActiveEnergyNegativeL2 => GetValue(1100216795391UL, 0.001), - ProcessVariable.ReactivePowerPositiveL2 => GetValue(1100233310463UL, 0.001), - ProcessVariable.ReactiveEnergyPositiveL2 => GetValue(1100233572607UL, 0.001), - ProcessVariable.ReactivePowerNegativeL2 => GetValue(1100250087679UL, 0.001), - ProcessVariable.ReactiveEnergyNegativeL2 => GetValue(1100250349823UL, 0.001), - ProcessVariable.ApparentPowerPositiveL2 => GetValue(1100333973759UL, 0.001), - ProcessVariable.ApparentEnergyPositiveL2 => GetValue(1100334235903UL, 0.001), - ProcessVariable.ApparentPowerNegativeL2 => GetValue(1100350750975UL, 0.001), - ProcessVariable.ApparentEnergyNegativeL2 => GetValue(1100351013119UL, 0.001), - ProcessVariable.CurrentL2 => GetValue(1100367528191UL, 0.001), - ProcessVariable.VoltageL2 => GetValue(1100384305407UL, 0.001), - ProcessVariable.PowerFactorL2 => GetValue(1100401082623UL, 0.001), - ProcessVariable.ActivePowerPositiveL3 => GetValue(1100535300351UL, 0.001), - ProcessVariable.ActiveEnergyPositiveL3 => GetValue(1100535562495UL, 0.001), - ProcessVariable.ActivePowerNegativeL3 => GetValue(1100552077567UL, 0.001), - ProcessVariable.ActiveEnergyNegativeL3 => GetValue(1100552339711UL, 0.001), - ProcessVariable.ReactivePowerPositiveL3 => GetValue(1100568854783UL, 0.001), - ProcessVariable.ReactiveEnergyPositiveL3 => GetValue(1100569116927UL, 0.001), - ProcessVariable.ReactivePowerNegativeL3 => GetValue(1100585631999UL, 0.001), - ProcessVariable.ReactiveEnergyNegativeL3 => GetValue(1100585894143UL, 0.001), - ProcessVariable.ApparentPowerPositiveL3 => GetValue(1100669518079UL, 0.001), - ProcessVariable.ApparentEnergyPositiveL3 => GetValue(1100669780223UL, 0.001), - ProcessVariable.ApparentPowerNegativeL3 => GetValue(1100686295295UL, 0.001), - ProcessVariable.ApparentEnergyNegativeL3 => GetValue(1100686557439UL, 0.001), - ProcessVariable.CurrentL3 => GetValue(1100703072511UL, 0.001), - ProcessVariable.VoltageL3 => GetValue(1100719849727UL, 0.001), - ProcessVariable.PowerFactorL3 => GetValue(1100736626943UL, 0.001), + public (double I1, double I2, double I3) GetCurrents() { + return ( + GetValue(EMVariable.CurrentL1), + GetValue(EMVariable.CurrentL2), + GetValue(EMVariable.CurrentL3) + ); + } + + public double GetValue(EMVariable variable) { + return variable switch { + EMVariable.ActivePowerPositive => GetValue(1099528667391UL, 0.001), + EMVariable.ActiveEnergyPositive => GetValue(1099528929535UL, 0.001), + EMVariable.ActivePowerNegative => GetValue(1099545444607UL, 0.001), + EMVariable.ActiveEnergyNegative => GetValue(1099545706751UL, 0.001), + EMVariable.ReactivePowerPositive => GetValue(1099562221823UL, 0.001), + EMVariable.ReactiveEnergyPositive => GetValue(1099562483967UL, 0.001), + EMVariable.ReactivePowerNegative => GetValue(1099578999039UL, 0.001), + EMVariable.ReactiveEnergyNegative => GetValue(1099579261183UL, 0.001), + EMVariable.ApparentPowerPositive => GetValue(1099662885119UL, 0.001), + EMVariable.ApparentEnergyPositive => GetValue(1099663147263UL, 0.001), + EMVariable.ApparentPowerNegative => GetValue(1099679662335UL, 0.001), + EMVariable.ApparentEnergyNegative => GetValue(1099679924479UL, 0.001), + EMVariable.PowerFactor => GetValue(1099729993983UL, 0.001), + EMVariable.SupplyFrequency => GetValue(1099746771199UL, 0.001), + EMVariable.ActivePowerPositiveL1 => GetValue(1099864211711UL, 0.001), + EMVariable.ActiveEnergyPositiveL1 => GetValue(1099864473855UL, 0.001), + EMVariable.ActivePowerNegativeL1 => GetValue(1099880988927UL, 0.001), + EMVariable.ActiveEnergyNegativeL1 => GetValue(1099881251071UL, 0.001), + EMVariable.ReactivePowerPositiveL1 => GetValue(1099897766143UL, 0.001), + EMVariable.ReactiveEnergyPositiveL1 => GetValue(1099898028287UL, 0.001), + EMVariable.ReactivePowerNegativeL1 => GetValue(1099914543359UL, 0.001), + EMVariable.ReactiveEnergyNegativeL1 => GetValue(1099914805503UL, 0.001), + EMVariable.ApparentPowerPositiveL1 => GetValue(1099998429439UL, 0.001), + EMVariable.ApparentEnergyPositiveL1 => GetValue(1099998691583UL, 0.001), + EMVariable.ApparentPowerNegativeL1 => GetValue(1100015206655UL, 0.001), + EMVariable.ApparentEnergyNegativeL1 => GetValue(1100015468799UL, 0.001), + EMVariable.CurrentL1 => GetValue(1100031983871UL, 0.001), + EMVariable.VoltageL1 => GetValue(1100048761087UL, 0.001), + EMVariable.PowerFactorL1 => GetValue(1100065538303UL, 0.001), + EMVariable.ActivePowerPositiveL2 => GetValue(1100199756031UL, 0.001), + EMVariable.ActiveEnergyPositiveL2 => GetValue(1100200018175UL, 0.001), + EMVariable.ActivePowerNegativeL2 => GetValue(1100216533247UL, 0.001), + EMVariable.ActiveEnergyNegativeL2 => GetValue(1100216795391UL, 0.001), + EMVariable.ReactivePowerPositiveL2 => GetValue(1100233310463UL, 0.001), + EMVariable.ReactiveEnergyPositiveL2 => GetValue(1100233572607UL, 0.001), + EMVariable.ReactivePowerNegativeL2 => GetValue(1100250087679UL, 0.001), + EMVariable.ReactiveEnergyNegativeL2 => GetValue(1100250349823UL, 0.001), + EMVariable.ApparentPowerPositiveL2 => GetValue(1100333973759UL, 0.001), + EMVariable.ApparentEnergyPositiveL2 => GetValue(1100334235903UL, 0.001), + EMVariable.ApparentPowerNegativeL2 => GetValue(1100350750975UL, 0.001), + EMVariable.ApparentEnergyNegativeL2 => GetValue(1100351013119UL, 0.001), + EMVariable.CurrentL2 => GetValue(1100367528191UL, 0.001), + EMVariable.VoltageL2 => GetValue(1100384305407UL, 0.001), + EMVariable.PowerFactorL2 => GetValue(1100401082623UL, 0.001), + EMVariable.ActivePowerPositiveL3 => GetValue(1100535300351UL, 0.001), + EMVariable.ActiveEnergyPositiveL3 => GetValue(1100535562495UL, 0.001), + EMVariable.ActivePowerNegativeL3 => GetValue(1100552077567UL, 0.001), + EMVariable.ActiveEnergyNegativeL3 => GetValue(1100552339711UL, 0.001), + EMVariable.ReactivePowerPositiveL3 => GetValue(1100568854783UL, 0.001), + EMVariable.ReactiveEnergyPositiveL3 => GetValue(1100569116927UL, 0.001), + EMVariable.ReactivePowerNegativeL3 => GetValue(1100585631999UL, 0.001), + EMVariable.ReactiveEnergyNegativeL3 => GetValue(1100585894143UL, 0.001), + EMVariable.ApparentPowerPositiveL3 => GetValue(1100669518079UL, 0.001), + EMVariable.ApparentEnergyPositiveL3 => GetValue(1100669780223UL, 0.001), + EMVariable.ApparentPowerNegativeL3 => GetValue(1100686295295UL, 0.001), + EMVariable.ApparentEnergyNegativeL3 => GetValue(1100686557439UL, 0.001), + EMVariable.CurrentL3 => GetValue(1100703072511UL, 0.001), + EMVariable.VoltageL3 => GetValue(1100719849727UL, 0.001), + EMVariable.PowerFactorL3 => GetValue(1100736626943UL, 0.001), _ => double.NaN, }; } diff --git a/TestApp/Program.cs b/TestApp/Program.cs index e87258b..6feb045 100644 --- a/TestApp/Program.cs +++ b/TestApp/Program.cs @@ -1,4 +1,5 @@ using System.Reflection; +using System.Runtime.CompilerServices; using TestApp.Configuration; using TestApp.Driver; @@ -9,8 +10,7 @@ namespace TestApp private static ConfigurationManager _ConfigurationManager; private static IChargerDriver? _Driver; private static EnergyManager _EnergyManager; - private static ProcessVariable _ProcessVariable; - private static PidController _PidController; + private static CurrentLimitter _CurrentLimitter; static async Task Main(string[] args) @@ -26,17 +26,24 @@ namespace TestApp } _EnergyManager = await EnergyManager.Create(); + _CurrentLimitter = new CurrentLimitter(_ConfigurationManager, _EnergyManager); while (true) { try { - // TODO I1, I2, I3 von Wallbox mit I1-3 von Zähler per Kombinatorik max vom Haus ausrechnen - // newLoadingCurrent = maxSicherung - maxHaus - var measurement = _EnergyManager.GetValue(_ProcessVariable); - var newLoadingCurrent = _PidController.Update(measurement); - //if (newLoadingCurrent < 6) { newLoadingCurrent = 0; } - _Driver?.SetLoadingCurrent(newLoadingCurrent); + if (_Driver is null) { + Thread.Sleep(1000); + continue; + } + + var newCurrent = double.MaxValue; + if (_ConfigurationManager.Settings.Mode == 2) { + newCurrent = GetMode2LoadingCurrent(); + } + + newCurrent = _CurrentLimitter.GetLimitedCurrent(_Driver, newCurrent); + _Driver?.SetLoadingCurrent(newCurrent); } catch (Exception ex) { Console.WriteLine($"Error in main loop: {ex.Message}"); @@ -45,10 +52,26 @@ namespace TestApp } } + private static double GetMode2LoadingCurrent() + { + var minNegativePower = _ConfigurationManager.Settings.MinNegativePower ?? Settings.DEFAULT_MIN_NEGATIVE_POWER; + + var negativePower = _EnergyManager.GetValue(EMVariable.ActivePowerNegative); + + if (negativePower < minNegativePower) { return 0; } + + var sparePower = negativePower - minNegativePower; + + var i1 = sparePower / _EnergyManager.GetValue(EMVariable.VoltageL1); + var i2 = sparePower / _EnergyManager.GetValue(EMVariable.VoltageL2); + var i3 = sparePower / _EnergyManager.GetValue(EMVariable.VoltageL3); + + return Math.Min(Math.Min(i1, i2), i3); + } + private static void OnSettingsChanged(object? sender, Settings settings) { UpdateDriverSettings(settings); - UpdateControllerSettings(settings); } private static void UpdateDriverSettings(Settings settings) { @@ -84,35 +107,5 @@ namespace TestApp _Driver.Port = settings.ChargerPort ?? Settings.DEFAULT_CHARGER_PORT; } - private static void UpdateControllerSettings(Settings settings) - { - var allModeSettings = settings.ModeSettings ?? Array.Empty(); - if (!allModeSettings.Any()) { - allModeSettings = new ModeSettings[]{ - new ModeSettings() { - ProcessVariable = ProcessVariable.ActivePowerPositive, - SetPoint = 0, - PositivePid = new PidSetting(), - NegativePid = new PidSetting(), - } - }; - } - - var mode = settings.Mode; - if (mode < 0) { mode = 0; } - if (mode >= allModeSettings.Length) { mode = allModeSettings.Length - 1; } - - var modeSetting = allModeSettings[mode]; - - if (_ProcessVariable != modeSetting.ProcessVariable) - { - _PidController = new PidController(); - _ProcessVariable = modeSetting.ProcessVariable; - } - - _PidController.SetPoint = modeSetting.SetPoint; - _PidController.PositiveSettings = modeSetting.PositivePid ?? new PidSetting(); - _PidController.NegativeSettings = modeSetting.NegativePid ?? new PidSetting(); - } } }