From 57ef475ab9cfe8a9c0be7684e6e24c3e687fa3a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=A4fliger?= Date: Wed, 5 Feb 2025 16:24:28 +0100 Subject: [PATCH] =?UTF-8?q?landwirtschaft=20gel=C3=B6scht=20und=20alles=20?= =?UTF-8?q?in=20normalem=20boiler=20integriert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Boiler_2_Stufig_Landwirtschaft/README.md | 67 ---- Boiler_2_Stufig_Landwirtschaft/form.json | 102 ------- Boiler_2_Stufig_Landwirtschaft/module.json | 12 - Boiler_2_Stufig_Landwirtschaft/module.php | 338 --------------------- Boiler_2_Stufig_Mit_Fueler/form.json | 6 +- library.json | 2 +- 6 files changed, 4 insertions(+), 523 deletions(-) delete mode 100644 Boiler_2_Stufig_Landwirtschaft/README.md delete mode 100644 Boiler_2_Stufig_Landwirtschaft/form.json delete mode 100644 Boiler_2_Stufig_Landwirtschaft/module.json delete mode 100644 Boiler_2_Stufig_Landwirtschaft/module.php diff --git a/Boiler_2_Stufig_Landwirtschaft/README.md b/Boiler_2_Stufig_Landwirtschaft/README.md deleted file mode 100644 index b059e3a..0000000 --- a/Boiler_2_Stufig_Landwirtschaft/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# 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);` \ No newline at end of file diff --git a/Boiler_2_Stufig_Landwirtschaft/form.json b/Boiler_2_Stufig_Landwirtschaft/form.json deleted file mode 100644 index 5415bc0..0000000 --- a/Boiler_2_Stufig_Landwirtschaft/form.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "elements": [ - { - "type": "Label", - "caption": "Konfiguration der nötigen Schaltkontakte und Nennleistungen" - }, - { - "type":"Select", - "name":"Boilertemperatur_glätten", - "caption":"Boilertemperatur glätten Ja oder Nein", - "options":[ - { - "caption":"Ja", - "value":true - }, - { - "caption":"Nein", - "value":false - } - ] - }, - { - "type": "NumberSpinner", - "name": "ZeitKonstante", - "caption": "Zeit Konstante", - "suffix": "" - }, - { - "type": "NumberSpinner", - "name": "IdleCounterMax", - "caption": "Zyklen zwischen zwei Leisutungsänderungen", - "suffix": "" - }, - { - "type": "NumberSpinner", - "name": "BoilerLeistungTeillast", - "caption": "Leistug Teillast", - "suffix": "" - }, - { - "type": "NumberSpinner", - "name": "BoilerLeistungVolllast", - "caption": "Leistug Vollast", - "suffix": "" - }, - { - "type": "SelectVariable", - "name": "Boilerfuehler_PT1", - "caption": "Variable für Boilerfühler PT1", - "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" - } - }, - { - "type": "NumberSpinner", - "name": "Boilervolumen", - "caption": "Boilervolumen", - "suffix": "Liter" - } - ] -} \ No newline at end of file diff --git a/Boiler_2_Stufig_Landwirtschaft/module.json b/Boiler_2_Stufig_Landwirtschaft/module.json deleted file mode 100644 index 95232b4..0000000 --- a/Boiler_2_Stufig_Landwirtschaft/module.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "id": "{64ABAB9F-7757-0ABA-0B81-501108A25565}", - "name": "Boiler_2_Stufig_Landwirtschaft", - "type": 3, - "vendor": "Belevo AG", - "aliases": [], - "parentRequirements": [], - "childRequirements": [], - "implemented": [], - "prefix": "GEF", - "url": "" -} \ No newline at end of file diff --git a/Boiler_2_Stufig_Landwirtschaft/module.php b/Boiler_2_Stufig_Landwirtschaft/module.php deleted file mode 100644 index 838cb0b..0000000 --- a/Boiler_2_Stufig_Landwirtschaft/module.php +++ /dev/null @@ -1,338 +0,0 @@ -RegisterPropertyInteger("BoilerLeistungTeillast", 3000); - $this->RegisterPropertyInteger("BoilerLeistungVolllast", 6000); - $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->RegisterPropertyString("Zeitplan", ""); - - - // 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); - $this->RegisterVariableInteger("Boilertemperatur", "Boilertemperatur", "", 0); - - - // 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", '', 0); - $this->RegisterVariableBoolean("Is_Peak_Shaving", "Is_Peak_Shaving", "", true); - - // 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",5000,"IPS_RequestAction(" .$this->InstanceID .', "Do_UserCalc", "");'); - - } - - public function ApplyChanges() - { - parent::ApplyChanges(); - - - - } - - 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) - { - // 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); - } elseif ( - $power == $this->ReadPropertyInteger("BoilerLeistungTeillast") - ) { - SetValue($this->ReadPropertyInteger("Kontakt_Volllast"), false); - SetValue($this->ReadPropertyInteger("Kontakt_Teillast"), true); - } else { - SetValue($this->ReadPropertyInteger("Kontakt_Volllast"), false); - SetValue($this->ReadPropertyInteger("Kontakt_Teillast"), false); - } - - // 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); - - // 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"); - - if ($boilertemperatur_glätten) { - // Wenn Glättung aktiviert ist, führe das Glätten durch - $boilerFuehlerPT1ID = $this->ReadPropertyInteger("Boilerfuehler_PT1"); - - 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("Boilerfuehler_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); - } - - - $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; - } 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([0, $teilLeistung, $vollLeistung]) ); - } elseif ( - $boilerTemp < $minTemp + 5 && - ($AktuelleVollast || $AktuelleTeillast) - ) { - $this->SetValue( - "PowerSteps", - json_encode([0, $teilLeistung, $vollLeistung]) - ); - } else { - $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])); - } 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; - } - } -} - -?> diff --git a/Boiler_2_Stufig_Mit_Fueler/form.json b/Boiler_2_Stufig_Mit_Fueler/form.json index d1bf1c1..8939af8 100644 --- a/Boiler_2_Stufig_Mit_Fueler/form.json +++ b/Boiler_2_Stufig_Mit_Fueler/form.json @@ -29,19 +29,19 @@ "type": "NumberSpinner", "name": "IdleCounterMax", "caption": "Zyklen zwischen zwei Leisutungsänderungen", - "suffix": "" + "suffix": "x5 Sekunden" }, { "type": "NumberSpinner", "name": "BoilerLeistungTeillast", "caption": "Leistug Teillast", - "suffix": "" + "suffix": "Watt" }, { "type": "NumberSpinner", "name": "BoilerLeistungVolllast", "caption": "Leistug Vollast", - "suffix": "" + "suffix": "Watt" }, { "type": "NumberSpinner", diff --git a/library.json b/library.json index cdb4dfe..186add1 100644 --- a/library.json +++ b/library.json @@ -6,7 +6,7 @@ "compatibility": { "version": "7.1" }, - "version": "1.036", + "version": "1.037", "build": 0, "date": 0 } \ No newline at end of file