feat(manager): Störungsüberwachung ans Portal anbinden
Tests / test (push) Successful in 47s

This commit is contained in:
dh
2026-09-27 15:41:15 +00:00
parent f47c908798
commit 2d24ce0900
6 changed files with 605 additions and 35 deletions
+31 -1
View File
@@ -70,6 +70,8 @@ final class ManagerModulstrukturTest extends TestCase
'PrognoseHausverbrauchVariableID',
'PrognoseSOCVariableID',
'PrognoseSendeintervall',
'StoerueberwachungAktiv',
'StoerungsSendeintervall',
] as $property) {
self::assertStringContainsString($property, $json);
}
@@ -201,7 +203,7 @@ final class ManagerModulstrukturTest extends TestCase
self::assertStringContainsString("'issueDeviceToken' =>", $inhalt);
self::assertStringContainsString("unset(\$neueLease['deviceToken'])", $inhalt);
self::assertStringContainsString(
"\$geraetezugangFehlt = (\$this->hatAnlagentopologie() || \$this->prognoseTelemetrieKonfiguriert())",
"|| \$this->ReadPropertyBoolean('StoerueberwachungAktiv'))",
$inhalt
);
self::assertStringContainsString(
@@ -237,6 +239,34 @@ final class ManagerModulstrukturTest extends TestCase
);
}
public function testManagerUebertraegtStoerungsvollsnapshotsMitRetry(): void
{
$inhalt = (string) file_get_contents(__DIR__ . '/../Manager/module.php');
self::assertFileExists(__DIR__ . '/../libs/StoerungsSnapshot.php');
self::assertStringContainsString(
'https://license.enelix.ch/api/v1/installations/%s/faults',
$inhalt
);
foreach ([
"RegisterPropertyBoolean('StoerueberwachungAktiv', false)",
"RegisterPropertyInteger('StoerungsSendeintervall', 300)",
"RegisterAttributeString('StoerungsSnapshot', '{}')",
"RegisterAttributeString('StoerungsGesendeterHash', '')",
"RegisterAttributeInteger('StoerungsNaechsterVersuch', 0)",
"'StoerungenSenden',",
'StoerungsSnapshot::erstellen(',
'StoerungsSnapshot::zustandHash(',
"CURLOPT_CUSTOMREQUEST => 'PUT'",
] as $erwartet) {
self::assertStringContainsString($erwartet, $inhalt);
}
self::assertStringNotContainsString(
'"name":"StoermeldeAnschluss"',
str_replace(' ', '', (string) file_get_contents(__DIR__ . '/../Manager/form.json'))
);
}
public function testManagerRegeltDieAnlagenweiteEinspeisegrenzeUndDenNetzfahrplan(): void
{
$inhalt = (string) file_get_contents(__DIR__ . '/../Manager/module.php');
+131
View File
@@ -0,0 +1,131 @@
<?php
declare(strict_types=1);
namespace Belevo\EnelixEMS\Tests;
use Belevo\EnelixEMS\StoerungsSnapshot;
use InvalidArgumentException;
use PHPUnit\Framework\TestCase;
final class StoerungsSnapshotTest extends TestCase
{
private const INSTALLATION_ID = '123e4567-e89b-42d3-a456-426614174000';
public function testSnapshotNormalisiertDedupliziertUndSortiertMeldungen(): void
{
$snapshot = StoerungsSnapshot::erstellen(
self::INSTALLATION_ID,
42,
'main',
true,
[
[
'sourceType' => 'consumer',
'sourceId' => 'ips:8',
'sourceName' => ' Boiler ',
'code' => 'Temp.High',
'severity' => 'warning',
'message' => " Temperatur hoch ",
],
[
'sourceType' => 'manager',
'sourceId' => 'ips:42',
'sourceName' => 'Manager',
'code' => 'Grid.Missing',
'severity' => 'critical',
'message' => 'Netzmessung fehlt',
],
[
'sourceType' => 'consumer',
'sourceId' => 'ips:8',
'sourceName' => 'Boiler',
'code' => 'Temp.High',
'severity' => 'warning',
'message' => 'Temperatur sehr hoch',
],
],
1_700_000_000
);
self::assertSame('1.0', $snapshot['version']);
self::assertSame('2023-11-14T22:13:20Z', $snapshot['capturedAt']);
self::assertSame(
['Grid.Missing', 'Temp.High'],
array_column($snapshot['faults'], 'code')
);
self::assertSame('Temperatur sehr hoch', $snapshot['faults'][1]['message']);
self::assertSame(
['instanceId' => 42, 'role' => 'main', 'active' => true],
$snapshot['manager']
);
}
public function testZustandHashIgnoriertDenErfassungszeitpunkt(): void
{
$a = StoerungsSnapshot::erstellen(
self::INSTALLATION_ID,
42,
'standalone',
false,
[],
1_700_000_000
);
$b = StoerungsSnapshot::erstellen(
self::INSTALLATION_ID,
42,
'standalone',
false,
[],
1_700_000_300
);
self::assertSame(StoerungsSnapshot::zustandHash($a), StoerungsSnapshot::zustandHash($b));
}
public function testSnapshotBegrenztSichAufHundertPriorisierteMeldungen(): void
{
$meldungen = [];
for ($index = 1; $index <= 101; ++$index) {
$meldungen[] = [
'sourceType' => 'consumer',
'sourceId' => 'ips:' . $index,
'sourceName' => sprintf('Quelle %03d', $index),
'code' => 'Fault.' . $index,
'severity' => $index === 101 ? 'critical' : 'warning',
'message' => 'Testmeldung ' . $index,
];
}
$snapshot = StoerungsSnapshot::erstellen(
self::INSTALLATION_ID,
42,
'standalone',
true,
$meldungen
);
self::assertCount(100, $snapshot['faults']);
self::assertSame('Fault.101', $snapshot['faults'][0]['code']);
}
public function testUngueltigerSchweregradWirdAbgelehnt(): void
{
$this->expectException(InvalidArgumentException::class);
StoerungsSnapshot::erstellen(
self::INSTALLATION_ID,
42,
'standalone',
true,
[[
'sourceType' => 'consumer',
'sourceId' => 'ips:8',
'sourceName' => 'Boiler',
'code' => 'Temp.High',
'severity' => 'alarm',
'message' => 'Temperatur hoch',
]]
);
}
}