This commit is contained in:
@@ -9,6 +9,8 @@ Die Demo erzeugt idempotent eine vollständige, spielbare EMS-Anlage in IP-Symco
|
||||
- einen bidirektionalen Batteriespeicher (10 kWh, +/-3,5 kW),
|
||||
- eine technische Anlagentopologie mit Hybridwechselrichter, PV-Fläche und
|
||||
Batteriespeicher für die Prognoseanbindung,
|
||||
- simulierte Istleistungs- und Leistungsbegrenzungsregister des Wechselrichters,
|
||||
- eine aktive anlagenweite Einspeisebegrenzung auf 3.000 W mit 100 W Toleranz,
|
||||
- Prognosetelemetrie aus PV, Hausverbrauch, Netzleistung und Batterie-SOC im
|
||||
60-Sekunden-Intervall,
|
||||
- simulierte PV-Erzeugung, variable Bewölkung, Tageslastgang, Zusatzlast,
|
||||
@@ -49,7 +51,12 @@ Südausrichtung. Der 10-kWh-Speicher nutzt den gemeinsamen Hybridwechselrichter;
|
||||
seine dynamischen Lade- und Entladegrenzen werden beim Bootstrap in die
|
||||
technischen Stammdaten übernommen. Bei aktiver Manager-Lizenz uebertraegt der
|
||||
Manager zusaetzlich PV-Leistung, Hausverbrauch, Netzleistung und Batterie-SOC
|
||||
alle 60 Sekunden an den Enelix-Prognosedienst.
|
||||
alle 60 Sekunden an den Enelix-Prognosedienst. Die Demo verwendet ein absolutes
|
||||
Wechselrichter-Leistungsregister in Watt. Der Manager begrenzt die tatsächliche
|
||||
PV-Produktion so, dass die Gesamtanlage höchstens 3.000 W einspeist; innerhalb
|
||||
einer Toleranz von 100 W bleibt der zuletzt gesetzte Stellwert bestehen. Der
|
||||
intelligente Netzfahrplan bleibt deaktiviert, solange dessen Backendfassung nur
|
||||
als ausstehende Version bereitliegt.
|
||||
|
||||
## Bedienung
|
||||
|
||||
@@ -60,7 +67,9 @@ eine ungeregelte Zusatzlast verändern. Bei aktivierten dynamischen Profilen
|
||||
entstehen reproduzierbare Morgen- und Abendspitzen, ziehende Bewölkung und ein
|
||||
Tagesgang der Außentemperatur. Der Manager verteilt den verfügbaren
|
||||
PV-Überschuss nach Priorität auf beide Boiler, Entfeuchter, Pufferspeicher und
|
||||
Batterie.
|
||||
Batterie. Bei hoher PV-Erzeugung ist die Abregelung an den technischen Variablen
|
||||
`PV-Wechselrichter Istleistung` und `PV-Wechselrichter Leistungsgrenze` sowie an
|
||||
der auf etwa 3.000 W begrenzten Netzeinspeisung sichtbar.
|
||||
|
||||
`Übersicht` zeigt die native Symcon-Energieverteilung. Die Kacheln `Boiler 1`,
|
||||
`Boiler 2`, `Pufferspeicher` und `Batteriespeicher` öffnen direkt die jeweiligen
|
||||
@@ -76,6 +85,8 @@ Simulationszeit.
|
||||
- Die fünf Verbraucher müssen Status 102 besitzen; der Manager nach Lizenzaktivierung ebenfalls (vorher erwarteter Status 203).
|
||||
- Der Manager muss fünf Teilnehmer aus vier unterschiedlichen Modultypen melden.
|
||||
- Bei ausreichendem PV-Überschuss müssen thermische Verbraucher schalten und die Batterie laden.
|
||||
- Bei höherem verbleibendem PV-Überschuss muss das Wechselrichterregister die PV-Leistung so begrenzen, dass ungefähr 3.000 W ins Netz eingespeist werden.
|
||||
- Wechselrichter-Istleistung und Leistungsgrenze müssen in der technischen Kategorie vorhanden und im Manager zugeordnet sein.
|
||||
- Puffertemperatur, Außentemperatur und Batterie-Ladezustand müssen sich über den Tageslauf verändern.
|
||||
- Netzleistung, PV-Leistung, Hausverbrauch, EMS-Leistung, Einzelverbräuche, Speicherleistung, Energiesummen und Temperaturen werden archiviert.
|
||||
- Die native Energieverteilung muss acht Knoten enthalten.
|
||||
|
||||
@@ -113,6 +113,8 @@ function enelixDemoInstall(): array
|
||||
$batteryManagement = enelixDemoEnsureVariable($technical, 'BatterieManagement', 'Batterie Managementregister', 1, '', 0, 340);
|
||||
$batteryMode = enelixDemoEnsureVariable($technical, 'BatterieModus', 'Batterie Modusregister', 1, '', 0, 350);
|
||||
$batteryRegisterPower = enelixDemoEnsureVariable($technical, 'BatterieRegisterLeistung', 'Batterie Leistungsregister', 2, 'ENELIX.Demo.PowerPositive', 0.0, 360);
|
||||
$inverterActual = enelixDemoEnsureVariable($technical, 'WechselrichterIstleistung', 'PV-Wechselrichter Istleistung', 2, 'ENELIX.Demo.PowerPositive', 0.0, 370);
|
||||
$inverterLimit = enelixDemoEnsureVariable($technical, 'WechselrichterLeistungsgrenze', 'PV-Wechselrichter Leistungsgrenze', 2, 'ENELIX.Demo.PowerPositive', max(0.0, (float) GetValue($peak)), 380);
|
||||
$chartUpdated = enelixDemoEnsureVariable($technical, 'LetztesDiagrammUpdate', 'Letztes Diagramm-Update', 1, '', 0, 390);
|
||||
IPS_SetHidden($chartUpdated, true);
|
||||
|
||||
@@ -136,10 +138,10 @@ function enelixDemoInstall(): array
|
||||
foreach ([$boiler11, $boiler12, $boiler21, $boiler22, $dryContact, $buffer1, $buffer2] as $actorId) {
|
||||
IPS_SetVariableCustomAction($actorId, $actorScript);
|
||||
}
|
||||
foreach ([$batteryManagement, $batteryMode, $batteryRegisterPower] as $registerId) {
|
||||
foreach ([$batteryManagement, $batteryMode, $batteryRegisterPower, $inverterLimit] as $registerId) {
|
||||
IPS_SetVariableCustomAction($registerId, $registerScript);
|
||||
}
|
||||
foreach ([$temp1, $temp2, $bufferTemp, $outsideTemp, $batteryMaxCharge, $batteryMaxDischarge, $batterySoc, $batteryActual] as $sensorId) {
|
||||
foreach ([$temp1, $temp2, $bufferTemp, $outsideTemp, $batteryMaxCharge, $batteryMaxDischarge, $batterySoc, $batteryActual, $inverterActual] as $sensorId) {
|
||||
SetValue($sensorId, GetValue($sensorId));
|
||||
}
|
||||
|
||||
@@ -285,6 +287,9 @@ function enelixDemoInstall(): array
|
||||
'ACNennleistung_kW' => $pvNennleistungKw,
|
||||
'ACEinspeisegrenze_kW' => 0.0,
|
||||
'ACBezugsgrenze_kW' => 0.0,
|
||||
'IstleistungVariableID' => $inverterActual,
|
||||
'BegrenzungVariableID' => $inverterLimit,
|
||||
'Begrenzungsart' => 'watt',
|
||||
]];
|
||||
$pvKonfiguration = [[
|
||||
'ID' => 'demo-pv-1',
|
||||
@@ -325,6 +330,10 @@ function enelixDemoInstall(): array
|
||||
'VerbraucherTimeout' => 15,
|
||||
'SollwertSolarladen' => 0.0,
|
||||
'Umschaltdifferenz' => 0.0,
|
||||
'EinspeisebegrenzungAktiv' => true,
|
||||
'Einspeisegrenze' => 3000.0,
|
||||
'Einspeisetoleranz' => 100.0,
|
||||
'NetzfahrplanAktiv' => false,
|
||||
'AnlagenWechselrichter' => json_encode(
|
||||
$wechselrichterKonfiguration,
|
||||
JSON_THROW_ON_ERROR
|
||||
@@ -476,7 +485,11 @@ function enelixDemoTick(string $source = 'Manual'): void
|
||||
$sun = ($hour >= 6.0 && $hour <= 18.0)
|
||||
? max(0.0, sin(M_PI * ($hour - 6.0) / 12.0))
|
||||
: 0.0;
|
||||
$pv = $peak * $sun * (1.0 - ($environment['cloud'] * 0.0085));
|
||||
$pvAvailable = $peak * $sun * (1.0 - ($environment['cloud'] * 0.0085));
|
||||
$inverterActual = enelixDemoRequiredId($technical, 'WechselrichterIstleistung');
|
||||
$inverterLimit = enelixDemoRequiredId($technical, 'WechselrichterLeistungsgrenze');
|
||||
$pv = enelixDemoLimitPvPower($pvAvailable, (float) GetValue($inverterLimit));
|
||||
SetValue($inverterActual, round($pv, 1));
|
||||
|
||||
$contacts = [
|
||||
'boiler11' => enelixDemoRequiredId($technical, 'Boiler1Stufe1'),
|
||||
@@ -541,6 +554,11 @@ function enelixDemoTick(string $source = 'Manual'): void
|
||||
IPS_RequestAction($consumerId, 'Melden', true);
|
||||
}
|
||||
IPS_RequestAction($manager, 'Regeln', true);
|
||||
$pv = enelixDemoLimitPvPower(
|
||||
$pvAvailable,
|
||||
(float) GetValue($inverterLimit)
|
||||
);
|
||||
SetValue($inverterActual, round($pv, 1));
|
||||
}
|
||||
|
||||
$battery = $managerReady
|
||||
@@ -597,6 +615,11 @@ function enelixDemoTick(string $source = 'Manual'): void
|
||||
}
|
||||
}
|
||||
|
||||
function enelixDemoLimitPvPower(float $availablePower, float $limitPower): float
|
||||
{
|
||||
return min(max(0.0, $availablePower), max(0.0, $limitPower));
|
||||
}
|
||||
|
||||
function enelixDemoRenderFlow(array $state): string
|
||||
{
|
||||
$format = static fn (float $value): string => number_format($value, 0, ',', "'");
|
||||
|
||||
Reference in New Issue
Block a user