This commit is contained in:
@@ -0,0 +1,190 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Belevo\EnelixEMS;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
final class WaermepumpenRegler
|
||||
{
|
||||
public const KONTAKTART_SPERRE_ERHOEHUNG = 0;
|
||||
public const KONTAKTART_SG_READY = 1;
|
||||
public const RUECKMELDUNG_LEISTUNG = 0;
|
||||
public const RUECKMELDUNG_BETRIEB = 1;
|
||||
public const STEUERZUSTAND_NORMAL = 0;
|
||||
public const STEUERZUSTAND_SPERRE = 1;
|
||||
public const STEUERZUSTAND_ERHOEHUNG = 2;
|
||||
|
||||
/** @return array{Kontakt1: bool, Kontakt2: bool} */
|
||||
public static function kontaktwerte(int $kontaktart, int $steuerzustand): array
|
||||
{
|
||||
self::pruefeKontaktart($kontaktart);
|
||||
self::pruefeSteuerzustand($steuerzustand);
|
||||
|
||||
return [
|
||||
'Kontakt1' => $steuerzustand === self::STEUERZUSTAND_SPERRE,
|
||||
'Kontakt2' => $steuerzustand === self::STEUERZUSTAND_ERHOEHUNG,
|
||||
];
|
||||
}
|
||||
|
||||
/** @param bool|int|float $rueckmeldung */
|
||||
public static function laeuft($rueckmeldung, int $rueckmeldungsart, float $laufschwelle): bool
|
||||
{
|
||||
self::pruefeRueckmeldungsart($rueckmeldungsart);
|
||||
if ($laufschwelle < 0) {
|
||||
throw new InvalidArgumentException('Die Laufschwelle darf nicht negativ sein.');
|
||||
}
|
||||
|
||||
if ($rueckmeldungsart === self::RUECKMELDUNG_BETRIEB) {
|
||||
return (bool) $rueckmeldung;
|
||||
}
|
||||
|
||||
return abs((float) $rueckmeldung) >= $laufschwelle;
|
||||
}
|
||||
|
||||
/** @param bool|int|float $rueckmeldung */
|
||||
public static function istleistung(
|
||||
$rueckmeldung,
|
||||
int $rueckmeldungsart,
|
||||
int $nennleistung
|
||||
): float {
|
||||
self::pruefeRueckmeldungsart($rueckmeldungsart);
|
||||
self::pruefeNennleistung($nennleistung);
|
||||
|
||||
if ($rueckmeldungsart === self::RUECKMELDUNG_BETRIEB) {
|
||||
return (bool) $rueckmeldung ? (float) $nennleistung : 0.0;
|
||||
}
|
||||
|
||||
return max(0.0, (float) $rueckmeldung);
|
||||
}
|
||||
|
||||
/** @return list<int> */
|
||||
public static function leistungsangebot(
|
||||
int $nennleistung,
|
||||
string $betriebsart,
|
||||
bool $laeuft,
|
||||
bool $verfuegbar,
|
||||
bool $mindestlaufzeitAktiv,
|
||||
bool $mindestsperrzeitAktiv,
|
||||
bool $sperrenZulaessig,
|
||||
bool $startenZulaessig,
|
||||
bool $sperrerholung
|
||||
): array {
|
||||
self::pruefeNennleistung($nennleistung);
|
||||
if (!in_array($betriebsart, [
|
||||
Nachrichtenvertrag::BETRIEBSART_PV,
|
||||
Nachrichtenvertrag::BETRIEBSART_PEAK,
|
||||
], true)) {
|
||||
throw new InvalidArgumentException('Die Betriebsart ist ungueltig.');
|
||||
}
|
||||
|
||||
if (!$verfuegbar) {
|
||||
return [$laeuft ? $nennleistung : 0];
|
||||
}
|
||||
if ($sperrerholung || $mindestlaufzeitAktiv) {
|
||||
return [$laeuft ? $nennleistung : 0];
|
||||
}
|
||||
|
||||
if ($betriebsart === Nachrichtenvertrag::BETRIEBSART_PV) {
|
||||
return ($laeuft || (!$mindestsperrzeitAktiv && $startenZulaessig))
|
||||
? [0, $nennleistung]
|
||||
: [0];
|
||||
}
|
||||
|
||||
return ($laeuft && $sperrenZulaessig)
|
||||
? [0, $nennleistung]
|
||||
: [$laeuft ? $nennleistung : 0];
|
||||
}
|
||||
|
||||
public static function restzeit(int $beginn, int $dauer, int $jetzt): int
|
||||
{
|
||||
if ($beginn < 0 || $dauer < 0 || $jetzt < 0) {
|
||||
throw new InvalidArgumentException('Zeitwerte duerfen nicht negativ sein.');
|
||||
}
|
||||
if ($beginn === 0 || $dauer === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return max(0, $beginn + $dauer - $jetzt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<array{Von: int, Bis: int}> $historie
|
||||
* @return list<array{Von: int, Bis: int}>
|
||||
*/
|
||||
public static function bereinigeSperrhistorie(array $historie, int $jetzt): array
|
||||
{
|
||||
if ($jetzt < 0) {
|
||||
throw new InvalidArgumentException('Der Zeitpunkt darf nicht negativ sein.');
|
||||
}
|
||||
|
||||
$grenze = $jetzt - 86400;
|
||||
$ergebnis = [];
|
||||
foreach ($historie as $intervall) {
|
||||
$von = (int) ($intervall['Von'] ?? -1);
|
||||
$bis = (int) ($intervall['Bis'] ?? -1);
|
||||
if ($von < 0 || $bis < $von || $bis <= $grenze) {
|
||||
continue;
|
||||
}
|
||||
$ergebnis[] = ['Von' => max($von, $grenze), 'Bis' => min($bis, $jetzt)];
|
||||
}
|
||||
|
||||
return $ergebnis;
|
||||
}
|
||||
|
||||
/** @param list<array{Von: int, Bis: int}> $historie */
|
||||
public static function sperrsekunden24h(
|
||||
array $historie,
|
||||
int $jetzt,
|
||||
?int $aktiverBeginn = null
|
||||
): int {
|
||||
$sekunden = 0;
|
||||
foreach (self::bereinigeSperrhistorie($historie, $jetzt) as $intervall) {
|
||||
$sekunden += $intervall['Bis'] - $intervall['Von'];
|
||||
}
|
||||
if ($aktiverBeginn !== null && $aktiverBeginn > 0) {
|
||||
$sekunden += max(0, $jetzt - max($aktiverBeginn, $jetzt - 86400));
|
||||
}
|
||||
|
||||
return min(86400, $sekunden);
|
||||
}
|
||||
|
||||
private static function pruefeKontaktart(int $kontaktart): void
|
||||
{
|
||||
if (!in_array($kontaktart, [
|
||||
self::KONTAKTART_SPERRE_ERHOEHUNG,
|
||||
self::KONTAKTART_SG_READY,
|
||||
], true)) {
|
||||
throw new InvalidArgumentException('Die Kontaktart ist ungueltig.');
|
||||
}
|
||||
}
|
||||
|
||||
private static function pruefeRueckmeldungsart(int $rueckmeldungsart): void
|
||||
{
|
||||
if (!in_array($rueckmeldungsart, [
|
||||
self::RUECKMELDUNG_LEISTUNG,
|
||||
self::RUECKMELDUNG_BETRIEB,
|
||||
], true)) {
|
||||
throw new InvalidArgumentException('Die Rueckmeldungsart ist ungueltig.');
|
||||
}
|
||||
}
|
||||
|
||||
private static function pruefeSteuerzustand(int $steuerzustand): void
|
||||
{
|
||||
if (!in_array($steuerzustand, [
|
||||
self::STEUERZUSTAND_NORMAL,
|
||||
self::STEUERZUSTAND_SPERRE,
|
||||
self::STEUERZUSTAND_ERHOEHUNG,
|
||||
], true)) {
|
||||
throw new InvalidArgumentException('Der Steuerzustand ist ungueltig.');
|
||||
}
|
||||
}
|
||||
|
||||
private static function pruefeNennleistung(int $nennleistung): void
|
||||
{
|
||||
if ($nennleistung <= 0) {
|
||||
throw new InvalidArgumentException('Die Nennleistung muss groesser als 0 sein.');
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user