82 lines
2.8 KiB
PHP
82 lines
2.8 KiB
PHP
<?php
|
|
|
|
class PowerStepCalculator
|
|
{
|
|
public const MODE_NEVER = 0;
|
|
public const MODE_ALWAYS = 1;
|
|
public const MODE_CONSTANT = 2;
|
|
public const MODE_SOLAR = 3;
|
|
public const MODE_MINIMAL_SOLAR = 4;
|
|
public const MODE_SOLAR_TARIFF = 5;
|
|
public const MODE_MINIMUM_ENERGY = 6;
|
|
public const MODE_TARGET_SOC = 7;
|
|
public const MODE_BIDIRECTIONAL = 8;
|
|
|
|
public function calculate(array $input): array
|
|
{
|
|
$currentPower = (int)round((float)($input['currentPowerW'] ?? 0));
|
|
if (!($input['idle'] ?? true)) {
|
|
return [$currentPower];
|
|
}
|
|
|
|
if (!($input['ladebereit'] ?? false) || ($input['manualLock'] ?? false)) {
|
|
return [0];
|
|
}
|
|
|
|
if (!($input['carDetected'] ?? false) || ($input['carFull'] ?? false)) {
|
|
return [0];
|
|
}
|
|
|
|
$mode = (int)($input['mode'] ?? self::MODE_NEVER);
|
|
if ($mode === self::MODE_NEVER) {
|
|
return [0];
|
|
}
|
|
|
|
$minCurrent = max(0.0, (float)($input['minCurrentA'] ?? 6.0));
|
|
$maxCurrent = max($minCurrent, (float)($input['maxCurrentA'] ?? 6.0));
|
|
$safeCurrent = max(0.0, (float)($input['safeCurrentA'] ?? 6.0));
|
|
$constantCurrent = max(0.0, (float)($input['constantCurrentA'] ?? $minCurrent));
|
|
$phaseCount = PhaseManager::normalizePhaseCount((int)($input['numberPhases'] ?? 3));
|
|
$voltage = (float)($input['voltage'] ?? 230.0);
|
|
|
|
$limitCurrent = $maxCurrent;
|
|
if (($input['groupLimitA'] ?? 0) > 0) {
|
|
$limitCurrent = min($limitCurrent, (float)$input['groupLimitA']);
|
|
}
|
|
if (($input['vnbLimitA'] ?? 0) > 0) {
|
|
$limitCurrent = min($limitCurrent, (float)$input['vnbLimitA']);
|
|
}
|
|
if (($input['vnbLimitW'] ?? 0) > 0) {
|
|
$limitCurrent = min($limitCurrent, PhaseManager::currentFromPower((float)$input['vnbLimitW'], $phaseCount, $voltage));
|
|
}
|
|
|
|
if ($limitCurrent < $minCurrent) {
|
|
return [0];
|
|
}
|
|
|
|
if ($mode === self::MODE_CONSTANT) {
|
|
$target = min(max($constantCurrent, $safeCurrent), $limitCurrent);
|
|
return $this->uniqueSorted([0, PhaseManager::wattsFromCurrent($target, $phaseCount, $voltage)]);
|
|
}
|
|
|
|
$steps = [0];
|
|
for ($current = (int)ceil($minCurrent); $current <= (int)floor($limitCurrent); $current++) {
|
|
$steps[] = PhaseManager::wattsFromCurrent((float)$current, $phaseCount, $voltage);
|
|
}
|
|
|
|
return $this->uniqueSorted($steps);
|
|
}
|
|
|
|
private function uniqueSorted(array $steps): array
|
|
{
|
|
$steps = array_map(static function ($value) {
|
|
return (int)round((float)$value);
|
|
}, $steps);
|
|
$steps = array_values(array_unique($steps));
|
|
sort($steps, SORT_NUMERIC);
|
|
return $steps;
|
|
}
|
|
}
|
|
|
|
?>
|