Energiemanager optimiert, Easee-Ladestation eingefügt.

This commit is contained in:
2025-08-07 08:45:19 +02:00
parent 6ffada6d29
commit aa150f58be
18 changed files with 1347 additions and 232 deletions

View File

@@ -1,67 +1,95 @@
# Manager_1
Beschreibung des Moduls.
# Belevo EMS Hauptmanager
### Inhaltsverzeichnis
Das **Belevo EMS Hauptmanager**-Modul fasst mehrere untergeordnete **Belevo EMS Manager**-Instanzen zusammen und verteilt die globale verfügbare Leistung direkt auf die einzelnen Verbraucher-Instanzen nicht nur auf die Manager. Jeder Unter-Manager meldet seine Verbraucher-Daten als JSON, der Hauptmanager berechnet die finalen Zuweisungen und liefert für jeden Unter-Manager ein JSON mit den fertigen Verbraucher-Leistungen zurück.
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)
---
### 1. Funktionsumfang
## Inhaltsverzeichnis
*
1. [Beschreibung](#beschreibung)
2. [Voraussetzungen](#voraussetzungen)
3. [Installation](#installation)
4. [Instanz anlegen & Konfiguration](#instanz-anlegen--konfiguration)
5. [Statusvariablen](#statusvariablen)
6. [Funktionsweise](#funktionsweise)
1. [Mode-Entscheid](#1-mode-entscheid)
2. [Datenaggregation](#2-datenaggregation)
3. [Globale Soll-Ist-Differenz](#3-globale-soll-ist-differenz)
4. [Verbraucher-Priorisierung](#4-verbraucher-priorisierung)
5. [Leistungszuweisung](#5-leistungszuweisung)
6. [Rückgabe an Unter-Manager](#6-rückgabe-an-unter-manager)
7. [Beispiel-Workflow](#beispiel-workflow)
8. [Mapping auf Code-Komponenten](#mapping-auf-code-komponenten)
9. [Zukünftige Erweiterungen](#zukünftige-erweiterungen)
10. [Support](#support)
### 2. Voraussetzungen
---
- IP-Symcon ab Version 7.1
## Beschreibung
### 3. Software-Installation
Der Hauptmanager koordiniert beliebig viele Unter-Manager (z. B. Hausanschluss, ZEV-Cluster, LEG-Center). Jeder Unter-Manager sammelt in seinem Zyklus die Daten aller angeschlossenen Verbraucher (JSON-Array mit Feldern wie `deviceID`, `priority`, `requestedLevels`, `currentDrawn`, `receivedTotal` usw.) und stellt dieses JSON in seiner `DatenZurueck`-Variable bereit. Der Hauptmanager
* Über den Module Store das 'Manager_1'-Modul installieren.
* Alternativ über das Module Control folgende URL hinzufügen
1. liest alle `DatenZurueck` JSONs der Unter-Manager ein,
2. entscheidet global über Solarlade- oder Peak-Shaving-Mode,
3. berechnet eine einzige **globale** SollIst-Differenz,
4. führt Priorisierung und Fair-Round-Robin über **alle** Verbraucher durch,
5. verteilt die verfügbare Leistung in Stufen (je Verbraucher aus `PowerSteps`),
6. erzeugt für jeden Unter-Manager ein JSON mit den finalen `assignedLevel`-Werten pro `deviceID`,
7. schreibt diese JSONs in die jeweilige `DatenHoch`-Variable.
### 4. Einrichten der Instanzen in IP-Symcon
Die Unter-Manager übernehmen das JSON und senden die fertigen `assignedLevel`-Werte an ihre lokalen Verbraucher-Instanzen.
Unter 'Instanz hinzufügen' kann das 'Manager_1'-Modul mithilfe des Schnellfilters gefunden werden.
- Weitere Informationen zum Hinzufügen von Instanzen in der [Dokumentation der Instanzen](https://www.symcon.de/service/dokumentation/konzepte/instanzen/#Instanz_hinzufügen)
---
__Konfigurationsseite__:
## Voraussetzungen
Name | Beschreibung
-------- | ------------------
|
|
- IP-Symcon **≥ 8.0**
- Bereits installierte **Belevo EMS Manager**-Instanzen
- Zugriff auf Git-Repository:
https://git.belevo.ch/dh/Symcon_Belevo_Energiemanagement_testing.git
### 5. Statusvariablen und Profile
yaml
Kopieren
Bearbeiten
Die Statusvariablen/Kategorien werden automatisch angelegt. Das Löschen einzelner kann zu Fehlfunktionen führen.
---
#### Statusvariablen
## Installation
Name | Typ | Beschreibung
------ | ------- | ------------
| |
| |
1. In IP-Symcon **Module Control** öffnen
2. **Hinzufügen → Git-Repository**
3. URL eintragen (s. o.)
4. Modul **„Belevo EMS Hauptmanager“** installieren
5. IP-Symcon neu starten
#### Profile
---
Name | Typ
------ | -------
|
|
## Instanz anlegen & Konfiguration
### 6. WebFront
1. Rechtsklick auf **Instanzen****Instanz hinzufügen**
2. Filter: **Belevo**
3. **„Belevo EMS Hauptmanager“** auswählen und Instanz erstellen
Die Funktionalität, die das Modul im WebFront bietet.
### Properties
### 7. PHP-Befehlsreferenz
| Name | Typ | Beschreibung |
|------------------------|----------------|------------------------------------------------------------------------------|
| **HauptmanagerAktiv** | Boolean | Schaltet globale Verteilungslogik ein/aus |
| **Interval** | Integer (s) | Zyklusintervall für Verteilung und Mode-Entscheid |
| **Sollleistung_Max** | Float (W) | Max. Gesamtleistung, die verteilt werden darf |
| **Ueberschussleistung**| Float (W) | Untergrenze für Solarlade-Mode (z. B. 0 W) |
| **Manager_Liste** | InstanceList | Liste aller untergeordneten Belevo EMS Manager-Instanzen |
| **DatenZurueck** | SelectVariable | Variable-ID (Integer) in jeder Unter-Manager-Instanz, aus der JSON gelesen wird |
| **DatenHoch** | SelectVariable | Variable-ID in jeder Unter-Manager-Instanz, in die JSON geschrieben wird |
`boolean GEF_BeispielFunktion(integer $InstanzID);`
Erklärung der Funktion.
---
Beispiel:
`GEF_BeispielFunktion(12345);`
## Statusvariablen
| Ident | Typ | Profil | Beschreibung |
|--------------------------|-----------|--------------|-----------------------------------------------------|
| **LetzteBerechnung** | DateTime | — | Zeitstempel der letzten Verteilung |
| **Globale_Differenz** | Float | ~Watt~~W~ | Zuletzt berechnete SollIst-Differenz global (W) |
| **Anzahl_Manager** | Integer | — | Anzahl aktuell verbundener Unter-Manager |
---

View File

@@ -110,12 +110,12 @@ class HauptManager extends IPSModule
}
// Addiere die aktuell bereits verwendete Leistung auf, um sie bei der verteilung zu berücksichtigen
if(in_array(0, $user["PowerSteps"], true)){
//if(in_array(0, $user["PowerSteps"], true)){
// Addiere die aktuell bereits verwendete Leistung auf, um sie bei der verteilung zu berücksichtigen
$totalAktuelle_Leistung += ($user["Aktuelle_Leistung"]- $user["Leistung_Delta"]);
}
//}
}
// Berücksichtigung der bereits verteilten Leistungen (nachher kann dafür wieder bei 0 begonnen werden zu verteilen)
@@ -206,9 +206,11 @@ class HauptManager extends IPSModule
if (empty($samePriorityUsers)) {
continue;
}
$withZero = [];
$withoutZero = [];
// Verbraucher die nicht 0 Annhemen können, bekommen einfach den tiefsten wert
$withoutZeroHigh = [];
$withoutZeroLow = [];
/* Alter Verteilalgor. zu testzwecken auskommentiert, wird dann gelöscht wenns funktioniert.
foreach ($samePriorityUsers as $entry) {
if (min($entry["PowerSteps"]) <= 0) {
$withZero[] = $entry;
@@ -217,18 +219,55 @@ class HauptManager extends IPSModule
}
}
// Verbraucher die nicht 0 annhemen können erhalten nun den minimalwert
if (!empty($withoutZero)) {
foreach ($withoutZero as $entry) {
$resultArray[] = [
'user' => $user['InstanceID'],
'Writeback' => $user['Writeback'],
'Set_Leistung' => min($entry["PowerSteps"])
];
$instanceID = $entry["InstanceID"];
$minPowerStep = min($entry["PowerSteps"]);
IPS_RequestAction($instanceID,"SetAktuelle_Leistung",$minPowerStep);
//$remainingPower -= $entry["Aktuelle_Leistung"];
}
}
*/
/* Neuer Block */
foreach ($samePriorityUsers as $entry) {
$withZero[] = $entry;
if (min($entry["PowerSteps"]) > 0) {
$withoutZeroHigh[] = $entry;
}
if (max($entry["PowerSteps"]) < 0) {
$withoutZeroLow[] = $entry;
}
}
// Verbraucher die nicht 0 annhemen können erhalten nun den minimalwert
if (!empty($withoutZeroHigh)) {
foreach ($withoutZeroHigh as $entry) {
$instanceID = $entry["InstanceID"];
$minPowerStep = min($entry["PowerSteps"]);
$remainingPower -= $minPowerStep;
}
}
// Verbraucher die nicht 0 annhemen können erhalten nun den minimalwert
if (!empty($withoutZeroLow)) {
foreach ($withoutZeroLow as $entry) {
$instanceID = $entry["InstanceID"];
$minPowerStep = max($entry["PowerSteps"]);
$remainingPower += $minPowerStep;
}
}
/* Neuer Block Ende */
// Nun die verteilen, die 0 erhalten können.
$samePriorityUsers = $withZero;
@@ -299,22 +338,36 @@ class HauptManager extends IPSModule
// Prüfen, dass jeder User mindestens seinen minimalwert an Leistung bekommt
foreach ($userEnergyProv as $userInstanceID => $leistung) {
$minimalleitsung = min(
array_column(
array_filter($allSteps, function ($entry) use (
$userInstanceID
) {
return $entry["user"] == $userInstanceID;
}),
"step"
)
);
$positiveValues = array_filter(
array_column(
$samePriorityUsers,
'PowerSteps',
'InstanceID'
)[$userInstanceID],
function ($l) {
return $l >= 0;
}
);
// 2. Falls keine Werte ≥ 0 vorhanden sind, auf 0 zurückfallen
$fallbackMinimum = empty($positiveValues)
? max( array_column(
$samePriorityUsers,
'PowerSteps',
'InstanceID'
)[$userInstanceID])
: min($positiveValues);
IPS_LogMessage("Manager", $userInstanceID);
IPS_LogMessage("Manager", $minimalleitsung);
IPS_LogMessage("Manager", $remainingPower);
// Jedem user den höheren der beiden werte aus minimalwert oder vergebenem zuteilen
$leistung = max($leistung["Set_Leistung"], $minimalleitsung);
// 3. minimalleistung = dieser Fallback
$minimalleistung = $fallbackMinimum;
// 4. den höheren Wert wählen und für IPS negativieren
//$schreibleistung = max($leistung, $minimalleistung);
if (abs($leistung["Set_Leistung"]) > abs($minimalleistung)) {
$leistung = $leistung["Set_Leistung"];
} else {
$leistung = $minimalleistung;
}
// Methode SetAktuelle_Leistung für jeden Verbraucher mit der entsprechenden Energie aufrufen
@@ -387,22 +440,37 @@ class HauptManager extends IPSModule
// Prüfen, dass jeder User mindestens seinen minimalwert an Leistung bekommt
foreach ($userEnergyProv as $userInstanceID => $leistung) {
$minimalleitsung = min(
array_column(
array_filter($allSteps, function ($entry) use (
$userInstanceID
) {
return $entry["user"] == $userInstanceID;
}),
"step"
)
);
$positiveValues = array_filter(
array_column(
$samePriorityUsers,
'PowerSteps',
'InstanceID'
)[$userInstanceID],
function ($l) {
return $l <= 0;
}
);
// 2. Falls keine Werte ≥ 0 vorhanden sind, auf 0 zurückfallen
$fallbackMinimum = empty($positiveValues)
? min( array_column(
$samePriorityUsers,
'PowerSteps',
'InstanceID'
)[$userInstanceID])
: max($positiveValues);
IPS_LogMessage("Manager", $userInstanceID);
IPS_LogMessage("Manager", $minimalleitsung);
IPS_LogMessage("Manager", $remainingPower);
// 3. minimalleistung = dieser Fallback
$minimalleistung = $fallbackMinimum;
// 4. den höheren Wert wählen und für IPS negativieren
//$schreibleistung = max($leistung, $minimalleistung);
if (abs($leistung["Set_Leistung"]) > abs($minimalleistung)) {
$leistung = $leistung["Set_Leistung"];
} else {
$leistung = $minimalleistung;
}
// Jedem user den höheren der beiden werte aus minimalwert oder vergebenem zuteilen
$leistung = max($leistung["Set_Leistung"], $minimalleitsung)*-1;
// Methode SetAktuelle_Leistung für jeden Verbraucher mit der entsprechenden Energie aufrufen