Tests / test (push) Failing after 1m12s
Add opt-in SDL measurement sources and independent visualization toggles. Exclude balancing power from household telemetry and new household energy. Preserve custom views and cover measurement, migration and Symcon 8.0 behavior.
703 lines
30 KiB
PHP
703 lines
30 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use Belevo\EnelixEMS\SymconTest\TestContext;
|
|
|
|
return static function (TestContext $test): void {
|
|
$netzleistungId = $test->createVariable(2, 'Netzleistung', -800.0);
|
|
$netzbezugEnergieId = $test->createVariable(2, 'Netzbezug-Energie', 32.0);
|
|
$netzeinspeisungEnergieId = $test->createVariable(2, 'Netzeinspeisung-Energie', 16.0);
|
|
$pvLeistungId = $test->createVariable(2, 'PV-Leistung', 4200.0);
|
|
$pvEnergieId = $test->createVariable(2, 'PV-Energie', 120.0);
|
|
$batterieLeistungId = $test->createVariable(2, 'Batterieleistung', 700.0);
|
|
$batterieLadeenergieId = $test->createVariable(2, 'Batterie-Ladeenergie', 18.0);
|
|
$batterieEntladeenergieId = $test->createVariable(2, 'Batterie-Entladeenergie', 12.0);
|
|
$batterieSocId = $test->createVariable(2, 'Batterie-Ladezustand', 62.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,
|
|
]
|
|
);
|
|
|
|
$pufferTemperaturId = $test->createVariable(2, 'Puffertemperatur', 52.0);
|
|
$aussenTemperaturId = $test->createVariable(2, 'Aussentemperatur', 5.0);
|
|
$pufferKontakte = [
|
|
$test->createActionVariable('Pufferspeicher Stufe 1'),
|
|
$test->createActionVariable('Pufferspeicher Stufe 2'),
|
|
];
|
|
$pufferspeicherId = $test->createInstance(
|
|
'{C92D5EEF-9632-47A5-9659-4B02BF40FBE9}',
|
|
'Pufferspeicher',
|
|
[
|
|
'PufferfuehlerVariableID' => $pufferTemperaturId,
|
|
'AussentemperaturVariableID' => $aussenTemperaturId,
|
|
'LeistungsStufen' => json_encode([
|
|
['Stufe' => 1, 'Leistung' => 1000, 'Schaltkontakt_Stufe' => $pufferKontakte[0]],
|
|
['Stufe' => 2, 'Leistung' => 2000, 'Schaltkontakt_Stufe' => $pufferKontakte[1]],
|
|
], JSON_THROW_ON_ERROR),
|
|
'LastwechselSperrzeit' => 0,
|
|
'PrioritaetPV' => 2,
|
|
'PrioritaetPeak' => 2,
|
|
'DiagnosevariablenAnzeigen' => true,
|
|
]
|
|
);
|
|
|
|
$zuordnung = [
|
|
['InstanzID' => $einStufigId, 'Aktiv' => true],
|
|
['InstanzID' => $warmwasserId, 'Aktiv' => true],
|
|
['InstanzID' => $pufferspeicherId, 'Aktiv' => true],
|
|
];
|
|
$wechselrichterKonfiguration = [[
|
|
'ID' => 'hybrid-1',
|
|
'Name' => 'Hybridwechselrichter',
|
|
'Typ' => 'hybrid',
|
|
'ACNennleistung_kW' => 10.0,
|
|
'IstleistungVariableID' => $pvLeistungId,
|
|
'Istleistungsfaktor' => 1.0,
|
|
'ErzeugungsenergieVariableID' => $pvEnergieId,
|
|
'Erzeugungsenergiefaktor' => 1.0,
|
|
]];
|
|
$pvKonfiguration = [[
|
|
'ID' => 'pv-1',
|
|
'Name' => 'Suedflaeche',
|
|
'DCLeistung_kWp' => 12.0,
|
|
'Neigung_Grad' => 30.0,
|
|
'Azimut_Grad' => 0.0,
|
|
'WechselrichterID' => 'hybrid-1',
|
|
'MPPT' => 'A',
|
|
'Modulanzahl' => 30,
|
|
'Modulleistung_Wp' => 400.0,
|
|
]];
|
|
$batterieKonfiguration = [[
|
|
'ID' => 'bat-1',
|
|
'Name' => 'Hausspeicher',
|
|
'Nennkapazitaet_kWh' => 13.5,
|
|
'Nutzkapazitaet_kWh' => 12.8,
|
|
'MaxLadeleistung_kW' => 5.0,
|
|
'MaxEntladeleistung_kW' => 5.0,
|
|
'WechselrichterID' => 'hybrid-1',
|
|
'Kopplung' => 'hybrid',
|
|
'LeistungVariableID' => $batterieLeistungId,
|
|
'Leistungsfaktor' => 1.0,
|
|
'SOCVariableID' => $batterieSocId,
|
|
'LadeenergieVariableID' => $batterieLadeenergieId,
|
|
'EntladeenergieVariableID' => $batterieEntladeenergieId,
|
|
'Energiefaktor' => 1.0,
|
|
]];
|
|
$lizenzcode = trim((string) getenv('ENELIX_TEST_LICENSE_CODE'));
|
|
$managerId = $test->createInstance(
|
|
'{6F771B18-59D4-4C8A-B951-3B2FE9F6A2C4}',
|
|
'Manager',
|
|
[
|
|
'NetzleistungVariableID' => $netzleistungId,
|
|
'NetzbezugEnergieVariableID' => $netzbezugEnergieId,
|
|
'NetzeinspeisungEnergieVariableID' => $netzeinspeisungEnergieId,
|
|
'EnergyPieAnzeigen' => true,
|
|
'EnergiediagrammeAnzeigen' => true,
|
|
'FunFactsAnzeigen' => true,
|
|
'EnergieflussAnzeigen' => true,
|
|
'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,
|
|
'AnlagenWechselrichter' => json_encode(
|
|
$wechselrichterKonfiguration,
|
|
JSON_THROW_ON_ERROR
|
|
),
|
|
'AnlagenPVFlaechen' => json_encode($pvKonfiguration, JSON_THROW_ON_ERROR),
|
|
'AnlagenBatterien' => json_encode($batterieKonfiguration, JSON_THROW_ON_ERROR),
|
|
'DiagnosevariablenAnzeigen' => true,
|
|
]
|
|
);
|
|
|
|
$melden = static function () use ($einStufigId, $warmwasserId, $pufferspeicherId): void {
|
|
foreach ([$einStufigId, $warmwasserId, $pufferspeicherId] as $instanzId) {
|
|
IPS_RequestAction($instanzId, 'Aktiv', true);
|
|
IPS_RequestAction($instanzId, 'Melden', true);
|
|
}
|
|
};
|
|
$regeln = static function (float $netzleistung) use (
|
|
$netzleistungId,
|
|
$managerId,
|
|
$einStufigId,
|
|
$warmwasserId,
|
|
$pufferspeicherId
|
|
): void {
|
|
IPS_RequestAction($einStufigId, 'Melden', true);
|
|
IPS_RequestAction($warmwasserId, 'Melden', true);
|
|
IPS_RequestAction($pufferspeicherId, '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]),
|
|
(bool) GetValue($pufferKontakte[0]),
|
|
(bool) GetValue($pufferKontakte[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 : [];
|
|
};
|
|
$lizenzInstallationID = static function () use ($test, $managerId): string {
|
|
$formular = IPS_GetConfigurationForm($managerId);
|
|
if (preg_match(
|
|
'/Installations-ID: ([0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})/i',
|
|
$formular,
|
|
$treffer
|
|
) !== 1) {
|
|
$test->fail('Das Manager-Formular enthaelt keine gueltige Installations-ID.');
|
|
}
|
|
|
|
return strtolower($treffer[1]);
|
|
};
|
|
$test->runCase('Installations-ID bleibt bei ApplyChanges stabil', static function (
|
|
TestContext $test
|
|
) use ($managerId, $lizenzInstallationID): void {
|
|
$vorher = $lizenzInstallationID();
|
|
IPS_ApplyChanges($managerId);
|
|
$test->assertSame($vorher, $lizenzInstallationID());
|
|
|
|
$topologie = json_decode(
|
|
ENELIX_AnlagentopologieExportieren($managerId),
|
|
true,
|
|
512,
|
|
JSON_THROW_ON_ERROR
|
|
);
|
|
$test->assertSame($vorher, $topologie['installationId'] ?? null);
|
|
$test->assertSame('1.0', $topologie['version'] ?? null);
|
|
$test->assertSame(12.0, $topologie['summary']['pvDcKwp'] ?? null);
|
|
$test->assertSame(10.0, $topologie['summary']['pvAcKw'] ?? null);
|
|
$test->assertSame(12.8, $topologie['summary']['usableBatteryKwh'] ?? null);
|
|
$test->assertSame('hybrid-1', $topologie['sharedAcLimits'][0]['inverterId'] ?? null);
|
|
$test->assertSame(['pv-1'], $topologie['sharedAcLimits'][0]['pvArrayIds'] ?? null);
|
|
$test->assertSame(['bat-1'], $topologie['sharedAcLimits'][0]['batteryIds'] ?? null);
|
|
});
|
|
$test->runCase('Energiewerte, Archivregeln und Unterobjekte werden erzeugt', static function (
|
|
TestContext $test
|
|
) use ($managerId, $pvLeistungId): void {
|
|
IPS_RequestAction($managerId, 'MesswerteAufzeichnen', true);
|
|
$test->assertSame(
|
|
4200.0,
|
|
GetValue($test->objectByIdent('PVLeistungArchiv', $managerId)),
|
|
sprintf(
|
|
'PV-Archiv unveraendert; Quelle %.1f W, Managerstatus %d, Konfiguration %s.',
|
|
(float) GetValue($pvLeistungId),
|
|
(int) IPS_GetInstance($managerId)['InstanceStatus'],
|
|
(string) IPS_GetProperty($managerId, 'AnlagenWechselrichter')
|
|
)
|
|
);
|
|
$test->assertSame(
|
|
2700.0,
|
|
GetValue($test->objectByIdent('HausverbrauchLeistungArchiv', $managerId))
|
|
);
|
|
$test->assertSame(
|
|
-800.0,
|
|
GetValue($test->objectByIdent('NetzleistungArchiv', $managerId))
|
|
);
|
|
$test->assertSame(
|
|
700.0,
|
|
GetValue($test->objectByIdent('BatterieleistungArchiv', $managerId))
|
|
);
|
|
|
|
$archive = IPS_GetInstanceListByModuleID(
|
|
'{43192F0B-135B-4CE7-A0A7-1475603F3060}'
|
|
);
|
|
$test->assertTrue($archive !== []);
|
|
$archivID = (int) $archive[0];
|
|
$leistungID = $test->objectByIdent('PVLeistungArchiv', $managerId);
|
|
$energieID = $test->objectByIdent('PVEnergie', $managerId);
|
|
$test->assertSame(true, AC_GetLoggingStatus($archivID, $leistungID));
|
|
$test->assertSame(0, AC_GetAggregationType($archivID, $leistungID));
|
|
$test->assertSame(1, AC_GetAggregationType($archivID, $energieID));
|
|
|
|
foreach (['Leistungsdiagramm', 'Energiediagramm'] as $ident) {
|
|
$medienID = $test->objectByIdent($ident, $managerId);
|
|
$test->assertSame(4, (int) IPS_GetMedia($medienID)['MediaType']);
|
|
}
|
|
$html = (string) GetValue($test->objectByIdent('EnergieFunFacts', $managerId));
|
|
$test->assertTrue(str_contains($html, 'Solar'));
|
|
$test->assertTrue(str_contains($html, 'Netz & Haus'));
|
|
$energieflussID = $test->objectByIdent('Energiefluss', $managerId);
|
|
$test->assertSame(
|
|
'{BA90FDB3-C203-8F26-B4D6-F3DB99905724}',
|
|
IPS_GetInstance($energieflussID)['ModuleInfo']['ModuleID']
|
|
);
|
|
$knoten = json_decode(
|
|
(string) IPS_GetProperty($energieflussID, 'Config'),
|
|
true,
|
|
512,
|
|
JSON_THROW_ON_ERROR
|
|
);
|
|
$namen = array_column($knoten, 'Name');
|
|
foreach (['Verbraucher 1-Stufig', 'Wassererwärmer', 'Pufferspeicher'] as $name) {
|
|
$test->assertTrue(in_array($name, $namen, true));
|
|
}
|
|
foreach ($knoten as $knotenEintrag) {
|
|
if (in_array(
|
|
$knotenEintrag['Name'],
|
|
['Verbraucher 1-Stufig', 'Wassererwärmer', 'Pufferspeicher'],
|
|
true
|
|
)) {
|
|
$test->assertTrue((int) $knotenEintrag['InfoVariableID'] > 1);
|
|
}
|
|
}
|
|
$pvFlussID = $test->objectByIdent('EnergieflussPV', $managerId);
|
|
$test->assertSame(
|
|
4200.0,
|
|
(float) GetValue($pvFlussID),
|
|
'Der anfaengliche PV-Energiefluss ist falsch.'
|
|
);
|
|
$test->assertSame('~Power', IPS_GetVariable($pvFlussID)['VariableProfile']);
|
|
|
|
$pieID = $test->objectByIdent('EnergyPie', $managerId);
|
|
$leistungsdiagrammID = $test->objectByIdent('Leistungsdiagramm', $managerId);
|
|
$energiediagrammID = $test->objectByIdent('Energiediagramm', $managerId);
|
|
$energiediagramm = json_decode(
|
|
base64_decode((string) IPS_GetMediaContent($energiediagrammID), true),
|
|
true,
|
|
512,
|
|
JSON_THROW_ON_ERROR
|
|
);
|
|
$energietitel = array_column($energiediagramm['datasets'] ?? [], 'title');
|
|
foreach ($energiediagramm['datasets'] ?? [] as $datensatz) {
|
|
$test->assertSame('bar', $datensatz['type'] ?? null);
|
|
}
|
|
foreach ([
|
|
'Netzbezug',
|
|
'Netzeinspeisung',
|
|
'Batterie laden gesamt',
|
|
'Batterie entladen gesamt',
|
|
] as $titel) {
|
|
$test->assertTrue(in_array($titel, $energietitel, true));
|
|
}
|
|
|
|
$angepasstesDiagramm = base64_encode(
|
|
json_encode(['datasets' => [], 'custom' => 'bleibt'], JSON_THROW_ON_ERROR)
|
|
);
|
|
IPS_SetMediaContent($energiediagrammID, $angepasstesDiagramm);
|
|
IPS_SetProperty($pieID, 'Zaehlerfaktor', 2.0);
|
|
IPS_ApplyChanges($pieID);
|
|
IPS_SetProperty($energieflussID, 'Config', '[]');
|
|
IPS_ApplyChanges($energieflussID);
|
|
IPS_SetProperty($managerId, 'EnergieflussLeistungseinheit', 1);
|
|
IPS_SetProperty($managerId, 'DiagrammPVModus', 2);
|
|
IPS_SetProperty($managerId, 'DiagrammBatterieModus', 2);
|
|
IPS_ApplyChanges($managerId);
|
|
|
|
$test->assertSame($pieID, $test->objectByIdent('EnergyPie', $managerId));
|
|
$test->assertSame(
|
|
$leistungsdiagrammID,
|
|
$test->objectByIdent('Leistungsdiagramm', $managerId)
|
|
);
|
|
$test->assertSame(
|
|
$energiediagrammID,
|
|
$test->objectByIdent('Energiediagramm', $managerId)
|
|
);
|
|
$test->assertSame(
|
|
$angepasstesDiagramm,
|
|
(string) IPS_GetMediaContent($energiediagrammID)
|
|
);
|
|
$test->assertSame(2.0, (float) IPS_GetProperty($pieID, 'Zaehlerfaktor'));
|
|
$test->assertSame('[]', (string) IPS_GetProperty($energieflussID, 'Config'));
|
|
$test->assertSame(
|
|
4200.0,
|
|
(float) GetValue($pvFlussID),
|
|
'Der bestehende PV-Energiefluss wurde beim Apply veraendert.'
|
|
);
|
|
$test->assertSame('~Power', IPS_GetVariable($pvFlussID)['VariableProfile']);
|
|
|
|
foreach ([
|
|
'EnergyPieAnzeigen',
|
|
'EnergiediagrammeAnzeigen',
|
|
'FunFactsAnzeigen',
|
|
'EnergieflussAnzeigen',
|
|
] as $property) {
|
|
IPS_SetProperty($managerId, $property, false);
|
|
}
|
|
IPS_ApplyChanges($managerId);
|
|
foreach ([
|
|
'EnergyPie',
|
|
'Leistungsdiagramm',
|
|
'Energiediagramm',
|
|
'EnergieFunFacts',
|
|
] as $ident) {
|
|
$test->assertSame(
|
|
false,
|
|
@IPS_GetObjectIDByIdent($ident, $managerId),
|
|
$ident . ' wurde beim Ausschalten nicht entfernt.'
|
|
);
|
|
}
|
|
$test->assertSame(
|
|
true,
|
|
(bool) IPS_GetObject($energieflussID)['ObjectIsHidden']
|
|
);
|
|
|
|
foreach ([
|
|
'EnergyPieAnzeigen',
|
|
'EnergiediagrammeAnzeigen',
|
|
'EnergieflussAnzeigen',
|
|
] as $property) {
|
|
IPS_SetProperty($managerId, $property, true);
|
|
}
|
|
IPS_ApplyChanges($managerId);
|
|
$neuerFlussID = $test->objectByIdent('Energiefluss', $managerId);
|
|
$test->assertSame($energieflussID, $neuerFlussID);
|
|
$test->assertSame(false, (bool) IPS_GetObject($neuerFlussID)['ObjectIsHidden']);
|
|
$test->assertTrue((string) IPS_GetProperty($neuerFlussID, 'Config') !== '[]');
|
|
$test->assertSame(4.2, (float) GetValue($pvFlussID));
|
|
$test->assertSame('Enelix.Power.kW', IPS_GetVariable($pvFlussID)['VariableProfile']);
|
|
|
|
$neuesLeistungsdiagramm = json_decode(
|
|
base64_decode(
|
|
(string) IPS_GetMediaContent(
|
|
$test->objectByIdent('Leistungsdiagramm', $managerId)
|
|
),
|
|
true
|
|
),
|
|
true,
|
|
512,
|
|
JSON_THROW_ON_ERROR
|
|
);
|
|
$leistungstitel = array_column(
|
|
$neuesLeistungsdiagramm['datasets'] ?? [],
|
|
'title'
|
|
);
|
|
foreach (['PV gesamt', 'Hybridwechselrichter', 'Batterie gesamt', 'Hausspeicher'] as $titel) {
|
|
$test->assertTrue(in_array($titel, $leistungstitel, true));
|
|
}
|
|
});
|
|
|
|
$test->runCase('SDL korrigiert Hauslast und ergaenzt bestehende Anzeigen idempotent', static function (
|
|
TestContext $test
|
|
) use ($managerId): void {
|
|
$leistungID = $test->createVariable(2, 'SDL Istleistung', -1.2);
|
|
$socID = $test->createVariable(2, 'SDL SOC', 47.5);
|
|
$flussID = $test->objectByIdent('Energiefluss', $managerId);
|
|
$chartID = $test->objectByIdent('Leistungsdiagramm', $managerId);
|
|
$flussVorher = json_decode(IPS_GetProperty($flussID, 'Config'), true, 512, JSON_THROW_ON_ERROR);
|
|
$chartVorher = json_decode(base64_decode(IPS_GetMediaContent($chartID)), true, 512, JSON_THROW_ON_ERROR);
|
|
try {
|
|
IPS_SetProperty($managerId, 'SDLAktiv', true);
|
|
IPS_SetProperty($managerId, 'SDLLeistungVariableID', $leistungID);
|
|
IPS_SetProperty($managerId, 'SDLLeistungsfaktor', -1000.0);
|
|
IPS_SetProperty($managerId, 'SDLSOCVariableID', $socID);
|
|
IPS_SetProperty($managerId, 'SDLEnergieflussAnzeigen', true);
|
|
IPS_SetProperty($managerId, 'SDLDiagrammeAnzeigen', true);
|
|
IPS_ApplyChanges($managerId);
|
|
$test->assertSame(1500.0, GetValue($test->objectByIdent('HausverbrauchLeistungArchiv', $managerId)));
|
|
$test->assertSame(1200.0, GetValue($test->objectByIdent('SDLLeistungArchiv', $managerId)));
|
|
$test->assertSame(47.5, GetValue($test->objectByIdent('SDLSOCArchiv', $managerId)));
|
|
$test->assertSame(1.2, GetValue($test->objectByIdent('EnergieflussSDL', $managerId)));
|
|
$test->assertSame('Aktiv', GetValue($test->objectByIdent('SDLStatus', $managerId)));
|
|
$fluss = json_decode(IPS_GetProperty($flussID, 'Config'), true, 512, JSON_THROW_ON_ERROR);
|
|
$test->assertSame($flussVorher, array_slice($fluss, 0, count($flussVorher)));
|
|
$test->assertSame(count($flussVorher) + 1, count($fluss));
|
|
$test->assertSame($test->objectByIdent('SDLSOCArchiv', $managerId), $fluss[count($fluss) - 1]['InfoVariableID']);
|
|
$chart = json_decode(base64_decode(IPS_GetMediaContent($chartID)), true, 512, JSON_THROW_ON_ERROR);
|
|
$test->assertSame($chartVorher['datasets'], array_slice($chart['datasets'], 0, count($chartVorher['datasets'])));
|
|
$test->assertSame('right', $chart['datasets'][count($chart['datasets']) - 1]['side']);
|
|
$test->assertSame('~Intensity.100', $chart['datasets'][count($chart['datasets']) - 1]['profile']);
|
|
IPS_ApplyChanges($managerId);
|
|
$test->assertSame($fluss, json_decode(IPS_GetProperty($flussID, 'Config'), true, 512, JSON_THROW_ON_ERROR));
|
|
$test->assertSame($chart, json_decode(base64_decode(IPS_GetMediaContent($chartID)), true, 512, JSON_THROW_ON_ERROR));
|
|
|
|
foreach ([0 => ['~Power', 1200.0], 1 => ['Enelix.Power.kW', 1.2]] as $einheit => $erwartet) {
|
|
IPS_SetProperty($managerId, 'EnergieflussAnzeigen', false);
|
|
IPS_ApplyChanges($managerId);
|
|
IPS_SetProperty($managerId, 'EnergieflussLeistungseinheit', $einheit);
|
|
IPS_SetProperty($managerId, 'EnergieflussAnzeigen', true);
|
|
IPS_ApplyChanges($managerId);
|
|
$flussID = $test->objectByIdent('Energiefluss', $managerId);
|
|
$sdlID = $test->objectByIdent('EnergieflussSDL', $managerId);
|
|
$test->assertSame($erwartet[0], IPS_GetVariable($sdlID)['VariableProfile']);
|
|
$test->assertSame($erwartet[1], GetValue($sdlID));
|
|
}
|
|
|
|
IPS_SetProperty($managerId, 'SDLEnergieflussAnzeigen', false);
|
|
IPS_SetProperty($managerId, 'SDLDiagrammeAnzeigen', false);
|
|
IPS_ApplyChanges($managerId);
|
|
$test->assertSame($flussVorher, json_decode(IPS_GetProperty($flussID, 'Config'), true, 512, JSON_THROW_ON_ERROR));
|
|
$test->assertSame($chartVorher, json_decode(base64_decode(IPS_GetMediaContent($chartID)), true, 512, JSON_THROW_ON_ERROR));
|
|
$test->assertSame(1500.0, GetValue($test->objectByIdent('HausverbrauchLeistungArchiv', $managerId)));
|
|
$test->assertEquals(1.9, GetValue($test->objectByIdent('EnergieflussBatterie', $managerId)), 0.000001);
|
|
|
|
IPS_SetProperty($managerId, 'SDLSOCVariableID', 0);
|
|
IPS_SetProperty($managerId, 'SDLDiagrammeAnzeigen', true);
|
|
IPS_ApplyChanges($managerId);
|
|
$chart = json_decode(base64_decode(IPS_GetMediaContent($chartID)), true, 512, JSON_THROW_ON_ERROR);
|
|
$test->assertSame(count($chartVorher['datasets']) + 1, count($chart['datasets']));
|
|
IPS_SetProperty($managerId, 'EnergieaufzeichnungAktiv', false);
|
|
$test->assertTrue(IPS_ApplyChanges($managerId));
|
|
$archivID = IPS_GetInstanceListByModuleID('{43192F0B-135B-4CE7-A0A7-1475603F3060}')[0];
|
|
foreach (['SDLLeistungArchiv', 'SDLSOCArchiv', 'SDLLadenEnergie', 'SDLEntladenEnergie'] as $ident) {
|
|
$test->assertSame(false, AC_GetLoggingStatus($archivID, $test->objectByIdent($ident, $managerId)));
|
|
}
|
|
} finally {
|
|
IPS_SetProperty($managerId, 'EnergieaufzeichnungAktiv', true);
|
|
IPS_SetProperty($managerId, 'SDLAktiv', false);
|
|
IPS_SetProperty($managerId, 'SDLEnergieflussAnzeigen', false);
|
|
IPS_SetProperty($managerId, 'SDLDiagrammeAnzeigen', false);
|
|
IPS_ApplyChanges($managerId);
|
|
}
|
|
$test->assertSame(2700.0, GetValue($test->objectByIdent('HausverbrauchLeistungArchiv', $managerId)));
|
|
});
|
|
$test->runCase('SDL weist fehlende und doppelte Leistungsquellen zurueck', static function (
|
|
TestContext $test
|
|
) use ($managerId, $batterieLeistungId): void {
|
|
try {
|
|
IPS_SetProperty($managerId, 'SDLAktiv', true);
|
|
foreach ([0, $batterieLeistungId] as $quelle) {
|
|
IPS_SetProperty($managerId, 'SDLLeistungVariableID', $quelle);
|
|
IPS_ApplyChanges($managerId);
|
|
$test->assertInstanceStatus($managerId, 202);
|
|
}
|
|
} finally {
|
|
IPS_SetProperty($managerId, 'SDLAktiv', false);
|
|
IPS_SetProperty($managerId, 'SDLLeistungVariableID', 0);
|
|
IPS_ApplyChanges($managerId);
|
|
}
|
|
});
|
|
|
|
$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, $verbraucherstatus): void {
|
|
IPS_RequestAction($managerId, 'Aktiv', true);
|
|
IPS_RequestAction($managerId, 'Regeln', true);
|
|
$test->assertInstanceStatus($managerId, 203);
|
|
$test->assertSame(
|
|
'Inaktiv',
|
|
GetValue($test->objectByIdent('Betriebsart', $managerId))
|
|
);
|
|
|
|
$daten = $verbraucherstatus();
|
|
$test->assertSame(false, $daten['Synchronisiert'] ?? null);
|
|
$test->assertSame(3, count($daten['NichtGeregelt'] ?? []));
|
|
foreach ($daten['NichtGeregelt'] as $detail) {
|
|
$test->assertTrue(is_int($detail['InstanzID'] ?? null));
|
|
$test->assertTrue(is_string($detail['Name'] ?? null));
|
|
$test->assertTrue(is_string($detail['Typ'] ?? null));
|
|
$test->assertSame('Lizenz nicht freigegeben', $detail['Grund'] ?? null);
|
|
}
|
|
$detailtext = (string) GetValue(
|
|
$test->objectByIdent('NichtGeregelteGeraete', $managerId)
|
|
);
|
|
$test->assertTrue(str_contains($detailtext, 'Boiler'));
|
|
$test->assertTrue(str_contains($detailtext, 'Lizenz nicht freigegeben'));
|
|
});
|
|
|
|
return;
|
|
}
|
|
|
|
$test->runCase('Manager und alle vorhandenen Verbrauchertypen sind verknüpft', static function (
|
|
TestContext $test
|
|
) use ($managerId, $einStufigId, $warmwasserId, $pufferspeicherId, $melden): void {
|
|
IPS_RequestAction($managerId, 'Aktiv', true);
|
|
$melden();
|
|
IPS_RequestAction($managerId, 'Regeln', true);
|
|
|
|
foreach ([$managerId, $einStufigId, $warmwasserId, $pufferspeicherId] as $instanzId) {
|
|
$test->assertInstanceStatus($instanzId);
|
|
}
|
|
$test->assertSame(
|
|
3,
|
|
GetValue($test->objectByIdent('VerbraucherAnzahl', $managerId))
|
|
);
|
|
$test->assertSame(
|
|
3,
|
|
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, false, false], 'Netz -3000 W');
|
|
$test->assertSame('PV', GetValue($test->objectByIdent('Betriebsart', $managerId)));
|
|
|
|
$regeln(-1000.0);
|
|
$warteAufKontakte([true, false, true, false, false], 'Netz -1000 W');
|
|
$regeln(0.0);
|
|
$warteAufKontakte([true, false, true, false, false], 'Netz 0 W');
|
|
|
|
IPS_Sleep(1100);
|
|
$regeln(1000.0);
|
|
$warteAufKontakte([false, false, false, false, false], 'Netz +1000 W');
|
|
$test->assertSame('Peak', GetValue($test->objectByIdent('Betriebsart', $managerId)));
|
|
|
|
IPS_Sleep(1100);
|
|
$regeln(3000.0);
|
|
$warteAufKontakte([false, false, 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(3, count($daten['Verbraucher'] ?? []));
|
|
|
|
SetValue($temperaturId, 53.0);
|
|
$test->waitUntil(static function () use (
|
|
$warmwasserId,
|
|
$verbraucherstatus,
|
|
$zustandswert
|
|
): bool {
|
|
$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)
|
|
));
|
|
});
|
|
|
|
$test->runCase('Veraltete Verbraucher werden aktiv neu angefordert', static function (
|
|
TestContext $test
|
|
) use (
|
|
$managerId,
|
|
$netzleistungId,
|
|
$warmwasserId,
|
|
$pufferspeicherId,
|
|
$melden,
|
|
$verbraucherstatus
|
|
): void {
|
|
IPS_SetProperty($managerId, 'VerbraucherTimeout', 1);
|
|
IPS_ApplyChanges($managerId);
|
|
SetValue($netzleistungId, -2400.0);
|
|
$melden();
|
|
IPS_RequestAction($managerId, 'Regeln', true);
|
|
$test->waitUntil(
|
|
static fn (): bool => ($verbraucherstatus()['Synchronisiert'] ?? false) === true
|
|
);
|
|
|
|
IPS_Sleep(1100);
|
|
IPS_RequestAction($warmwasserId, 'Melden', true);
|
|
IPS_RequestAction($pufferspeicherId, 'Melden', true);
|
|
IPS_RequestAction($managerId, 'Regeln', true);
|
|
|
|
$daten = $verbraucherstatus();
|
|
$test->assertSame(true, $daten['Synchronisiert'] ?? null);
|
|
$test->assertSame(3, count($daten['Verbraucher'] ?? []));
|
|
$test->assertSame(0, count($daten['NichtGeregelt'] ?? []));
|
|
$test->assertTrue(
|
|
(float) GetValue($test->objectByIdent('Verteilbudget', $managerId)) > 0.0
|
|
);
|
|
});
|
|
};
|