Files
Enelix-EMS/tests/Symcon/modules/LadestationGateway.php
T
2026-10-06 13:45:54 +00:00

322 lines
12 KiB
PHP

<?php
declare(strict_types=1);
use Belevo\EnelixEMS\SymconTest\TestContext;
return static function (TestContext $test): void {
$gateway = $test->createInstance(
'{B7552FC9-87BC-49D0-8CCB-076BBB045BBE}',
'Easee Gateway fuer Ladestation',
[
'Active' => true,
'Testmodus' => true,
]
);
$station = $test->createInstance(
'{32F65988-BE55-4FD6-9FFF-CF1C4C8628F8}',
'Easee Ladestation',
[
'Betriebsmodus' => 0,
'Ladestationskennung' => 'EH123456',
'MaximalerLadestrom' => 16,
'Ladefreigabe' => true,
'Solarladen' => true,
'EinstellungenInVisu' => true,
'DiagnosevariablenAnzeigen' => true,
]
);
IPS_ConnectInstance($station, $gateway);
IPS_ApplyChanges($station);
$nurSolar = $test->createInstance(
'{32F65988-BE55-4FD6-9FFF-CF1C4C8628F8}',
'Easee nur Solarladen',
[
'Betriebsmodus' => 1,
'Ladestationskennung' => 'EH654321',
'MaximalerLadestrom' => 16,
'Ladefreigabe' => true,
'Solarladen' => false,
'EinstellungenInVisu' => true,
'DiagnosevariablenAnzeigen' => true,
]
);
IPS_ConnectInstance($nurSolar, $gateway);
IPS_ApplyChanges($nurSolar);
$sendeBeobachtung = static function (
string $seriennummer,
int $id,
$value
) use ($gateway): void {
IPS_RequestAction($gateway, 'TestObservation', json_encode([
'serialNumber' => $seriennummer,
'id' => $id,
'value' => $value,
], JSON_THROW_ON_ERROR));
};
foreach (['EH123456', 'EH654321'] as $seriennummer) {
$sendeBeobachtung($seriennummer, 47, 16.0);
$sendeBeobachtung($seriennummer, 104, 32.0);
$sendeBeobachtung($seriennummer, 109, 3);
$sendeBeobachtung($seriennummer, 110, 30);
$sendeBeobachtung($seriennummer, 120, 1.0);
$sendeBeobachtung($seriennummer, 182, 2.1);
$sendeBeobachtung($seriennummer, 183, 2.0);
$sendeBeobachtung($seriennummer, 184, 2.2);
}
$test->runCase('Fahrzeug und drei Phasen folgen direkt den API-Ereignissen', static function (
TestContext $test
) use ($station): void {
$test->assertSame(
true,
GetValue($test->objectByIdent('FahrzeugVerbunden', $station))
);
$test->assertSame(
3,
GetValue($test->objectByIdent('Phasenzahl', $station))
);
$test->assertSame(
3,
GetValue($test->objectByIdent('Fahrzeugstatus', $station))
);
$test->assertEquals(
2.2,
(float) GetValue($test->objectByIdent('Ladestrom', $station)),
0.01
);
});
$test->runCase('Event erzeugt ohne Polling ein dreiphasiges Leistungsangebot', static function (
TestContext $test
) use ($station): void {
IPS_RequestAction($station, 'Aktiv', true);
$test->assertSame(
'[0,4104,4788,5472,6156,6840,7524,8208,8892,9576,10260,10944]',
(string) GetValue(
$test->objectByIdent('LeistungsangebotDiagnose', $station)
)
);
$test->assertTrue(str_contains(
(string) GetValue(
$test->objectByIdent('LetzterGeraetebefehl', $station)
),
'"Ampere":0'
));
});
$test->runCase('Wartezustand startet konservativ ohne aktive Phase', static function (
TestContext $test
) use ($sendeBeobachtung, $station): void {
$sendeBeobachtung('EH123456', 42, true);
$sendeBeobachtung('EH123456', 43, true);
$sendeBeobachtung('EH123456', 96, 55);
$sendeBeobachtung('EH123456', 102, true);
$sendeBeobachtung('EH123456', 109, 2);
$sendeBeobachtung('EH123456', 110, 0);
IPS_RequestAction($station, 'Solarladen', false);
$test->assertSame(
0,
GetValue($test->objectByIdent('Phasenzahl', $station))
);
$test->assertInstanceStatus($station);
$test->assertSame(
'[3680]',
(string) GetValue(
$test->objectByIdent('LeistungsangebotDiagnose', $station)
)
);
$test->assertTrue(str_contains(
(string) GetValue(
$test->objectByIdent('LetzterGeraetebefehl', $station)
),
'"Ampere":16'
));
$test->assertTrue(str_contains(
(string) GetValue(
$test->objectByIdent('LetzterStartbefehl', $station)
),
'"Aktion":"StartCharging"'
));
$test->assertSame(
55,
GetValue($test->objectByIdent('GrundKeinLadestrom', $station))
);
$test->assertSame(
true,
GetValue($test->objectByIdent('AutorisierungErforderlich', $station))
);
IPS_RequestAction($station, 'Solarladen', true);
$sendeBeobachtung('EH123456', 110, 30);
$sendeBeobachtung('EH123456', 109, 3);
});
$test->runCase('Nur-Solar-Variante laesst Solarladen nicht abschalten', static function (
TestContext $test
) use ($nurSolar): void {
IPS_RequestAction($nurSolar, 'Solarladen', false);
$test->assertSame(
true,
GetValue($test->objectByIdent('Solarladen', $nurSolar))
);
});
$test->runCase('Unbekannter API-Status sperrt die Regelung', static function (
TestContext $test
) use ($sendeBeobachtung, $station): void {
$sendeBeobachtung('EH123456', 109, 99);
$test->assertSame(
false,
GetValue($test->objectByIdent('FahrzeugVerbunden', $station))
);
$test->assertInstanceStatus($station, 203);
$sendeBeobachtung('EH123456', 109, 3);
$test->assertSame(
true,
GetValue($test->objectByIdent('FahrzeugVerbunden', $station))
);
$test->assertInstanceStatus($station);
});
$test->runCase('Solarumschaltung wartet auf die neue Manager-Vorgabe', static function (
TestContext $test
) use ($station, $sendeBeobachtung): void {
$managerId = $test->createInstance(
'{6F771B18-59D4-4C8A-B951-3B2FE9F6A2C4}',
'Hilfsmanager Easee-Uebergang',
[
'AutomatischeSuche' => false,
'VerbraucherZuordnung' => json_encode([
['InstanzID' => $station, 'Aktiv' => true],
], JSON_THROW_ON_ERROR),
]
);
$sendeSollwert = static function (int $leistung) use ($managerId, $station): void {
IPS_RequestAction($station, 'ManagerdatenEmpfangen', json_encode([
'Kopf' => [
'Version' => '4.0',
'AbsenderID' => $managerId,
'EmpfaengerID' => $station,
'Zeitpunkt' => time(),
],
'Betriebsart' => 'PV',
'Sollleistung_W' => $leistung,
], JSON_THROW_ON_ERROR));
};
$sendeSollwert(4104);
$befehlVorUmschaltung = (string) GetValue(
$test->objectByIdent('LetzterGeraetebefehl', $station)
);
IPS_RequestAction($station, 'Solarladen', false);
$test->assertSame(
$befehlVorUmschaltung,
(string) GetValue($test->objectByIdent('LetzterGeraetebefehl', $station))
);
$test->assertSame(
0,
GetValue($test->objectByIdent('Sollleistung', $station)),
'Die verworfene Manager-Vorgabe darf nicht als aktuelle Sollleistung stehen bleiben.'
);
$test->assertSame(false, GetValue($test->objectByIdent('SollwertGueltig', $station)));
$sendeSollwert(10944);
$test->assertTrue(str_contains(
(string) GetValue($test->objectByIdent('LetzterGeraetebefehl', $station)),
'"Ampere":16'
));
IPS_RequestAction($station, 'Solarladen', true);
$sendeSollwert(0);
$test->assertSame(true, GetValue($test->objectByIdent('SollwertGueltig', $station)));
$test->assertSame(0, GetValue($test->objectByIdent('Sollleistung', $station)));
$sendeSollwert(10944);
$sendeBeobachtung('EH123456', 109, 1);
$test->assertSame('[0]', GetValue($test->objectByIdent('LeistungsangebotDiagnose', $station)));
$test->assertSame(false, GetValue($test->objectByIdent('SollwertGueltig', $station)));
$test->assertSame(0, GetValue($test->objectByIdent('Sollleistung', $station)));
$test->assertTrue(str_contains(
(string) GetValue($test->objectByIdent('LetzterGeraetebefehl', $station)),
'"Ampere":0'
));
$sendeBeobachtung('EH123456', 110, 30);
$sendeBeobachtung('EH123456', 109, 3);
$sendeSollwert(10944);
IPS_RequestAction($station, 'VorgabeTimeout', 0);
$test->assertSame(false, GetValue($test->objectByIdent('SollwertGueltig', $station)));
$test->assertSame(0, GetValue($test->objectByIdent('Sollleistung', $station)));
});
$test->runCase('SignalR-Abbruch erreicht die Ladestation', static function (
TestContext $test
) use ($gateway, $station): void {
IPS_RequestAction(
$gateway,
'TestSignalRFrame',
json_encode(['type' => 7], JSON_THROW_ON_ERROR)
);
$test->assertInstanceStatus($gateway, 203);
$test->assertInstanceStatus($station, 202);
$test->assertSame(
false,
GetValue($test->objectByIdent('GatewayVerbunden', $station))
);
IPS_RequestAction($gateway, 'TestSignalRFrame', '{}');
$test->assertInstanceStatus($gateway);
$test->assertInstanceStatus($station);
$test->assertSame(
true,
GetValue($test->objectByIdent('GatewayVerbunden', $station))
);
});
$test->runCase('Gateway-Ausfall verwirft Fahrzeug- und Phasenstatus', static function (
TestContext $test
) use ($gateway, $station): void {
IPS_SetProperty($gateway, 'Active', false);
IPS_ApplyChanges($gateway);
$test->assertSame(
false,
GetValue($test->objectByIdent('FahrzeugVerbunden', $station))
);
$test->assertSame(
0,
GetValue($test->objectByIdent('Phasenzahl', $station))
);
$test->assertInstanceStatus($station, 202);
});
$test->runCase('Leistungswerte und Fahrzeugstatus folgen ihrer Sichtbarkeitsgruppe', static function (
TestContext $test
) use ($station): void {
IPS_SetProperty($station, 'EinstellungenInVisu', true);
IPS_SetProperty($station, 'DiagnosevariablenAnzeigen', false);
IPS_ApplyChanges($station);
$test->assertTrue(@IPS_GetObjectIDByIdent('Istleistung', $station) !== false);
$test->assertTrue(@IPS_GetObjectIDByIdent('Sollleistung', $station) !== false);
$test->assertSame(false, @IPS_GetObjectIDByIdent('Fahrzeugstatus', $station));
IPS_SetProperty($station, 'EinstellungenInVisu', false);
IPS_SetProperty($station, 'DiagnosevariablenAnzeigen', true);
IPS_ApplyChanges($station);
$test->assertSame(false, @IPS_GetObjectIDByIdent('Istleistung', $station));
$test->assertSame(false, @IPS_GetObjectIDByIdent('Sollleistung', $station));
$test->assertTrue(@IPS_GetObjectIDByIdent('Fahrzeugstatus', $station) !== false);
});
};