Files
Symcon_Belevo_Energiemanage…/Ladestation_OCPP/libs/PowerStepCalculator.php
T

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