252 lines
9.0 KiB
PHP
252 lines
9.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use Belevo\EnelixEMS\SymconTest\TestContext;
|
|
|
|
return static function (TestContext $test): void {
|
|
$netzleistungId = $test->createVariable(2, 'Netzleistung', 0.0);
|
|
$einKontaktId = $test->createActionVariable('Kontakt Verbraucher 1-Stufig');
|
|
$einStufigId = $test->createInstance(
|
|
'{15879A4E-D0C2-4495-83DE-46E1E462591E}',
|
|
'Verbraucher 1-Stufig',
|
|
[
|
|
'Nennleistung' => 1000,
|
|
'SchaltkontaktVariableID' => $einKontaktId,
|
|
'Mindesteinschaltdauer' => 0,
|
|
'Mindestausschaltdauer' => 0,
|
|
'PrioritaetPV' => 0,
|
|
'PrioritaetPeak' => 0,
|
|
'DiagnosevariablenAnzeigen' => true,
|
|
]
|
|
);
|
|
|
|
$temperaturId = $test->createVariable(2, 'Boilertemperatur', 52.0);
|
|
$warmKontakte = [
|
|
$test->createActionVariable('Warmwasser Stufe 1'),
|
|
$test->createActionVariable('Warmwasser Stufe 2'),
|
|
];
|
|
$warmStufen = [
|
|
['Stufe' => 1, 'Leistung' => 1000, 'Schaltkontakt_Stufe' => $warmKontakte[0]],
|
|
['Stufe' => 2, 'Leistung' => 2000, 'Schaltkontakt_Stufe' => $warmKontakte[1]],
|
|
];
|
|
$warmwasserId = $test->createInstance(
|
|
'{B7C54AF4-AD7D-4FE4-B75D-203693906251}',
|
|
'Wassererwärmer',
|
|
[
|
|
'Boilerfuehler_PT1' => $temperaturId,
|
|
'LeistungsStufen' => json_encode($warmStufen, JSON_THROW_ON_ERROR),
|
|
'LastwechselSperrzeit' => 1,
|
|
'LegionellenfunktionAktiv' => false,
|
|
'PrioritaetPV' => 1,
|
|
'PrioritaetPeak' => 1,
|
|
'DiagnosevariablenAnzeigen' => true,
|
|
]
|
|
);
|
|
|
|
$zuordnung = [
|
|
['InstanzID' => $einStufigId, 'Aktiv' => true],
|
|
['InstanzID' => $warmwasserId, 'Aktiv' => true],
|
|
];
|
|
$lizenzcode = trim((string) getenv('ENELIX_TEST_LICENSE_CODE'));
|
|
$managerId = $test->createInstance(
|
|
'{6F771B18-59D4-4C8A-B951-3B2FE9F6A2C4}',
|
|
'Manager',
|
|
[
|
|
'NetzleistungVariableID' => $netzleistungId,
|
|
'Lizenzcode' => $lizenzcode,
|
|
'AutomatischeSuche' => false,
|
|
'VerbraucherZuordnung' => json_encode($zuordnung, JSON_THROW_ON_ERROR),
|
|
'KeepAlive' => 30,
|
|
'VerbraucherTimeout' => 10,
|
|
'Lastspitzenmodus' => 1,
|
|
'Lastspitzengrenze' => 0.0,
|
|
'SollwertSolarladen' => 0.0,
|
|
'Umschaltdifferenz' => 0.0,
|
|
'DiagnosevariablenAnzeigen' => true,
|
|
]
|
|
);
|
|
|
|
$melden = static function () use ($einStufigId, $warmwasserId): void {
|
|
foreach ([$einStufigId, $warmwasserId] as $instanzId) {
|
|
IPS_RequestAction($instanzId, 'Aktiv', true);
|
|
IPS_RequestAction($instanzId, 'Melden', true);
|
|
}
|
|
};
|
|
$regeln = static function (float $netzleistung) use (
|
|
$netzleistungId,
|
|
$managerId,
|
|
$einStufigId,
|
|
$warmwasserId
|
|
): void {
|
|
IPS_RequestAction($einStufigId, 'Melden', true);
|
|
IPS_RequestAction($warmwasserId, 'Melden', true);
|
|
SetValue($netzleistungId, $netzleistung);
|
|
IPS_RequestAction($managerId, 'Regeln', true);
|
|
};
|
|
$kontaktzustand = static fn (): array => [
|
|
(bool) GetValue($einKontaktId),
|
|
(bool) GetValue($warmKontakte[0]),
|
|
(bool) GetValue($warmKontakte[1]),
|
|
];
|
|
$warteAufKontakte = static function (array $erwartet, string $schritt) use (
|
|
$test,
|
|
$kontaktzustand,
|
|
$managerId
|
|
): void {
|
|
$deadline = microtime(true) + 5.0;
|
|
do {
|
|
if ($kontaktzustand() === $erwartet) {
|
|
return;
|
|
}
|
|
IPS_Sleep(50);
|
|
} while (microtime(true) < $deadline);
|
|
|
|
$test->fail(sprintf(
|
|
'%s: Kontaktbild %s statt %s; Betriebsart %s; Verteilbudget %.0f W.',
|
|
$schritt,
|
|
json_encode($kontaktzustand(), JSON_THROW_ON_ERROR),
|
|
json_encode($erwartet, JSON_THROW_ON_ERROR),
|
|
(string) GetValue($test->objectByIdent('Betriebsart', $managerId)),
|
|
(float) GetValue($test->objectByIdent('Verteilbudget', $managerId))
|
|
));
|
|
};
|
|
$verbraucherstatus = static function () use ($test, $managerId): array {
|
|
$json = (string) GetValue($test->objectByIdent('Verbraucherstatus', $managerId));
|
|
$daten = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
|
|
|
|
return is_array($daten) ? $daten : [];
|
|
};
|
|
$zustandswert = static function (array $daten, int $instanzId, string $kennung) {
|
|
foreach ($daten['Verbraucher'] ?? [] as $verbraucher) {
|
|
if (($verbraucher['InstanzID'] ?? 0) !== $instanzId) {
|
|
continue;
|
|
}
|
|
foreach ($verbraucher['Daten']['Zustand'] ?? [] as $zustand) {
|
|
if (($zustand['Kennung'] ?? '') === $kennung) {
|
|
return $zustand['Wert'] ?? null;
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
};
|
|
|
|
if ($lizenzcode === '') {
|
|
$test->runCase('Manager bleibt ohne Lizenz sicher gesperrt', static function (
|
|
TestContext $test
|
|
) use ($managerId): void {
|
|
IPS_RequestAction($managerId, 'Aktiv', true);
|
|
IPS_RequestAction($managerId, 'Regeln', true);
|
|
$test->assertInstanceStatus($managerId, 203);
|
|
$test->assertSame(
|
|
'Inaktiv',
|
|
GetValue($test->objectByIdent('Betriebsart', $managerId))
|
|
);
|
|
});
|
|
|
|
return;
|
|
}
|
|
|
|
$test->runCase('Manager und alle vorhandenen Verbrauchertypen sind verknüpft', static function (
|
|
TestContext $test
|
|
) use ($managerId, $einStufigId, $warmwasserId, $melden): void {
|
|
IPS_RequestAction($managerId, 'Aktiv', true);
|
|
$melden();
|
|
IPS_RequestAction($managerId, 'Regeln', true);
|
|
|
|
foreach ([$managerId, $einStufigId, $warmwasserId] as $instanzId) {
|
|
$test->assertInstanceStatus($instanzId);
|
|
}
|
|
$test->assertSame(
|
|
2,
|
|
GetValue($test->objectByIdent('VerbraucherAnzahl', $managerId))
|
|
);
|
|
$test->assertSame(
|
|
2,
|
|
GetValue($test->objectByIdent('VerbraucherVerfuegbar', $managerId))
|
|
);
|
|
});
|
|
|
|
$test->runCase('Netzleistung wird in beide Richtungen in PV und Peak geregelt', static function (
|
|
TestContext $test
|
|
) use ($managerId, $regeln, $warteAufKontakte): void {
|
|
$regeln(-3000.0);
|
|
$warteAufKontakte([true, false, true], 'Netz -3000 W');
|
|
$test->assertSame('PV', GetValue($test->objectByIdent('Betriebsart', $managerId)));
|
|
|
|
$regeln(-1000.0);
|
|
$warteAufKontakte([true, false, true], 'Netz -1000 W');
|
|
$regeln(0.0);
|
|
$warteAufKontakte([true, false, true], 'Netz 0 W');
|
|
|
|
IPS_Sleep(1100);
|
|
$regeln(1000.0);
|
|
$warteAufKontakte([true, true, false], 'Netz +1000 W');
|
|
$test->assertSame('Peak', GetValue($test->objectByIdent('Betriebsart', $managerId)));
|
|
|
|
IPS_Sleep(1100);
|
|
$regeln(3000.0);
|
|
$warteAufKontakte([false, false, false], 'Netz +3000 W');
|
|
});
|
|
|
|
$test->runCase('Keep-alive ist aktiv und erneuert unveränderte Sollwerte', static function (
|
|
TestContext $test
|
|
) use ($managerId, $einStufigId): void {
|
|
$sollwertId = $test->objectByIdent('Sollleistung', $einStufigId);
|
|
$vorher = (int) IPS_GetVariable($sollwertId)['VariableUpdated'];
|
|
IPS_Sleep(1100);
|
|
IPS_RequestAction($managerId, 'Regeln', true);
|
|
$test->waitUntil(
|
|
static fn (): bool => (int) IPS_GetVariable($sollwertId)['VariableUpdated'] > $vorher
|
|
);
|
|
});
|
|
|
|
$test->runCase('Alle definierten Nachrichtenauslöser aktualisieren den Manager', static function (
|
|
TestContext $test
|
|
) use (
|
|
$managerId,
|
|
$einStufigId,
|
|
$warmwasserId,
|
|
$temperaturId,
|
|
$melden,
|
|
$verbraucherstatus,
|
|
$zustandswert
|
|
): void {
|
|
$melden();
|
|
IPS_RequestAction($managerId, 'Regeln', false);
|
|
$daten = $verbraucherstatus();
|
|
$test->assertSame(2, count($daten['Verbraucher'] ?? []));
|
|
|
|
SetValue($temperaturId, 53.0);
|
|
$test->waitUntil(static function () use (
|
|
$managerId,
|
|
$warmwasserId,
|
|
$verbraucherstatus,
|
|
$zustandswert
|
|
): bool {
|
|
IPS_RequestAction($managerId, 'Regeln', false);
|
|
$wert = $zustandswert(
|
|
$verbraucherstatus(),
|
|
$warmwasserId,
|
|
'Wassertemperatur_C'
|
|
);
|
|
return is_numeric($wert) && abs((float) $wert - 53.0) < 0.01;
|
|
}, 4000, 100);
|
|
|
|
IPS_RequestAction($einStufigId, 'Melden', true);
|
|
IPS_RequestAction($warmwasserId, 'Melden', true);
|
|
IPS_RequestAction($managerId, 'Regeln', true);
|
|
$daten = $verbraucherstatus();
|
|
$test->assertTrue(
|
|
is_bool($zustandswert($daten, $einStufigId, 'Schaltzustand'))
|
|
);
|
|
$test->assertTrue(
|
|
is_int($zustandswert($daten, $warmwasserId, 'AktiveStufe'))
|
|
);
|
|
$test->assertSame(false, GetValue(
|
|
$test->objectByIdent('Sammelstoerung', $managerId)
|
|
));
|
|
});
|
|
};
|