feat(manager): Energievisualisierung und Synchronisierung erweitern
Tests / test (push) Successful in 50s
Tests / test (push) Successful in 50s
This commit is contained in:
+52
-9
@@ -260,10 +260,14 @@
|
||||
"type": "Label",
|
||||
"caption": "Energiezaehler werden in kWh erwartet; ueber den Faktor koennen beispielsweise Wh (0,001) umgerechnet werden."
|
||||
},
|
||||
{
|
||||
"type": "Label",
|
||||
"caption": "Die Wechselrichter-Tabelle beschreibt die AC-Wandler der Anlage. PV-Flaechen und Batteriespeicher verweisen darauf, damit gemeinsame Leistungsgrenzen und die elektrische Kopplung eindeutig sind. Bei einem Hybridgeraet verwenden PV und Batterie dieselbe Wechselrichter-ID; bei einem AC-gekoppelten Speicher wird dessen separater Batteriewechselrichter erfasst."
|
||||
},
|
||||
{
|
||||
"type": "List",
|
||||
"name": "AnlagenWechselrichter",
|
||||
"caption": "Wechselrichter",
|
||||
"caption": "Wechselrichter / AC-Wandler",
|
||||
"rowCount": 4,
|
||||
"add": true,
|
||||
"delete": true,
|
||||
@@ -459,6 +463,10 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Label",
|
||||
"caption": "Der Batterieeintrag beschreibt den Speicher selbst: Kapazitaet, Leistung, Ladezustand und Energiezaehler. Die Wechselrichter-ID ist nur die Verknuepfung zum zugehoerigen AC-Wandler und keine doppelte Batteriekonfiguration."
|
||||
},
|
||||
{
|
||||
"type": "List",
|
||||
"name": "AnlagenBatterien",
|
||||
@@ -722,26 +730,61 @@
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "EnergyPieAnzeigen",
|
||||
"caption": "Energy Pie unter dem Manager anzeigen",
|
||||
"onChange": "IPS_RequestAction($id, 'FormEnergyPieAnzeigen', $EnergyPieAnzeigen);"
|
||||
"caption": "Energy Pie unter dem Manager anzeigen"
|
||||
},
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "EnergiediagrammeAnzeigen",
|
||||
"caption": "Leistungs- und Energiediagramm unter dem Manager anzeigen",
|
||||
"onChange": "IPS_RequestAction($id, 'FormEnergiediagrammeAnzeigen', $EnergiediagrammeAnzeigen);"
|
||||
"caption": "Leistungs- und Energiediagramm unter dem Manager anzeigen"
|
||||
},
|
||||
{
|
||||
"type": "RowLayout",
|
||||
"items": [
|
||||
{
|
||||
"type": "Select",
|
||||
"name": "DiagrammPVModus",
|
||||
"caption": "PV in Diagrammen",
|
||||
"options": [
|
||||
{"caption": "Summe", "value": 0},
|
||||
{"caption": "Einzelne Anlagen", "value": 1},
|
||||
{"caption": "Summe und einzelne Anlagen", "value": 2}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Select",
|
||||
"name": "DiagrammBatterieModus",
|
||||
"caption": "Batterien in Diagrammen",
|
||||
"options": [
|
||||
{"caption": "Summe", "value": 0},
|
||||
{"caption": "Einzelne Speicher", "value": 1},
|
||||
{"caption": "Summe und einzelne Speicher", "value": 2}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "LadestationenSeparatAnzeigen",
|
||||
"caption": "Ladestationen separat in Energiefluss und Diagrammen anzeigen"
|
||||
},
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "VerbraucherSeparatAnzeigen",
|
||||
"caption": "Uebrige Verbraucher separat in Energiefluss und Diagrammen anzeigen"
|
||||
},
|
||||
{
|
||||
"type": "Label",
|
||||
"caption": "Bestehende Energy Pies, Diagramme und Energiefluesse bleiben bei Apply unveraendert. Fuer eine Neuerzeugung den jeweiligen Schalter ausschalten, Apply ausfuehren, wieder einschalten und erneut Apply ausfuehren."
|
||||
},
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "FunFactsAnzeigen",
|
||||
"caption": "Energy Facts unter dem Manager anzeigen",
|
||||
"onChange": "IPS_RequestAction($id, 'FormFunFactsAnzeigen', $FunFactsAnzeigen);"
|
||||
"caption": "Energy Facts unter dem Manager anzeigen"
|
||||
},
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "EnergieflussAnzeigen",
|
||||
"caption": "Energiefluss unter dem Manager anzeigen",
|
||||
"onChange": "IPS_RequestAction($id, 'FormEnergieflussAnzeigen', $EnergieflussAnzeigen);"
|
||||
"caption": "Energiefluss unter dem Manager anzeigen"
|
||||
},
|
||||
{
|
||||
"type": "Select",
|
||||
|
||||
+63
-11
@@ -171,6 +171,10 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
||||
$this->RegisterPropertyInteger('EnergieLoeschenMonate', 0);
|
||||
$this->RegisterPropertyBoolean('EnergyPieAnzeigen', false);
|
||||
$this->RegisterPropertyBoolean('EnergiediagrammeAnzeigen', false);
|
||||
$this->RegisterPropertyInteger('DiagrammPVModus', 0);
|
||||
$this->RegisterPropertyInteger('DiagrammBatterieModus', 0);
|
||||
$this->RegisterPropertyBoolean('LadestationenSeparatAnzeigen', true);
|
||||
$this->RegisterPropertyBoolean('VerbraucherSeparatAnzeigen', true);
|
||||
$this->RegisterPropertyBoolean('FunFactsAnzeigen', false);
|
||||
$this->RegisterPropertyBoolean('EnergieflussAnzeigen', false);
|
||||
$this->RegisterPropertyInteger('EnergieflussLeistungseinheit', 0);
|
||||
@@ -203,6 +207,9 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
||||
$this->RegisterAttributeInteger('MessungLetzteEnergieaufzeichnung', 0);
|
||||
$this->RegisterAttributeString('MessungEnergiePuffer', '{}');
|
||||
$this->RegisterAttributeString('MessungZaehlerstaende', '{}');
|
||||
$this->RegisterAttributeString('EnergiediagrammKonfiguration', '{}');
|
||||
$this->RegisterAttributeString('EnergieflussKonfiguration', '{}');
|
||||
$this->RegisterAttributeBoolean('EnergieflussNeuErzeugen', false);
|
||||
|
||||
// Die alten Timer bleiben deaktiviert registriert, damit bestehende Instanzen sauber migrieren.
|
||||
$this->RegisterTimer('Regelzyklus', 0, '');
|
||||
@@ -238,8 +245,8 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
||||
|
||||
try {
|
||||
$this->pruefeKonfiguration();
|
||||
$this->konfiguriereEnergiearchiv();
|
||||
$this->synchronisiereEnergievisualisierungen();
|
||||
$this->konfiguriereEnergiearchiv();
|
||||
} catch (Throwable $fehler) {
|
||||
$this->SetStatus(self::STATUS_KONFIGURATION_UNGUELTIG);
|
||||
$this->SetTimerInterval('Regelzyklus', 0);
|
||||
@@ -616,7 +623,10 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
||||
];
|
||||
$this->WriteAttributeString('VerbraucherCache', json_encode($cache, JSON_THROW_ON_ERROR));
|
||||
$this->aktualisiereEnergieflusswerte();
|
||||
$this->regeln(false);
|
||||
$this->aktualisiereDiagrammMesswerte();
|
||||
if ($this->GetBuffer('VerbraucherSynchronisierungAktiv') !== '1') {
|
||||
$this->regeln(false);
|
||||
}
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $daten */
|
||||
@@ -1008,13 +1018,20 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
||||
|
||||
foreach ($ids as $instanzID) {
|
||||
$eintrag = $cache[(string) $instanzID] ?? null;
|
||||
$grund = '';
|
||||
if (!is_array($eintrag) || !isset($eintrag['EmpfangenAm'], $eintrag['Daten'])) {
|
||||
$grund = 'Noch keine Meldung';
|
||||
} elseif (time() - (int) $eintrag['EmpfangenAm'] > $timeout) {
|
||||
$grund = 'Meldung ist veraltet';
|
||||
} elseif (($eintrag['Daten']['Betriebsart'] ?? null) !== $betriebsart) {
|
||||
$grund = 'Leistungsangebot gehoert nicht zur Betriebsart ' . $betriebsart;
|
||||
$grund = $this->verbraucherMeldegrund($eintrag, $betriebsart, $timeout);
|
||||
$synchronisierungsfehler = '';
|
||||
if (in_array($grund, ['Noch keine Meldung', 'Meldung ist veraltet'], true)) {
|
||||
try {
|
||||
$this->SetBuffer('VerbraucherSynchronisierungAktiv', '1');
|
||||
IPS_RequestAction($instanzID, 'Melden', true);
|
||||
} catch (Throwable $fehler) {
|
||||
$synchronisierungsfehler = $fehler->getMessage();
|
||||
} finally {
|
||||
$this->SetBuffer('VerbraucherSynchronisierungAktiv', '0');
|
||||
}
|
||||
$cache = $this->leseJsonAttribut('VerbraucherCache');
|
||||
$eintrag = $cache[(string) $instanzID] ?? null;
|
||||
$grund = $this->verbraucherMeldegrund($eintrag, $betriebsart, $timeout);
|
||||
}
|
||||
|
||||
if ($grund !== '') {
|
||||
@@ -1025,8 +1042,11 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
||||
try {
|
||||
$this->sendeManagerdaten($instanzID, $betriebsart, null);
|
||||
} catch (Throwable $fehler) {
|
||||
$stoerungen[] = $detail['Name'] . ': Betriebsart konnte nicht uebermittelt werden: '
|
||||
. $fehler->getMessage();
|
||||
$synchronisierungsfehler = $fehler->getMessage();
|
||||
}
|
||||
if ($synchronisierungsfehler !== '') {
|
||||
$stoerungen[] = $detail['Name'] . ': Vollmeldung konnte nicht angefordert werden: '
|
||||
. $synchronisierungsfehler;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -1039,6 +1059,27 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
||||
return $aktuell;
|
||||
}
|
||||
|
||||
/** @param array<string, mixed>|null $eintrag */
|
||||
private function verbraucherMeldegrund(
|
||||
?array $eintrag,
|
||||
string $betriebsart,
|
||||
int $timeout
|
||||
): string {
|
||||
if (!isset($eintrag['EmpfangenAm'], $eintrag['Daten'])
|
||||
|| !is_array($eintrag['Daten'])
|
||||
) {
|
||||
return 'Noch keine Meldung';
|
||||
}
|
||||
if (time() - (int) $eintrag['EmpfangenAm'] > $timeout) {
|
||||
return 'Meldung ist veraltet';
|
||||
}
|
||||
if (($eintrag['Daten']['Betriebsart'] ?? null) !== $betriebsart) {
|
||||
return 'Leistungsangebot gehoert nicht zur Betriebsart ' . $betriebsart;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
private function setzeNichtGeregelteVerbraucher(string $grund): void
|
||||
{
|
||||
try {
|
||||
@@ -2120,6 +2161,7 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
||||
$this->WriteAttributeInteger('MessungLetzteEnergieaufzeichnung', $jetzt);
|
||||
}
|
||||
|
||||
$this->aktualisiereDiagrammMesswerte(true);
|
||||
$funFactsID = @IPS_GetObjectIDByIdent('EnergieFunFacts', $this->InstanceID);
|
||||
if (is_int($funFactsID) && $funFactsID > 0 && IPS_VariableExists($funFactsID)) {
|
||||
$this->aktualisiereFunFacts($funFactsID);
|
||||
@@ -2647,6 +2689,16 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
||||
throw new InvalidArgumentException($property . ' darf nicht negativ sein.');
|
||||
}
|
||||
}
|
||||
foreach (['DiagrammPVModus', 'DiagrammBatterieModus'] as $property) {
|
||||
if (!in_array($this->ReadPropertyInteger($property), [0, 1, 2], true)) {
|
||||
throw new InvalidArgumentException($property . ' muss 0, 1 oder 2 sein.');
|
||||
}
|
||||
}
|
||||
if (!in_array($this->ReadPropertyInteger('EnergieflussLeistungseinheit'), [0, 1], true)) {
|
||||
throw new InvalidArgumentException(
|
||||
'EnergieflussLeistungseinheit muss 0 oder 1 sein.'
|
||||
);
|
||||
}
|
||||
$energieLoeschen = $this->ReadPropertyInteger('EnergieLoeschenMonate');
|
||||
$energieVerdichten = $this->ReadPropertyInteger('EnergieVerdichtenMonate');
|
||||
if ($energieLoeschen > 0 && $energieLoeschen <= $energieVerdichten) {
|
||||
|
||||
Reference in New Issue
Block a user