32) { throw new InvalidArgumentException('Erkennungsstrom muss zwischen 6 und 32 A liegen.'); } $trennleistung = 2 * self::LEISTUNG_PRO_AMPERE_EINPHASIG * $angeforderterStrom; return $leistung > $trennleistung ? self::PHASEN_DREI : self::PHASEN_EIN; } /** * Die Schwelle und der Zuschlag von 2.5 A stammen aus der Enelix-1-Ladestation. * Ein Ladeende wird erst nach zuvor gemessener Ladeleistung angenommen, damit * die Anlaufzeit nach einer neuen Stromvorgabe nicht als volles Fahrzeug gilt. * * @param array{Rohstatus: int, Istleistung_W: float, Iststrom_A?: float, Phasenzahl?: int} $rohstatus * @return array */ public static function normalisiereStatus( array $rohstatus, bool $warVerbunden, bool $warGeladen = false, bool $ladungErwartet = true, bool $ladeleistungWurdeErkannt = false, int $bekanntePhasenzahl = self::PHASEN_UNBEKANNT ): array { $verbunden = $rohstatus['Rohstatus'] !== 1; $leistung = max(0.0, $rohstatus['Istleistung_W']); $phasen = self::PHASEN_UNBEKANNT; $ladestrom = 0.0; $geladen = false; if ($verbunden) { if (in_array($bekanntePhasenzahl, [self::PHASEN_EIN, self::PHASEN_DREI], true)) { $phasen = $bekanntePhasenzahl; } elseif (isset($rohstatus['Phasenzahl']) && in_array($rohstatus['Phasenzahl'], [self::PHASEN_EIN, self::PHASEN_DREI], true) ) { $phasen = (int) $rohstatus['Phasenzahl']; } elseif ($leistung > 7500.0) { $phasen = self::PHASEN_DREI; } $nenner = $phasen === self::PHASEN_DREI ? self::LEISTUNG_PRO_AMPERE_DREIPHASIG : self::LEISTUNG_PRO_AMPERE_EINPHASIG; $ladestrom = isset($rohstatus['Iststrom_A']) ? max(0.0, (float) $rohstatus['Iststrom_A']) : ($phasen === self::PHASEN_UNBEKANNT ? 0.0 : $leistung / $nenner); $ermittelterMaximalstrom = 2.5 + $ladestrom; $geladen = $warGeladen || ($warVerbunden && $ladungErwartet && $ladeleistungWurdeErkannt && $ermittelterMaximalstrom < 6.0); } if (!$verbunden) { $fahrzeugstatus = 1; } elseif ($geladen) { $fahrzeugstatus = 4; } elseif ($leistung > 0.0) { $fahrzeugstatus = 3; } else { $fahrzeugstatus = 2; } return [ 'FahrzeugVerbunden' => $verbunden, 'FahrzeugGeladen' => $geladen, 'Fahrzeugstatus' => $fahrzeugstatus, 'Phasenzahl' => $phasen, 'Istleistung_W' => $leistung, 'Ladestrom_A' => $ladestrom, ]; } public static function ermittleFahrzeugMaximalstrom( int $vorgegebenerStrom, float $gemessenerStrom, int $konfigurierterMaximalstrom ): ?int { if ($konfigurierterMaximalstrom < 6 || $konfigurierterMaximalstrom > 32) { throw new InvalidArgumentException('MaximalerLadestrom muss zwischen 6 und 32 A liegen.'); } if ($vorgegebenerStrom < 6 || $gemessenerStrom < 5.5) { return null; } $kandidat = max( 6, min($konfigurierterMaximalstrom, (int) floor($gemessenerStrom + 2.5)) ); if ($kandidat > $vorgegebenerStrom - 2 || $kandidat >= $konfigurierterMaximalstrom) { return null; } return $kandidat; } /** @return list */ public static function leistungsangebot( bool $aktiv, bool $ladefreigabe, bool $verbunden, bool $geladen, int $phasenzahl, int $maximalerLadestrom, bool $solarladen, bool $peakbetrieb ): array { if (!$aktiv || !$ladefreigabe || !$verbunden || $geladen) { return [0]; } if ($phasenzahl === self::PHASEN_UNBEKANNT) { return [0]; } $stufen = self::leistungsstufen($phasenzahl, $maximalerLadestrom); if ($stufen === []) { return [0]; } if ($solarladen) { return $peakbetrieb ? [0] : array_merge([0], $stufen); } if ($peakbetrieb) { return array_merge([0], $stufen); } return [$stufen[count($stufen) - 1]]; } public static function stromFuerLeistung(int $leistung, int $phasenzahl): int { if ($leistung <= 0) { return 0; } $stufen = self::stufenFuerPhasen($phasenzahl); if ($leistung < $stufen[0]) { return 0; } $strom = 6; foreach ($stufen as $index => $schwelle) { if ($leistung < $schwelle) { break; } $strom = 6 + $index; } return min(32, $strom); } /** @return list */ private static function leistungsstufen(int $phasenzahl, int $maximalerLadestrom): array { if ($maximalerLadestrom < 6 || $maximalerLadestrom > 32) { throw new InvalidArgumentException('MaximalerLadestrom muss zwischen 6 und 32 A liegen.'); } return array_slice(self::stufenFuerPhasen($phasenzahl), 0, $maximalerLadestrom - 5); } /** @return list */ private static function stufenFuerPhasen(int $phasenzahl): array { if ($phasenzahl === self::PHASEN_EIN) { $leistungProAmpere = self::LEISTUNG_PRO_AMPERE_EINPHASIG; } elseif ($phasenzahl === self::PHASEN_DREI) { $leistungProAmpere = self::LEISTUNG_PRO_AMPERE_DREIPHASIG; } else { throw new InvalidArgumentException('Phasenzahl muss 1 oder 3 sein.'); } return array_map( static fn (int $strom): int => $strom * $leistungProAmpere, range(6, 32) ); } }