This commit is contained in:
@@ -4,6 +4,12 @@ Alle wesentlichen Aenderungen an Enelix EMS werden in dieser Datei dokumentiert.
|
||||
|
||||
## Unreleased
|
||||
|
||||
- Manager: Energy Pie verwendet die bilanzielle Gesamtanlage inklusive SDL
|
||||
unabhaengig von SDLAktiv. Kein Mischen des SDL-bereinigten Hauszaehlers mit
|
||||
physischen Netzzaehlern, keine doppelte Addition von SDL-Energie. Benoetigt
|
||||
zuerst Enelix Utils mit Gesamtbilanz-Unterstuetzung; Quellen, Farben, Archive,
|
||||
Hauslast fuer Regelung/Prognose und Stellpfade bleiben unveraendert.
|
||||
|
||||
- Ladestation Stand-Alone: Ladepausen und einzelne Nullwerte verriegeln das
|
||||
Fahrzeug nicht mehr als geladen. Ladeende nur mit aktuellem eindeutigen
|
||||
Geraetesignal; Pico hat kein solches Voll-Signal. go-e-Fehler, Pico-Status
|
||||
|
||||
@@ -405,6 +405,30 @@ der wirksamen Lastspitzengrenze zu `Peak`. Zwischen den beiden Zielwerten
|
||||
bleibt sie erhalten. `Umschaltdifferenz` verhindert zusätzlich einen Wechsel,
|
||||
wenn sich die beiden berechneten Korrekturen nicht ausreichend unterscheiden.
|
||||
|
||||
## Energy Pie: Gesamtbilanz inklusive SDL
|
||||
|
||||
Der Manager aktiviert am eigenen Energy Pie `Gesamtbilanz=true`, unabhaengig
|
||||
von `SDLAktiv`. Der bilanzielle Gesamtverbrauch ist Produktion plus physischer
|
||||
Netzbezug minus Einspeisung (mindestens 0). SDL-Ladung bzw. -Abgabe wirkt damit
|
||||
ueber die bereits vorhandenen Netzzaehler; separate SDL-Zaehler werden nicht
|
||||
nochmals addiert. Eine Versorgung des Hauses durch SDL ist keine Netzeinspeisung.
|
||||
Die Hausquelle bleibt gespeichert, fliesst jedoch nicht in diese Gesamtbilanz ein.
|
||||
Die weiterhin SDL-bereinigte Hauslast fuer Regelung und Prognose bleibt unveraendert.
|
||||
|
||||
Die Quoten sind ausdruecklich **bilanziell**, keine reine PV-Herkunftszuordnung
|
||||
oder physische Hausautarkie. Speicherentladung kann den Netto-Bilanzverbrauch
|
||||
senken; bei negativem Saldo zeigt der Pie einen Hinweis und begrenzt Verbrauch
|
||||
und Quoten auf 0. Fehlende Daten werden weiterhin als unbekannt behandelt.
|
||||
|
||||
Migration: zuerst Enelix Utils mit Gesamtbilanz-Unterstuetzung aktualisieren,
|
||||
dann den EMS-Manager anwenden. Zaehlervariablen, Archivdaten und individuelle
|
||||
Farben bleiben erhalten. Historische Zeitraeume werden neu aus den vorhandenen
|
||||
drei Zaehlern berechnet. Die alte Property `EnergieanteileBerechenbar` bleibt
|
||||
fuer einen Rueckwechsel erhalten und blockiert die Gesamtbilanz nicht.
|
||||
Mit einem alten Utils bleibt die bisherige SDL-Schutzlogik bestehen, bis Utils
|
||||
aktualisiert wird; es wird keine falsche Hausbilanz erzwungen. Kein Anlagenrollout
|
||||
oder Stellbefehl ist Teil dieser Quellcode-Aenderung.
|
||||
|
||||
## Laufzeit und Fehlerverhalten
|
||||
|
||||
- Netzleistungsänderungen und Verbrauchermeldungen lösen die Berechnung aus.
|
||||
|
||||
@@ -297,9 +297,21 @@ trait ManagerEnergieTrait
|
||||
|
||||
private function synchronisiereEnergyPieAnteile(int $instanzID, bool $anwenden = true): void
|
||||
{
|
||||
// Physischer Netzbezug enthaelt SDL, die Hausenergie dagegen nicht.
|
||||
$berechenbar = !$this->ReadPropertyBoolean('SDLAktiv');
|
||||
$konfiguration = json_decode(IPS_GetConfiguration($instanzID), true, 512, JSON_THROW_ON_ERROR);
|
||||
if (is_array($konfiguration) && array_key_exists('Gesamtbilanz', $konfiguration)) {
|
||||
// Physical grid counters already include SDL; Utils derives the complete site balance.
|
||||
IPS_SetHidden($instanzID, false);
|
||||
if (IPS_GetProperty($instanzID, 'Gesamtbilanz') !== true) {
|
||||
IPS_SetProperty($instanzID, 'Gesamtbilanz', true);
|
||||
if ($anwenden) {
|
||||
IPS_ApplyChanges($instanzID);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Compatibility until Utils is updated: do not enable the old mixed-boundary calculation.
|
||||
$berechenbar = !$this->ReadPropertyBoolean('SDLAktiv');
|
||||
if (!is_array($konfiguration) || !array_key_exists('EnergieanteileBerechenbar', $konfiguration)) {
|
||||
IPS_SetHidden($instanzID, !$berechenbar);
|
||||
if (!$berechenbar) {
|
||||
|
||||
@@ -413,6 +413,44 @@ final class ManagerSDLTest extends TestCase
|
||||
self::assertSame($custom, ManagerSDLRuntime::$properties[303]);
|
||||
}
|
||||
|
||||
public function testModernEnergyPieUsesOverallBalanceWithAndWithoutSDL(): void
|
||||
{
|
||||
$custom = [
|
||||
'ProduktionZaehlerID' => 801, 'NetzbezugZaehlerID' => 802,
|
||||
'EinspeisungZaehlerID' => 803, 'VerbrauchZaehlerID' => 804,
|
||||
'FarbeEigenverbrauch' => '#123456', 'FarbeAutarkie' => '#ABCDEF',
|
||||
'Standardzeitraum' => 'month', 'EnergieanteileBerechenbar' => false,
|
||||
'Gesamtbilanz' => false,
|
||||
];
|
||||
foreach ([true, false] as $sdl) {
|
||||
ManagerSDLRuntime::$properties[303] = $custom;
|
||||
ManagerSDLRuntime::$hidden[303] = true;
|
||||
$this->properties(['SDLAktiv' => $sdl]);
|
||||
$this->invoke('synchronisiereEnergyPieAnteile', [303]);
|
||||
self::assertSame(array_replace($custom, ['Gesamtbilanz' => true]),
|
||||
ManagerSDLRuntime::$properties[303]);
|
||||
self::assertFalse(ManagerSDLRuntime::$hidden[303]);
|
||||
$writes = ManagerSDLRuntime::$writes;
|
||||
$this->invoke('synchronisiereEnergyPieAnteile', [303]);
|
||||
self::assertSame($writes, ManagerSDLRuntime::$writes);
|
||||
}
|
||||
self::assertSame([], ManagerSDLRuntime::$logs);
|
||||
}
|
||||
|
||||
public function testUtilsUpgradeRestoresBalanceWithoutResettingCustomSources(): void
|
||||
{
|
||||
ManagerSDLRuntime::$properties[303] = ['ProduktionZaehlerID' => 801];
|
||||
$this->properties(['SDLAktiv' => true]);
|
||||
$this->invoke('synchronisiereEnergyPieAnteile', [303]);
|
||||
self::assertTrue(ManagerSDLRuntime::$hidden[303]);
|
||||
ManagerSDLRuntime::$properties[303]['Gesamtbilanz'] = false;
|
||||
ManagerSDLRuntime::$properties[303]['EnergieanteileBerechenbar'] = false;
|
||||
$this->invoke('synchronisiereEnergyPieAnteile', [303]);
|
||||
self::assertFalse(ManagerSDLRuntime::$hidden[303]);
|
||||
self::assertTrue(ManagerSDLRuntime::$properties[303]['Gesamtbilanz']);
|
||||
self::assertSame(801, ManagerSDLRuntime::$properties[303]['ProduktionZaehlerID']);
|
||||
}
|
||||
|
||||
public function testOlderEnergyPieStaysVisibleWithoutSDLAndKeepsConfiguration(): void
|
||||
{
|
||||
$custom = ['ProduktionZaehlerID' => 801, 'FarbeEigenverbrauch' => '#123456'];
|
||||
|
||||
Reference in New Issue
Block a user