Files
2026-10-06 13:45:54 +00:00

213 lines
7.3 KiB
PHP

<?php
declare(strict_types=1);
use Belevo\EnelixEMS\SymconTest\TestContext;
return static function (TestContext $test): void {
$numerischesRegister = static function (
TestContext $test,
string $name,
int $typ = 2
): int {
$variableID = $test->createVariable(
$typ,
$name,
$typ === 1 ? 0 : 0.0
);
$skriptID = IPS_CreateScript(0);
IPS_SetParent($skriptID, $test->rootId());
IPS_SetName($skriptID, $name . ' Aktion');
IPS_SetHidden($skriptID, true);
IPS_SetScriptContent($skriptID, <<<'PHP'
<?php
SetValue((int) $_IPS['VARIABLE'], $_IPS['VALUE']);
PHP
);
IPS_SetVariableCustomAction($variableID, $skriptID);
return $variableID;
};
$maxLadenID = $test->createVariable(2, 'Max Laden', 2000.0);
$maxEntladenID = $test->createVariable(2, 'Max Entladen', 2000.0);
$ladezustandID = $test->createVariable(2, 'Ladezustand', 50.0);
$netzleistungID = $test->createVariable(2, 'Netzleistung', 0.0);
$istleistungID = $test->createVariable(2, 'Batterieleistung', 0.0);
$managementID = $numerischesRegister($test, 'Management', 1);
$modusID = $numerischesRegister($test, 'Modus', 1);
$leistungID = $numerischesRegister($test, 'Leistung', 2);
$batterieID = $test->createInstance(
'{437FB683-517F-4FEC-8CCB-FE6B0A62B69E}',
'Batterie GoodWe',
[
'Batterietyp' => 2,
'Batteriemanagement' => 2,
'MaxLadeleistungVariableID' => $maxLadenID,
'MaxEntladeleistungVariableID' => $maxEntladenID,
'LadezustandVariableID' => $ladezustandID,
'NetzleistungVariableID' => $netzleistungID,
'IstleistungVariableID' => $istleistungID,
'ManagementRegisterVariableID' => $managementID,
'ModusRegisterVariableID' => $modusID,
'LeistungsRegisterVariableID' => $leistungID,
'ReserveLadezustand' => 20.0,
'MindestLadezustand' => 10.0,
'LadezustandHysterese' => 2.0,
'MesswertMaxAlter' => 120,
'Aenderungssperre' => 0,
'DiagnosevariablenAnzeigen' => true,
]
);
$managerID = $test->createInstance(
'{6F771B18-59D4-4C8A-B951-3B2FE9F6A2C4}',
'Hilfsmanager Batterie',
[
'AutomatischeSuche' => false,
'VerbraucherZuordnung' => json_encode([
['InstanzID' => $batterieID, 'Aktiv' => true],
], JSON_THROW_ON_ERROR),
]
);
$managerdatenSenden = static function (
string $betriebsart,
?int $leistung
) use ($managerID, $batterieID): void {
IPS_RequestAction($batterieID, 'ManagerdatenEmpfangen', json_encode([
'Kopf' => [
'Version' => '4.0',
'AbsenderID' => $managerID,
'EmpfaengerID' => $batterieID,
'Zeitpunkt' => time(),
],
'Betriebsart' => $betriebsart,
'Sollleistung_W' => $leistung,
], JSON_THROW_ON_ERROR));
};
$test->runCase(
'Instanz und Diagnosevariablen werden angelegt',
static function (TestContext $test) use ($batterieID): void {
$test->assertInstanceStatus($batterieID);
foreach ([
'Aktiv',
'Ladestatus',
'Istleistung',
'Sollleistung',
'Ladezustand',
'LadezustandGueltig',
'HystereseAktiv',
'LeistungsangebotDiagnose',
'LetzterRegisterbefehl',
] as $ident) {
$test->objectByIdent($ident, $batterieID);
}
}
);
$test->runCase(
'GoodWe-Laden schreibt Leistung Modus und Management direkt',
static function (TestContext $test) use (
$batterieID,
$managerdatenSenden,
$managementID,
$modusID,
$leistungID
): void {
IPS_RequestAction($batterieID, 'Aktiv', true);
$managerdatenSenden('PV', null);
$managerdatenSenden('PV', 537);
$test->waitUntil(
static fn (): bool => (float) GetValue($leistungID) === 537.0
&& (int) GetValue($modusID) === 11
&& (int) GetValue($managementID) === 2
);
}
);
$test->runCase(
'GoodWe-Entladen verwendet negativen Managerwert und Modus 12',
static function (TestContext $test) use (
$managerdatenSenden,
$batterieID,
$modusID,
$leistungID
): void {
$managerdatenSenden('PV', -843);
$test->waitUntil(
static fn (): bool => (float) GetValue($leistungID) === 843.0
&& (int) GetValue($modusID) === 12
);
$test->assertSame(-843, GetValue($test->objectByIdent('Sollleistung', $batterieID)));
IPS_RequestAction($batterieID, 'VorgabeTimeout', 0);
$test->assertSame(false, GetValue($test->objectByIdent('SollwertGueltig', $batterieID)));
$test->assertSame(0, GetValue($test->objectByIdent('Sollleistung', $batterieID)));
}
);
$test->runCase(
'Istleistungsereignis aktualisiert den Ladestatus ohne Regelzyklus',
static function (TestContext $test) use (
$batterieID,
$istleistungID
): void {
SetValue($istleistungID, -250.0);
$ladestatusID = $test->objectByIdent('Ladestatus', $batterieID);
$test->waitUntil(
static fn (): bool => (int) GetValue($ladestatusID) === 3
);
SetValue($istleistungID, 250.0);
$test->waitUntil(
static fn (): bool => (int) GetValue($ladestatusID) === 2
);
}
);
$test->runCase(
'Benutzerdefinierte Nachladeleistung begrenzt das Schutzangebot',
static function (TestContext $test) use (
$batterieID,
$ladezustandID,
$managerdatenSenden
): void {
$test->configureInstance($batterieID, [
'Batteriemanagement' => 2,
'NachladenMitMaximalleistung' => false,
'MaximaleNachladeleistung' => 400,
]);
IPS_RequestAction($batterieID, 'Aktiv', true);
SetValue($ladezustandID, 19.0);
$managerdatenSenden('PV', null);
$angebotID = $test->objectByIdent('LeistungsangebotDiagnose', $batterieID);
$test->waitUntil(
static fn (): bool => json_decode(
(string) GetValue($angebotID),
true
) === [400]
);
}
);
$test->runCase(
'Wechselrichtersteuerung setzt Leistung auf null und Automatikmodus',
static function (TestContext $test) use (
$batterieID,
$managementID,
$leistungID
): void {
$test->configureInstance($batterieID, ['Batteriemanagement' => 1]);
$test->assertSame(0, GetValue($test->objectByIdent('Sollleistung', $batterieID)));
$test->waitUntil(
static fn (): bool => (float) GetValue($leistungID) === 0.0
&& (int) GetValue($managementID) === 1
);
}
);
};