Version 2.0.0 Beta
This commit is contained in:
67
Ansteuerung_Askoheat/README.md
Normal file
67
Ansteuerung_Askoheat/README.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# Manager_1
|
||||
Beschreibung des Moduls.
|
||||
|
||||
### 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)
|
||||
|
||||
### 1. Funktionsumfang
|
||||
|
||||
*
|
||||
|
||||
### 2. Voraussetzungen
|
||||
|
||||
- IP-Symcon ab Version 7.1
|
||||
|
||||
### 3. Software-Installation
|
||||
|
||||
* Über den Module Store das 'Manager_1'-Modul installieren.
|
||||
* Alternativ über das Module Control folgende URL hinzufügen
|
||||
|
||||
### 4. Einrichten der Instanzen in IP-Symcon
|
||||
|
||||
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__:
|
||||
|
||||
Name | Beschreibung
|
||||
-------- | ------------------
|
||||
|
|
||||
|
|
||||
|
||||
### 5. Statusvariablen und Profile
|
||||
|
||||
Die Statusvariablen/Kategorien werden automatisch angelegt. Das Löschen einzelner kann zu Fehlfunktionen führen.
|
||||
|
||||
#### Statusvariablen
|
||||
|
||||
Name | Typ | Beschreibung
|
||||
------ | ------- | ------------
|
||||
| |
|
||||
| |
|
||||
|
||||
#### Profile
|
||||
|
||||
Name | Typ
|
||||
------ | -------
|
||||
|
|
||||
|
|
||||
|
||||
### 6. WebFront
|
||||
|
||||
Die Funktionalität, die das Modul im WebFront bietet.
|
||||
|
||||
### 7. PHP-Befehlsreferenz
|
||||
|
||||
`boolean GEF_BeispielFunktion(integer $InstanzID);`
|
||||
Erklärung der Funktion.
|
||||
|
||||
Beispiel:
|
||||
`GEF_BeispielFunktion(12345);`
|
||||
103
Ansteuerung_Askoheat/form.json
Normal file
103
Ansteuerung_Askoheat/form.json
Normal file
@@ -0,0 +1,103 @@
|
||||
{
|
||||
"elements": [
|
||||
{
|
||||
"type": "Label",
|
||||
"caption": "Einstellungen für einstufigen Verbruacher Ein-Aus"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "IdleCounterMax",
|
||||
"caption": "Zyklen zwischen zwei Leistungsänderungen (Multipliziert sich mit Interval)",
|
||||
"suffix": ""
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Interval",
|
||||
"caption": "Intervall Neuberechnung der Werte Erst für spätere Versionen, aktuell auf 5 lassen!",
|
||||
"suffix": "Sekunden"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "BoilerLeistung",
|
||||
"caption": "Maximalleitsung Askoheat",
|
||||
"suffix": ""
|
||||
},
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
"name": "Variable_Leistung",
|
||||
"caption": "Variable mit der Nennleistung",
|
||||
"test": true
|
||||
},
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
"name": "Variable_Temperatur",
|
||||
"caption": "Variable mit der Solltemperatur Boiler",
|
||||
"test": true
|
||||
},
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
"name": "Variable_Temperatur_Ist",
|
||||
"caption": "Variable mit der Isttemperatur Boiler",
|
||||
"test": true
|
||||
},
|
||||
{
|
||||
"type":"Select",
|
||||
"name":"Boilertemperatur_glätten",
|
||||
"caption":"Boilertemperatur glätten",
|
||||
"options":[
|
||||
{
|
||||
"caption":"Ja",
|
||||
"value":true
|
||||
},
|
||||
{
|
||||
"caption":"Nein",
|
||||
"value":false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "ZeitKonstante",
|
||||
"caption": "Zeit Konstante",
|
||||
"suffix": ""
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Boilervolumen",
|
||||
"caption": "Boilervolumen",
|
||||
"suffix": "Liter"
|
||||
},
|
||||
{
|
||||
"type": "List",
|
||||
"name": "Zeitplan",
|
||||
"caption": "Zeitplan für Solltemperaturen",
|
||||
"columns": [
|
||||
{
|
||||
"caption": "Uhrzeit",
|
||||
"name": "Uhrzeit",
|
||||
"width": "150px",
|
||||
"add": "00:00",
|
||||
"edit": {
|
||||
"type": "ValidationTextBox"
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": "Solltemperatur",
|
||||
"name": "Solltemperatur",
|
||||
"width": "150px",
|
||||
"add": 0,
|
||||
"edit": {
|
||||
"type": "NumberSpinner"
|
||||
}
|
||||
}
|
||||
],
|
||||
"add": true,
|
||||
"delete": true,
|
||||
"sort": {
|
||||
"column": "Uhrzeit",
|
||||
"direction": "ascending"
|
||||
}
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
12
Ansteuerung_Askoheat/module.json
Normal file
12
Ansteuerung_Askoheat/module.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"id": "{C042B0F6-CD02-9843-8D21-31BC3049BC14}",
|
||||
"name": "Ansteuerung_Askoheat",
|
||||
"type": 3,
|
||||
"vendor": "Belevo AG",
|
||||
"aliases": [],
|
||||
"parentRequirements": [],
|
||||
"childRequirements": [],
|
||||
"implemented": [],
|
||||
"prefix": "GEF",
|
||||
"url": ""
|
||||
}
|
||||
337
Ansteuerung_Askoheat/module.php
Normal file
337
Ansteuerung_Askoheat/module.php
Normal file
@@ -0,0 +1,337 @@
|
||||
<?php
|
||||
class Ansteuerung_Askoheat extends IPSModule
|
||||
{
|
||||
private $timerID;
|
||||
|
||||
public function Create()
|
||||
{
|
||||
parent::Create();
|
||||
|
||||
// Verbraucherspezifische Properties
|
||||
$this->RegisterPropertyInteger("ZeitKonstante", 120);
|
||||
$this->RegisterPropertyBoolean("Boilertemperatur_glätten", false);
|
||||
$this->RegisterPropertyInteger("Boilervolumen", 300);
|
||||
$this->RegisterPropertyString("Zeitplan", "");
|
||||
$this->RegisterPropertyInteger("BoilerLeistung", 3500); // Standardwert für Volllast
|
||||
$this->RegisterPropertyInteger("Interval", 5); // Recheninterval
|
||||
$this->RegisterPropertyInteger("Variable_Leistung", 0); // Recheninterval
|
||||
$this->RegisterPropertyInteger("Variable_Temperatur", 0); // Recheninterval
|
||||
$this->RegisterPropertyInteger("Variable_Temperatur_Ist", 0); // Recheninterval
|
||||
|
||||
// Variabeln für Kommunkation mit Manager
|
||||
$this->RegisterVariableInteger("Sperre_Prio", "Sperre_Prio");
|
||||
$this->RegisterVariableInteger("PV_Prio", "PV_Prio");
|
||||
$this->RegisterVariableBoolean("Idle", "Idle", "", 0);
|
||||
$this->RegisterVariableInteger("Aktuelle_Leistung", "Aktuelle_Leistung", "", 0);
|
||||
$this->RegisterVariableFloat("Bezogene_Energie", "Bezogene_Energie", "", 0);
|
||||
$this->RegisterVariableString("PowerSteps", "PowerSteps");
|
||||
$this->RegisterVariableInteger("Power", "Power");
|
||||
$this->RegisterVariableBoolean("Is_Peak_Shaving", "Is_Peak_Shaving");
|
||||
$this->RegisterVariableInteger("Leistung_Delta", "Leistung_Delta", "", 0);
|
||||
$this->RegisterVariableFloat("Boilertemperatur", "Boilertemperatur", "", 0);
|
||||
|
||||
// Boiler spezifische Variablen
|
||||
$this->RegisterVariableInteger("Mindesttemperatur","Mindesttemperatur","",45);
|
||||
$this->RegisterVariableInteger("Maximaltemperatur","Maximaltemperatur","",60);
|
||||
$this->RegisterVariableInteger("Legionellentemperatur","Legionellentemperatur","",65);
|
||||
$this->RegisterVariableInteger("LegioCounter", "LegioCounter", "", 0);
|
||||
$this->RegisterVariableInteger("Boilertemperatur", "Boilertemperatur", "", 0);
|
||||
|
||||
// Hilfsvariabeln für Idle zustand
|
||||
$this->RegisterPropertyInteger("IdleCounterMax", 2);
|
||||
$this->RegisterVariableInteger("IdleCounter", "IdleCounter", "", 0);
|
||||
$this->SetValue("IdleCounter", 0);
|
||||
|
||||
// Initialisiere Idle
|
||||
$this->SetValue("Idle", true);
|
||||
|
||||
$this->RegisterTimer("Timer_Do_UserCalc_Verb",$this->ReadPropertyInteger("Interval")*1000,"IPS_RequestAction(" .$this->InstanceID .', "Do_UserCalc", "");');
|
||||
|
||||
}
|
||||
|
||||
public function ApplyChanges()
|
||||
{
|
||||
parent::ApplyChanges();
|
||||
$this->SetTimerInterval("Timer_Do_UserCalc_Verb",$this->ReadPropertyInteger("Interval")*1000);
|
||||
|
||||
}
|
||||
|
||||
public function RequestAction($Ident, $Value)
|
||||
{
|
||||
switch ($Ident) {
|
||||
|
||||
case "SetAktuelle_Leistung":
|
||||
$this->SetValue("Power", (int)$Value);
|
||||
break;
|
||||
|
||||
case "GetCurrentData":
|
||||
$this->SetValue("Is_Peak_Shaving", (bool)$Value);
|
||||
break;
|
||||
|
||||
case "Do_UserCalc":
|
||||
$this->SetAktuelle_Leistung($this->GetValue("Power"));
|
||||
$this->GetCurrentData($this->GetValue("Is_Peak_Shaving"));
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Exception("Invalid Ident");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function getNextTimeAndTemperature($zeitplan) {
|
||||
$arr = json_decode($zeitplan, true);
|
||||
if (empty($arr)) {
|
||||
return null;
|
||||
}
|
||||
$currentTime = new DateTime();
|
||||
$nextEntry = null;
|
||||
$minDiff = PHP_INT_MAX;
|
||||
|
||||
foreach ($arr as $entry) {
|
||||
$entryTime = DateTime::createFromFormat('H:i', $entry['Uhrzeit']);
|
||||
if ($entryTime < $currentTime) {
|
||||
$entryTime->modify('+1 day');
|
||||
}
|
||||
$diff = $currentTime->diff($entryTime)->format('%r%a') * 24 * 60 + $currentTime->diff($entryTime)->format('%r%h') * 60 + $currentTime->diff($entryTime)->format('%r%i');
|
||||
if ($diff < $minDiff) {
|
||||
$minDiff = $diff;
|
||||
$nextEntry = $entry;
|
||||
}
|
||||
}
|
||||
|
||||
return $nextEntry;
|
||||
}
|
||||
|
||||
public function calculateRemainingTime($nextTime) {
|
||||
$currentTime = new DateTime();
|
||||
$nextDateTime = DateTime::createFromFormat('H:i', $nextTime);
|
||||
if ($nextDateTime < $currentTime) {
|
||||
$nextDateTime->modify('+1 day');
|
||||
}
|
||||
$interval = $currentTime->diff($nextDateTime);
|
||||
return $interval->h + ($interval->i / 60);
|
||||
}
|
||||
|
||||
public function calculateRequiredHeat($boilervolumen, $tempDiff) {
|
||||
// Annahme: spezifische Wärmekapazität von Wasser = 4.186 J/g°C
|
||||
// 1 Liter Wasser = 1000 Gramm
|
||||
$specificHeatCapacity = 4.186; // J/g°C
|
||||
$waterMass = $boilervolumen * 1000; // Gramm
|
||||
return $specificHeatCapacity * $waterMass * $tempDiff; // Joules
|
||||
}
|
||||
|
||||
public function canBoilerReachTemperature($boilervolumen, $boilerTemper, $nextTemp, $remainingTime, $vollleistung) {
|
||||
$tempDiff = $nextTemp - $boilerTemper;
|
||||
$requiredHeat = $this->calculateRequiredHeat($boilervolumen, $tempDiff);
|
||||
$availableHeat = $vollleistung * $remainingTime * 3600; // Leistung in Watt * Zeit in Sekunden
|
||||
return $availableHeat >= $requiredHeat;
|
||||
}
|
||||
|
||||
// Methode zum Setzen des aktuellen Stromverbrauchs
|
||||
public function SetAktuelle_Leistung(int $power)
|
||||
{
|
||||
RequestAction($this->ReadPropertyInteger("Variable_Leistung"), $power);
|
||||
|
||||
// Prüfe auf Änderung der Power im Vergleich zur letzten Einstellung
|
||||
$lastPower = GetValue($this->GetIDForIdent("Aktuelle_Leistung"));
|
||||
if ($power != $lastPower) {
|
||||
$this->SetValue("Idle", false);
|
||||
$this->SetValue(
|
||||
"IdleCounter",
|
||||
$this->ReadPropertyInteger("IdleCounterMax")
|
||||
);
|
||||
}
|
||||
|
||||
// Setze die neue Aktuelle_Leistung
|
||||
$this->SetValue("Aktuelle_Leistung", $power);
|
||||
$this->SetValue("Bezogene_Energie", ($this->GetValue("Bezogene_Energie") + ($this->GetValue("Aktuelle_Leistung")*($this->ReadPropertyInteger("Interval")/3600))));
|
||||
// IdleCounter verarbeiten
|
||||
$this->ProcessIdleCounter();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function Calc_Seven_Steps(int $power)
|
||||
{
|
||||
$steps = [];
|
||||
$increment = $power / 7;
|
||||
|
||||
for ($i = 0; $i <= 7; $i++) {
|
||||
$steps[] = $i * $increment;
|
||||
}
|
||||
|
||||
return $steps;
|
||||
}
|
||||
|
||||
// Methode zum Abrufen der aktuellen Daten
|
||||
public function GetCurrentData(bool $Peak)
|
||||
{
|
||||
$LegioCounter = $this->GetValue("LegioCounter");
|
||||
|
||||
|
||||
$boilertemperatur_glätten = $this->ReadPropertyBoolean("Boilertemperatur_glätten");
|
||||
|
||||
if ($boilertemperatur_glätten) {
|
||||
// Wenn Glättung aktiviert ist, führe das Glätten durch
|
||||
$boilerFuehlerPT1ID = $this->ReadPropertyInteger("Variable_Temperatur_Ist");
|
||||
|
||||
if (IPS_VariableExists($boilerFuehlerPT1ID)) {
|
||||
$boilerPT1 = GetValue($boilerFuehlerPT1ID);
|
||||
} else {
|
||||
$boilerPT1 = 0.0; // Standardwert
|
||||
}
|
||||
|
||||
$boilerTempID = $this->GetIDForIdent("Boilertemperatur");
|
||||
if (IPS_VariableExists($boilerTempID)) {
|
||||
$boilerTemp = $this->GetValue("Boilertemperatur");
|
||||
} else {
|
||||
$boilerTemp = 0.0; // Standardwert
|
||||
}
|
||||
|
||||
// PT
|
||||
$time_constant= $this->ReadPropertyInteger("ZeitKonstante");
|
||||
$delta_t = 5; // Zeitdifferenz zwischen den Messungen (30 Sekunden)
|
||||
$alpha = $delta_t / ($time_constant + $delta_t);
|
||||
$newBoilerTemp = $boilerTemp + $alpha * ($boilerPT1 - $boilerTemp);
|
||||
$this->SetValue("Boilertemperatur", $newBoilerTemp);
|
||||
} else {
|
||||
// Wenn Glättung nicht aktiviert ist, setze die Boilertemperatur direkt auf den Wert des Boilerfühlers
|
||||
$boilerFuehlerPT1ID = $this->ReadPropertyInteger("Variable_Temperatur_Ist");
|
||||
|
||||
if (IPS_VariableExists($boilerFuehlerPT1ID)) {
|
||||
$boilerPT1 = GetValue($boilerFuehlerPT1ID);
|
||||
} else {
|
||||
$boilerPT1 = 0.0; // Standardwert
|
||||
}
|
||||
|
||||
// Setze Boilertemperatur direkt auf den Wert des Boilerfühlers
|
||||
$this->SetValue("Boilertemperatur", $boilerPT1);
|
||||
}
|
||||
|
||||
|
||||
$boilerTemp = $this->GetValue("Boilertemperatur");
|
||||
$minTemp = $this->GetValue("Mindesttemperatur");
|
||||
$maxTemp = $this->GetValue("Maximaltemperatur");
|
||||
$LegioTemp = $this->GetValue("Legionellentemperatur");
|
||||
$vollLeistung = $this->ReadPropertyInteger("BoilerLeistung");
|
||||
|
||||
|
||||
$nextEntry = $this->getNextTimeAndTemperature($this->ReadPropertyString("Zeitplan"));
|
||||
if ($nextEntry !== null) {
|
||||
$remainingTime = $this->calculateRemainingTime($nextEntry['Uhrzeit']);
|
||||
$nextTemp = $nextEntry['Solltemperatur'];
|
||||
|
||||
if (!$this->canBoilerReachTemperature($this->ReadPropertyInteger("Boilervolumen"), $boilerTemp, $nextTemp, $remainingTime, $vollLeistung)) {
|
||||
$minTemp = $nextTemp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
$boilerIsOn = (GetValue($this->ReadPropertyInteger("Variable_Leistung"))>0);
|
||||
$AktuelleVollast = GetValue(
|
||||
$this->ReadPropertyInteger("Variable_Leistung")
|
||||
);
|
||||
|
||||
|
||||
if ($boilerTemp > $LegioTemp) {
|
||||
$LegioCounter = 0;
|
||||
} else {
|
||||
$LegioCounter = $LegioCounter + 1;
|
||||
}
|
||||
if ($LegioCounter > 69120) {
|
||||
$maxTemp = $LegioTemp;
|
||||
}
|
||||
if ($LegioCounter > 120960 && $this->ist_nachts()) {
|
||||
$minTemp = $LegioTemp;
|
||||
}
|
||||
if ($LegioCounter > 138240) { // Timeout für Legio wenn temperatur nicht erreicht werden kann, setze legionellenfunktion zurück
|
||||
$LegioCounter = 0;
|
||||
}
|
||||
|
||||
$this->SetValue("LegioCounter", $LegioCounter);
|
||||
|
||||
if ($Peak) {
|
||||
if ($boilerTemp < $minTemp) {
|
||||
$this->SetValue( "PowerSteps", json_encode($this->Calc_Seven_Steps($vollLeistung)) );
|
||||
} elseif (
|
||||
$boilerTemp < $minTemp + 5 &&
|
||||
($boilerIsOn)
|
||||
) {
|
||||
$this->SetValue(
|
||||
"PowerSteps",
|
||||
json_encode($this->Calc_Seven_Steps($vollLeistung))
|
||||
);
|
||||
} else {
|
||||
$this->SetValue("PowerSteps", json_encode([0]));
|
||||
}
|
||||
} else {
|
||||
if ($boilerTemp < $minTemp) {
|
||||
$this->SetValue("PowerSteps", json_encode([$vollLeistung]));
|
||||
} elseif (
|
||||
$boilerTemp < $minTemp + 5 &&
|
||||
($boilerIsOn)
|
||||
) {
|
||||
$this->SetValue("PowerSteps", json_encode([$vollLeistung]));
|
||||
} elseif ($boilerTemp < $maxTemp - 5) {
|
||||
$this->SetValue("PowerSteps", json_encode($this->Calc_Seven_Steps($vollLeistung)));
|
||||
} elseif ( $boilerTemp < $maxTemp && ($boilerIsOn)
|
||||
) {
|
||||
$this->SetValue( "PowerSteps", json_encode($this->Calc_Seven_Steps($vollLeistung)));
|
||||
} else {
|
||||
$this->SetValue("PowerSteps", json_encode([0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function ProcessIdleCounter()
|
||||
{
|
||||
// IdleCounter auslesen und verarbeiten
|
||||
$idleCounter = $this->GetValue("IdleCounter");
|
||||
if ($idleCounter > 0) {
|
||||
$this->SetValue("Idle", false);
|
||||
$this->SetValue("IdleCounter", $idleCounter - 1);
|
||||
} else {
|
||||
$this->SetValue("Idle", true);
|
||||
}
|
||||
}
|
||||
|
||||
private function CheckIdle($power)
|
||||
{
|
||||
$lastpower = GetValue("Aktuelle_Leistung");
|
||||
if ($lastpower != GetValue("Aktuelle_Leistung")) {
|
||||
$this->SetValue("Idle", false);
|
||||
$this->SetValue(
|
||||
"IdleCounter",
|
||||
$this->ReadPropertyInteger("IdleCounterMax")
|
||||
);
|
||||
}
|
||||
// IdleCounter auslesen und verarbeiten
|
||||
$idleCounter = $this->GetValue("IdleCounter");
|
||||
if ($idleCounter > 0) {
|
||||
$this->SetValue("Idle", false);
|
||||
$this->SetValue("IdleCounter", $idleCounter - 1);
|
||||
} else {
|
||||
$this->SetValue("Idle", true);
|
||||
}
|
||||
}
|
||||
|
||||
private function ist_nachts()
|
||||
{
|
||||
date_default_timezone_set("Europe/Berlin"); // Setze hier deine Zeitzone
|
||||
|
||||
$aktuelle_zeit = strtotime(date("H:i")); // Aktuelle Zeit in Stunden und Minuten umwandeln
|
||||
$start_nacht = strtotime("22:00"); // Startzeit der Nacht (22 Uhr)
|
||||
$ende_nacht = strtotime("07:00"); // Endzeit der Nacht (7 Uhr)
|
||||
|
||||
if ($aktuelle_zeit >= $start_nacht || $aktuelle_zeit < $ende_nacht) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -7,15 +7,27 @@
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "IdleCounterMax",
|
||||
"caption": "Zyklen zwischen zwei Leisutungsänderungen",
|
||||
"caption": "Zyklen zwischen zwei Leistungsänderungen (Multipliziert sich mit Interval)",
|
||||
"suffix": ""
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Interval",
|
||||
"caption": "Intervall Neuberechnung der Werte",
|
||||
"suffix": "Sekunden"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "MaxBatterieleistung",
|
||||
"caption": "Maximale Batterieleistung",
|
||||
"suffix": ""
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "MaxNachladen",
|
||||
"caption": "Maximum Nachladen",
|
||||
"suffix": ""
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "AufdasNachladen",
|
||||
@@ -29,12 +41,36 @@
|
||||
"caption": "Minimum des Batterieladezustand",
|
||||
"suffix": ""
|
||||
},
|
||||
{
|
||||
"type":"Select",
|
||||
"name":"Batteriemanagement",
|
||||
"caption":"Batteriemanagement",
|
||||
"options":[
|
||||
{
|
||||
"caption":"Durch Wechselrichter",
|
||||
"value":1
|
||||
},
|
||||
{
|
||||
"caption":"Durch EMS Symcon",
|
||||
"value":4
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
"name": "Batterieladezustand",
|
||||
"caption": "Batterieladezustand",
|
||||
"test": true
|
||||
},
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
"name": "Netzbezug",
|
||||
"caption": "Variable mit dem zu regelnden Netzbezug"
|
||||
},
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
"name": "Batterieleistung_Effektiv",
|
||||
"caption": "Effektive, aktuelle Batterieleistung"
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
|
||||
@@ -12,11 +12,17 @@ class Batterie extends IPSModule
|
||||
$this->RegisterPropertyInteger("AufdasNachladen",0);
|
||||
$this->RegisterPropertyInteger("MinimumEntladen",0);
|
||||
$this->RegisterPropertyInteger("Batterieladezustand",0);
|
||||
|
||||
|
||||
$this->RegisterPropertyInteger("Batteriemanagement", 1);
|
||||
$this->RegisterPropertyInteger("MaxNachladen",0);
|
||||
$this->RegisterPropertyInteger("Netzbezug", 0); // Initialisierung mit 0
|
||||
$this->RegisterPropertyInteger("Interval", 2); // Recheninterval
|
||||
$this->RegisterPropertyInteger("Batterieleistung_Effektiv", 0); // Recheninterval
|
||||
|
||||
// Variabeln für Kommunkation mit Manager
|
||||
$this->RegisterVariableFloat("Ladestrom", "Ladestrom", "", 0);
|
||||
$this->RegisterVariableFloat("Entladestrom", "Entladestrom", "", 0);
|
||||
$this->RegisterVariableFloat("Entladeleistung","Entladeleistung", "",0);
|
||||
$this->RegisterVariableInteger("Batteriemanagement_Variabel","Batteriemanagement_Variabel", "",0);
|
||||
$this->RegisterVariableInteger("Laden3_Entladen4","Laden3_Entladen4", "",3);
|
||||
$this->RegisterVariableFloat("Ladeleistung","Ladeleistung", "",0);
|
||||
$this->RegisterVariableInteger("Aktuelle_Leistung", "Aktuelle_Leistung", "", 0);
|
||||
$this->RegisterVariableString("PowerSteps", "PowerSteps");
|
||||
$this->RegisterVariableBoolean("Idle", "Idle", "", 0);
|
||||
@@ -24,6 +30,10 @@ class Batterie extends IPSModule
|
||||
$this->RegisterVariableInteger("PV_Prio", "PV_Prio");
|
||||
$this->RegisterVariableInteger("Power", "Power");
|
||||
$this->RegisterVariableBoolean("Is_Peak_Shaving", "Is_Peak_Shaving");
|
||||
$this->RegisterVariableInteger("Leistung_Delta", "Leistung_Delta", "", 0);
|
||||
|
||||
$this->RegisterVariableBoolean("Hysterese", "Hysterese","",false);
|
||||
|
||||
|
||||
|
||||
$this->RegisterVariableFloat("Bezogene_Energie", "Bezogene_Energie", "", 0);
|
||||
@@ -36,7 +46,7 @@ class Batterie extends IPSModule
|
||||
// Initialisiere Idle
|
||||
$this->SetValue("Idle", true);
|
||||
|
||||
$this->RegisterTimer("Timer_Do_UserCalc",5000,"IPS_RequestAction(" .$this->InstanceID .', "Do_UserCalc", "");');
|
||||
$this->RegisterTimer("Timer_Do_UserCalc_Battery",$this->ReadPropertyInteger("Interval")*1000,"IPS_RequestAction(" .$this->InstanceID .', "Do_UserCalc", "");');
|
||||
|
||||
|
||||
}
|
||||
@@ -45,22 +55,53 @@ class Batterie extends IPSModule
|
||||
{
|
||||
parent::ApplyChanges();
|
||||
|
||||
|
||||
$batterieManagement = $this->ReadPropertyInteger("Batteriemanagement");
|
||||
$this->SetValue("Batteriemanagement_Variabel", $batterieManagement);
|
||||
$this->SetTimerInterval("Timer_Do_UserCalc_Battery",$this->ReadPropertyInteger("Interval")*1000);
|
||||
}
|
||||
|
||||
private function GeneratePowerSteps()
|
||||
{
|
||||
$maxleistung = $this->ReadPropertyInteger("MaxBatterieleistung");
|
||||
$array_powersteps = [];
|
||||
$stepSize = 250; // Schrittgröße
|
||||
|
||||
// Erstellen der PowerSteps
|
||||
for ($i = 0; $i <= $maxleistung * 2; $i += $stepSize) {
|
||||
$array_powersteps[] = $i;
|
||||
private function GeneratePowerSteps($additionalValue)
|
||||
{
|
||||
$maxleistung = $this->ReadPropertyInteger("MaxBatterieleistung");
|
||||
$stepSize = 250; // Schrittgröße
|
||||
$stepSizeSmall = 50; // Kleine Schrittgröße
|
||||
|
||||
// Array direkt als Range erzeugen (schneller als Schleife)
|
||||
$array_powersteps = range(-$maxleistung, $maxleistung, $stepSize);
|
||||
|
||||
// Nächstgelegenen Wert direkt bestimmen (rundet auf den nächsten Step)
|
||||
$closestValue = round($additionalValue / $stepSize) * $stepSize;
|
||||
|
||||
// Falls der Wert nicht im Bereich liegt, abbrechen
|
||||
if (!in_array($closestValue, $array_powersteps)) {
|
||||
return $array_powersteps;
|
||||
}
|
||||
|
||||
// Index des gefundenen Werts suchen
|
||||
$index = array_search($closestValue, $array_powersteps);
|
||||
|
||||
// Zusätzliche Werte berechnen und auf MaxLeistung begrenzen
|
||||
$newValues = array_filter([
|
||||
$closestValue - 4 * $stepSizeSmall,
|
||||
$closestValue - 3 * $stepSizeSmall,
|
||||
$closestValue - 2 * $stepSizeSmall,
|
||||
$closestValue - $stepSizeSmall,
|
||||
$closestValue,
|
||||
$closestValue + $stepSizeSmall,
|
||||
$closestValue + 2 * $stepSizeSmall,
|
||||
$closestValue + 3 * $stepSizeSmall,
|
||||
$closestValue + 4 * $stepSizeSmall,
|
||||
], function ($value) use ($maxleistung) {
|
||||
return $value >= -$maxleistung && $value <= $maxleistung;
|
||||
});
|
||||
|
||||
// Effizienteres Einfügen der Werte (direkt an der Stelle)
|
||||
array_splice($array_powersteps, $index, 1, $newValues);
|
||||
|
||||
return $array_powersteps;
|
||||
}
|
||||
|
||||
return $array_powersteps;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -90,30 +131,39 @@ public function RequestAction($Ident, $Value)
|
||||
|
||||
public function SetAktuelle_Leistung(int $power)
|
||||
{
|
||||
$batterieladezustand = $this->ReadPropertyInteger("Batterieladezustand"); // Als Property gelesen
|
||||
$maxleistung = $this->ReadPropertyInteger("MaxBatterieleistung"); // Als Property gelesen
|
||||
$spannung = $this->ReadPropertyInteger("Batteriespannung"); // Spannung ebenfalls als Property
|
||||
$ladestrom = GetValue($this->GetIDForIdent("Ladestrom"));
|
||||
$entladestrom = GetValue($this->GetIDForIdent("Entladestrom"));
|
||||
|
||||
IPS_LogMessage("Batterie", "power: " . $power);
|
||||
$batterieManagement = $this->ReadPropertyInteger("Batteriemanagement");
|
||||
// Wechselrichter steuert das Laden/Entladen der Batterie
|
||||
if ($batterieManagement == 1) {
|
||||
$this->SetValue("Entladeleistung", 0);
|
||||
$this->SetValue("Ladeleistung", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($spannung <= 0) {
|
||||
IPS_LogMessage("Batterie", "Fehler: Batteriespannung ist 0 oder ungültig.");
|
||||
return;
|
||||
}
|
||||
// Batterie entladen oder laden basierend auf der Leistung
|
||||
if ($power > $maxleistung) {
|
||||
$ladestrom = ($power - $maxleistung) / $spannung;
|
||||
$this->SetValue("Ladestrom", $ladestrom);
|
||||
$this->SetValue("Entladestrom", 0);
|
||||
//IPS_LogMessage("Batterie", "Ladestrom: " . $ladestrom);
|
||||
|
||||
if($this->GetValue("Is_Peak_Shaving")==true){
|
||||
if ($power >= 0) {
|
||||
$this->SetValue("Ladeleistung", $power);
|
||||
$this->SetValue("Entladeleistung", 0);
|
||||
$this->SetValue("Laden3_Entladen4", 3);
|
||||
} else {
|
||||
$entladestrom = $power / $spannung;
|
||||
$this->SetValue("Entladestrom", $entladestrom);
|
||||
$this->SetValue("Ladestrom", 0);
|
||||
//IPS_LogMessage("Batterie", "Entladestrom: " . $entladestrom);
|
||||
$this->SetValue("Entladeleistung", abs($power));
|
||||
$this->SetValue("Ladeleistung", 0);
|
||||
$this->SetValue("Laden3_Entladen4", 4);
|
||||
}
|
||||
|
||||
}else{
|
||||
if ($power >= 0) {
|
||||
$this->SetValue("Ladeleistung", $power);
|
||||
$this->SetValue("Entladeleistung", 0);
|
||||
$this->SetValue("Laden3_Entladen4", 3);
|
||||
} else {
|
||||
$this->SetValue("Entladeleistung", abs($power));
|
||||
$this->SetValue("Ladeleistung", 0);
|
||||
$this->SetValue("Laden3_Entladen4", 4);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Prüfe auf Änderung der Leistung im Vergleich zur letzten Einstellung
|
||||
$lastPower = GetValue($this->GetIDForIdent("Aktuelle_Leistung"));
|
||||
@@ -127,62 +177,119 @@ public function RequestAction($Ident, $Value)
|
||||
|
||||
// Setze die neue aktuelle Leistung
|
||||
$this->SetValue("Aktuelle_Leistung", $power);
|
||||
|
||||
$this->SetValue("Bezogene_Energie", ($this->GetValue("Bezogene_Energie") + ($this->GetValue("Aktuelle_Leistung")*($this->ReadPropertyInteger("Interval")/3600))));
|
||||
|
||||
// IdleCounter verarbeiten
|
||||
$this->ProcessIdleCounter();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function GetCurrentData(bool $Peak)
|
||||
{
|
||||
IPS_LogMessage("Batterie", "peak: " . ($Peak ? "true" : "false"));
|
||||
IPS_LogMessage("Batterie", "Currentdata");
|
||||
|
||||
$array_powersteps = $this->GeneratePowerSteps();
|
||||
$array_powersteps = $this->GeneratePowerSteps($this->GetValue("Aktuelle_Leistung"));
|
||||
$aufdasnachladen = $this->ReadPropertyInteger("AufdasNachladen");
|
||||
$minimumentladen = $this->ReadPropertyInteger("MinimumEntladen");
|
||||
$batterieladezustand = GetValue($this->ReadPropertyInteger("Batterieladezustand"));
|
||||
|
||||
$maxleistung = $this->ReadPropertyInteger("MaxBatterieleistung");
|
||||
$dummy_array = [];
|
||||
$batterieladezustand = GetValue($this->ReadPropertyInteger("Batterieladezustand"));
|
||||
$filtered_powersteps_entladen = [];
|
||||
if ($this->ReadPropertyInteger("Batteriemanagement") == 1) {
|
||||
$dummy_array[] = 0;
|
||||
return $this->SetValue("PowerSteps", json_encode($dummy_array));
|
||||
}
|
||||
|
||||
|
||||
if ($Peak) {
|
||||
if ($batterieladezustand <= $minimumentladen) {
|
||||
$filtered_powersteps = array_filter($array_powersteps, function ($value) use ($maxleistung) {
|
||||
return $value > $maxleistung; // Hochpass filtern
|
||||
$netzbezug = GetValue($this->ReadPropertyInteger("Netzbezug"));
|
||||
if (abs($netzbezug) > $maxleistung) {
|
||||
$netzbezug = $maxleistung * (-1);
|
||||
}
|
||||
|
||||
if($batterieladezustand>(5+$aufdasnachladen)){
|
||||
|
||||
$this->SetValue("Hysterese", false);
|
||||
|
||||
}elseif($batterieladezustand<=$aufdasnachladen){
|
||||
$this->SetValue("Hysterese", true);
|
||||
}
|
||||
|
||||
$hyst = $this->GetValue("Hysterese");
|
||||
|
||||
if($Peak){
|
||||
IPS_LogMessage("Batterie", "Im if teil");
|
||||
|
||||
if($batterieladezustand>$aufdasnachladen && $hyst==false){
|
||||
|
||||
$dummy_array[] = $netzbezug;
|
||||
$this->SetValue("PowerSteps", json_encode($dummy_array));
|
||||
|
||||
}elseif($batterieladezustand>$aufdasnachladen && $hyst==true){
|
||||
|
||||
|
||||
$filtered_powersteps = array_filter($array_powersteps, function ($value) {
|
||||
return $value <= 0;
|
||||
});
|
||||
$filtered_powersteps_laden = array_values($filtered_powersteps);
|
||||
$this->SetValue("PowerSteps", json_encode($filtered_powersteps_laden));
|
||||
IPS_LogMessage("Batterie", "Batterie laden: ");
|
||||
|
||||
} elseif ($batterieladezustand >= $aufdasnachladen) {
|
||||
$filtered_powersteps_entladen = array_filter($array_powersteps, function ($value) use ($maxleistung) {
|
||||
return $value < $maxleistung; // Tiefpass filtern
|
||||
}elseif($batterieladezustand>$minimumentladen){
|
||||
|
||||
$this->SetValue("PowerSteps", json_encode($array_powersteps));
|
||||
}
|
||||
else{
|
||||
|
||||
$filtered_powersteps = array_filter($array_powersteps, function ($value) {
|
||||
return $value >= 0;
|
||||
});
|
||||
$this->SetValue("PowerSteps", json_encode($filtered_powersteps_entladen));
|
||||
IPS_LogMessage("Batterie", "Batterie entladen: " );
|
||||
|
||||
} elseif ($batterieladezustand < $aufdasnachladen && $batterieladezustand > $minimumentladen) {
|
||||
$this->SetValue("PowerSteps", json_encode($array_powersteps));
|
||||
IPS_LogMessage("Batterie", "In Hysterese: ");
|
||||
|
||||
} else {
|
||||
$this->SetValue("PowerSteps", json_encode($array_powersteps[0]));
|
||||
IPS_LogMessage("Batterie", "Weder noch: ");
|
||||
$filtered_powersteps_laden = array_values($filtered_powersteps);
|
||||
$this->SetValue("PowerSteps", json_encode($filtered_powersteps_laden));
|
||||
}
|
||||
|
||||
} else { // Solar
|
||||
}else{
|
||||
IPS_LogMessage("Batterie", "Im else teil");
|
||||
|
||||
|
||||
if($batterieladezustand>99){
|
||||
IPS_LogMessage("Batterie", "im 1");
|
||||
|
||||
$filtered_powersteps = array_filter($array_powersteps, function ($value) {
|
||||
return $value <= 0;
|
||||
});
|
||||
$filtered_powersteps_laden = array_values($filtered_powersteps);
|
||||
$this->SetValue("PowerSteps", json_encode($filtered_powersteps_laden));
|
||||
|
||||
}elseif($batterieladezustand>$aufdasnachladen && $hyst==false){
|
||||
|
||||
$this->SetValue("PowerSteps", json_encode($array_powersteps));
|
||||
IPS_LogMessage("Batterie", "im 2");
|
||||
|
||||
|
||||
}elseif($batterieladezustand>=$aufdasnachladen && $hyst==true){
|
||||
|
||||
$filtered_powersteps = array_filter($array_powersteps, function ($value) {
|
||||
return $value >= 0;
|
||||
});
|
||||
$filtered_powersteps_laden = array_values($filtered_powersteps);
|
||||
$this->SetValue("PowerSteps", json_encode($filtered_powersteps_laden));
|
||||
|
||||
|
||||
}elseif($batterieladezustand<$aufdasnachladen){
|
||||
|
||||
$dummy_array[] = $this->ReadPropertyInteger("MaxNachladen");
|
||||
$this->SetValue("PowerSteps", json_encode($dummy_array));
|
||||
IPS_LogMessage("Batterie", "im 3");
|
||||
|
||||
}
|
||||
|
||||
$filtered_powersteps_solar = array_filter($array_powersteps, function ($value) use ($maxleistung) {
|
||||
return $value > $maxleistung; // Hochpass filtern
|
||||
});
|
||||
|
||||
$this->SetValue("PowerSteps", json_encode($filtered_powersteps_solar));
|
||||
IPS_LogMessage("Batterie", "Solarmodus");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private function CheckIdle($power)
|
||||
{
|
||||
$lastpower = GetValue("Aktuelle_Leistung");
|
||||
@@ -215,5 +322,6 @@ public function RequestAction($Ident, $Value)
|
||||
$this->SetValue("Idle", true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
?>
|
||||
|
||||
67
Belevo_Bezahl_Modul/README.md
Normal file
67
Belevo_Bezahl_Modul/README.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# Manager_1
|
||||
Beschreibung des Moduls.
|
||||
|
||||
### 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)
|
||||
|
||||
### 1. Funktionsumfang
|
||||
|
||||
*
|
||||
|
||||
### 2. Voraussetzungen
|
||||
|
||||
- IP-Symcon ab Version 7.1
|
||||
|
||||
### 3. Software-Installation
|
||||
|
||||
* Über den Module Store das 'Manager_1'-Modul installieren.
|
||||
* Alternativ über das Module Control folgende URL hinzufügen
|
||||
|
||||
### 4. Einrichten der Instanzen in IP-Symcon
|
||||
|
||||
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__:
|
||||
|
||||
Name | Beschreibung
|
||||
-------- | ------------------
|
||||
|
|
||||
|
|
||||
|
||||
### 5. Statusvariablen und Profile
|
||||
|
||||
Die Statusvariablen/Kategorien werden automatisch angelegt. Das Löschen einzelner kann zu Fehlfunktionen führen.
|
||||
|
||||
#### Statusvariablen
|
||||
|
||||
Name | Typ | Beschreibung
|
||||
------ | ------- | ------------
|
||||
| |
|
||||
| |
|
||||
|
||||
#### Profile
|
||||
|
||||
Name | Typ
|
||||
------ | -------
|
||||
|
|
||||
|
|
||||
|
||||
### 6. WebFront
|
||||
|
||||
Die Funktionalität, die das Modul im WebFront bietet.
|
||||
|
||||
### 7. PHP-Befehlsreferenz
|
||||
|
||||
`boolean GEF_BeispielFunktion(integer $InstanzID);`
|
||||
Erklärung der Funktion.
|
||||
|
||||
Beispiel:
|
||||
`GEF_BeispielFunktion(12345);`
|
||||
22
Belevo_Bezahl_Modul/form.json
Normal file
22
Belevo_Bezahl_Modul/form.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"elements":[
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
"name": "Reservate",
|
||||
"caption": "Betrag reservieren",
|
||||
"test": true
|
||||
},
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
"name": "GetAmount",
|
||||
"caption": "Betrag Abziehen",
|
||||
"test": true
|
||||
},
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
"name": "HTMLBox",
|
||||
"caption": "HTMLBox",
|
||||
"test": true
|
||||
}
|
||||
]
|
||||
}
|
||||
12
Belevo_Bezahl_Modul/module.json
Normal file
12
Belevo_Bezahl_Modul/module.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"id": "{466A36DA-3C90-06E8-1D57-161D921B45EE}",
|
||||
"name": "Belevo_Bezahl_Modul",
|
||||
"type": 3,
|
||||
"vendor": "Belevo AG",
|
||||
"aliases": [],
|
||||
"parentRequirements": [],
|
||||
"childRequirements": [],
|
||||
"implemented": [],
|
||||
"prefix": "GEF",
|
||||
"url": ""
|
||||
}
|
||||
126
Belevo_Bezahl_Modul/module.php
Normal file
126
Belevo_Bezahl_Modul/module.php
Normal file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
class Belevo_Bezahl_Modul extends IPSModule
|
||||
{
|
||||
public function Create()
|
||||
{
|
||||
parent::Create();
|
||||
$this->RegisterPropertyInteger("Reservate", 0);
|
||||
$this->RegisterPropertyInteger("GetAmount", 0);
|
||||
$this->RegisterPropertyInteger("HTMLBox", 0);
|
||||
$this->RegisterVariableInteger("ReservationAmount", "ReservationAmount", '', 0);
|
||||
$this->RegisterVariableBoolean("AmountIsReserved", "AmountIsReserved", '', false);
|
||||
}
|
||||
|
||||
public function ApplyChanges()
|
||||
{
|
||||
parent::ApplyChanges();
|
||||
$this->SetHTMLContent();
|
||||
}
|
||||
|
||||
private function SetHTMLContent()
|
||||
{
|
||||
$apiKey = "pk_test_51Qkr79LJAcsNrpivA90lt7ULEzyXKR8l0pAqTBgfeuAIWlsLS4A3BdIBITc9UooFANbImvlJQ2F2jOZ0X5j8GI7Q00hNNasvQm"; // Test-API-Schlüssel
|
||||
|
||||
$html = "<html lang='en'>
|
||||
<head>
|
||||
<meta charset='UTF-8'>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
|
||||
<title>Google Pay mit Stripe</title>
|
||||
<!-- Stripe.js -->
|
||||
<script src='https://js.stripe.com/v3/'></script>
|
||||
<!-- Google Pay API -->
|
||||
<script src='https://pay.google.com/gp/p/js/pay.js' async></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Google Pay Integration mit Stripe</h1>
|
||||
<button id='google-pay-button'>Mit Google Pay bezahlen</button>
|
||||
|
||||
<script>
|
||||
// Stripe initialisieren
|
||||
const stripe = Stripe('pk_test_51Qkr79LJAcsNrpivA90lt7ULEzyXKR8l0pAqTBgfeuAIWlsLS4A3BdIBITc9UooFANbImvlJQ2F2jOZ0X5j8GI7Q00hNNasvQm'); // Ersetze mit deinem Stripe-Publishable-Key
|
||||
|
||||
const googlePayButton = document.getElementById('google-pay-button');
|
||||
|
||||
// Google Pay-Konfiguration
|
||||
const googlePayConfig = {
|
||||
apiVersion: 2,
|
||||
apiVersionMinor: 0,
|
||||
allowedPaymentMethods: [
|
||||
{
|
||||
type: 'CARD',
|
||||
parameters: {
|
||||
allowedAuthMethods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'],
|
||||
allowedCardNetworks: ['VISA', 'MASTERCARD'],
|
||||
},
|
||||
tokenizationSpecification: {
|
||||
type: 'PAYMENT_GATEWAY',
|
||||
parameters: {
|
||||
gateway: 'stripe',
|
||||
'stripe:version': '2020-08-27',
|
||||
'stripe:publishableKey': 'pk_test_51Qkr79LJAcsNrpivA90lt7ULEzyXKR8l0pAqTBgfeuAIWlsLS4A3BdIBITc9UooFANbImvlJQ2F2jOZ0X5j8GI7Q00hNNasvQm', // Ersetze hier ebenfalls
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
merchantInfo: {
|
||||
merchantId: 'TEST', // Für Testumgebungen
|
||||
merchantName: 'Dein Unternehmen',
|
||||
},
|
||||
transactionInfo: {
|
||||
totalPriceStatus: 'FINAL',
|
||||
totalPrice: '100.00', // Betrag in CHF
|
||||
currencyCode: 'CHF',
|
||||
},
|
||||
};
|
||||
|
||||
// Eventlistener für den Google Pay-Button
|
||||
googlePayButton.addEventListener('click', async () => {
|
||||
try {
|
||||
const googlePayClient = new google.payments.api.PaymentsClient({ environment: 'TEST' });
|
||||
|
||||
// Prüfen, ob Google Pay verfügbar ist
|
||||
const isReadyToPay = await googlePayClient.isReadyToPay(googlePayConfig);
|
||||
if (!isReadyToPay.result) {
|
||||
alert('Google Pay ist auf diesem Gerät nicht verfügbar.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Google Pay PaymentData abrufen
|
||||
const paymentData = await googlePayClient.loadPaymentData(googlePayConfig);
|
||||
|
||||
// Token aus dem PaymentData extrahieren
|
||||
const paymentToken = paymentData.paymentMethodData.tokenizationData.token;
|
||||
|
||||
// Token an das Backend senden
|
||||
const response = await fetch('/path-to-your-backend.php', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ token: paymentToken }),
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.clientSecret) {
|
||||
// Zahlung mit Stripe abschließen
|
||||
const stripeResult = await stripe.confirmCardPayment(result.clientSecret);
|
||||
|
||||
if (stripeResult.error) {
|
||||
alert('Zahlung fehlgeschlagen: ' + stripeResult.error.message);
|
||||
} else if (stripeResult.paymentIntent && stripeResult.paymentIntent.status === 'succeeded') {
|
||||
alert('Zahlung erfolgreich abgeschlossen!');
|
||||
}
|
||||
} else {
|
||||
alert('Ein Fehler ist im Backend aufgetreten.');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Fehler bei der Zahlung:', error);
|
||||
alert('Ein Fehler ist aufgetreten: ' + error.message);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>";
|
||||
|
||||
SetValue($this->ReadPropertyInteger("HTMLBox"), $html);
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
{
|
||||
"type":"Select",
|
||||
"name":"Boilertemperatur_glätten",
|
||||
"caption":"Boilertemperatur glätten Ja oder Nein",
|
||||
"caption":"Boilertemperatur glätten",
|
||||
"options":[
|
||||
{
|
||||
"caption":"Ja",
|
||||
@@ -24,24 +24,36 @@
|
||||
"name": "ZeitKonstante",
|
||||
"caption": "Zeit Konstante",
|
||||
"suffix": ""
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Interval",
|
||||
"caption": "Intervall Neuberechnung der Werte Erst für spätere Versionen, aktuell auf 5 lassen!",
|
||||
"suffix": "Sekunden"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "IdleCounterMax",
|
||||
"caption": "Zyklen zwischen zwei Leisutungsänderungen",
|
||||
"caption": "Zyklen zwischen zwei Leistungsänderungen (Multipliziert sich mit Interval)",
|
||||
"suffix": ""
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "BoilerLeistungTeillast",
|
||||
"caption": "Leistug Teillast",
|
||||
"suffix": ""
|
||||
"suffix": "Watt"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "BoilerLeistungVolllast",
|
||||
"caption": "Leistug Vollast",
|
||||
"suffix": ""
|
||||
"suffix": "Watt"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Boilervolumen",
|
||||
"caption": "Boilervolumen",
|
||||
"suffix": "Liter"
|
||||
},
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
@@ -60,7 +72,37 @@
|
||||
"name": "Kontakt_Volllast",
|
||||
"caption": "Schaltkontakt Volllast",
|
||||
"test": true
|
||||
},
|
||||
{
|
||||
"type": "List",
|
||||
"name": "Zeitplan",
|
||||
"caption": "Zeitplan für Solltemperaturen",
|
||||
"columns": [
|
||||
{
|
||||
"caption": "Uhrzeit",
|
||||
"name": "Uhrzeit",
|
||||
"width": "150px",
|
||||
"add": "00:00",
|
||||
"edit": {
|
||||
"type": "ValidationTextBox"
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": "Solltemperatur",
|
||||
"name": "Solltemperatur",
|
||||
"width": "150px",
|
||||
"add": 0,
|
||||
"edit": {
|
||||
"type": "NumberSpinner"
|
||||
}
|
||||
}
|
||||
],
|
||||
"add": true,
|
||||
"delete": true,
|
||||
"sort": {
|
||||
"column": "Uhrzeit",
|
||||
"direction": "ascending"
|
||||
}
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,10 @@ class Boiler_2_Stufig_Mit_Fueler extends IPSModule
|
||||
$this->RegisterPropertyInteger("Kontakt_Teillast", 0);
|
||||
$this->RegisterPropertyInteger("Kontakt_Volllast", 0);
|
||||
$this->RegisterPropertyBoolean("Boilertemperatur_glätten", false);
|
||||
$this->RegisterPropertyInteger("Boilervolumen", 300);
|
||||
$this->RegisterPropertyString("Zeitplan", "");
|
||||
$this->RegisterPropertyInteger("Interval", 5); // Recheninterval
|
||||
|
||||
|
||||
// Boiler spezifische Variablen
|
||||
|
||||
@@ -21,7 +25,6 @@ class Boiler_2_Stufig_Mit_Fueler extends IPSModule
|
||||
$this->RegisterVariableInteger("Maximaltemperatur","Maximaltemperatur","",60);
|
||||
$this->RegisterVariableInteger("Legionellentemperatur","Legionellentemperatur","",65);
|
||||
$this->RegisterVariableInteger("LegioCounter", "LegioCounter", "", 0);
|
||||
//$this->RegisterVariableInteger("Boilertemperatur", "Boilertemperatur", "", 0);
|
||||
$this->RegisterVariableInteger("Boilertemperatur", "Boilertemperatur", "", 0);
|
||||
|
||||
|
||||
@@ -32,8 +35,9 @@ class Boiler_2_Stufig_Mit_Fueler extends IPSModule
|
||||
$this->RegisterVariableInteger("Aktuelle_Leistung", "Aktuelle_Leistung", "", 0);
|
||||
$this->RegisterVariableFloat("Bezogene_Energie", "Bezogene_Energie", "", 0);
|
||||
$this->RegisterVariableString("PowerSteps", "PowerSteps");
|
||||
$this->RegisterVariableInteger("Power", "Power", "", 0);
|
||||
$this->RegisterVariableInteger("Power", "Power", '', 0);
|
||||
$this->RegisterVariableBoolean("Is_Peak_Shaving", "Is_Peak_Shaving", "", true);
|
||||
$this->RegisterVariableInteger("Leistung_Delta", "Leistung_Delta", "", 0);
|
||||
|
||||
// Hilfsvariabeln für Idle zustand
|
||||
$this->RegisterPropertyInteger("IdleCounterMax", 2);
|
||||
@@ -43,13 +47,14 @@ class Boiler_2_Stufig_Mit_Fueler extends IPSModule
|
||||
// Initialisiere Idle
|
||||
$this->SetValue("Idle", true);
|
||||
|
||||
$this->RegisterTimer("Timer_Do_UserCalc",5000,"IPS_RequestAction(" .$this->InstanceID .', "Do_UserCalc", "");');
|
||||
$this->RegisterTimer("Timer_Do_UserCalc_Boiler",$this->ReadPropertyInteger("Interval")*1000,"IPS_RequestAction(" .$this->InstanceID .', "Do_UserCalc", "");');
|
||||
|
||||
}
|
||||
|
||||
public function ApplyChanges()
|
||||
{
|
||||
parent::ApplyChanges();
|
||||
$this->SetTimerInterval("Timer_Do_UserCalc_Boiler",$this->ReadPropertyInteger("Interval")*1000);
|
||||
|
||||
|
||||
|
||||
@@ -78,6 +83,57 @@ class Boiler_2_Stufig_Mit_Fueler extends IPSModule
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function getNextTimeAndTemperature($zeitplan) {
|
||||
$arr = json_decode($zeitplan, true);
|
||||
if (empty($arr)) {
|
||||
return null;
|
||||
}
|
||||
$currentTime = new DateTime();
|
||||
$nextEntry = null;
|
||||
$minDiff = PHP_INT_MAX;
|
||||
|
||||
foreach ($arr as $entry) {
|
||||
$entryTime = DateTime::createFromFormat('H:i', $entry['Uhrzeit']);
|
||||
if ($entryTime < $currentTime) {
|
||||
$entryTime->modify('+1 day');
|
||||
}
|
||||
$diff = $currentTime->diff($entryTime)->format('%r%a') * 24 * 60 + $currentTime->diff($entryTime)->format('%r%h') * 60 + $currentTime->diff($entryTime)->format('%r%i');
|
||||
if ($diff < $minDiff) {
|
||||
$minDiff = $diff;
|
||||
$nextEntry = $entry;
|
||||
}
|
||||
}
|
||||
|
||||
return $nextEntry;
|
||||
}
|
||||
|
||||
public function calculateRemainingTime($nextTime) {
|
||||
$currentTime = new DateTime();
|
||||
$nextDateTime = DateTime::createFromFormat('H:i', $nextTime);
|
||||
if ($nextDateTime < $currentTime) {
|
||||
$nextDateTime->modify('+1 day');
|
||||
}
|
||||
$interval = $currentTime->diff($nextDateTime);
|
||||
return $interval->h + ($interval->i / 60);
|
||||
}
|
||||
|
||||
public function calculateRequiredHeat($boilervolumen, $tempDiff) {
|
||||
// Annahme: spezifische Wärmekapazität von Wasser = 4.186 J/g°C
|
||||
// 1 Liter Wasser = 1000 Gramm
|
||||
$specificHeatCapacity = 4.186; // J/g°C
|
||||
$waterMass = $boilervolumen * 1000; // Gramm
|
||||
return $specificHeatCapacity * $waterMass * $tempDiff; // Joules
|
||||
}
|
||||
|
||||
public function canBoilerReachTemperature($boilervolumen, $boilerTemper, $nextTemp, $remainingTime, $vollleistung) {
|
||||
$tempDiff = $nextTemp - $boilerTemper;
|
||||
$requiredHeat = $this->calculateRequiredHeat($boilervolumen, $tempDiff);
|
||||
$availableHeat = $vollleistung * $remainingTime * 3600; // Leistung in Watt * Zeit in Sekunden
|
||||
return $availableHeat >= $requiredHeat;
|
||||
}
|
||||
|
||||
// Methode zum Setzen des aktuellen Stromverbrauchs
|
||||
public function SetAktuelle_Leistung(int $power)
|
||||
{
|
||||
@@ -107,7 +163,7 @@ class Boiler_2_Stufig_Mit_Fueler extends IPSModule
|
||||
|
||||
// Setze die neue Aktuelle_Leistung
|
||||
$this->SetValue("Aktuelle_Leistung", $power);
|
||||
|
||||
$this->SetValue("Bezogene_Energie", ($this->GetValue("Bezogene_Energie") + ($this->GetValue("Aktuelle_Leistung")*($this->ReadPropertyInteger("Interval")/3600))));
|
||||
// IdleCounter verarbeiten
|
||||
$this->ProcessIdleCounter();
|
||||
}
|
||||
@@ -139,7 +195,7 @@ class Boiler_2_Stufig_Mit_Fueler extends IPSModule
|
||||
|
||||
// PT
|
||||
$time_constant= $this->ReadPropertyInteger("ZeitKonstante");
|
||||
$delta_t = 30; // Zeitdifferenz zwischen den Messungen (30 Sekunden)
|
||||
$delta_t = 5; // Zeitdifferenz zwischen den Messungen (30 Sekunden)
|
||||
$alpha = $delta_t / ($time_constant + $delta_t);
|
||||
$newBoilerTemp = $boilerTemp + $alpha * ($boilerPT1 - $boilerTemp);
|
||||
$this->SetValue("Boilertemperatur", $newBoilerTemp);
|
||||
@@ -158,8 +214,6 @@ class Boiler_2_Stufig_Mit_Fueler extends IPSModule
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
$boilerTemp = $this->GetValue("Boilertemperatur");
|
||||
$minTemp = $this->GetValue("Mindesttemperatur");
|
||||
$maxTemp = $this->GetValue("Maximaltemperatur");
|
||||
@@ -167,6 +221,19 @@ class Boiler_2_Stufig_Mit_Fueler extends IPSModule
|
||||
$teilLeistung = $this->ReadPropertyInteger("BoilerLeistungTeillast");
|
||||
$vollLeistung = $this->ReadPropertyInteger("BoilerLeistungVolllast");
|
||||
|
||||
|
||||
$nextEntry = $this->getNextTimeAndTemperature($this->ReadPropertyString("Zeitplan"));
|
||||
if ($nextEntry !== null) {
|
||||
$remainingTime = $this->calculateRemainingTime($nextEntry['Uhrzeit']);
|
||||
$nextTemp = $nextEntry['Solltemperatur'];
|
||||
|
||||
if (!$this->canBoilerReachTemperature($this->ReadPropertyInteger("Boilervolumen"), $boilerTemp, $nextTemp, $remainingTime, $vollLeistung)) {
|
||||
$minTemp = $nextTemp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
$AktuelleVollast = GetValue(
|
||||
$this->ReadPropertyInteger("Kontakt_Volllast")
|
||||
);
|
||||
|
||||
67
HauptManager/README.md
Normal file
67
HauptManager/README.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# Manager_1
|
||||
Beschreibung des Moduls.
|
||||
|
||||
### 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)
|
||||
|
||||
### 1. Funktionsumfang
|
||||
|
||||
*
|
||||
|
||||
### 2. Voraussetzungen
|
||||
|
||||
- IP-Symcon ab Version 7.1
|
||||
|
||||
### 3. Software-Installation
|
||||
|
||||
* Über den Module Store das 'Manager_1'-Modul installieren.
|
||||
* Alternativ über das Module Control folgende URL hinzufügen
|
||||
|
||||
### 4. Einrichten der Instanzen in IP-Symcon
|
||||
|
||||
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__:
|
||||
|
||||
Name | Beschreibung
|
||||
-------- | ------------------
|
||||
|
|
||||
|
|
||||
|
||||
### 5. Statusvariablen und Profile
|
||||
|
||||
Die Statusvariablen/Kategorien werden automatisch angelegt. Das Löschen einzelner kann zu Fehlfunktionen führen.
|
||||
|
||||
#### Statusvariablen
|
||||
|
||||
Name | Typ | Beschreibung
|
||||
------ | ------- | ------------
|
||||
| |
|
||||
| |
|
||||
|
||||
#### Profile
|
||||
|
||||
Name | Typ
|
||||
------ | -------
|
||||
|
|
||||
|
|
||||
|
||||
### 6. WebFront
|
||||
|
||||
Die Funktionalität, die das Modul im WebFront bietet.
|
||||
|
||||
### 7. PHP-Befehlsreferenz
|
||||
|
||||
`boolean GEF_BeispielFunktion(integer $InstanzID);`
|
||||
Erklärung der Funktion.
|
||||
|
||||
Beispiel:
|
||||
`GEF_BeispielFunktion(12345);`
|
||||
57
HauptManager/form.json
Normal file
57
HauptManager/form.json
Normal file
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"elements": [
|
||||
{
|
||||
"type": "Label",
|
||||
"caption": "Einstellungen Energiemanager"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Peakleistung",
|
||||
"caption": "Sollwertvorgabe für Peakshaving",
|
||||
"suffix": "Watt"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Ueberschussleistung",
|
||||
"caption": "Sollwertvorgabe für Solarladen",
|
||||
"suffix": "Watt"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Interval",
|
||||
"caption": "Intervall Neuberechnung der Werte",
|
||||
"suffix": "Sekunden"
|
||||
},
|
||||
{
|
||||
"type": "List",
|
||||
"name": "Verbraucher_Liste",
|
||||
"caption": "Verbraucher, die gemanagt werden sollen.",
|
||||
"add": true,
|
||||
"delete": true,
|
||||
"sortable": true,
|
||||
"columns": [
|
||||
{
|
||||
"caption": "Verbraucher Lesen",
|
||||
"name": "User_Up",
|
||||
"width": "auto",
|
||||
"add": 0,
|
||||
"edit": {
|
||||
"type": "SelectVariable",
|
||||
"filter": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": "Verbraucher Steuern",
|
||||
"name": "User_Down",
|
||||
"width": "auto",
|
||||
"add": 0,
|
||||
"edit": {
|
||||
"type": "SelectVariable",
|
||||
"filter": "String"
|
||||
}
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
12
HauptManager/module.json
Normal file
12
HauptManager/module.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"id": "{F1F645F9-7F78-2843-2728-5D1708B4F835}",
|
||||
"name": "HauptManager",
|
||||
"type": 3,
|
||||
"vendor": "Belevo AG",
|
||||
"aliases": [],
|
||||
"parentRequirements": [],
|
||||
"childRequirements": [],
|
||||
"implemented": [],
|
||||
"prefix": "GEF",
|
||||
"url": ""
|
||||
}
|
||||
452
HauptManager/module.php
Normal file
452
HauptManager/module.php
Normal file
@@ -0,0 +1,452 @@
|
||||
<?php
|
||||
|
||||
class HauptManager extends IPSModule
|
||||
{
|
||||
public function Create()
|
||||
{
|
||||
parent::Create();
|
||||
|
||||
// Systemvariablen registrieren
|
||||
$this->RegisterPropertyInteger("Peakleistung", 0);
|
||||
$this->RegisterPropertyInteger("Ueberschussleistung", 0);
|
||||
$this->RegisterPropertyInteger("Netzbezug", 0); // Initialisierung mit 0
|
||||
$this->RegisterPropertyString("Verbraucher_Liste", "[]");
|
||||
$this->RegisterPropertyInteger("Interval", 3); // Recheninterval
|
||||
|
||||
$this->RegisterVariableInteger("Gesamtnetzbezug", "Gesamtnetzbezug", "", 0);
|
||||
|
||||
// Timer registrieren
|
||||
$this->RegisterTimer("Timer_DistributeEnergy",$this->ReadPropertyInteger("Interval")*1000,"IPS_RequestAction(" .$this->InstanceID .', "DistributeEnergy", "");');
|
||||
}
|
||||
|
||||
public function ApplyChanges()
|
||||
{
|
||||
parent::ApplyChanges();
|
||||
$this->SetTimerInterval("Timer_DistributeEnergy",$this->ReadPropertyInteger("Interval")*1000);
|
||||
|
||||
//Liste aller Verbraucher einlesen
|
||||
}
|
||||
|
||||
public function RequestAction($Ident, $Value)
|
||||
{
|
||||
switch ($Ident) {
|
||||
case "DistributeEnergy":
|
||||
$this->DistributeEnergy();
|
||||
break;
|
||||
case "ApplyChanges":
|
||||
$this->ApplyChanges();
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Invalid Ident");
|
||||
}
|
||||
}
|
||||
|
||||
public function DistributeEnergy()
|
||||
{
|
||||
$Verbraucher_Liste = json_decode($this->ReadPropertyString("Verbraucher_Liste"), true);
|
||||
|
||||
$currentTime = time();
|
||||
$Netzbezug = 0;
|
||||
$Verbraucher_Liste_Korr = [];
|
||||
|
||||
foreach ($Verbraucher_Liste as $user) {
|
||||
|
||||
$decodedUser = json_decode(GetValue($user["User_Up"]), true);
|
||||
|
||||
if (isset($decodedUser["Timestamp"]) && (($currentTime - $decodedUser["Timestamp"])) < 30) {
|
||||
|
||||
foreach ($decodedUser["Users"] as $subuser) {
|
||||
$subuser['Writeback'] = $user["User_Down"];
|
||||
|
||||
$Verbraucher_Liste_Korr[0]["User"][] = $subuser;
|
||||
|
||||
}
|
||||
$Netzbezug += $decodedUser["Netzbezug"];
|
||||
}else{
|
||||
|
||||
RequestAction($user["User_Down"],'{"timestamp":'.time().',"Is_Peak_Shaving":'.true.',"User":[]}');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
$this->SetValue("Gesamtnetzbezug", $Netzbezug);
|
||||
|
||||
|
||||
$Peakleistung = $this->ReadPropertyInteger("Peakleistung");
|
||||
$Ueberschussleistung = $this->ReadPropertyInteger("Ueberschussleistung");
|
||||
$Is_Peak_Shaving = false;
|
||||
// Fallunterscheidung ob auf Solarladen oder Peakshaving gerregelt wird.
|
||||
if ($Netzbezug < ($Peakleistung - $Ueberschussleistung) / 2) {
|
||||
$remainingPower = -1 * (-1 * $Ueberschussleistung + $Netzbezug);
|
||||
$Is_Peak_Shaving = false;
|
||||
} else {
|
||||
$remainingPower = $Peakleistung - $Netzbezug;
|
||||
$Is_Peak_Shaving = true;
|
||||
}
|
||||
$resultArray = [];
|
||||
// Alle Energieverbraucher auslesen und dekodieren
|
||||
|
||||
if (empty($Verbraucher_Liste_Korr[0]["User"])) {
|
||||
// Liste ist leer, daher nichts zu tun
|
||||
IPS_LogMessage("Manager", "aufgerufen leere liste");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$allIdle = true; // Variable zur Überprüfung, ob alle Benutzer Idle = true sind
|
||||
$totalAktuelle_Leistung = 0; // Variable zur Summierung der Aktuelle_Leistung Werte
|
||||
|
||||
// Fülle das Array mit allen entsprechenden Werten der Verbraucher ab
|
||||
foreach ($Verbraucher_Liste_Korr[0]["User"] as $user) {
|
||||
|
||||
// Überprüfen, ob alle Benutzer Idle = true sind, wenn einer nicht ist, wird später verworfen...
|
||||
if (!$user["Idle"]) {
|
||||
$allIdle = false;
|
||||
IPS_LogMessage("Manager", "nciht idle");
|
||||
|
||||
}
|
||||
|
||||
// Addiere die aktuell bereits verwendete Leistung auf, um sie bei der verteilung zu berücksichtigen
|
||||
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)
|
||||
$remainingPower += $totalAktuelle_Leistung;
|
||||
|
||||
// Wenn nicht alle Benutzer Idle = true sind, rufe SetAktuelle_Leistung mit Aktuelle_Leistung Werten auf, (alle Verbraucher behalten die aktuelle Leistung)
|
||||
if (!$allIdle) {
|
||||
// Schritt 1: Benutzer nach Writeback-Wert aufteilen
|
||||
$writebackArrays = [];
|
||||
foreach ($Verbraucher_Liste_Korr[0]["User"] as $user) {
|
||||
$writeback = $user['Writeback'];
|
||||
IPS_LogMessage("Manager", $writeback);
|
||||
|
||||
if (!isset($writebackArrays[$writeback])) {
|
||||
$writebackArrays[$writeback] = [];
|
||||
}
|
||||
$writebackArrays[$writeback][] = $user;
|
||||
}
|
||||
|
||||
// Schritt 2: Foreach-Schleife pro Writeback-Array
|
||||
foreach ($writebackArrays as $writeback => $users) {
|
||||
$resultArray = [
|
||||
'timestamp' => time(),
|
||||
'Is_Peak_Shaving' => $Is_Peak_Shaving,
|
||||
'User' => []
|
||||
];
|
||||
|
||||
foreach ($users as $user) {
|
||||
$resultArray['User'][] = [
|
||||
'InstanceID' => $user['InstanceID'],
|
||||
'Set_Leistung' => $user['Aktuelle_Leistung']
|
||||
];
|
||||
}
|
||||
|
||||
// Schritt 3: Array in String konvertieren
|
||||
$resultString = json_encode($resultArray);
|
||||
|
||||
// Schritt 4: RequestAction aufrufen
|
||||
RequestAction($writeback, $resultString);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Sortiere die Verbruacher nach Priorität entweder der PV_Prio oder der Peak Prio
|
||||
usort($Verbraucher_Liste_Korr[0]["User"], function ($a, $b) use (
|
||||
$Is_Peak_Shaving
|
||||
) {
|
||||
$primaryKey = $Is_Peak_Shaving ? "Sperre_Prio" : "PV_Prio";
|
||||
// Wenn die Prio geleich ist, sortiere danach welcher verbraucher bisher am wenigsten Energie bekommen hat.
|
||||
if ($a[$primaryKey] == $b[$primaryKey]) {
|
||||
return round($a["Bezogene_Energie"]/2000) <=> round($b["Bezogene_Energie"]/2000);
|
||||
}
|
||||
return $a[$primaryKey] <=> $b[$primaryKey];
|
||||
});
|
||||
|
||||
// Primärschlüssel für die Priorität basierend auf dem Parameter auswählen (für sortierung in gruppen anschliessend)
|
||||
$priorityKey = $Is_Peak_Shaving ? "Sperre_Prio" : "PV_Prio";
|
||||
|
||||
// Schleife durch alle Prioritäten
|
||||
$priorities = array_unique(
|
||||
array_column($Verbraucher_Liste_Korr[0]["User"], $priorityKey)
|
||||
);
|
||||
$groupedUsers = [];
|
||||
|
||||
foreach ($priorities as $priority) {
|
||||
$groupedUsers[$priority] = array_filter(
|
||||
$Verbraucher_Liste_Korr[0]["User"],
|
||||
function ($user) use ($priority, $priorityKey) {
|
||||
return $user[$priorityKey] == $priority;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Jetzt werden die energien pro gruppe verteilt (Immer alle pro prio in einer gruppe miteinander)
|
||||
foreach ($groupedUsers as $priority => $users) {
|
||||
// Verbraucher mit gleicher Priorität sammeln
|
||||
$samePriorityUsers = isset($groupedUsers[$priority])
|
||||
? $groupedUsers[$priority]
|
||||
: [];
|
||||
|
||||
|
||||
// Wenn keine Verbraucher mit gleicher Priorität vorhanden sind, überspringen
|
||||
if (empty($samePriorityUsers)) {
|
||||
continue;
|
||||
}
|
||||
$withZero = [];
|
||||
$withoutZero = [];
|
||||
// Verbraucher die nicht 0 Annhemen können, bekommen einfach den tiefsten wert
|
||||
foreach ($samePriorityUsers as $entry) {
|
||||
if (min($entry["PowerSteps"]) <= 0) {
|
||||
$withZero[] = $entry;
|
||||
} else {
|
||||
$withoutZero[] = $entry;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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"])
|
||||
];
|
||||
//$remainingPower -= $entry["Aktuelle_Leistung"];
|
||||
}
|
||||
}
|
||||
|
||||
// Nun die verteilen, die 0 erhalten können.
|
||||
$samePriorityUsers = $withZero;
|
||||
// Array für die verteilte Energie pro User erstellen
|
||||
$userEnergyProv = [];
|
||||
|
||||
foreach ($samePriorityUsers as $user) {
|
||||
$userEnergyProv[$user['InstanceID']] = [
|
||||
'user' => $user['InstanceID'],
|
||||
'Writeback' => $user['Writeback'],
|
||||
//'Leistung_Delta' => $user["Leistung_Delta"],
|
||||
'Set_Leistung' => 0
|
||||
];
|
||||
}
|
||||
|
||||
if($remainingPower>=0){
|
||||
// Alle Schritte der Benutzer in einem Array sammeln
|
||||
$allSteps = [];
|
||||
foreach ($samePriorityUsers as $user) {
|
||||
foreach ($user["PowerSteps"] as $step) {
|
||||
$allSteps[] = [
|
||||
"user" => $user["InstanceID"],
|
||||
"Writeback" => $user["Writeback"],
|
||||
"step" => $step
|
||||
//"Leistung_Delta" => $user["Leistung_Delta"]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Sortiere die Schritte nach Größe
|
||||
usort($allSteps, function ($a, $b) {
|
||||
return $a["step"] <=> $b["step"];
|
||||
});
|
||||
|
||||
|
||||
// Iteriere durch alle Schritte
|
||||
foreach ($allSteps as $entry) {
|
||||
$user = $entry["user"];
|
||||
$manager = $entry["Writeback"];
|
||||
$powerstep = $entry["step"];
|
||||
|
||||
|
||||
$aktleistung = array_filter($userEnergyProv, function($entry2) use ($user, $manager) {
|
||||
|
||||
|
||||
return $entry2["user"] == $user && $entry2["Writeback"] == $manager;
|
||||
});
|
||||
|
||||
foreach($aktleistung as $entry){
|
||||
$aktleistung = $entry;
|
||||
}
|
||||
|
||||
// Überprüfe, ob noch genügend verbleibende Energie für den nächsten Schritt vorhanden ist
|
||||
if ($remainingPower >= $powerstep - $aktleistung['Set_Leistung']) {
|
||||
// Aktualisiere die verbleibende Energie und die bereitgestellte Energie für den Benutzer
|
||||
$remainingPower -= $powerstep - $aktleistung['Set_Leistung'];
|
||||
|
||||
array_walk($userEnergyProv, function(&$entry3) use ($user, $manager, $powerstep) {
|
||||
if ($entry3["user"] == $user && $entry3["Writeback"] == $manager) {
|
||||
$entry3["Set_Leistung"] = $powerstep;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 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"
|
||||
)
|
||||
);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
// Methode SetAktuelle_Leistung für jeden Verbraucher mit der entsprechenden Energie aufrufen
|
||||
|
||||
$resultArray[] = $userEnergyProv[$userInstanceID]; //[
|
||||
// 'InstanceID' => $user['InstanceID'],
|
||||
// 'Writeback' => $user['Writeback'],
|
||||
// 'Set_Leistung' => $leistung
|
||||
// ];
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else{
|
||||
|
||||
// Alle Schritte der Benutzer in einem Array sammeln
|
||||
$allSteps = [];
|
||||
foreach ($samePriorityUsers as $user) {
|
||||
foreach ($user["PowerSteps"] as $step) {
|
||||
$allSteps[] = [
|
||||
"user" => $user["InstanceID"],
|
||||
"Writeback" => $user["Writeback"],
|
||||
"step" => $step*-1
|
||||
//"Leistung_Delta" => $user["Leistung_Delta"]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Sortiere die Schritte nach Größe
|
||||
usort($allSteps, function ($a, $b) {
|
||||
return $a["step"] <=> $b["step"];
|
||||
});
|
||||
|
||||
$remainingPower = $remainingPower *-1;
|
||||
|
||||
// Iteriere durch alle Schritte
|
||||
foreach ($allSteps as $entry) {
|
||||
$user = $entry["user"];
|
||||
$manager = $entry["Writeback"];
|
||||
$powerstep = $entry["step"];
|
||||
|
||||
|
||||
$aktleistung = array_filter($userEnergyProv, function($entry2) use ($user, $manager) {
|
||||
|
||||
|
||||
return $entry2["user"] == $user && $entry2["Writeback"] == $manager;
|
||||
});
|
||||
|
||||
foreach($aktleistung as $entry){
|
||||
$aktleistung = $entry;
|
||||
}
|
||||
|
||||
// Überprüfe, ob noch genügend verbleibende Energie für den nächsten Schritt vorhanden ist
|
||||
if ($remainingPower >= $powerstep - $aktleistung['Set_Leistung']) {
|
||||
// Aktualisiere die verbleibende Energie und die bereitgestellte Energie für den Benutzer
|
||||
$remainingPower -= $powerstep - $aktleistung['Set_Leistung'];
|
||||
|
||||
array_walk($userEnergyProv, function(&$entry3) use ($user, $manager, $powerstep) {
|
||||
if ($entry3["user"] == $user && $entry3["Writeback"] == $manager) {
|
||||
$entry3["Set_Leistung"] = $powerstep;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
$remainingPower = $remainingPower *-1;
|
||||
|
||||
// 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"
|
||||
)
|
||||
);
|
||||
|
||||
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)*-1;
|
||||
|
||||
|
||||
// Methode SetAktuelle_Leistung für jeden Verbraucher mit der entsprechenden Energie aufrufen
|
||||
|
||||
$resultArray[] = $userEnergyProv[$userInstanceID]; //[
|
||||
// 'InstanceID' => $user['InstanceID'],
|
||||
// 'Writeback' => $user['Writeback'],
|
||||
// 'Set_Leistung' => $leistung
|
||||
// ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//IPS_LogMessage("Manager", print_r($resultArray));
|
||||
|
||||
$writebackArrays = [];
|
||||
foreach ($resultArray as $user) {
|
||||
$writeback = $user['Writeback'];
|
||||
|
||||
if (!isset($writebackArrays[$writeback])) {
|
||||
$writebackArrays[$writeback] = [];
|
||||
}
|
||||
$writebackArrays[$writeback][] = $user;
|
||||
}
|
||||
|
||||
// Schritt 2: Foreach-Schleife pro Writeback-Array
|
||||
foreach ($writebackArrays as $writeback => $users) {
|
||||
$resultArray = [
|
||||
'timestamp' => time(),
|
||||
'Is_Peak_Shaving' => $Is_Peak_Shaving,
|
||||
'User' => []
|
||||
];
|
||||
|
||||
foreach ($users as $user) {
|
||||
$resultArray['User'][] = [
|
||||
'InstanceID' => $user['user'],
|
||||
'Set_Leistung' => $user['Set_Leistung']
|
||||
];
|
||||
}
|
||||
|
||||
// Schritt 3: Array in String konvertieren
|
||||
$resultString = json_encode($resultArray);
|
||||
|
||||
// Schritt 4: RequestAction aufrufen
|
||||
RequestAction($writeback, $resultString);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -16,6 +16,10 @@
|
||||
{
|
||||
"caption": "Smart-Me Pico",
|
||||
"value": 3
|
||||
},
|
||||
{
|
||||
"caption": "Dummy Station (Ohne Ansteuerung)",
|
||||
"value": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -42,9 +46,15 @@
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "IdleCounterMax",
|
||||
"caption": "Zyklen zwischen zwei Leistungsänderungen",
|
||||
"caption": "Zyklen zwischen zwei Leistungsänderungen (Multipliziert sich mit Interval)",
|
||||
"suffix": ""
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Interval",
|
||||
"caption": "Intervall Neuberechnung der Werte",
|
||||
"suffix": "Sekunden"
|
||||
},
|
||||
{
|
||||
"type": "ValidationTextBox",
|
||||
"name": "IP_Adresse",
|
||||
|
||||
@@ -17,6 +17,7 @@ class Ladestation_Universal extends IPSModule
|
||||
$this->RegisterPropertyString("Seriennummer", "");
|
||||
$this->RegisterPropertyString("Username", "");
|
||||
$this->RegisterPropertyString("Password", "");
|
||||
$this->RegisterPropertyInteger("Interval", 5); // Recheninterval
|
||||
|
||||
|
||||
// Ladestationspezifische Variabeln
|
||||
@@ -38,6 +39,8 @@ class Ladestation_Universal extends IPSModule
|
||||
$this->RegisterVariableString("PowerSteps", "PowerSteps");
|
||||
$this->RegisterVariableInteger("Power", "Power");
|
||||
$this->RegisterVariableBoolean("Is_Peak_Shaving", "Is_Peak_Shaving");
|
||||
$this->RegisterVariableInteger("Leistung_Delta", "Leistung_Delta", "", 0);
|
||||
$this->RegisterVariableInteger("Power_Count", "Power_Count", "", 0);
|
||||
|
||||
// Hilfsvariabeln für Idle zustand
|
||||
$this->RegisterPropertyInteger("IdleCounterMax", 2);
|
||||
@@ -47,13 +50,15 @@ class Ladestation_Universal extends IPSModule
|
||||
// Initialisiere Idle
|
||||
$this->SetValue("Idle", true);
|
||||
|
||||
$this->RegisterTimer("Timer_Do_UserCalc",5000,"IPS_RequestAction(" .$this->InstanceID .', "Do_UserCalc", "");');
|
||||
$this->RegisterTimer("Timer_Do_UserCalc_EVC",$this->ReadPropertyInteger("Interval")*1000,"IPS_RequestAction(" .$this->InstanceID .', "Do_UserCalc", "");');
|
||||
|
||||
}
|
||||
|
||||
public function ApplyChanges()
|
||||
{
|
||||
parent::ApplyChanges();
|
||||
$this->SetTimerInterval("Timer_Do_UserCalc_EVC",$this->ReadPropertyInteger("Interval")*1000);
|
||||
|
||||
// Zusätzliche Anpassungen nach Bedarf
|
||||
}
|
||||
|
||||
@@ -82,12 +87,15 @@ class Ladestation_Universal extends IPSModule
|
||||
|
||||
|
||||
|
||||
|
||||
public function SetAktuelle_Leistung(int $power)
|
||||
{
|
||||
|
||||
$internalPower = GetValue($this->GetIDForIdent("Aktuelle_Leistung"));
|
||||
// Aktuelle Leistungsvorgabe setzen
|
||||
SetValue($this->GetIDForIdent("Aktuelle_Leistung"), $power);
|
||||
$this->SetValue("Bezogene_Energie", ($this->GetValue("Bezogene_Energie") + ($this->GetValue("Aktuelle_Leistung")*($this->ReadPropertyInteger("Interval")/3600))));
|
||||
|
||||
if ($power != $internalPower) {
|
||||
// Setze die interne Leistungsvorgabe
|
||||
|
||||
@@ -173,6 +181,8 @@ class Ladestation_Universal extends IPSModule
|
||||
$maxLeistung = $this->ReadPropertyInteger("MaxLeistung");
|
||||
}
|
||||
|
||||
|
||||
|
||||
$ch = curl_init();
|
||||
|
||||
// Setze die URL
|
||||
@@ -182,12 +192,28 @@ class Ladestation_Universal extends IPSModule
|
||||
CURLOPT_URL,
|
||||
"http://" . $this->ReadPropertyString("IP_Adresse") . "/api/status"
|
||||
);
|
||||
// Setze die Option, die Antwort als String zurückzugeben
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
|
||||
// Führe die Anfrage aus und speichere die Antwort
|
||||
$response = curl_exec($ch);
|
||||
|
||||
// Schließe cURL
|
||||
curl_close($ch);
|
||||
}elseif($this->ReadPropertyInteger("Ladestation")==1){
|
||||
curl_setopt(
|
||||
$ch,
|
||||
CURLOPT_URL,
|
||||
"http://" . $this->ReadPropertyString("IP_Adresse") . "/mqtt?payload="
|
||||
);
|
||||
// Setze die Option, die Antwort als String zurückzugeben
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
|
||||
// Führe die Anfrage aus und speichere die Antwort
|
||||
$response = curl_exec($ch);
|
||||
|
||||
// Schließe cURL
|
||||
curl_close($ch);
|
||||
}
|
||||
elseif($this->ReadPropertyInteger("Ladestation")==3){
|
||||
curl_setopt(
|
||||
@@ -197,10 +223,7 @@ class Ladestation_Universal extends IPSModule
|
||||
);
|
||||
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
|
||||
curl_setopt($ch, CURLOPT_USERPWD, $this->ReadPropertyString("Username") . ":" . $this->ReadPropertyString("Password"));
|
||||
}
|
||||
|
||||
|
||||
// Setze die Option, die Antwort als String zurückzugeben
|
||||
// Setze die Option, die Antwort als String zurückzugeben
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
|
||||
// Führe die Anfrage aus und speichere die Antwort
|
||||
@@ -208,13 +231,20 @@ class Ladestation_Universal extends IPSModule
|
||||
|
||||
// Schließe cURL
|
||||
curl_close($ch);
|
||||
}
|
||||
elseif($this->ReadPropertyInteger("Ladestation")==4){
|
||||
|
||||
$response = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Überprüfe, ob die Antwort nicht leer ist
|
||||
if ($response) {
|
||||
// Dekodiere die JSON-Antwort
|
||||
$data = json_decode($response, true);
|
||||
|
||||
if($this->ReadPropertyInteger("Ladestation")==2||$this->ReadPropertyInteger("Ladestation")==1){
|
||||
if($this->ReadPropertyInteger("Ladestation")==2){
|
||||
// Überprüfe, ob das JSON-Dekodieren erfolgreich war und der Schlüssel "car" existiert
|
||||
if (json_last_error() === JSON_ERROR_NONE && isset($data["car"])) {
|
||||
// Speichere den Wert von "car" in der Variable $status
|
||||
@@ -233,6 +263,26 @@ class Ladestation_Universal extends IPSModule
|
||||
}
|
||||
}
|
||||
}
|
||||
if($this->ReadPropertyInteger("Ladestation")==1){
|
||||
// Überprüfe, ob das JSON-Dekodieren erfolgreich war und der Schlüssel "car" existiert
|
||||
if (json_last_error() === JSON_ERROR_NONE && isset($data["car"])) {
|
||||
// Speichere den Wert von "car" in der Variable $status
|
||||
|
||||
SetValue(
|
||||
$this->GetIDForIdent("Ladeleistung_Effektiv"),
|
||||
$data["nrg"][11]*10
|
||||
);
|
||||
|
||||
SetValue($this->GetIDForIdent("Fahrzeugstatus"), $data["car"]);
|
||||
|
||||
if ($data["nrg"][6] > 1 && $data["car"] == 2) {
|
||||
SetValue($this->GetIDForIdent("Lademodus"), 1);
|
||||
} elseif ($data["nrg"][6] <= 1 && $data["car"] == 2) {
|
||||
SetValue($this->GetIDForIdent("Lademodus"), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($this->ReadPropertyInteger("Ladestation")==3){
|
||||
// Überprüfe, ob das JSON-Dekodieren erfolgreich war und der Schlüssel "car" existiert
|
||||
if (json_last_error() === JSON_ERROR_NONE && isset($data["State"])) {
|
||||
@@ -245,7 +295,7 @@ class Ladestation_Universal extends IPSModule
|
||||
|
||||
SetValue($this->GetIDForIdent("Fahrzeugstatus"), $data["State"]);
|
||||
|
||||
if($data["MaxAllowedChargingCurrent"]>0 && $data["State"] != 1){
|
||||
if(($this->GetValue("Ladeleistung_Effektiv")>0)&& ($data["MaxAllowedChargingCurrent"]>0)){
|
||||
if ($data["ActiveChargingPower"]/$data["MaxAllowedChargingCurrent"] > 0.4/* && $data["State"] != 1*/) {
|
||||
SetValue($this->GetIDForIdent("Lademodus"), 1);
|
||||
} elseif ($data["State"] != 1) {
|
||||
@@ -257,12 +307,46 @@ class Ladestation_Universal extends IPSModule
|
||||
}
|
||||
}
|
||||
}
|
||||
if($this->ReadPropertyInteger("Ladestation")==4){
|
||||
|
||||
// Nichts zu tun hier...
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Peak-Wert speichern
|
||||
$this->SetValue("Peak", $Peak);
|
||||
|
||||
|
||||
IPS_LogMessage("Lades", "Hier");
|
||||
|
||||
$akt = $this->GetValue("Ladeleistung_Effektiv");
|
||||
$pow = $this->GetValue("Aktuelle_Leistung");
|
||||
IPS_LogMessage("akt", $akt);
|
||||
IPS_LogMessage("pow", $pow);
|
||||
|
||||
$timeout = $this->ReadPropertyInteger("Interval")*$this->ReadPropertyInteger("IdleCounterMax")*2;
|
||||
if(($akt<(0.8*$pow)) && ($pow>0)){
|
||||
IPS_LogMessage("Lades", "Hier2");
|
||||
|
||||
$dummy = $this->GetValue("Power_Count")+1;
|
||||
$this->SetValue("Power_Count", $dummy);
|
||||
|
||||
}elseif($this->GetValue("Power_Count")<=$timeout) {
|
||||
IPS_LogMessage("Lades", "Hier3");
|
||||
|
||||
$this->SetValue("Power_Count", 0);
|
||||
|
||||
}
|
||||
IPS_LogMessage("Lades", "Hier4");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Array für die Powersteps initialisieren
|
||||
$powerSteps = [0];
|
||||
|
||||
@@ -284,16 +368,26 @@ class Ladestation_Universal extends IPSModule
|
||||
} elseif ($solarladen && $Peak) {
|
||||
$powerSteps = [0];
|
||||
} else {
|
||||
if($this->GetValue("Power_Count")>$timeout){
|
||||
|
||||
$maxLeistung = 1.05 * $this->GetValue("Ladeleistung_Effektiv");
|
||||
IPS_LogMessage("Lades", "Hier5");
|
||||
|
||||
}
|
||||
|
||||
$powerSteps += $this->getRangeLimits(
|
||||
$minLeistung,
|
||||
$maxLeistung,
|
||||
GetValue($this->GetIDForIdent("Lademodus"))
|
||||
);
|
||||
}
|
||||
}else{
|
||||
|
||||
$this->SetValue("Power_Count", 0);
|
||||
}
|
||||
// PowerSteps in der RegisterVariable speichern
|
||||
SetValue($this->GetIDForIdent("PowerSteps"), json_encode($powerSteps));
|
||||
|
||||
$this->SetValue("Leistung_Delta", $this->GetValue("Ladeleistung_Effektiv")-$this->GetValue("Ladeleistung"));
|
||||
// Rückgabe der Powersteps
|
||||
return $powerSteps;
|
||||
}
|
||||
@@ -304,14 +398,16 @@ class Ladestation_Universal extends IPSModule
|
||||
|
||||
if($this->ReadPropertyInteger("Ladestation")==2){
|
||||
$baseUrl ="http://" . $this->ReadPropertyString("IP_Adresse") . "/api/set?";
|
||||
|
||||
}elseif($this->ReadPropertyInteger("Ladestation")==1){
|
||||
$baseUrl ="http://" . $this->ReadPropertyString("IP_Adresse") . "/mqtt?payload=";
|
||||
|
||||
}elseif($this->ReadPropertyInteger("Ladestation")==3){
|
||||
$baseUrl ="https://api.smart-me.com/pico/loadmanagementgroup/current/" . $this->ReadPropertyString("Seriennummer") . "?current=";
|
||||
|
||||
}
|
||||
// Base URL
|
||||
|
||||
IPS_LogMessage("Ladestation", "Aufgerufene ip" . $baseUrl);
|
||||
$value = $this->convertPowerToCurrent(
|
||||
$value,
|
||||
GetValue($this->GetIDForIdent("Lademodus"))
|
||||
@@ -381,7 +477,11 @@ class Ladestation_Universal extends IPSModule
|
||||
|
||||
}elseif($this->ReadPropertyInteger("Ladestation")==3){
|
||||
// Nichts zu tun für Smart-Me station
|
||||
} }elseif($this->ReadPropertyInteger("Ladestation")==4){
|
||||
// Nichts zu tun für Dummy station
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Second request
|
||||
@@ -449,9 +549,11 @@ class Ladestation_Universal extends IPSModule
|
||||
// Return responses
|
||||
return;
|
||||
|
||||
}
|
||||
}elseif($this->ReadPropertyInteger("Ladestation")==4){
|
||||
// Nichts zu tun für Dummy station
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// If value is out of range
|
||||
else {
|
||||
|
||||
67
Ladestation_v2/README.md
Normal file
67
Ladestation_v2/README.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# Manager_1
|
||||
Beschreibung des Moduls.
|
||||
|
||||
### 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)
|
||||
|
||||
### 1. Funktionsumfang
|
||||
|
||||
*
|
||||
|
||||
### 2. Voraussetzungen
|
||||
|
||||
- IP-Symcon ab Version 7.1
|
||||
|
||||
### 3. Software-Installation
|
||||
|
||||
* Über den Module Store das 'Manager_1'-Modul installieren.
|
||||
* Alternativ über das Module Control folgende URL hinzufügen
|
||||
|
||||
### 4. Einrichten der Instanzen in IP-Symcon
|
||||
|
||||
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__:
|
||||
|
||||
Name | Beschreibung
|
||||
-------- | ------------------
|
||||
|
|
||||
|
|
||||
|
||||
### 5. Statusvariablen und Profile
|
||||
|
||||
Die Statusvariablen/Kategorien werden automatisch angelegt. Das Löschen einzelner kann zu Fehlfunktionen führen.
|
||||
|
||||
#### Statusvariablen
|
||||
|
||||
Name | Typ | Beschreibung
|
||||
------ | ------- | ------------
|
||||
| |
|
||||
| |
|
||||
|
||||
#### Profile
|
||||
|
||||
Name | Typ
|
||||
------ | -------
|
||||
|
|
||||
|
|
||||
|
||||
### 6. WebFront
|
||||
|
||||
Die Funktionalität, die das Modul im WebFront bietet.
|
||||
|
||||
### 7. PHP-Befehlsreferenz
|
||||
|
||||
`boolean GEF_BeispielFunktion(integer $InstanzID);`
|
||||
Erklärung der Funktion.
|
||||
|
||||
Beispiel:
|
||||
`GEF_BeispielFunktion(12345);`
|
||||
83
Ladestation_v2/form.json
Normal file
83
Ladestation_v2/form.json
Normal file
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"elements": [
|
||||
{
|
||||
"type": "Select",
|
||||
"name": "Ladestation",
|
||||
"caption": "Ladestation",
|
||||
"options": [
|
||||
{
|
||||
"caption": "Go-E Wallbox (Alte Version)",
|
||||
"value": 1
|
||||
},
|
||||
{
|
||||
"caption": "Go-E Germini / Germini Flex",
|
||||
"value": 2
|
||||
},
|
||||
{
|
||||
"caption": "Smart-Me Pico",
|
||||
"value": 3
|
||||
},
|
||||
{
|
||||
"caption": "Dummy Station (Ohne Ansteuerung)",
|
||||
"value": 4
|
||||
},
|
||||
{
|
||||
"caption": "Easee",
|
||||
"value": 5
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "IdleCounterMax",
|
||||
"caption": "Zyklen zwischen zwei Leistungsänderungen (Multipliziert sich mit Interval)",
|
||||
"suffix": ""
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Interval",
|
||||
"caption": "Intervall Neuberechnung der Werte",
|
||||
"suffix": "Sekunden"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Max_Current_abs",
|
||||
"caption": "Maximaler Ladestrom",
|
||||
"suffix": "Ampere"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Zeit_Zwischen_Zustandswechseln",
|
||||
"caption": "Mindestlaufzeit des Verbrauchers bei Lastschaltung",
|
||||
"suffix": ""
|
||||
},
|
||||
{
|
||||
"type": "ValidationTextBox",
|
||||
"name": "IP_Adresse",
|
||||
"caption": "IP-Adresse Ladestation"
|
||||
},
|
||||
{
|
||||
"type": "ValidationTextBox",
|
||||
"name": "ID",
|
||||
"caption": "ID"
|
||||
|
||||
},
|
||||
{
|
||||
"type": "ValidationTextBox",
|
||||
"name": "Seriennummer",
|
||||
"caption": "Seriennummer"
|
||||
|
||||
},
|
||||
{
|
||||
"type": "ValidationTextBox",
|
||||
"name": "Username",
|
||||
"caption": "Username"
|
||||
|
||||
},
|
||||
{ "type": "PasswordTextBox",
|
||||
"name": "Password",
|
||||
"caption": "Passwort"
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
12
Ladestation_v2/module.json
Normal file
12
Ladestation_v2/module.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"id": "{51E121F0-E2E9-D0C2-C8BD-92601B143EB8}",
|
||||
"name": "Ladestation_v2",
|
||||
"type": 3,
|
||||
"vendor": "Belevo AG",
|
||||
"aliases": [],
|
||||
"parentRequirements": [],
|
||||
"childRequirements": [],
|
||||
"implemented": [],
|
||||
"prefix": "GEF",
|
||||
"url": ""
|
||||
}
|
||||
621
Ladestation_v2/module.php
Normal file
621
Ladestation_v2/module.php
Normal file
@@ -0,0 +1,621 @@
|
||||
<?php
|
||||
|
||||
class Ladestation_v2 extends IPSModule
|
||||
{
|
||||
public function Create()
|
||||
{
|
||||
|
||||
parent::Create();
|
||||
|
||||
// Ladestationspezifische Properties
|
||||
$this->RegisterPropertyString("IP_Adresse", "0.0.0.0");
|
||||
$this->RegisterPropertyInteger("Ladestation", 2);
|
||||
$this->RegisterPropertyString("ID", "");
|
||||
$this->RegisterPropertyString("Seriennummer", "");
|
||||
$this->RegisterPropertyString("Username", "");
|
||||
$this->RegisterPropertyString("Password", "");
|
||||
$this->RegisterPropertyInteger("Interval", 5); // Recheninterval
|
||||
$this->RegisterPropertyInteger("Max_Current_abs", 32); // Recheninterval
|
||||
$this->RegisterPropertyInteger("Zeit_Zwischen_Zustandswechseln", 1);
|
||||
|
||||
|
||||
// Ladestationspezifische Variabeln
|
||||
$this->RegisterVariableFloat("Max_Current","Maximaler Ladestrom","", 0);
|
||||
IPS_SetHidden($this->GetIDForIdent("Max_Current"), true);
|
||||
$this->RegisterVariableBoolean("Is_1_ph", "Auto lädt 1-Phasig", "~Switch", false);
|
||||
$this->RegisterVariableBoolean("Car_detected", "Auto erkannt","~Switch", false);
|
||||
$this->RegisterVariableInteger("Pending_Counter", "Pending_Counter", "", 0);
|
||||
IPS_SetHidden($this->GetIDForIdent("Pending_Counter"), true);
|
||||
$this->RegisterVariableBoolean("Car_is_full", "Auto fertig geladen", "~Switch", false);
|
||||
$this->RegisterVariableBoolean("Ladebereit", "Ladestation ein", "~Switch", true);
|
||||
$this->EnableAction("Ladebereit");
|
||||
$this->RegisterVariableBoolean("Solarladen", "Solarladen ein", "~Switch", false);
|
||||
$this->EnableAction("Solarladen");
|
||||
$this->RegisterVariableInteger("Fahrzeugstatus", "Fahrzeugstatus", "", 0);
|
||||
IPS_SetHidden($this->GetIDForIdent("Fahrzeugstatus"), true);
|
||||
|
||||
$this->RegisterVariableFloat("Ladeleistung_Effektiv", "Aktuelle Ladeleistung", "", 0);
|
||||
$this->RegisterVariableBoolean("Peak", "Peak", "", 0);
|
||||
IPS_SetHidden($this->GetIDForIdent("Peak"), true);
|
||||
|
||||
$this->RegisterVariableBoolean("IsTimerActive", "IsTimerActive", "", false);
|
||||
$this->RegisterTimer("ZustandswechselTimer",0,"IPS_RequestAction(" .$this->InstanceID .', "ResetTimer", "");');
|
||||
|
||||
|
||||
|
||||
// Variabeln für Kommunkation mit Manager
|
||||
$this->RegisterVariableInteger("Sperre_Prio", "Priorität Sperre", "", 0);
|
||||
$this->EnableAction("Sperre_Prio");
|
||||
IPS_SetHidden($this->GetIDForIdent("Sperre_Prio"), true);
|
||||
|
||||
$this->RegisterVariableInteger("PV_Prio", "Priorität Solarladen", "", 0);
|
||||
$this->EnableAction("PV_Prio");
|
||||
IPS_SetHidden($this->GetIDForIdent("PV_Prio"), true);
|
||||
|
||||
$this->RegisterVariableBoolean("Idle", "Idle", "", 0);
|
||||
IPS_SetHidden($this->GetIDForIdent("Idle"), true);
|
||||
|
||||
$this->RegisterVariableInteger("Aktuelle_Leistung", "Aktuelle_Leistung", "", 0);
|
||||
IPS_SetHidden($this->GetIDForIdent("Aktuelle_Leistung"), true);
|
||||
|
||||
$this->RegisterVariableFloat("Bezogene_Energie", "Gesamter Energiebezug", "", 0);
|
||||
IPS_SetHidden($this->GetIDForIdent("Bezogene_Energie"), true);
|
||||
|
||||
$this->RegisterVariableString("PowerSteps", "Leistungsschritte");
|
||||
IPS_SetHidden($this->GetIDForIdent("PowerSteps"), true);
|
||||
|
||||
$this->RegisterVariableInteger("Power", "Power");
|
||||
IPS_SetHidden($this->GetIDForIdent("Power"), true);
|
||||
|
||||
$this->RegisterVariableBoolean("Is_Peak_Shaving", "Is_Peak_Shaving");
|
||||
IPS_SetHidden($this->GetIDForIdent("Is_Peak_Shaving"), true);
|
||||
|
||||
$this->RegisterVariableInteger("Leistung_Delta", "Leistung_Delta", "", 0);
|
||||
IPS_SetHidden($this->GetIDForIdent("Leistung_Delta"), true);
|
||||
|
||||
// Hilfsvariabeln für Idle zustand
|
||||
$this->RegisterPropertyInteger("IdleCounterMax", 2);
|
||||
$this->RegisterVariableInteger("IdleCounter", "IdleCounter", "", 0);
|
||||
IPS_SetHidden($this->GetIDForIdent("IdleCounter"), true);
|
||||
$this->SetValue("IdleCounter", 0);
|
||||
|
||||
// Initialisiere Idle
|
||||
$this->SetValue("Idle", true);
|
||||
|
||||
$this->RegisterTimer("Timer_Do_UserCalc_EVC",$this->ReadPropertyInteger("Interval")*1000,"IPS_RequestAction(" .$this->InstanceID .', "Do_UserCalc", "");');
|
||||
|
||||
}
|
||||
|
||||
public function ApplyChanges()
|
||||
{
|
||||
parent::ApplyChanges();
|
||||
$this->SetTimerInterval("Timer_Do_UserCalc_EVC",$this->ReadPropertyInteger("Interval")*1000);
|
||||
|
||||
// Zusätzliche Anpassungen nach Bedarf
|
||||
}
|
||||
|
||||
|
||||
public function RequestAction($Ident, $Value)
|
||||
{
|
||||
switch ($Ident) {
|
||||
|
||||
case "SetAktuelle_Leistung":
|
||||
$this->SetValue("Power", (int)$Value);
|
||||
break;
|
||||
|
||||
case "GetCurrentData":
|
||||
$this->SetValue("Is_Peak_Shaving", (bool)$Value);
|
||||
break;
|
||||
|
||||
case "Do_UserCalc":
|
||||
|
||||
|
||||
if($this->Detect_Car($this->ReadPropertyInteger("Ladestation"))){
|
||||
$this->SetAktuelle_Leistung($this->GetValue("Power"));
|
||||
$this->GetCurrentData($this->GetValue("Is_Peak_Shaving"));
|
||||
}
|
||||
else{
|
||||
SetValue($this->GetIDForIdent("PowerSteps"), json_encode([0]));
|
||||
$this->SetValue("PowerSteps", json_encode([0]));
|
||||
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case "Sperre_Prio":
|
||||
$this->SetValue("Sperre_Prio", (bool)$Value);
|
||||
break;
|
||||
|
||||
case "PV_Prio":
|
||||
$this->SetValue("PV_Prio", (bool)$Value);
|
||||
break;
|
||||
|
||||
case "Solarladen":
|
||||
$this->SetValue("Solarladen", (bool)$Value);
|
||||
break;
|
||||
|
||||
case "Ladebereit":
|
||||
$this->SetValue("Ladebereit", (bool)$Value);
|
||||
break;
|
||||
|
||||
case "ResetTimer":
|
||||
$this->ResetTimer();
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Exception("Invalid Ident");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function Detect_Car(int $carType)
|
||||
{
|
||||
|
||||
if($this->GetValue("Car_detected")==true){
|
||||
if($this->Get_Car_Status($carType)==true){
|
||||
$this->SetValue("Car_detected", true);
|
||||
if($this->GetValue("Max_Current")<6){
|
||||
$this->SetValue("Car_is_full", true);
|
||||
}
|
||||
|
||||
}else{
|
||||
$this->SetValue("Car_detected", false);
|
||||
$this->SetValue("Car_is_full", false);
|
||||
|
||||
}
|
||||
}
|
||||
else{
|
||||
if($this->Get_Car_Status($carType)==true){
|
||||
|
||||
$this->sendPowerToStation($this->ReadPropertyInteger("Max_Current_abs"));
|
||||
|
||||
$counter = $this->GetValue("Pending_Counter");
|
||||
|
||||
if($counter>(60/($this->ReadPropertyInteger("Interval")))){
|
||||
|
||||
$this->SetValue("Pending_Counter", 0);
|
||||
if($this->GetValue("Ladeleistung_Effektiv")>7500){
|
||||
$this->SetValue("Is_1_ph", false);
|
||||
$this->Calc_Max_Current(false);
|
||||
|
||||
}
|
||||
else{
|
||||
$this->SetValue("Is_1_ph", true);
|
||||
$this->Calc_Max_Current(true);
|
||||
|
||||
}
|
||||
|
||||
$this->SetValue("Car_detected", true);
|
||||
|
||||
|
||||
}
|
||||
else{
|
||||
$this->SetValue("Pending_Counter", $counter+1);
|
||||
$this->SetValue("Car_detected", false);
|
||||
|
||||
}
|
||||
|
||||
}else{
|
||||
$this->SetValue("Car_detected", false);
|
||||
$this->sendPowerToStation($this->ReadPropertyInteger("Max_Current_abs"));
|
||||
}
|
||||
}
|
||||
|
||||
return $this->GetValue("Car_detected");
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Methode zum Setzen der PowerSteps und Timer starten
|
||||
public function SetTimerOn()
|
||||
{
|
||||
// Timer setzen, der nach "Zeit_Zwischen_Zustandswechseln" abläuft
|
||||
$zeitZwischenZustandswechseln = $this->ReadPropertyInteger("Zeit_Zwischen_Zustandswechseln");
|
||||
|
||||
if($zeitZwischenZustandswechseln>0){
|
||||
$this->SetTimerInterval("ZustandswechselTimer", $zeitZwischenZustandswechseln * 60000); // Timer in Millisekunden
|
||||
// Timer-Status auf true setzen
|
||||
$this->SetValue("IsTimerActive", true);
|
||||
}else{
|
||||
$this->SetValue("IsTimerActive", false);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Methode zum Zurücksetzen von PowerSteps nach Ablauf des Timers
|
||||
public function ResetTimer()
|
||||
{
|
||||
// Timer stoppen
|
||||
$this->SetTimerInterval("ZustandswechselTimer", 0);
|
||||
|
||||
// Timer-Status auf false setzen
|
||||
$this->SetValue("IsTimerActive", false);
|
||||
}
|
||||
|
||||
|
||||
public function Get_Car_Status(int $carType)
|
||||
{
|
||||
$ch = curl_init();
|
||||
$car_on_station = $this->GetValue("Car_detected");
|
||||
switch ($carType) {
|
||||
case 1:
|
||||
curl_setopt($ch, CURLOPT_URL, "http://" . $this->ReadPropertyString("IP_Adresse") . "/mqtt?payload=");
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
$response = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
$data = json_decode($response, true);
|
||||
|
||||
if (json_last_error() === JSON_ERROR_NONE && isset($data["car"])) {
|
||||
/*if ($data["car"] != 1) {
|
||||
$this->SetValue("Car_detected", true);
|
||||
}
|
||||
else{
|
||||
$this->SetValue("Car_detected", false);
|
||||
}*/
|
||||
if ($data["car"] != 1) {
|
||||
$car_on_station = true;
|
||||
}
|
||||
else{
|
||||
$car_on_station = false;
|
||||
}
|
||||
$this->SetValue("Ladeleistung_Effektiv", $data["nrg"][11]*10);
|
||||
$this->SetValue("Fahrzeugstatus", $data["car"]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
curl_setopt($ch, CURLOPT_URL, "http://" . $this->ReadPropertyString("IP_Adresse") . "/api/status");
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
$response = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
$data = json_decode($response, true);
|
||||
|
||||
if (json_last_error() === JSON_ERROR_NONE && isset($data["car"])) {
|
||||
/*if ($data["car"] != 1) {
|
||||
$this->SetValue("Car_detected", true);
|
||||
}
|
||||
else{
|
||||
$this->SetValue("Car_detected", false);
|
||||
}*/
|
||||
if ($data["car"] != 1) {
|
||||
$car_on_station = true;
|
||||
}
|
||||
else{
|
||||
$car_on_station = false;
|
||||
}
|
||||
$this->SetValue("Ladeleistung_Effektiv", $data["nrg"][11]);
|
||||
$this->SetValue("Fahrzeugstatus", $data["car"]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
curl_setopt($ch, CURLOPT_URL, "https://api.smart-me.com/pico/charging/" . $this->ReadPropertyString("ID"));
|
||||
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
|
||||
curl_setopt($ch, CURLOPT_USERPWD, $this->ReadPropertyString("Username") . ":" . $this->ReadPropertyString("Password"));
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
$response = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
$data = json_decode($response, true);
|
||||
|
||||
if (json_last_error() === JSON_ERROR_NONE && isset($data["State"])) {
|
||||
/*if ($data["car"] != 1) {
|
||||
$this->SetValue("Car_detected", true);
|
||||
}
|
||||
else{
|
||||
$this->SetValue("Car_detected", false);
|
||||
}*/
|
||||
if ($data["State"] != 1) {
|
||||
$car_on_station = true;
|
||||
}
|
||||
else{
|
||||
$car_on_station = false;
|
||||
}
|
||||
$this->SetValue("Ladeleistung_Effektiv", round($data["ActiveChargingPower"]*1000));
|
||||
$this->SetValue("Fahrzeugstatus", $data["State"]);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
$this->SetValue("Car_detected", true);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
echo "Fall 5";
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->SetValue("Car_detected", false);
|
||||
$this->SetValue("Fahrzeugstatus", -1);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return $car_on_station;
|
||||
}
|
||||
|
||||
public function Calc_Max_Current(bool $is_1_ph)
|
||||
{
|
||||
$maxCurrent = 32;
|
||||
if($is_1_ph){
|
||||
$maxCurrent = 1.5 + ($this->GetValue("Ladeleistung_Effektiv") / 230);
|
||||
}
|
||||
else{
|
||||
$maxCurrent = 1.5 + ($this->GetValue("Ladeleistung_Effektiv") / (1.71*400));
|
||||
}
|
||||
if($maxCurrent>$this->ReadPropertyInteger("Max_Current_abs")){
|
||||
$maxCurrent = $this->ReadPropertyInteger("Max_Current_abs");
|
||||
}
|
||||
$this->SetValue("Max_Current", $maxCurrent);
|
||||
}
|
||||
|
||||
public function Get_Current_From_Power(bool $is_1_ph, int $power)
|
||||
{
|
||||
if ($is_1_ph) {
|
||||
$current = round($power / 230);
|
||||
} else {
|
||||
$current = round($power / (400 * 1.71));
|
||||
}
|
||||
|
||||
return $current;
|
||||
}
|
||||
|
||||
public function Get_Array_From_Current(bool $is_1_ph, float $current)
|
||||
{
|
||||
$resultArray = [];
|
||||
$resultArray[] = 0;
|
||||
for ($i = 6; $i <= $current; $i++) {
|
||||
if ($is_1_ph) {
|
||||
$resultArray[] = $i * 230;
|
||||
} else {
|
||||
$resultArray[] = $i * 400 * 1.71;
|
||||
}
|
||||
}
|
||||
|
||||
return $resultArray;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function SetAktuelle_Leistung(int $power)
|
||||
{
|
||||
// Hier eine Leistungsänderung detektieren für Idle und interne Mindestlaufzeiten
|
||||
$this->CheckIdle($power);
|
||||
if ($this->GetValue("Aktuelle_Leistung") != $power) {
|
||||
$this->SetTimerOn();
|
||||
}
|
||||
|
||||
$internalPower = GetValue($this->GetIDForIdent("Aktuelle_Leistung"));
|
||||
|
||||
// Aktuelle Leistungsvorgabe setzen
|
||||
SetValue($this->GetIDForIdent("Aktuelle_Leistung"), $power);
|
||||
if($power <= 0){
|
||||
$this->SetValue("Pending_Counter", 0);
|
||||
}
|
||||
|
||||
$this->SetValue("Bezogene_Energie", ($this->GetValue("Bezogene_Energie") + ($this->GetValue("Aktuelle_Leistung")*($this->ReadPropertyInteger("Interval")/3600))));
|
||||
|
||||
if ($power != $internalPower) {
|
||||
// Setze die interne Leistungsvorgabe
|
||||
|
||||
// Idle für 4 Zyklen auf false setzen
|
||||
SetValue($this->GetIDForIdent("Idle"), false);
|
||||
SetValue(
|
||||
$this->GetIDForIdent("IdleCounter"),
|
||||
$this->ReadPropertyInteger("IdleCounterMax")
|
||||
);
|
||||
} else {
|
||||
// IdleCallCounter herunterzählen, wenn power == interne Leistungsvorgabe
|
||||
$idleCounter = GetValue($this->GetIDForIdent("IdleCounter"));
|
||||
if ($idleCounter > 0) {
|
||||
$idleCounter--;
|
||||
$this->SetValue("Pending_Counter", 0);
|
||||
SetValue($this->GetIDForIdent("IdleCounter"), $idleCounter);
|
||||
if ($idleCounter == 0) {
|
||||
SetValue($this->GetIDForIdent("Idle"), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ladeleistung setzen
|
||||
$peak = GetValue($this->GetIDForIdent("Peak"));
|
||||
$solarladen = GetValue($this->GetIDForIdent("Solarladen"));
|
||||
$Ladebereit = GetValue($this->GetIDForIdent("Ladebereit"));
|
||||
if (!$Ladebereit) {
|
||||
|
||||
$this->sendPowerToStation(0);
|
||||
|
||||
} elseif (!$peak && !$solarladen) {
|
||||
// Wenn weder Peak noch Solarladen aktiv sind, setze Ladeleistung auf MaxLeistung
|
||||
$this->sendPowerToStation($this->Get_Current_From_Power($this->GetValue("Is_1_ph"), $power));
|
||||
|
||||
} else {
|
||||
// Ansonsten setze Ladeleistung auf die aktuelle Leistungsvorgabe (Aktuelle_Leistung)
|
||||
$this->sendPowerToStation($this->Get_Current_From_Power($this->GetValue("Is_1_ph"), $power));
|
||||
}
|
||||
}
|
||||
|
||||
// Methode zum Abrufen der aktuellen Daten
|
||||
public function GetCurrentData(bool $Peak)
|
||||
{
|
||||
|
||||
// Überprüfen, ob der Timer aktiv ist
|
||||
if ($this->GetValue("IsTimerActive")) {
|
||||
// Timer ist aktiv, PowerSteps setzen
|
||||
$this->SetValue("PowerSteps", json_encode([$this->GetValue("Aktuelle_Leistung")]));
|
||||
$this->SetValue("Leistung_Delta", $this->GetValue("Aktuelle_Leistung")-$this->GetValue("Ladeleistung_Effektiv"));
|
||||
|
||||
return;
|
||||
}else{
|
||||
$this->SetValue("Leistung_Delta", 0);
|
||||
}
|
||||
|
||||
// Aktuelle Properties abrufen
|
||||
$ladebereit = GetValue($this->GetIDForIdent("Ladebereit"));
|
||||
$solarladen = GetValue($this->GetIDForIdent("Solarladen"));
|
||||
|
||||
|
||||
// Peak-Wert speichern
|
||||
$this->SetValue("Peak", $Peak);
|
||||
|
||||
// Array für die Powersteps initialisieren
|
||||
$powerSteps = [];
|
||||
|
||||
// Konfiguration des powerSteps-Arrays basierend auf den Properties
|
||||
if (!$ladebereit) {
|
||||
$powerSteps = [0];
|
||||
} elseif (!$Peak && !$solarladen) {
|
||||
$powerSteps = [max($this->Get_Array_From_Current($this->GetValue("Is_1_ph"),$this->GetValue("Max_Current")))];
|
||||
} elseif (!$Peak && $solarladen) {
|
||||
$powerSteps = $this->Get_Array_From_Current($this->GetValue("Is_1_ph"),$this->GetValue("Max_Current"));
|
||||
} elseif ($solarladen && $Peak) {
|
||||
$powerSteps = [0];
|
||||
} else {
|
||||
$powerSteps = $this->Get_Array_From_Current($this->GetValue("Is_1_ph"),$this->GetValue("Max_Current"));
|
||||
}
|
||||
|
||||
// PowerSteps in der RegisterVariable speichern
|
||||
SetValue($this->GetIDForIdent("PowerSteps"), json_encode($powerSteps));
|
||||
// Rückgabe der Powersteps
|
||||
$counter = $this->GetValue("Pending_Counter");
|
||||
|
||||
if($this->GetValue("Aktuelle_Leistung")>(1.11*$this->GetValue("Ladeleistung_Effektiv"))){
|
||||
$this->SetValue("Pending_Counter", $counter+1);
|
||||
|
||||
}elseif(max($this->Get_Array_From_Current($this->GetValue("Is_1_ph"),$this->GetValue("Max_Current")))<(1.11*$this->GetValue("Ladeleistung_Effektiv"))){ // diesen elseif ggf wieder rauslöschen
|
||||
$this->SetValue("Pending_Counter", $counter+1);
|
||||
|
||||
}
|
||||
else{
|
||||
|
||||
$this->SetValue("Pending_Counter", 0);
|
||||
|
||||
}
|
||||
|
||||
if($counter>(90/($this->ReadPropertyInteger("Interval")))){
|
||||
|
||||
$this->SetValue("Pending_Counter", 0);
|
||||
$this->Calc_Max_Current($this->GetValue("Is_1_ph"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return $powerSteps;
|
||||
}
|
||||
|
||||
public function sendPowerToStation(float $value)
|
||||
{
|
||||
$baseUrl = "";
|
||||
$stationType = $this->ReadPropertyInteger("Ladestation");
|
||||
|
||||
switch ($stationType) {
|
||||
case 1:
|
||||
$baseUrl = "http://" . $this->ReadPropertyString("IP_Adresse") . "/mqtt?payload=";
|
||||
break;
|
||||
case 2:
|
||||
$baseUrl = "http://" . $this->ReadPropertyString("IP_Adresse") . "/api/set?";
|
||||
break;
|
||||
case 3:
|
||||
$baseUrl = "https://api.smart-me.com/pico/loadmanagementgroup/current/" . $this->ReadPropertyString("Seriennummer") . "?current=";
|
||||
break;
|
||||
case 4:
|
||||
// Nichts zu tun für Dummy station
|
||||
return;
|
||||
}
|
||||
|
||||
$ch = curl_init();
|
||||
IPS_LogMessage("value", "nach konvertierung" . $value);
|
||||
|
||||
if ($value == 0) {
|
||||
switch ($stationType) {
|
||||
case 1:
|
||||
$url = $baseUrl . "alw=0";
|
||||
break;
|
||||
case 2:
|
||||
$url = $baseUrl . "frc=1&sua=false";
|
||||
|
||||
break;
|
||||
case 3:
|
||||
$url = $baseUrl . "0";
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
|
||||
curl_setopt($ch, CURLOPT_USERPWD, $this->ReadPropertyString("Username") . ":" . $this->ReadPropertyString("Password"));
|
||||
break;
|
||||
case 4:
|
||||
// Nichts zu tun für Dummy station
|
||||
return;
|
||||
default:
|
||||
return "Invalid station type.";
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
$response = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
return $response;
|
||||
} elseif ($value >= 1 && $value <= 32) {
|
||||
switch ($stationType) {
|
||||
case 1:
|
||||
$url1 = $baseUrl . "alw=1";
|
||||
$url2 = $baseUrl . "amp=$value";
|
||||
break;
|
||||
case 2:
|
||||
$url1 = $baseUrl . "frc=2";
|
||||
$url2 = $baseUrl . "amp=$value";
|
||||
break;
|
||||
case 3:
|
||||
$url2 = $baseUrl . ($value * 1000);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
|
||||
curl_setopt($ch, CURLOPT_USERPWD, $this->ReadPropertyString("Username") . ":" . $this->ReadPropertyString("Password"));
|
||||
break;
|
||||
case 4:
|
||||
// Nichts zu tun für Dummy station
|
||||
return;
|
||||
default:
|
||||
return "Invalid station type.";
|
||||
}
|
||||
|
||||
if (isset($url1)) {
|
||||
curl_setopt($ch, CURLOPT_URL, $url1);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
$response1 = curl_exec($ch);
|
||||
if (curl_errno($ch)) {
|
||||
curl_close($ch);
|
||||
return "Error:" . curl_error($ch);
|
||||
}
|
||||
}
|
||||
|
||||
curl_setopt($ch, CURLOPT_URL, $url2);
|
||||
$response2 = curl_exec($ch);
|
||||
if (curl_errno($ch)) {
|
||||
curl_close($ch);
|
||||
return "Error:" . curl_error($ch);
|
||||
}
|
||||
curl_close($ch);
|
||||
return;
|
||||
} else {
|
||||
return "Invalid value. Must be between 0 and 32.";
|
||||
}
|
||||
}
|
||||
|
||||
public function CheckIdle($power)
|
||||
{
|
||||
$lastpower = GetValue($this->GetIDForIdent("Aktuelle_Leistung"));
|
||||
if ($lastpower != $power) {
|
||||
$this->SetValue("Idle", false);
|
||||
$this->SetValue("IdleCounter",$this->ReadPropertyInteger("IdleCounterMax"));
|
||||
}
|
||||
// IdleCounter auslesen und verarbeiten
|
||||
$idleCounter = $this->GetValue("IdleCounter");
|
||||
if ($idleCounter > 0) {
|
||||
$this->SetValue("Idle", false);
|
||||
$this->SetValue("IdleCounter", $idleCounter - 1);
|
||||
} else {
|
||||
$this->SetValue("Idle", true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
?>
|
||||
@@ -22,6 +22,32 @@
|
||||
"name": "Netzbezug",
|
||||
"caption": "Variable mit dem zu regelnden Netzbezug"
|
||||
},
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "HauptmanagerAktiv",
|
||||
"caption": "Hauptmanager Aktiv"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "ManagerID",
|
||||
"caption": "Manager ID"
|
||||
},
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
"name": "DatenHoch",
|
||||
"caption": "Daten Hoch"
|
||||
},
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
"name": "DatenZuruck",
|
||||
"caption": "Daten Zurück"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Interval",
|
||||
"caption": "Intervall Neuberechnung der Werte",
|
||||
"suffix": "Sekunden"
|
||||
},
|
||||
{
|
||||
"type": "List",
|
||||
"name": "Verbraucher_Liste",
|
||||
|
||||
@@ -11,23 +11,51 @@ class Manager extends IPSModule
|
||||
$this->RegisterPropertyInteger("Ueberschussleistung", 0);
|
||||
$this->RegisterPropertyInteger("Netzbezug", 0); // Initialisierung mit 0
|
||||
$this->RegisterPropertyString("Verbraucher_Liste", "[]");
|
||||
$this->RegisterPropertyBoolean("HauptmanagerAktiv", false); // Initialisierung mit 0
|
||||
$this->RegisterPropertyInteger("ManagerID", 0); // Initialisierung mit 0
|
||||
$this->RegisterPropertyInteger("DatenHoch", 0); // Initialisierung mit 0
|
||||
$this->RegisterPropertyInteger("DatenZuruck", 0); // Initialisierung mit 0
|
||||
$this->RegisterPropertyInteger("Interval", 2); // Recheninterval
|
||||
|
||||
// Timer registrieren
|
||||
$this->RegisterTimer("Timer_DistributeEnergy",5000,"IPS_RequestAction(" .$this->InstanceID .', "DistributeEnergy", "");');
|
||||
// Timer registrieren
|
||||
|
||||
$this->RegisterTimer("Timer_DistributeEnergy",$this->ReadPropertyInteger("Interval")*1000,"IPS_RequestAction(" .$this->InstanceID .', "DistributeEnergy", "");');
|
||||
}
|
||||
|
||||
public function ApplyChanges()
|
||||
{
|
||||
parent::ApplyChanges();
|
||||
//Liste aller Verbraucher einlesen
|
||||
$Verbraucher_Liste = $this->ReadPropertyString("Verbraucher_Liste");
|
||||
$this->SetTimerInterval("Timer_DistributeEnergy",$this->ReadPropertyInteger("Interval")*1000);
|
||||
|
||||
}
|
||||
|
||||
public function RequestAction($Ident, $Value)
|
||||
{
|
||||
switch ($Ident) {
|
||||
case "DistributeEnergy":
|
||||
if($this->ReadPropertyBoolean("HauptmanagerAktiv")==true ){
|
||||
|
||||
$data = json_decode(GetValue($this->ReadPropertyInteger("DatenZuruck")), true);
|
||||
IPS_LogMessage("Manager", print_r($data));
|
||||
IPS_LogMessage("Manager", $data["timestamp"]);
|
||||
|
||||
if (isset($data["timestamp"])) {
|
||||
$timestamp = $data["timestamp"];
|
||||
$currentTime = time();
|
||||
IPS_LogMessage("Manager", ($currentTime - $timestamp));
|
||||
|
||||
if (($currentTime - $timestamp) < 3600) {
|
||||
$this->DistributeEnergy_Extern();
|
||||
}
|
||||
} else {
|
||||
$this->DistributeEnergy();
|
||||
}
|
||||
|
||||
}else{
|
||||
$this->DistributeEnergy();
|
||||
}
|
||||
|
||||
break;
|
||||
case "ApplyChanges":
|
||||
$this->ApplyChanges();
|
||||
@@ -52,6 +80,7 @@ class Manager extends IPSModule
|
||||
$remainingPower = $Peakleistung - $Netzbezug;
|
||||
$Is_Peak_Shaving = true;
|
||||
}
|
||||
IPS_LogMessage("Manag anfang", $remainingPower);
|
||||
|
||||
// Alle Energieverbraucher auslesen und dekodieren
|
||||
$Verbraucher_Liste = json_decode($this->ReadPropertyString("Verbraucher_Liste"), true);
|
||||
@@ -80,18 +109,18 @@ class Manager extends IPSModule
|
||||
foreach ($Verbraucher_Liste as $user) {
|
||||
if (!IPS_InstanceExists($user["Verbraucher"])) {
|
||||
IPS_LogMessage("Manager", "aufgerufen komisch");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Werte direkt von der Verbraucher-Instanz abrufen
|
||||
$Aktuelle_Leistung = GetValue(IPS_GetObjectIDByIdent("Aktuelle_Leistung", $user["Verbraucher"]));
|
||||
$Aktuelle_Leistung = GetValue(IPS_GetObjectIDByIdent("Power", $user["Verbraucher"])); // Aktuelle Leistung durch Power ersetzt
|
||||
$Bezogene_Energie = GetValue(IPS_GetObjectIDByIdent("Bezogene_Energie", $user["Verbraucher"]));
|
||||
$PV_Prio = GetValue(IPS_GetObjectIDByIdent("PV_Prio", $user["Verbraucher"]));
|
||||
$Sperre_Prio = GetValue(IPS_GetObjectIDByIdent("Sperre_Prio", $user["Verbraucher"]));
|
||||
$idle = GetValue(IPS_GetObjectIDByIdent("Idle", $user["Verbraucher"]));
|
||||
$powerStepsJson = GetValue(IPS_GetObjectIDByIdent("PowerSteps", $user["Verbraucher"]));
|
||||
$powerSteps = json_decode($powerStepsJson, true);
|
||||
$delta = GetValue(IPS_GetObjectIDByIdent("Leistung_Delta", $user["Verbraucher"]));
|
||||
|
||||
// Verbraucher-Daten zum gefilterten Array hinzufügen
|
||||
$filteredVerbraucher[] = [
|
||||
@@ -103,6 +132,7 @@ class Manager extends IPSModule
|
||||
"Sperre_Prio" => $Sperre_Prio,
|
||||
"Idle" => $idle,
|
||||
"PowerSteps" => $powerSteps,
|
||||
"Leistung_Delta" => $delta
|
||||
];
|
||||
|
||||
// Überprüfen, ob alle Benutzer Idle = true sind, wenn einer nicht ist, wird später verworfen...
|
||||
@@ -111,13 +141,18 @@ class Manager extends IPSModule
|
||||
IPS_LogMessage("Manager", "nciht idle");
|
||||
|
||||
}
|
||||
if(in_array(0, $powerSteps, true)){
|
||||
|
||||
// Addiere die aktuell bereits verwendete Leistung auf, um sie bei der verteilung zu berücksichtigen
|
||||
$totalAktuelle_Leistung += $Aktuelle_Leistung;
|
||||
$totalAktuelle_Leistung += ($Aktuelle_Leistung-$delta);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// Berücksichtigung der bereits verteilten Leistungen (nachher kann dafür wieder bei 0 begonnen werden zu verteilen)
|
||||
$remainingPower += $totalAktuelle_Leistung;
|
||||
|
||||
|
||||
// Abbrechen wenn es keine gefilterten User gibt
|
||||
if (empty($filteredVerbraucher)) {
|
||||
return;
|
||||
@@ -140,14 +175,13 @@ class Manager extends IPSModule
|
||||
$primaryKey = $Is_Peak_Shaving ? "Sperre_Prio" : "PV_Prio";
|
||||
// Wenn die Prio geleich ist, sortiere danach welcher verbraucher bisher am wenigsten Energie bekommen hat.
|
||||
if ($a[$primaryKey] == $b[$primaryKey]) {
|
||||
return $a["Bezogene_Energie"] <=> $b["Bezogene_Energie"];
|
||||
return round($a["Bezogene_Energie"]/2000) <=> round($b["Bezogene_Energie"]/2000);
|
||||
}
|
||||
return $a[$primaryKey] <=> $b[$primaryKey];
|
||||
});
|
||||
|
||||
// Primärschlüssel für die Priorität basierend auf dem Parameter auswählen (für sortierung in gruppen anschliessend)
|
||||
$priorityKey = $Is_Peak_Shaving ? "Sperre_Prio" : "PV_Prio";
|
||||
|
||||
// Schleife durch alle Prioritäten
|
||||
$priorities = array_unique(
|
||||
array_column($filteredVerbraucher, $priorityKey)
|
||||
@@ -177,7 +211,7 @@ class Manager extends IPSModule
|
||||
$withoutZero = [];
|
||||
// Verbraucher die nicht 0 Annhemen können, bekommen einfach den tiefsten wert
|
||||
foreach ($samePriorityUsers as $entry) {
|
||||
if (in_array(0, $entry["PowerSteps"])) {
|
||||
if (min($entry["PowerSteps"]) <= 0) {
|
||||
$withZero[] = $entry;
|
||||
} else {
|
||||
$withoutZero[] = $entry;
|
||||
@@ -190,69 +224,149 @@ class Manager extends IPSModule
|
||||
$minPowerStep = min($entry["PowerSteps"]);
|
||||
|
||||
IPS_RequestAction($instanceID,"SetAktuelle_Leistung",$minPowerStep);
|
||||
$remainingPower -= $entry["Aktuelle_Leistung"];
|
||||
//$remainingPower -= $entry["Aktuelle_Leistung"];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Nun die verteilen, die 0 erhalten können.
|
||||
$samePriorityUsers = $withZero;
|
||||
// Array für die verteilte Energie pro User erstellen
|
||||
|
||||
$userEnergyProv = [];
|
||||
$userEnergyProv = array_fill_keys(array_column($samePriorityUsers, "InstanceID"), 0); // Initialisierung für jeden Benutzer auf 0 setzen
|
||||
|
||||
// Alle Schritte der Benutzer in einem Array sammeln
|
||||
$allSteps = [];
|
||||
foreach ($samePriorityUsers as $user) {
|
||||
foreach ($user["PowerSteps"] as $step) {
|
||||
$allSteps[] = [
|
||||
"user" => $user["InstanceID"],
|
||||
"step" => $step,
|
||||
];
|
||||
IPS_LogMessage("Manag", $remainingPower);
|
||||
|
||||
if($remainingPower>=0){
|
||||
// Alle Schritte der Benutzer in einem Array sammeln
|
||||
$allSteps = [];
|
||||
foreach ($samePriorityUsers as $user) {
|
||||
foreach ($user["PowerSteps"] as $step) {
|
||||
if($step>=0){
|
||||
$allSteps[] = [
|
||||
"user" => $user["InstanceID"],
|
||||
//"Leistung_Delta" => $user["Leistung_Delta"],
|
||||
"step" => $step,
|
||||
];}
|
||||
}
|
||||
}
|
||||
|
||||
// Sortiere die Schritte nach Größe
|
||||
usort($allSteps, function ($a, $b) {
|
||||
return $a["step"] <=> $b["step"];
|
||||
});
|
||||
|
||||
//if remaining power >0
|
||||
// Iteriere durch alle Schritte
|
||||
foreach ($allSteps as $entry) {
|
||||
$user = $entry["user"];
|
||||
$powerstep = $entry["step"];
|
||||
|
||||
// Überprüfe, ob noch genügend verbleibende Energie für den nächsten Schritt vorhanden ist
|
||||
if ($remainingPower >= $powerstep - $userEnergyProv[$user]) { // oder bedingung testen
|
||||
// Aktualisiere die verbleibende Energie und die bereitgestellte Energie für den Benutzer
|
||||
$remainingPower -= $powerstep - $userEnergyProv[$user];
|
||||
$userEnergyProv[$user] = $powerstep;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//else
|
||||
|
||||
|
||||
// mache invertierte verteilung
|
||||
|
||||
|
||||
// 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"
|
||||
)
|
||||
);
|
||||
|
||||
// Jedem user den höheren der beiden werte aus minimalwert oder vergebenem zuteilen
|
||||
$leistung = max($leistung, $minimalleitsung);
|
||||
|
||||
|
||||
|
||||
// Methode SetAktuelle_Leistung für jeden Verbraucher mit der entsprechenden Energie aufrufen
|
||||
if (IPS_InstanceExists($userInstanceID)) {
|
||||
IPS_RequestAction($userInstanceID,"SetAktuelle_Leistung",$leistung);
|
||||
IPS_LogMessage("Manager", "aufgerufen setleistung if". $leistung);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
// Alle Schritte der Benutzer in einem Array sammeln
|
||||
$allSteps = [];
|
||||
foreach ($samePriorityUsers as $user) {
|
||||
foreach ($user["PowerSteps"] as $step) {
|
||||
if($step<=0){
|
||||
$allSteps[] = [
|
||||
"user" => $user["InstanceID"],
|
||||
"Leistung_Delta" => $user["Leistung_Delta"],
|
||||
"step" => -1*$step,
|
||||
];}
|
||||
}
|
||||
}
|
||||
|
||||
// Sortiere die Schritte nach Größe
|
||||
usort($allSteps, function ($a, $b) {
|
||||
return $a["step"] <=> $b["step"];
|
||||
});
|
||||
|
||||
|
||||
$remainingPower = $remainingPower *-1;
|
||||
// Iteriere durch alle Schritte
|
||||
foreach ($allSteps as $entry) {
|
||||
$user = $entry["user"];
|
||||
$powerstep = $entry["step"];
|
||||
|
||||
// Überprüfe, ob noch genügend verbleibende Energie für den nächsten Schritt vorhanden ist
|
||||
if ($remainingPower >= $powerstep - $userEnergyProv[$user]) { // oder bedingung testen
|
||||
// Aktualisiere die verbleibende Energie und die bereitgestellte Energie für den Benutzer
|
||||
$remainingPower -= $powerstep - $userEnergyProv[$user];
|
||||
$userEnergyProv[$user] = $powerstep;
|
||||
}
|
||||
|
||||
}
|
||||
$remainingPower = $remainingPower *-1;
|
||||
|
||||
|
||||
// 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"
|
||||
)
|
||||
);
|
||||
|
||||
// Jedem user den höheren der beiden werte aus minimalwert oder vergebenem zuteilen
|
||||
$schreibleistung = max($leistung, $minimalleitsung)*-1;
|
||||
|
||||
|
||||
|
||||
// Methode SetAktuelle_Leistung für jeden Verbraucher mit der entsprechenden Energie aufrufen
|
||||
if (IPS_InstanceExists($userInstanceID)) {
|
||||
IPS_RequestAction($userInstanceID,"SetAktuelle_Leistung",$schreibleistung);
|
||||
IPS_LogMessage("Manager", "aufgerufen setleistung else ".$schreibleistung);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sortiere die Schritte nach Größe
|
||||
usort($allSteps, function ($a, $b) {
|
||||
return $a["step"] <=> $b["step"];
|
||||
});
|
||||
|
||||
// Iteriere durch alle Schritte
|
||||
foreach ($allSteps as $entry) {
|
||||
$user = $entry["user"];
|
||||
$powerstep = $entry["step"];
|
||||
|
||||
// Überprüfe, ob noch genügend verbleibende Energie für den nächsten Schritt vorhanden ist
|
||||
if ($remainingPower >= $powerstep - $userEnergyProv[$user]) {
|
||||
// Aktualisiere die verbleibende Energie und die bereitgestellte Energie für den Benutzer
|
||||
$remainingPower -= $powerstep - $userEnergyProv[$user];
|
||||
$userEnergyProv[$user] = $powerstep;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 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"
|
||||
)
|
||||
);
|
||||
|
||||
// Jedem user den höheren der beiden werte aus minimalwert oder vergebenem zuteilen
|
||||
$leistung = max($leistung, $minimalleitsung);
|
||||
|
||||
// Methode SetAktuelle_Leistung für jeden Verbraucher mit der entsprechenden Energie aufrufen
|
||||
if (IPS_InstanceExists($userInstanceID)) {
|
||||
IPS_RequestAction($userInstanceID,"SetAktuelle_Leistung",$leistung);
|
||||
IPS_LogMessage("Manager", "aufgerufen setleistung normal");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -260,5 +374,72 @@ class Manager extends IPSModule
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function DistributeEnergy_Extern()
|
||||
{
|
||||
// Systemvariablen abrufen
|
||||
$Netzbezug = GetValue($this->ReadPropertyInteger("Netzbezug"));
|
||||
|
||||
|
||||
$Verbraucher_Liste = json_decode($this->ReadPropertyString("Verbraucher_Liste"), true);
|
||||
$filteredVerbraucher = [];
|
||||
// Fülle das Array mit allen entsprechenden Werten der Verbraucher ab
|
||||
foreach ($Verbraucher_Liste as $user) {
|
||||
|
||||
|
||||
// Werte direkt von der Verbraucher-Instanz abrufen
|
||||
$Aktuelle_Leistung = GetValue(IPS_GetObjectIDByIdent("Aktuelle_Leistung", $user["Verbraucher"]));
|
||||
$Bezogene_Energie = GetValue(IPS_GetObjectIDByIdent("Bezogene_Energie", $user["Verbraucher"]));
|
||||
$PV_Prio = GetValue(IPS_GetObjectIDByIdent("PV_Prio", $user["Verbraucher"]));
|
||||
$Sperre_Prio = GetValue(IPS_GetObjectIDByIdent("Sperre_Prio", $user["Verbraucher"]));
|
||||
$idle = GetValue(IPS_GetObjectIDByIdent("Idle", $user["Verbraucher"]));
|
||||
$powerStepsJson = GetValue(IPS_GetObjectIDByIdent("PowerSteps", $user["Verbraucher"]));
|
||||
$delta = GetValue(IPS_GetObjectIDByIdent("Leistung_Delta", $user["Verbraucher"]));
|
||||
$powerSteps = json_decode($powerStepsJson, true);
|
||||
|
||||
// Verbraucher-Daten zum gefilterten Array hinzufügen
|
||||
$filteredVerbraucher[] = [
|
||||
"Verbraucher" => $user["Verbraucher"],
|
||||
"InstanceID" => $user["Verbraucher"],
|
||||
"Aktuelle_Leistung" => $Aktuelle_Leistung,
|
||||
"Bezogene_Energie" => $Bezogene_Energie,
|
||||
"PV_Prio" => $PV_Prio,
|
||||
"Sperre_Prio" => $Sperre_Prio,
|
||||
"Idle" => $idle,
|
||||
"PowerSteps" => $powerSteps,
|
||||
"Leistung_Delta" => $delta,
|
||||
"ParentManager" => $this->ReadPropertyInteger("ManagerID")
|
||||
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
|
||||
$sendarray = [];
|
||||
|
||||
$sendarray = [
|
||||
"Users" => $filteredVerbraucher,
|
||||
"Netzbezug" => $Netzbezug,
|
||||
"Timestamp" => time()
|
||||
|
||||
];
|
||||
|
||||
RequestAction($this->ReadPropertyInteger("DatenHoch"), json_encode($sendarray));
|
||||
|
||||
$answerArray = json_decode(GetValue($this->ReadPropertyInteger("DatenZuruck")), true);
|
||||
|
||||
foreach($answerArray["User"] as $user){
|
||||
IPS_RequestAction($user["InstanceID"],"GetCurrentData", $answerArray["Is_Peak_Shaving"]);
|
||||
|
||||
IPS_RequestAction($user["InstanceID"],"SetAktuelle_Leistung",$user["Set_Leistung"]);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -8,9 +8,15 @@
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "IdleCounterMax",
|
||||
"caption": "Zyklen zwischen zwei Leisutungsänderungen",
|
||||
"caption": "Zyklen zwischen zwei Leistungsänderungen (Multipliziert sich mit Interval)",
|
||||
"suffix": ""
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Interval",
|
||||
"caption": "Intervall Neuberechnung der Werte Erst für spätere Versionen, aktuell auf 5 lassen!",
|
||||
"suffix": "Sekunden"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Mindesttlaufzeit",
|
||||
|
||||
@@ -12,6 +12,7 @@ class Verbraucher_1_Stufig extends IPSModule
|
||||
$this->RegisterPropertyInteger("Mindesttlaufzeit", 4); // Standardwert für Volllast
|
||||
$this->RegisterPropertyInteger("Zeit_Zwischen_Zustandswechseln", 1);
|
||||
$this->RegisterPropertyInteger("Schaltkontakt1", 0);
|
||||
$this->RegisterPropertyInteger("Interval", 5); // Recheninterval
|
||||
|
||||
// Verbraucherspezifische Variabeln
|
||||
$this->RegisterVariableBoolean("IstNacht", "IstNacht", "", 0);
|
||||
@@ -31,6 +32,7 @@ class Verbraucher_1_Stufig extends IPSModule
|
||||
$this->RegisterVariableString("PowerSteps", "PowerSteps");
|
||||
$this->RegisterVariableInteger("Power", "Power");
|
||||
$this->RegisterVariableBoolean("Is_Peak_Shaving", "Is_Peak_Shaving");
|
||||
$this->RegisterVariableInteger("Leistung_Delta", "Leistung_Delta", "", 0);
|
||||
|
||||
// Hilfsvariabeln für Idle zustand
|
||||
$this->RegisterPropertyInteger("IdleCounterMax", 2);
|
||||
@@ -40,13 +42,15 @@ class Verbraucher_1_Stufig extends IPSModule
|
||||
// Initialisiere Idle
|
||||
$this->SetValue("Idle", true);
|
||||
|
||||
$this->RegisterTimer("Timer_Do_UserCalc",5000,"IPS_RequestAction(" .$this->InstanceID .', "Do_UserCalc", "");');
|
||||
$this->RegisterTimer("Timer_Do_UserCalc_Verb",$this->ReadPropertyInteger("Interval")*1000,"IPS_RequestAction(" .$this->InstanceID .', "Do_UserCalc", "");');
|
||||
|
||||
}
|
||||
|
||||
public function ApplyChanges()
|
||||
{
|
||||
parent::ApplyChanges();
|
||||
$this->SetTimerInterval("Timer_Do_UserCalc_Verb",$this->ReadPropertyInteger("Interval")*1000);
|
||||
|
||||
}
|
||||
|
||||
public function RequestAction($Ident, $Value)
|
||||
@@ -77,6 +81,7 @@ class Verbraucher_1_Stufig extends IPSModule
|
||||
|
||||
|
||||
|
||||
|
||||
// Methode zum Setzen der PowerSteps und Timer starten
|
||||
public function SetTimerOn()
|
||||
{
|
||||
@@ -117,6 +122,8 @@ class Verbraucher_1_Stufig extends IPSModule
|
||||
$this->SetTimerOn();
|
||||
}
|
||||
$this->SetValue("Aktuelle_Leistung", $power);
|
||||
$this->SetValue("Bezogene_Energie", ($this->GetValue("Bezogene_Energie") + ($this->GetValue("Aktuelle_Leistung")*($this->ReadPropertyInteger("Interval")/3600))));
|
||||
|
||||
$boilerLeistung = $this->ReadPropertyInteger("BoilerLeistung");
|
||||
$schaltkontaktID = $this->ReadPropertyInteger("Schaltkontakt1");
|
||||
|
||||
|
||||
67
Verbraucher_Sperrbar/README.md
Normal file
67
Verbraucher_Sperrbar/README.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# Manager_1
|
||||
Beschreibung des Moduls.
|
||||
|
||||
### 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)
|
||||
|
||||
### 1. Funktionsumfang
|
||||
|
||||
*
|
||||
|
||||
### 2. Voraussetzungen
|
||||
|
||||
- IP-Symcon ab Version 7.1
|
||||
|
||||
### 3. Software-Installation
|
||||
|
||||
* Über den Module Store das 'Manager_1'-Modul installieren.
|
||||
* Alternativ über das Module Control folgende URL hinzufügen
|
||||
|
||||
### 4. Einrichten der Instanzen in IP-Symcon
|
||||
|
||||
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__:
|
||||
|
||||
Name | Beschreibung
|
||||
-------- | ------------------
|
||||
|
|
||||
|
|
||||
|
||||
### 5. Statusvariablen und Profile
|
||||
|
||||
Die Statusvariablen/Kategorien werden automatisch angelegt. Das Löschen einzelner kann zu Fehlfunktionen führen.
|
||||
|
||||
#### Statusvariablen
|
||||
|
||||
Name | Typ | Beschreibung
|
||||
------ | ------- | ------------
|
||||
| |
|
||||
| |
|
||||
|
||||
#### Profile
|
||||
|
||||
Name | Typ
|
||||
------ | -------
|
||||
|
|
||||
|
|
||||
|
||||
### 6. WebFront
|
||||
|
||||
Die Funktionalität, die das Modul im WebFront bietet.
|
||||
|
||||
### 7. PHP-Befehlsreferenz
|
||||
|
||||
`boolean GEF_BeispielFunktion(integer $InstanzID);`
|
||||
Erklärung der Funktion.
|
||||
|
||||
Beispiel:
|
||||
`GEF_BeispielFunktion(12345);`
|
||||
52
Verbraucher_Sperrbar/form.json
Normal file
52
Verbraucher_Sperrbar/form.json
Normal file
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"elements": [
|
||||
{
|
||||
"type": "Label",
|
||||
"caption": "Einstellungen für einstufigen Verbruacher Ein-Aus"
|
||||
},
|
||||
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "IdleCounterMax",
|
||||
"caption": "Zyklen zwischen zwei Leistungsänderungen (Multipliziert sich mit Interval)",
|
||||
"suffix": " Zyklen"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Interval",
|
||||
"caption": "Intervall Neuberechnung der Werte ",
|
||||
"suffix": "Sekunden"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Mindestsperrleistung",
|
||||
"caption": "Minimaler Leistungswert um eine Sperre zu starten",
|
||||
"suffix": "Watt"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "MaxSperrZeit",
|
||||
"caption": "Maximale Sperrzeit Verbraucher pro Tag",
|
||||
"suffix": ""
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Zeit_Zwischen_Zustandswechseln",
|
||||
"caption": "Mindestlaufzeit des Verbrauchers bei Lastschaltung",
|
||||
"suffix": ""
|
||||
},
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
"name": "Leistung",
|
||||
"caption": "Variable mit aktueller Leistung des Verbrauchers",
|
||||
"suffix": ""
|
||||
},
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
"name": "Schaltkontakt1",
|
||||
"caption": "Zu schaltenden Kontakt für Sperre",
|
||||
"test": true
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
12
Verbraucher_Sperrbar/module.json
Normal file
12
Verbraucher_Sperrbar/module.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"id": "{0A15319E-AC03-0E5A-33B4-A46BB9330B17}",
|
||||
"name": "Verbraucher_Sperrbar",
|
||||
"type": 3,
|
||||
"vendor": "Belevo AG",
|
||||
"aliases": [],
|
||||
"parentRequirements": [],
|
||||
"childRequirements": [],
|
||||
"implemented": [],
|
||||
"prefix": "GEF",
|
||||
"url": ""
|
||||
}
|
||||
220
Verbraucher_Sperrbar/module.php
Normal file
220
Verbraucher_Sperrbar/module.php
Normal file
@@ -0,0 +1,220 @@
|
||||
<?php
|
||||
class Verbraucher_Sperrbar extends IPSModule
|
||||
{
|
||||
private $timerID;
|
||||
|
||||
public function Create()
|
||||
{
|
||||
parent::Create();
|
||||
|
||||
// Verbraucherspezifische Properties
|
||||
$this->RegisterPropertyInteger("Leistung", 0); // Standardwert für Volllast
|
||||
$this->RegisterPropertyInteger("MaxSperrZeit", 4);
|
||||
$this->RegisterPropertyInteger("Zeit_Zwischen_Zustandswechseln", 1);
|
||||
$this->RegisterPropertyInteger("Schaltkontakt1", 0);
|
||||
$this->RegisterPropertyInteger("Interval", 5); // Recheninterval
|
||||
$this->RegisterPropertyInteger("Mindestsperrleistung", 100);
|
||||
|
||||
|
||||
// Verbraucherspezifische Variabeln
|
||||
$this->RegisterVariableInteger("DailyOnTime", "DailyOnTime", "", 0);
|
||||
$this->RegisterVariableBoolean("IsTimerActive", "IsTimerActive", "", 0);
|
||||
$this->RegisterVariableBoolean("IstNacht", "IstNacht", "", 0);
|
||||
$this->RegisterVariableInteger("Letzte_Sperrleistung", "Letzte_Sperrleistung", "", 0);
|
||||
|
||||
|
||||
// Verbraucherspezifischer Timer
|
||||
$this->SetValue("IsTimerActive", false);
|
||||
$this->RegisterTimer("ZustandswechselTimer",0,"IPS_RequestAction(" .$this->InstanceID .', "ResetTimer", "");');
|
||||
|
||||
// Variabeln für Kommunkation mit Manager
|
||||
$this->RegisterVariableInteger("Sperre_Prio", "Sperre_Prio");
|
||||
$this->RegisterVariableInteger("PV_Prio", "PV_Prio");
|
||||
$this->RegisterVariableBoolean("Idle", "Idle", "", 0);
|
||||
$this->RegisterVariableInteger("Aktuelle_Leistung", "Aktuelle_Leistung", "", 0);
|
||||
$this->RegisterVariableFloat("Bezogene_Energie", "Bezogene_Energie", "", 0);
|
||||
$this->RegisterVariableString("PowerSteps", "PowerSteps");
|
||||
$this->RegisterVariableInteger("Power", "Power");
|
||||
$this->RegisterVariableBoolean("Is_Peak_Shaving", "Is_Peak_Shaving");
|
||||
$this->RegisterVariableInteger("Leistung_Delta", "Leistung_Delta", "", 0);
|
||||
|
||||
// Hilfsvariabeln für Idle zustand
|
||||
$this->RegisterPropertyInteger("IdleCounterMax", 2);
|
||||
$this->RegisterVariableInteger("IdleCounter", "IdleCounter", "", 0);
|
||||
$this->SetValue("IdleCounter", 0);
|
||||
|
||||
// Initialisiere Idle
|
||||
$this->SetValue("Idle", true);
|
||||
|
||||
$this->RegisterTimer("Timer_Do_UserCalc_Verb",$this->ReadPropertyInteger("Interval")*1000,"IPS_RequestAction(" .$this->InstanceID .', "Do_UserCalc", "");');
|
||||
|
||||
}
|
||||
|
||||
public function ApplyChanges()
|
||||
{
|
||||
parent::ApplyChanges();
|
||||
$this->SetTimerInterval("Timer_Do_UserCalc_Verb",$this->ReadPropertyInteger("Interval")*1000);
|
||||
}
|
||||
|
||||
public function RequestAction($Ident, $Value)
|
||||
{
|
||||
switch ($Ident) {
|
||||
|
||||
case "SetAktuelle_Leistung":
|
||||
$this->SetValue("Power", (int)$Value);
|
||||
break;
|
||||
|
||||
case "GetCurrentData":
|
||||
$this->SetValue("Is_Peak_Shaving", (bool)$Value);
|
||||
break;
|
||||
|
||||
case "ResetTimer":
|
||||
$this->ResetTimer();
|
||||
break;
|
||||
|
||||
case "Do_UserCalc":
|
||||
$this->SetAktuelle_Leistung($this->GetValue("Power"));
|
||||
$this->GetCurrentData($this->GetValue("Is_Peak_Shaving"));
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Exception("Invalid Ident");
|
||||
}
|
||||
}
|
||||
|
||||
// Methode zum Setzen der PowerSteps und Timer starten
|
||||
public function SetTimerOn()
|
||||
{
|
||||
// Timer setzen, der nach "Zeit_Zwischen_Zustandswechseln" abläuft
|
||||
$zeitZwischenZustandswechseln = $this->ReadPropertyInteger("Zeit_Zwischen_Zustandswechseln");
|
||||
|
||||
if($zeitZwischenZustandswechseln>0){
|
||||
$this->SetTimerInterval("ZustandswechselTimer", $zeitZwischenZustandswechseln * 60000); // Timer in Millisekunden
|
||||
// Timer-Status auf true setzen
|
||||
$this->SetValue("IsTimerActive", true);
|
||||
}else{
|
||||
$this->SetValue("IsTimerActive", false);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Methode zum Zurücksetzen von PowerSteps nach Ablauf des Timers
|
||||
public function ResetTimer()
|
||||
{
|
||||
// Timer stoppen
|
||||
$this->SetTimerInterval("ZustandswechselTimer", 0);
|
||||
|
||||
// Timer-Status auf false setzen
|
||||
$this->SetValue("IsTimerActive", false);
|
||||
}
|
||||
|
||||
// Methode zum Setzen des aktuellen Stromverbrauchs
|
||||
public function SetAktuelle_Leistung(float $power)
|
||||
{
|
||||
// Hier eine Leistungsänderung detektieren für Idle und interne Mindestlaufzeiten
|
||||
$this->CheckIdle($power);
|
||||
if ($this->GetValue("Aktuelle_Leistung") != $power) {
|
||||
$this->SetTimerOn();
|
||||
}
|
||||
$this->SetValue("Aktuelle_Leistung", $power);
|
||||
|
||||
// Verbrauchte Energie berechnen
|
||||
$this->SetValue("Bezogene_Energie", ($this->GetValue("Bezogene_Energie") + ($this->GetValue("Aktuelle_Leistung")*($this->ReadPropertyInteger("Interval")/3600))));
|
||||
|
||||
$Leistung = GetValue($this->ReadPropertyInteger("Leistung"));
|
||||
$schaltkontaktID = $this->ReadPropertyInteger("Schaltkontakt1");
|
||||
|
||||
|
||||
if ($this->GetValue("Is_Peak_Shaving") == false) {
|
||||
$schaltkontaktStatus = false;
|
||||
} elseif($power==0 && ((GetValue($schaltkontaktID)==true)||($Leistung>=$this->ReadPropertyInteger("Mindestsperrleistung")))){
|
||||
$schaltkontaktStatus = true;
|
||||
}else{
|
||||
$schaltkontaktStatus = false;
|
||||
}
|
||||
|
||||
// Schaltkontaktstatus ändern
|
||||
SetValue($this->ReadPropertyInteger("Schaltkontakt1"), $schaltkontaktStatus);
|
||||
|
||||
if ($schaltkontaktStatus==true) {
|
||||
$this->SetValue("DailyOnTime", $this->GetValue("DailyOnTime") + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Methode zum Abrufen der aktuellen Daten
|
||||
public function GetCurrentData(bool $Peak)
|
||||
{
|
||||
$IstNacht = $this->GetValue("IstNacht");
|
||||
$NeuesIstNacht = $this->ist_nachts();
|
||||
|
||||
if ($IstNacht == false && $NeuesIstNacht == true) {
|
||||
$this->SetValue("DailyOnTime", 0);
|
||||
}
|
||||
|
||||
$this->SetValue("IstNacht", $NeuesIstNacht);
|
||||
|
||||
if(GetValue($this->ReadPropertyInteger("Leistung"))>=$this->ReadPropertyInteger("Mindestsperrleistung")){
|
||||
$this->SetValue("Letzte_Sperrleistung", GetValue($this->ReadPropertyInteger("Leistung"))) ;
|
||||
}
|
||||
|
||||
// Überprüfen, ob der Timer aktiv ist
|
||||
if ($this->GetValue("IsTimerActive")) {
|
||||
// Timer ist aktiv, PowerSteps setzen
|
||||
$this->SetValue("PowerSteps", json_encode([$this->GetValue("Aktuelle_Leistung")]));
|
||||
return;
|
||||
}
|
||||
|
||||
$DailyOnTime = $this->GetValue("DailyOnTime");
|
||||
$maxlaufzeit = $this->ReadPropertyInteger("MaxSperrZeit") * 60 * 60 / $this->ReadPropertyInteger("Interval");
|
||||
|
||||
if($Peak==false){
|
||||
$this->SetValue("PowerSteps",json_encode([0]));
|
||||
} // Wenn Maxlaufzeit nicht erreicht ist
|
||||
elseif($DailyOnTime < $maxlaufzeit) {
|
||||
if((GetValue($this->ReadPropertyInteger("Leistung"))>=$this->ReadPropertyInteger("Mindestsperrleistung")) || GetValue($this->ReadPropertyInteger("Schaltkontakt1"))==true) {
|
||||
$this->SetValue("PowerSteps", json_encode([0, (int)$this->GetValue("Letzte_Sperrleistung")]));
|
||||
} else {
|
||||
$this->SetValue("PowerSteps",json_encode([0]));
|
||||
}
|
||||
}
|
||||
// Andernfalls
|
||||
else {
|
||||
$this->SetValue("PowerSteps",json_encode([$this->GetValue("Letzte_Sperrleistung")]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function CheckIdle($power)
|
||||
{
|
||||
$lastpower = GetValue($this->GetIDForIdent("Aktuelle_Leistung"));
|
||||
if ($lastpower != $power) {
|
||||
$this->SetValue("Idle", false);
|
||||
$this->SetValue("IdleCounter",$this->ReadPropertyInteger("IdleCounterMax"));
|
||||
}
|
||||
// IdleCounter auslesen und verarbeiten
|
||||
$idleCounter = $this->GetValue("IdleCounter");
|
||||
if ($idleCounter > 0) {
|
||||
$this->SetValue("Idle", false);
|
||||
$this->SetValue("IdleCounter", $idleCounter - 1);
|
||||
} else {
|
||||
$this->SetValue("Idle", true);
|
||||
}
|
||||
}
|
||||
|
||||
private function ist_nachts()
|
||||
{
|
||||
date_default_timezone_set("Europe/Berlin"); // Setze hier deine Zeitzone
|
||||
|
||||
$aktuelle_zeit = strtotime(date("H:i")); // Aktuelle Zeit in Stunden und Minuten umwandeln
|
||||
$start_nacht = strtotime("24:00"); // Startzeit der Nacht (22 Uhr)
|
||||
$ende_nacht = strtotime("07:00"); // Endzeit der Nacht (7 Uhr)
|
||||
|
||||
if ($aktuelle_zeit >= $start_nacht || $aktuelle_zeit < $ende_nacht) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
67
Verbraucher_extern/README.md
Normal file
67
Verbraucher_extern/README.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# Manager_1
|
||||
Beschreibung des Moduls.
|
||||
|
||||
### 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)
|
||||
|
||||
### 1. Funktionsumfang
|
||||
|
||||
*
|
||||
|
||||
### 2. Voraussetzungen
|
||||
|
||||
- IP-Symcon ab Version 7.1
|
||||
|
||||
### 3. Software-Installation
|
||||
|
||||
* Über den Module Store das 'Manager_1'-Modul installieren.
|
||||
* Alternativ über das Module Control folgende URL hinzufügen
|
||||
|
||||
### 4. Einrichten der Instanzen in IP-Symcon
|
||||
|
||||
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__:
|
||||
|
||||
Name | Beschreibung
|
||||
-------- | ------------------
|
||||
|
|
||||
|
|
||||
|
||||
### 5. Statusvariablen und Profile
|
||||
|
||||
Die Statusvariablen/Kategorien werden automatisch angelegt. Das Löschen einzelner kann zu Fehlfunktionen führen.
|
||||
|
||||
#### Statusvariablen
|
||||
|
||||
Name | Typ | Beschreibung
|
||||
------ | ------- | ------------
|
||||
| |
|
||||
| |
|
||||
|
||||
#### Profile
|
||||
|
||||
Name | Typ
|
||||
------ | -------
|
||||
|
|
||||
|
|
||||
|
||||
### 6. WebFront
|
||||
|
||||
Die Funktionalität, die das Modul im WebFront bietet.
|
||||
|
||||
### 7. PHP-Befehlsreferenz
|
||||
|
||||
`boolean GEF_BeispielFunktion(integer $InstanzID);`
|
||||
Erklärung der Funktion.
|
||||
|
||||
Beispiel:
|
||||
`GEF_BeispielFunktion(12345);`
|
||||
76
Verbraucher_extern/form.json
Normal file
76
Verbraucher_extern/form.json
Normal file
@@ -0,0 +1,76 @@
|
||||
{
|
||||
"elements": [
|
||||
{
|
||||
"type": "Label",
|
||||
"caption": "Einstellungen für einstufigen Verbruacher Ein-Aus"
|
||||
},
|
||||
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "IdleCounterMax",
|
||||
"caption": "Zyklen zwischen zwei Leistungsänderungen (Multipliziert sich mit Interval)",
|
||||
"suffix": ""
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Interval",
|
||||
"caption": "Intervall Neuberechnung der Werte Erst für spätere Versionen",
|
||||
"suffix": "Sekunden"
|
||||
},
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
"name": "Is_Peak",
|
||||
"caption": "Variable zur Signalisierung der Peakleistung",
|
||||
"suffix": ""
|
||||
},
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
"name": "delta_power",
|
||||
"caption": "Variable mit dem Leistungsunterschied",
|
||||
"suffix": ""
|
||||
},
|
||||
{
|
||||
"type": "List",
|
||||
"name": "Verbraucher_Liste",
|
||||
"caption": "Verbraucher, die gemanagt werden sollen.",
|
||||
"add": true,
|
||||
"delete": true,
|
||||
"sortable": true,
|
||||
"columns": [
|
||||
{
|
||||
"caption": "Anfragende Variable",
|
||||
"name": "Read_Var",
|
||||
"width": "auto",
|
||||
"add": 0,
|
||||
"edit": {
|
||||
"type": "SelectVariable",
|
||||
"filter": "Verbraucher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": "Zu schreibende Variable",
|
||||
"name": "Write_Var",
|
||||
"width": "auto",
|
||||
"add": 0,
|
||||
"edit": {
|
||||
"type": "SelectVariable",
|
||||
"filter": "Verbraucher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "P_Nenn",
|
||||
"width": "auto",
|
||||
"add": 0,
|
||||
"edit": {
|
||||
"type": "NumberSpinner"
|
||||
},
|
||||
"caption": "Nennleistung des Verbrauchers",
|
||||
"test": true
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
12
Verbraucher_extern/module.json
Normal file
12
Verbraucher_extern/module.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"id": "{E3D14937-80F8-5728-A3D7-991EA2DBC2D4}",
|
||||
"name": "Verbraucher_extern",
|
||||
"type": 3,
|
||||
"vendor": "Belevo AG",
|
||||
"aliases": [],
|
||||
"parentRequirements": [],
|
||||
"childRequirements": [],
|
||||
"implemented": [],
|
||||
"prefix": "GEF",
|
||||
"url": ""
|
||||
}
|
||||
173
Verbraucher_extern/module.php
Normal file
173
Verbraucher_extern/module.php
Normal file
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
class Verbraucher_extern extends IPSModule
|
||||
{
|
||||
private $timerID;
|
||||
|
||||
public function Create()
|
||||
{
|
||||
parent::Create();
|
||||
|
||||
// Verbraucherspezifische Properties
|
||||
$this->RegisterPropertyString("Verbraucher_Liste", "[]");
|
||||
$this->RegisterPropertyInteger("Is_Peak", 0);
|
||||
$this->RegisterPropertyInteger("delta_power", 0);
|
||||
$this->RegisterPropertyInteger("Interval", 5); // Recheninterval
|
||||
|
||||
// Variabeln für Kommunkation mit Manager
|
||||
$this->RegisterVariableInteger("Sperre_Prio", "Sperre_Prio");
|
||||
$this->RegisterVariableInteger("PV_Prio", "PV_Prio");
|
||||
$this->RegisterVariableBoolean("Idle", "Idle", "", 0);
|
||||
$this->RegisterVariableInteger("Aktuelle_Leistung", "Aktuelle_Leistung", "", 0);
|
||||
$this->RegisterVariableFloat("Bezogene_Energie", "Bezogene_Energie", "", 0);
|
||||
$this->RegisterVariableString("PowerSteps", "PowerSteps");
|
||||
$this->RegisterVariableInteger("Power", "Power");
|
||||
$this->RegisterVariableBoolean("Is_Peak_Shaving", "Is_Peak_Shaving");
|
||||
$this->RegisterVariableInteger("Leistung_Delta", "Leistung_Delta", "", 0);
|
||||
|
||||
|
||||
// Hilfsvariabeln für Idle zustand
|
||||
$this->RegisterPropertyInteger("IdleCounterMax", 2);
|
||||
$this->RegisterVariableInteger("IdleCounter", "IdleCounter", "", 0);
|
||||
$this->SetValue("IdleCounter", 0);
|
||||
|
||||
// Initialisiere Idle
|
||||
$this->SetValue("Idle", true);
|
||||
|
||||
$this->RegisterTimer("Timer_Do_UserCalc_Verb",$this->ReadPropertyInteger("Interval")*1000,"IPS_RequestAction(" .$this->InstanceID .', "Do_UserCalc", "");');
|
||||
|
||||
}
|
||||
|
||||
public function ApplyChanges()
|
||||
{
|
||||
parent::ApplyChanges();
|
||||
$this->SetTimerInterval("Timer_Do_UserCalc_Verb",$this->ReadPropertyInteger("Interval")*1000);
|
||||
|
||||
}
|
||||
|
||||
public function RequestAction($Ident, $Value)
|
||||
{
|
||||
switch ($Ident) {
|
||||
|
||||
case "SetAktuelle_Leistung":
|
||||
$this->SetValue("Power", (int)$Value);
|
||||
break;
|
||||
|
||||
case "GetCurrentData":
|
||||
$this->SetValue("Is_Peak_Shaving", (bool)$Value);
|
||||
break;
|
||||
|
||||
case "Do_UserCalc":
|
||||
$this->SetAktuelle_Leistung($this->GetValue("Power"));
|
||||
$this->GetCurrentData($this->GetValue("Is_Peak_Shaving"));
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Exception("Invalid Ident");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function berechneKombinationen(array $verbraucherListe){
|
||||
$kombinationen = [];
|
||||
foreach ($verbraucherListe as $verbraucher) {
|
||||
|
||||
if (GetValue($verbraucher['Read_Var']) == 1) {
|
||||
$tempListe = [];
|
||||
if(empty($kombinationen)){
|
||||
$kombinationen[] = $verbraucher['P_Nenn'];
|
||||
}else{
|
||||
foreach ($kombinationen as $wert) {
|
||||
$tempListe[] = $wert + $verbraucher['P_Nenn'];
|
||||
}
|
||||
$kombinationen = array_merge($kombinationen, $tempListe);
|
||||
}
|
||||
}
|
||||
}
|
||||
sort($kombinationen);
|
||||
return array_values(array_unique($kombinationen));
|
||||
}
|
||||
|
||||
|
||||
private function find($target, $values, $current, &$result) {
|
||||
if ($target == 0) {
|
||||
$result[] = $current;
|
||||
return;
|
||||
}
|
||||
if ($target < 0) {
|
||||
return;
|
||||
}
|
||||
for ($i = 0; $i < count($values); $i++) {
|
||||
$newValues = array_slice($values, $i + 1);
|
||||
$this->find($target - $values[$i], $newValues, array_merge($current, [$values[$i]]), $result);
|
||||
}
|
||||
}
|
||||
|
||||
private function berechneInverseKombinationen()
|
||||
{
|
||||
$values = json_decode($this->GetValue("PowerSteps"));
|
||||
$result = [];
|
||||
|
||||
$this->find($this->GetValue("Power"), $values, [], $result);
|
||||
|
||||
$verbraucherListe = json_decode($this->ReadPropertyString("Verbraucher_Liste"), true);
|
||||
|
||||
|
||||
$firstCombination = $result[0];
|
||||
|
||||
foreach ($verbraucherListe as &$verbraucher) {
|
||||
if (in_array($verbraucher['P_Nenn'], $firstCombination)) {
|
||||
SetValue($verbraucher['Write_Var'], 1);
|
||||
} else {
|
||||
SetValue($verbraucher['Write_Var'], 0);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function SetAktuelle_Leistung(float $power) {
|
||||
$this->CheckIdle($power);
|
||||
$this->SetValue("Aktuelle_Leistung", $power);
|
||||
$this->SetValue("Bezogene_Energie", ($this->GetValue("Bezogene_Energie") + ($this->GetValue("Aktuelle_Leistung")*($this->ReadPropertyInteger("Interval")/3600))));
|
||||
|
||||
$verbraucherListe = json_decode($this->ReadPropertyString("Verbraucher_Liste"), true);
|
||||
|
||||
$this->berechneInverseKombinationen();
|
||||
$this->SetValue("Leistung_Delta", GetValue($this->ReadPropertyInteger("delta_power")));
|
||||
}
|
||||
|
||||
public function GetCurrentData(bool $Peak)
|
||||
{
|
||||
$this->SetValue("Is_Peak_Shaving", $Peak);
|
||||
SetValue($this->ReadPropertyInteger("Is_Peak"), $Peak);
|
||||
|
||||
$verbraucherListe = json_decode($this->ReadPropertyString("Verbraucher_Liste"), true);
|
||||
$kombinationen = $this->berechneKombinationen($verbraucherListe);
|
||||
$this->SetValue("PowerSteps", json_encode($kombinationen));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public function CheckIdle($power)
|
||||
{
|
||||
$lastpower = GetValue($this->GetIDForIdent("Aktuelle_Leistung"));
|
||||
if ($lastpower != $power) {
|
||||
$this->SetValue("Idle", false);
|
||||
$this->SetValue("IdleCounter",$this->ReadPropertyInteger("IdleCounterMax"));
|
||||
}
|
||||
$idleCounter = $this->GetValue("IdleCounter");
|
||||
if ($idleCounter > 0) {
|
||||
$this->SetValue("Idle", false);
|
||||
$this->SetValue("IdleCounter", $idleCounter - 1);
|
||||
} else {
|
||||
$this->SetValue("Idle", true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -65,6 +65,12 @@
|
||||
"name": "WW_Temp",
|
||||
"caption": "Variable mit der Aktuellen Warmwassertemperatur",
|
||||
"test": true
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Interval",
|
||||
"caption": "Intervall Neuberechnung der Werte Erst für spätere Versionen, aktuell auf 5 lassen!",
|
||||
"suffix": "Sekunden"
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
@@ -16,6 +16,7 @@ class WP_Steuerung extends IPSModule
|
||||
$this->RegisterPropertyBoolean("Schwellwert_Anwenden", false);
|
||||
$this->RegisterPropertyInteger("Schwellwert", 0);
|
||||
$this->RegisterPropertyInteger("WW_Temp", 1);
|
||||
$this->RegisterPropertyInteger("Interval", 5); // Recheninterval
|
||||
|
||||
// WP-Spezifische Variabeln
|
||||
$this->RegisterVariableBoolean("Sperrzeit", "Sperrzeit", "", false);
|
||||
@@ -32,10 +33,11 @@ class WP_Steuerung extends IPSModule
|
||||
$this->RegisterVariableInteger("PV_Prio", "PV_Prio");
|
||||
$this->RegisterVariableBoolean("Idle", "Idle", "", 0);
|
||||
$this->RegisterVariableInteger("Aktuelle_Leistung", "Aktuelle_Leistung", "", 0);
|
||||
$this->RegisterVariableFloat("Bezogene_Energie", "Bezogene_Energie", "", 0);
|
||||
$this->RegisterVariableFloat("Bezogene_Energie", "Bezogene_Energie", "", 0);
|
||||
$this->RegisterVariableString("PowerSteps", "PowerSteps");
|
||||
$this->RegisterVariableInteger("Power", "Power");
|
||||
$this->RegisterVariableBoolean("Is_Peak_Shaving", "Is_Peak_Shaving");
|
||||
$this->RegisterVariableInteger("Leistung_Delta", "Leistung_Delta", "", 0);
|
||||
|
||||
// Hilfsvariabeln für Idle zustand
|
||||
$this->RegisterPropertyInteger("IdleCounterMax", 2);
|
||||
@@ -45,13 +47,15 @@ class WP_Steuerung extends IPSModule
|
||||
// Initialisiere Idle
|
||||
$this->SetValue("Idle", true);
|
||||
|
||||
$this->RegisterTimer("Timer_Do_UserCalc",5000,"IPS_RequestAction(" .$this->InstanceID .', "Do_UserCalc", "");');
|
||||
$this->RegisterTimer("Timer_Do_UserCalc_WP",$this->ReadPropertyInteger("Interval")*1000,"IPS_RequestAction(" .$this->InstanceID .', "Do_UserCalc", "");');
|
||||
|
||||
}
|
||||
|
||||
public function ApplyChanges()
|
||||
{
|
||||
parent::ApplyChanges();
|
||||
$this->SetTimerInterval("Timer_Do_UserCalc_WP",$this->ReadPropertyInteger("Interval")*1000);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -82,6 +86,7 @@ class WP_Steuerung extends IPSModule
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Methode zum Setzen des aktuellen Stromverbrauchs
|
||||
public function SetAktuelle_Leistung(float $power)
|
||||
{
|
||||
@@ -259,6 +264,8 @@ class WP_Steuerung extends IPSModule
|
||||
$newCount = $this->GetValue("WP_Laufzeit_Zahler");
|
||||
$this->SetValue("WP_Laufzeit_Zahler", $newCount + 1);
|
||||
}
|
||||
|
||||
$this->SetValue("Bezogene_Energie", ($this->GetValue("Bezogene_Energie") + ($this->GetValue("Aktuelle_Leistung")*($this->ReadPropertyInteger("Interval")/3600))));
|
||||
}
|
||||
|
||||
// Methode zum Abrufen der aktuellen Daten
|
||||
|
||||
@@ -4,10 +4,9 @@
|
||||
"author": "Daniel Haefliger",
|
||||
"url": "https://git.belevo.ch/dh/Symcon_Belevo_Energiemanagement",
|
||||
"compatibility": {
|
||||
"version": "7.1"
|
||||
"version": "8.0"
|
||||
},
|
||||
"version": "1.0011",
|
||||
|
||||
"version": "2.000",
|
||||
"build": 0,
|
||||
"date": 0
|
||||
}
|
||||
Reference in New Issue
Block a user