Files
EMOS-TestApp/TestApp/CurrentLimitter.cs
2023-02-19 09:44:28 +01:00

68 lines
2.9 KiB
C#

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