diff --git a/Belevo_PV_Visu/README.md b/Belevo_PV_Visu/README.md index f01450a..91e9b74 100644 --- a/Belevo_PV_Visu/README.md +++ b/Belevo_PV_Visu/README.md @@ -1,92 +1,81 @@ # Belevo_PV_Visu -Visualisierung des Eigenverbrauchs: Tages-Quoten für PV-Produktion vs. Einspeisung und Verbrauch vs. Netz-Bezug in IP-Symcon WebFront. +Visualisierung des Eigenverbrauchs: Tages-Quoten für PV-Produktion vs. Einspeisung und +Verbrauch vs. Netz-Bezug in IP-Symcon WebFront. ### Inhaltsverzeichnis 1. [Funktionsumfang](#1-funktionsumfang) 2. [Voraussetzungen](#2-voraussetzungen) 3. [Software-Installation](#3-software-installation) -4. [Einrichten der Instanzen in IP-Symcon](#4-einrichten-der-instanzen-in-ip-symcon) -5. [Statusvariablen und Profile](#5-statusvariablen-und-profile) -6. [WebFront](#6-webfront) -7. [PHP-Befehlsreferenz](#7-php-befehlsreferenz) +4. [Instanz einrichten](#4-instanz-einrichten) +5. [WebFront](#5-webfront) +6. [PHP-Befehlsreferenz](#6-php-befehlsreferenz) --- ### 1. Funktionsumfang -* Anzeige von Tages-Quoten (in %) - * **Produktion** aufgeteilt in *Eigenverbrauch* vs. *Einspeisung* - * **Verbrauch** aufgeteilt in *PV-Anteil* vs. *Netz-Anteil* -* Zwei untereinander angeordnete Balkendiagramme -* Automatische Tages-Aggregation der Zählerwerte (kWh) -* Live-Update beim Laden der WebFront-Tile +- Anzeige von Tages-Quoten (in %) + - **Produktion** → Eigenverbrauch vs. Einspeisung + - **Verbrauch** → PV-Anteil vs. Netz-Anteil +- Zwei untereinander angeordnete Balkendiagramme +- Absolute Tages-Summen (kWh) in Beschriftung +- Live-Update beim Laden der Tile --- ### 2. Voraussetzungen - IP-Symcon **ab Version 7.1** -- Aktiviertes **Archiv-Modul** (für Aggregation) -- Vier Zähler-Variablen (Produktion, Verbrauch, Einspeisung, Netz-Bezug) mit kWh-Zählerprofil +- Aktiviertes **Archiv-Modul** +- Vier Zähler-Variablen (kWh-Profile) für Produktion, Verbrauch, Einspeisung und Netz-Bezug --- ### 3. Software-Installation -1. **Über den Module Store** +1. **Module Store** - In der IPS-Konsole unter **Module → Modul Store** nach **Belevo_PV_Visu** suchen und installieren. -2. **Manuell per URL** - - In **Module → Einstellungen → Repositories** folgende Git-URL hinzufügen: +2. **Manuell per Repository** + - Unter **Module → Einstellungen → Repositories** URL hinzufügen: ``` https://github.com/DeinRepo/Belevo_PV_Visu.git ``` - - Anschließend **Module neu einlesen** und installieren. + - Danach **Module neu einlesen**. --- -### 4. Einrichten der Instanzen in IP-Symcon +### 4. Instanz einrichten -Unter **Instanz hinzufügen** findet man das Modul über den Schnellfilter **“Belevo_PV_Visu”**. +1. **Instanz hinzufügen** → Schnellfilter **“Belevo_PV_Visu”** +2. Im Konfig-Dialog vier Variablen auswählen: -__Konfigurationsseite__: + | Property | Beschreibung | + |----------------|-------------------------------------| + | VarProduction | PV-Produktionszähler (kWh) | + | VarConsumption | Gesamtverbrauchszähler (kWh) | + | VarFeedIn | Einspeisezähler (kWh) | + | VarGrid | Netz-Bezugszähler (kWh) | -| Name | Beschreibung | -|------------------|----------------------------------------------------| -| **VarProduction**| Variable mit dem PV-Produktionszähler (kWh) | -| **VarConsumption**| Variable mit dem Gesamtverbrauchszähler (kWh) | -| **VarFeedIn** | Variable mit dem Einspeisezähler (kWh) | -| **VarGrid** | Variable mit dem Netz-Bezugszähler (kWh) | - -> Nach dem Speichern der Konfiguration stehen die Variablen zur Live-Auswertung in der WebFront-Tile zur Verfügung. +3. Speichern – die Tile zeigt sofort die aktuellen Werte an. --- -### 5. Statusvariablen und Profile +### 5. WebFront -Dieses Modul legt **keine** eigenen Statusvariablen an, sondern nutzt ausschließlich die vom Anwender ausgewählten Zähler. Profiles müssen für die Quoten-Balken nicht angelegt werden – sämtliche Formatierung erfolgt in der HTML-SDK. +- **Tile-Typ:** „Belevo_PV_Visu“ +- **Oberes Balken­diagramm:** Produktion (Grün) + - Eigenverbrauch (dunkelgrün) + - Einspeisung (hellgrün) +- **Unteres Balken­diagramm:** Verbrauch (Orange/Rot) + - PV-Anteil (orange) + - Netz-Anteil (rot) --- -### 6. WebFront - -* **Tile-Typ:** „Belevo_PV_Visu“ -* Zwei Balkendiagramme untereinander - 1. **Produktion** – Grün-Töne (Eigenverbrauch/Einspeisung) - 2. **Verbrauch** – Orange/Rot-Töne (PV-Anteil/Netz-Anteil) -* Beschriftung zeigt absolute Tages-Summen (kWh) -* Prozentwerte als Breite der jeweiligen Balken - -WebFront Tiles - ---- - -### 7. PHP-Befehlsreferenz - -Zur manuellen Aktualisierung der Visualisierung kann folgender Aufruf in einem Script verwendet werden: +### 6. PHP-Befehlsreferenz ```php -// Aktualisiert die WebFront-Tile 'Belevo_PV_Visu' der Instanz $InstanceID +// Manuelles Update der Tile anstoßen IPS_RequestAction($InstanceID, 'update', true); -Dieser Befehl löst das Neuberechnen der Tages-Aggregation aus und aktualisiert die Anzeige im WebFront. \ No newline at end of file diff --git a/Belevo_PV_Visu/form.json b/Belevo_PV_Visu/form.json index 23e3e32..eeb6e7e 100644 --- a/Belevo_PV_Visu/form.json +++ b/Belevo_PV_Visu/form.json @@ -20,5 +20,6 @@ "name": "VarGrid", "caption": "Bezug Netz (kWh)" } - ] + ], + "actions": [] } diff --git a/Belevo_PV_Visu/module.html b/Belevo_PV_Visu/module.html index 01ff2e1..cb988b1 100644 --- a/Belevo_PV_Visu/module.html +++ b/Belevo_PV_Visu/module.html @@ -1,64 +1,58 @@ + -
+
-
+
diff --git a/Belevo_PV_Visu/module.json b/Belevo_PV_Visu/module.json index 5524c6f..be845c4 100644 --- a/Belevo_PV_Visu/module.json +++ b/Belevo_PV_Visu/module.json @@ -1,12 +1,12 @@ { - "id": "{BD6A4CE3-E911-76B3-A91D-AB9926E86FB2}", - "name": "Belevo_PV_Visu", - "type": 3, - "vendor": "Belevo AG", - "aliases": [], - "parentRequirements": [], - "childRequirements": [], - "implemented": [], - "prefix": "GEF", - "url": "" -} \ No newline at end of file + "id": "{466A36DA-3C90-06E8-1D57-161D921B45EE}", + "name": "Belevo_PV_Visu", + "type": 3, + "vendor": "BelevoAG", + "aliases": [], + "parentRequirements": [], + "childRequirements": [], + "implemented": [], + "prefix": "GEF", + "url": "" +} diff --git a/Belevo_PV_Visu/module.php b/Belevo_PV_Visu/module.php index f1d7c54..30ccbd1 100644 --- a/Belevo_PV_Visu/module.php +++ b/Belevo_PV_Visu/module.php @@ -1,11 +1,11 @@ -RegisterPropertyInteger('VarProduction', 0); $this->RegisterPropertyInteger('VarConsumption', 0); $this->RegisterPropertyInteger('VarFeedIn', 0); @@ -14,83 +14,69 @@ class Belevo_PV_Visu extends IPSModule $this->SetVisualizationType(3); } - public function GetConfigurationForm(): string - { - return json_encode([ - 'elements' => [ - [ - 'type' => 'SelectVariable', - 'name' => 'VarProduction', - 'caption' => 'Produktion (kWh)' - ], - [ - 'type' => 'SelectVariable', - 'name' => 'VarConsumption', - 'caption' => 'Verbrauch (kWh)' - ], - [ - 'type' => 'SelectVariable', - 'name' => 'VarFeedIn', - 'caption' => 'Einspeisung (kWh)' - ], - [ - 'type' => 'SelectVariable', - 'name' => 'VarGrid', - 'caption' => 'Bezug Netz (kWh)' - ] - ], - 'actions' => [] - ]); - } + /** + * Wird aufgerufen, wenn IPS das statische form.json nicht findet + * (hier leer, denn wir nutzen form.json im Root) + */ + // public function GetConfigurationForm(): string + // { + // return ''; + // } /** - * Wird automatisch aufgerufen, wenn die Visu die Tile anfordert + * Liefert das HTML-Template für die WebFront-Tile */ public function GetVisualizationTile(int $InstanceID): string { $file = __DIR__ . '/module.html'; if (!file_exists($file)) { + $this->LogMessage("module.html nicht gefunden in $file", KL_ERROR); return ''; } - // Übersetzungen einbinden return $this->Translate(file_get_contents($file)); } /** - * JS-requestAction ruft das auf, um frische Daten anzufordern + * Callback aus dem HTML: Daten neu berechnen und senden */ public function RequestAction(string $Ident, $Value): void { if ($Ident === 'update') { - $this->Update(); + $this->UpdateData(); } else { - throw new Exception('Unknown Ident'); + throw new Exception("Unknown Ident"); } } /** - * Berechnet die Tages-Summen und sendet sie an die Visu + * Tägliche Summen holen, Quoten berechnen und ans Frontend senden */ - private function Update(): void + protected function UpdateData(): void { $start = strtotime('today 00:00'); $end = time(); - $prod = $this->GetDailyTotal($this->ReadPropertyInteger('VarProduction'), $start, $end); - $cons = $this->GetDailyTotal($this->ReadPropertyInteger('VarConsumption'), $start, $end); - $feed = $this->GetDailyTotal($this->ReadPropertyInteger('VarFeedIn'), $start, $end); - $grid = $this->GetDailyTotal($this->ReadPropertyInteger('VarGrid'), $start, $end); - // Quoten berechnen - $prodCons = $prod > 0 ? ($cons / $prod) * 100 : 0; - $prodFeed = $prod > 0 ? ($feed / $prod) * 100 : 0; - $consPV = $cons > 0 ? (min($cons, $prod) / $cons) * 100 : 0; - $consGrid = $cons > 0 ? ($grid / $cons) * 100 : 0; + $prodID = $this->ReadPropertyInteger('VarProduction'); + $consID = $this->ReadPropertyInteger('VarConsumption'); + $feedID = $this->ReadPropertyInteger('VarFeedIn'); + $gridID = $this->ReadPropertyInteger('VarGrid'); + + $prod = $this->GetDailyTotal($prodID, $start, $end); + $cons = $this->GetDailyTotal($consID, $start, $end); + $feed = $this->GetDailyTotal($feedID, $start, $end); + $grid = $this->GetDailyTotal($gridID, $start, $end); + + // Quoten in Prozent + $prodCons = ($prod > 0) ? ($cons / $prod) * 100 : 0; + $prodFeed = ($prod > 0) ? ($feed / $prod) * 100 : 0; + $consPV = ($cons > 0) ? min($prod, $cons) / $cons * 100 : 0; + $consGrid = ($cons > 0) ? ($grid / $cons) * 100 : 0; $data = [ - 'prodCons' => round($prodCons, 2), - 'prodFeed' => round($prodFeed, 2), - 'consPV' => round($consPV, 2), - 'consGrid' => round($consGrid, 2), + 'prodCons' => round($prodCons, 1), + 'prodFeed' => round($prodFeed, 1), + 'consPV' => round($consPV, 1), + 'consGrid' => round($consGrid, 1), 'value' => [ 'prod' => round($prod, 2), 'cons' => round($cons, 2), @@ -98,29 +84,28 @@ class Belevo_PV_Visu extends IPSModule 'grid' => round($grid, 2) ] ]; + $this->UpdateVisualizationValue($data); } /** - * Ruft den Tages-Gesamtwert aus dem Archiv ab (tägliche Aggregation) + * Aggregierte Tageswerte aus dem Archiv */ private function GetDailyTotal(int $varID, int $start, int $end): float { if ($varID <= 0) { return 0.0; } - // Erste Archive-Instanz finden + // Erstes Archivmodul finden $archives = IPS_GetInstanceListByModuleID('{43192F11-5B02-4B5D-9B53-8B4DBD4769E9}'); if (empty($archives)) { return 0.0; } $archiveID = $archives[0]; - // AC_GetAggregatedValues( InstanzID, VarID, AggregationLevel(1=Täglich), Start, Ende, Limit=1 ) $values = AC_GetAggregatedValues($archiveID, $varID, 1, $start, $end, 1); if (empty($values)) { return 0.0; } - // Bei Counter-Variablen enthält 'Avg' die Summe der Deltas return (float)$values[0]['Avg']; } }