From c823c3eedfe7baea74ea87a0c36136ed28d8b0b9 Mon Sep 17 00:00:00 2001 From: "belevo\\mh" Date: Wed, 1 Oct 2025 07:12:54 +0200 Subject: [PATCH] no message --- Puffer_Speicher/form.json | 102 ++++++++------- Puffer_Speicher/module.php | 224 ++++++++++----------------------- Pufferspeicher_def/module.json | 4 +- Pufferspeicher_def/module.php | 2 +- 4 files changed, 119 insertions(+), 213 deletions(-) diff --git a/Puffer_Speicher/form.json b/Puffer_Speicher/form.json index 9cb05ce..979eedf 100644 --- a/Puffer_Speicher/form.json +++ b/Puffer_Speicher/form.json @@ -1,3 +1,4 @@ + { "elements": [ { @@ -6,8 +7,8 @@ }, { "type":"Select", - "name":"Boilertemperatur_glätten", - "caption":"Boilertemperatur glätten", + "name":"Puffertemperatur_glätten", + "caption":"Puffertemperatur glätten", "options":[ { "caption":"Ja", @@ -39,70 +40,67 @@ }, { "type": "NumberSpinner", - "name": "BoilerLeistungTeillast", - "caption": "Leistug Teillast", + "name": "PufferLeistung", + "caption": "Puffer Volllast", "suffix": "Watt" }, { "type": "NumberSpinner", - "name": "BoilerLeistungVolllast", - "caption": "Leistug Vollast", + "name": "PufferTeilLeistung", + "caption": "Puffer Teillast", "suffix": "Watt" }, + { + "type": "Label", + "caption": "Endpunkte der Pufferfunktion bestimmen: VT = f(AT)" + }, { "type": "NumberSpinner", - "name": "Boilervolumen", - "caption": "Boilervolumen", - "suffix": "Liter" + "name": "MaxVT_Temp", + "caption": "Max Temperatur VT", + "suffix": "°C" + }, + { + "type": "NumberSpinner", + "name": "MinVT_Temp", + "caption": "Min Temperatur VT", + "suffix": "°C" + }, + { + "type": "NumberSpinner", + "name": "MaxAT_Temp", + "caption": "Max Temperatur AT", + "suffix": "°C" + }, + { + "type": "NumberSpinner", + "name": "MinAT_Temp", + "caption": "Min Temperatur AT", + "suffix": "°C" }, { "type": "SelectVariable", - "name": "Boilerfuehler_PT1", - "caption": "Variable für Boilerfühler PT1", + "name": "Pufferfuehler_PT1", + "caption": "Variable für Pufferfühler PT1", + "test": true + }, + { + "type": "SelectVariable", + "name": "Heizkontakt1_Puffer", + "caption": "Heizkontakt Puffer 1.Stufe", + "test": true + }, + { + "type": "SelectVariable", + "name": "Heizkontakt2_Puffer", + "caption": "Heizkontakt Puffer 2.Stufe", "test": true }, { "type": "SelectVariable", - "name": "Kontakt_Teillast", - "caption": "Schaltkontakt Teillast", - "test": true - }, - { - "type": "SelectVariable", - "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" - } + "name": "Aussentemp", + "caption": "Aussentemperatur", + "suffix": "°C" } ] -} \ No newline at end of file +} diff --git a/Puffer_Speicher/module.php b/Puffer_Speicher/module.php index 01ddb74..889465f 100644 --- a/Puffer_Speicher/module.php +++ b/Puffer_Speicher/module.php @@ -6,26 +6,27 @@ class Puffer_Speicher extends IPSModule { parent::Create(); - // Boiler spezifische Properties - $this->RegisterPropertyInteger("BoilerLeistungTeillast", 3000); - $this->RegisterPropertyInteger("BoilerLeistungVolllast", 6000); + $this->RegisterPropertyInteger("PufferLeistung", 6000); + $this->RegisterPropertyInteger("PufferTeilLeistung", 3000); $this->RegisterPropertyInteger("ZeitKonstante", 120); - $this->RegisterPropertyInteger("Boilerfuehler_PT1", 0); - $this->RegisterPropertyInteger("Kontakt_Teillast", 0); - $this->RegisterPropertyInteger("Kontakt_Volllast", 0); - $this->RegisterPropertyBoolean("Boilertemperatur_glätten", false); - $this->RegisterPropertyInteger("Boilervolumen", 300); + $this->RegisterPropertyInteger("Pufferfuehler_PT1", 0); + $this->RegisterPropertyInteger("Heizkontakt2_Puffer", 0); + $this->RegisterPropertyInteger("Heizkontakt1_Puffer", 0); + $this->RegisterPropertyInteger("Aussentemp", 20); + $this->RegisterPropertyInteger("MinVT_Temp", 20); + $this->RegisterPropertyInteger("MaxVT_Temp", 80); + $this->RegisterPropertyInteger("MaxAT_Temp", 20); + $this->RegisterPropertyInteger("MinAT_Temp", 0); + $this->RegisterPropertyBoolean("Puffertemperatur_glätten", false); $this->RegisterPropertyString("Zeitplan", ""); $this->RegisterPropertyInteger("Interval", 5); // Recheninterval - - // 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); + // Puffer spezifische Variablen + $this->RegisterVariableInteger("Steigung","Steigung","",0); + $this->RegisterVariableInteger("Maximaltemperatur"," Berechnete Maximaltemperatur VT","",60); + $this->RegisterVariableInteger("Puffertemperatur", "Puffertemperatur", "", 40); + $this->RegisterVariableInteger("Aussentemperatur", "Aussentemperatur", "", 15); + $this->RegisterVariableBoolean("Hysterese", "Hysterese","",false); // Variabeln für Kommunkation mit Manager @@ -63,7 +64,6 @@ class Puffer_Speicher extends IPSModule public function RequestAction($Ident, $Value) { switch ($Ident) { - case "SetAktuelle_Leistung": $this->SetValue("Power", (int)$Value); break; @@ -73,11 +73,9 @@ class Puffer_Speicher extends IPSModule break; case "Do_UserCalc": - $this->SetAktuelle_Leistung($this->GetValue("Power")); $this->GetCurrentData($this->GetValue("Is_Peak_Shaving")); break; - default: throw new Exception("Invalid Ident"); } @@ -85,73 +83,24 @@ class Puffer_Speicher 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 + // Methode zum Setzen des aktuellen Stromverbrauchs public function SetAktuelle_Leistung(int $power) { // Schalte Kontakt Teillast und Vollast entsprechend der Power-Einstellung - if ($power == $this->ReadPropertyInteger("BoilerLeistungVolllast")) { - SetValue($this->ReadPropertyInteger("Kontakt_Volllast"), true); - SetValue($this->ReadPropertyInteger("Kontakt_Teillast"), false); + if ($power == $this->ReadPropertyInteger("PufferLeistung")) { + SetValue($this->ReadPropertyInteger("Heizkontakt2_Puffer"), true); + SetValue($this->ReadPropertyInteger("Heizkontakt1_Puffer"), false); } elseif ( - $power == $this->ReadPropertyInteger("BoilerLeistungTeillast") + $power == $this->ReadPropertyInteger("PufferTeilLeistung") ) { - SetValue($this->ReadPropertyInteger("Kontakt_Volllast"), false); - SetValue($this->ReadPropertyInteger("Kontakt_Teillast"), true); + SetValue($this->ReadPropertyInteger("Heizkontakt2_Puffer"), false); + SetValue($this->ReadPropertyInteger("Heizkontakt1_Puffer"), true); } else { - SetValue($this->ReadPropertyInteger("Kontakt_Volllast"), false); - SetValue($this->ReadPropertyInteger("Kontakt_Teillast"), false); + SetValue($this->ReadPropertyInteger("Heizkontakt2_Puffer"), false); + SetValue($this->ReadPropertyInteger("Heizkontakt1_Puffer"), false); } - - // Prüfe auf Änderung der Power im Vergleich zur letzten Einstellung + + // Prüfe auf Änderung der Power im Vergleich zur letzten Einstellung $lastPower = GetValue($this->GetIDForIdent("Aktuelle_Leistung")); if ($power != $lastPower) { $this->SetValue("Idle", false); @@ -160,25 +109,21 @@ class Puffer_Speicher extends IPSModule $this->ReadPropertyInteger("IdleCounterMax") ); } - - // Setze die neue Aktuelle_Leistung + // 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 + // IdleCounter verarbeiten $this->ProcessIdleCounter(); } - // Methode zum Abrufen der aktuellen Daten public function GetCurrentData(bool $Peak) { - $LegioCounter = $this->GetValue("LegioCounter"); - - - $boilertemperatur_glätten = $this->ReadPropertyBoolean("Boilertemperatur_glätten"); - + + + $boilertemperatur_glätten = $this->ReadPropertyBoolean("Puffertemperatur_glätten"); if ($boilertemperatur_glätten) { // Wenn Glättung aktiviert ist, führe das Glätten durch - $boilerFuehlerPT1ID = $this->ReadPropertyInteger("Boilerfuehler_PT1"); + $boilerFuehlerPT1ID = $this->ReadPropertyInteger("Pufferfuehler_PT1"); if (IPS_VariableExists($boilerFuehlerPT1ID)) { $boilerPT1 = GetValue($boilerFuehlerPT1ID); @@ -198,93 +143,56 @@ class Puffer_Speicher extends IPSModule $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); + $this->SetValue("Puffertemperatur", $newBoilerTemp); } else { // Wenn Glättung nicht aktiviert ist, setze die Boilertemperatur direkt auf den Wert des Boilerfühlers - $boilerFuehlerPT1ID = $this->ReadPropertyInteger("Boilerfuehler_PT1"); + $boilerFuehlerPT1ID = $this->ReadPropertyInteger("Pufferfuehler_PT1"); 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); + $this->SetValue("Puffertemperatur", $boilerPT1); } - $boilerTemp = $this->GetValue("Boilertemperatur"); - $minTemp = $this->GetValue("Mindesttemperatur"); - $maxTemp = $this->GetValue("Maximaltemperatur"); - $LegioTemp = $this->GetValue("Legionellentemperatur"); - $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") - ); - $AktuelleTeillast = GetValue( - $this->ReadPropertyInteger("Kontakt_Teillast") - ); - - if ($boilerTemp > $LegioTemp) { - $LegioCounter = 0; + $at = GetValue($this->ReadPropertyInteger("Aussentemp")); + $this->SetValue("Aussentemperatur", $at); + $m = $this->GetValue("Steigung"); + $minVT = $this->ReadPropertyInteger("MinVT_Temp"); // z.B. 20 + $maxVT = $this->ReadPropertyInteger("MaxVT_Temp"); // z.B. 80 + $maxAT = $this->ReadPropertyInteger("MaxAT_Temp"); // z.B. 20 + $minAT = $this->ReadPropertyInteger("MinAT_Temp"); // z.B. 0 + $m = ($maxVT - $minVT) / ($minAT - $maxAT); + $this->SetValue("Steigung", $m); + if ($at < $minAT){ + $VT = $maxVT; + } elseif ($at > $maxAT){ + $VT = $minVT; } else { - $LegioCounter = $LegioCounter + 1; + $VT = $m * $at + $maxVT; } - if ($LegioCounter > 69120) { - $maxTemp = $LegioTemp; + $this->SetValue("Maximaltemperatur", $VT ); + $boilerTemp = $this->GetValue("Puffertemperatur"); + $pufferLeistung = $this->ReadPropertyInteger("PufferLeistung"); + $pufferTeilLeistung = $this->ReadPropertyInteger("PufferTeilLeistung"); + $hyst = $this->GetValue("Hysterese"); + + if($VT < $boilerTemp){ + $this->SetValue("Hysterese", false ); + }elseif($VT-5 >= $boilerTemp){ + $this->SetValue("Hysterese", true); } - 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([0, $teilLeistung, $vollLeistung]) ); - } elseif ( - $boilerTemp < $minTemp + 5 && - ($AktuelleVollast || $AktuelleTeillast) - ) { - $this->SetValue( - "PowerSteps", - json_encode([0, $teilLeistung, $vollLeistung]) - ); - } else { - $this->SetValue("PowerSteps", json_encode([0])); - } + $this->SetValue( "PowerSteps", json_encode([0]) ); } else { - if ($boilerTemp < $minTemp) { - $this->SetValue("PowerSteps", json_encode([$vollLeistung])); - } elseif ( - $boilerTemp < $minTemp + 5 && - ($AktuelleVollast || $AktuelleTeillast) - ) { - $this->SetValue("PowerSteps", json_encode([$vollLeistung])); - } elseif ($boilerTemp < $maxTemp - 5) { - $this->SetValue("PowerSteps", json_encode([0, $teilLeistung, $vollLeistung])); - } elseif ( $boilerTemp < $maxTemp && ($AktuelleVollast || $AktuelleTeillast) - ) { - $this->SetValue( "PowerSteps", json_encode([0, $teilLeistung, $vollLeistung])); + if ($boilerTemp < $VT && $hyst== true) { + $this->SetValue("PowerSteps", json_encode([0,$pufferTeilLeistung ,$pufferLeistung])); + } elseif ($boilerTemp > $VT - 5 && $hyst== false) { + $this->SetValue("PowerSteps", json_encode([0])); } else { $this->SetValue("PowerSteps", json_encode([0])); } diff --git a/Pufferspeicher_def/module.json b/Pufferspeicher_def/module.json index 3a0cf27..a593edd 100644 --- a/Pufferspeicher_def/module.json +++ b/Pufferspeicher_def/module.json @@ -1,6 +1,6 @@ { - "id": "{C5106707-3EAD-2B32-49EF-4E2F9C59E520}", - "name": "Pufferspeicher", + "id": "{987DD1AD-810D-23F0-3AE9-7349FED4A1DA}", + "name": "Pufferspeicher_def", "type": 3, "vendor": "Belevo AG", "aliases": [], diff --git a/Pufferspeicher_def/module.php b/Pufferspeicher_def/module.php index 4bb4416..e4ddab8 100644 --- a/Pufferspeicher_def/module.php +++ b/Pufferspeicher_def/module.php @@ -1,6 +1,6 @@