68 lines
2.9 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|