feat: Demoanlage an Prognosetopologie anbinden
Tests / test (push) Successful in 49s

This commit is contained in:
dh
2026-09-23 05:46:07 +00:00
parent 1e6481330a
commit f250dea59a
5 changed files with 72 additions and 2 deletions
+7 -2
View File
@@ -156,7 +156,12 @@ class Manager extends IPSModule implements ManagerSchnittstelle
$this->SetTimerInterval('KeepAlive', $this->ReadPropertyInteger('KeepAlive') * 1000); $this->SetTimerInterval('KeepAlive', $this->ReadPropertyInteger('KeepAlive') * 1000);
$this->setzeDiagnosewert('Monatsgrenzen', $this->ReadPropertyString('Monatsgrenzen')); $this->setzeDiagnosewert('Monatsgrenzen', $this->ReadPropertyString('Monatsgrenzen'));
$this->aktualisiereAnschlussstatus(); $this->aktualisiereAnschlussstatus();
if (!$this->aktualisiereLizenzfreigabe($this->ReadPropertyString('Lizenzcode'), false)) { $geraetezugangFehlt = $this->hatAnlagentopologie()
&& $this->ReadAttributeString('PrognoseInstallationsToken') === '';
if (!$this->aktualisiereLizenzfreigabe(
$this->ReadPropertyString('Lizenzcode'),
$geraetezugangFehlt
)) {
$this->SetValue('Betriebsart', ManagerRegler::BETRIEBSART_INAKTIV); $this->SetValue('Betriebsart', ManagerRegler::BETRIEBSART_INAKTIV);
$this->SetStatus(self::STATUS_LIZENZ_UNGUELTIG); $this->SetStatus(self::STATUS_LIZENZ_UNGUELTIG);
return; return;
@@ -265,7 +270,7 @@ class Manager extends IPSModule implements ManagerSchnittstelle
{ {
return json_encode( return json_encode(
$this->leseAnlagentopologie(), $this->leseAnlagentopologie(),
JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES | JSON_PRESERVE_ZERO_FRACTION
); );
} }
+8
View File
@@ -7,6 +7,8 @@ Die Demo erzeugt idempotent eine vollständige, spielbare EMS-Anlage in IP-Symco
- einen einstufigen Entfeuchter (0,9 kW), - einen einstufigen Entfeuchter (0,9 kW),
- einen zweistufigen Pufferspeicher (1,8/3,6 kW) mit Heizkurve, - einen zweistufigen Pufferspeicher (1,8/3,6 kW) mit Heizkurve,
- einen bidirektionalen Batteriespeicher (10 kWh, +/-3,5 kW), - einen bidirektionalen Batteriespeicher (10 kWh, +/-3,5 kW),
- eine technische Anlagentopologie mit Hybridwechselrichter, PV-Fläche und
Batteriespeicher für die Prognoseanbindung,
- simulierte PV-Erzeugung, variable Bewölkung, Tageslastgang, Zusatzlast, - simulierte PV-Erzeugung, variable Bewölkung, Tageslastgang, Zusatzlast,
Außentemperatur, Wärmeverluste, Netzleistung und Speicherzustände, Außentemperatur, Wärmeverluste, Netzleistung und Speicherzustände,
- native Symcon-Instanz `Energy Distribution` für acht Energieflussknoten, - native Symcon-Instanz `Energy Distribution` für acht Energieflussknoten,
@@ -39,6 +41,12 @@ damit keine Lizenzfehler protokolliert werden. Nach der Aktivierung den
Bootstrap erneut ausführen; er ordnet dann alle fünf Teilnehmer zu und startet Bootstrap erneut ausführen; er ordnet dann alle fünf Teilnehmer zu und startet
die Regelung. die Regelung.
Die Demo übernimmt die einstellbare PV-Spitzenleistung als AC- und
DC-Anlagenleistung. Für die feste Beispieltopologie gelten 30 Grad Neigung und
Südausrichtung. Der 10-kWh-Speicher nutzt den gemeinsamen Hybridwechselrichter;
seine dynamischen Lade- und Entladegrenzen werden beim Bootstrap in die
technischen Stammdaten übernommen.
## Bedienung ## Bedienung
In der Kachelvisualisierung öffnet die Startkategorie `Enelix 2 Demoanlage`. In der Kachelvisualisierung öffnet die Startkategorie `Enelix 2 Demoanlage`.
+42
View File
@@ -277,6 +277,39 @@ function enelixDemoInstall(): array
static fn (int $id): array => ['InstanzID' => $id, 'Aktiv' => true], static fn (int $id): array => ['InstanzID' => $id, 'Aktiv' => true],
[$boiler1, $boiler2, $dryer, $buffer, $battery] [$boiler1, $boiler2, $dryer, $buffer, $battery]
); );
$pvNennleistungKw = max(0.1, (float) GetValue($peak) / 1000.0);
$wechselrichterKonfiguration = [[
'ID' => 'demo-hybrid-1',
'Name' => 'Demo-Hybridwechselrichter',
'Typ' => 'hybrid',
'ACNennleistung_kW' => $pvNennleistungKw,
'ACEinspeisegrenze_kW' => 0.0,
'ACBezugsgrenze_kW' => 0.0,
]];
$pvKonfiguration = [[
'ID' => 'demo-pv-1',
'Name' => 'Demo-PV-Anlage',
'DCLeistung_kWp' => $pvNennleistungKw,
'Neigung_Grad' => 30.0,
'Azimut_Grad' => 0.0,
'WechselrichterID' => 'demo-hybrid-1',
'MPPT' => 'A',
'Modulanzahl' => 0,
'Modulleistung_Wp' => 0.0,
]];
$batterieKonfiguration = [[
'ID' => 'demo-battery-1',
'Name' => 'Batteriespeicher 10 kWh',
'Nennkapazitaet_kWh' => 10.0,
'Nutzkapazitaet_kWh' => 10.0,
'MaxLadeleistung_kW' => max(0.1, (float) GetValue($batteryMaxCharge) / 1000.0),
'MaxEntladeleistung_kW' => max(
0.1,
(float) GetValue($batteryMaxDischarge) / 1000.0
),
'WechselrichterID' => 'demo-hybrid-1',
'Kopplung' => 'hybrid',
]];
$managerProperties = [ $managerProperties = [
'NetzleistungVariableID' => $grid, 'NetzleistungVariableID' => $grid,
'Netzleistungsfaktor' => 1.0, 'Netzleistungsfaktor' => 1.0,
@@ -288,6 +321,15 @@ function enelixDemoInstall(): array
'VerbraucherTimeout' => 15, 'VerbraucherTimeout' => 15,
'SollwertSolarladen' => 0.0, 'SollwertSolarladen' => 0.0,
'Umschaltdifferenz' => 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, 'DiagnosevariablenAnzeigen' => true,
'LoggingEin' => false, 'LoggingEin' => false,
]; ];
+6
View File
@@ -116,6 +116,12 @@ final class DemoanlageBootstrapTest extends TestCase
self::assertStringContainsString("'BatterieListe'", $source); self::assertStringContainsString("'BatterieListe'", $source);
self::assertStringContainsString('ENELIX_DEMO_BUFFER_MODULE', $source); self::assertStringContainsString('ENELIX_DEMO_BUFFER_MODULE', $source);
self::assertStringContainsString('ENELIX_DEMO_BATTERY_MODULE', $source); self::assertStringContainsString('ENELIX_DEMO_BATTERY_MODULE', $source);
self::assertStringContainsString("'AnlagenWechselrichter'", $source);
self::assertStringContainsString("'AnlagenPVFlaechen'", $source);
self::assertStringContainsString("'AnlagenBatterien'", $source);
self::assertStringContainsString("'demo-hybrid-1'", $source);
self::assertStringContainsString("'demo-pv-1'", $source);
self::assertStringContainsString("'demo-battery-1'", $source);
self::assertStringContainsString("'EnergieflussPVkW'", $source); self::assertStringContainsString("'EnergieflussPVkW'", $source);
self::assertStringContainsString("'~Power'", $source); self::assertStringContainsString("'~Power'", $source);
self::assertStringContainsString("'~Electricity'", $source); self::assertStringContainsString("'~Electricity'", $source);
+9
View File
@@ -186,8 +186,17 @@ final class ManagerModulstrukturTest extends TestCase
"RegisterAttributeString('PrognoseInstallationsToken', '')", "RegisterAttributeString('PrognoseInstallationsToken', '')",
$inhalt $inhalt
); );
self::assertStringContainsString('JSON_PRESERVE_ZERO_FRACTION', $inhalt);
self::assertStringContainsString("'issueDeviceToken' =>", $inhalt); self::assertStringContainsString("'issueDeviceToken' =>", $inhalt);
self::assertStringContainsString("unset(\$neueLease['deviceToken'])", $inhalt); self::assertStringContainsString("unset(\$neueLease['deviceToken'])", $inhalt);
self::assertStringContainsString(
"\$geraetezugangFehlt = \$this->hatAnlagentopologie()",
$inhalt
);
self::assertStringContainsString(
"\$this->ReadPropertyString('Lizenzcode'),\n \$geraetezugangFehlt",
$inhalt
);
self::assertStringContainsString('synchronisiereAnlagentopologie()', $inhalt); self::assertStringContainsString('synchronisiereAnlagentopologie()', $inhalt);
self::assertStringContainsString("'Authorization: Bearer ' . \$token", $inhalt); self::assertStringContainsString("'Authorization: Bearer ' . \$token", $inhalt);
self::assertStringNotContainsString( self::assertStringNotContainsString(