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); } } }