diff --git a/Peakshaving/README.md b/Peakshaving/README.md new file mode 100644 index 0000000..b059e3a --- /dev/null +++ b/Peakshaving/README.md @@ -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);` \ No newline at end of file diff --git a/Peakshaving/form.json b/Peakshaving/form.json new file mode 100644 index 0000000..401a93b --- /dev/null +++ b/Peakshaving/form.json @@ -0,0 +1,206 @@ +{ + "elements": [ + { + "type": "ExpansionPanel", + "caption": "Ziel-Module", + "items": [ + { + "type": "SelectInstance", + "name": "CapacityTargetInstance", + "caption": "Batterie Instanz" + }, + { + "type": "ValidationTextBox", + "name": "CapacityTargetProperty", + "caption": "Property-Name Kapazität" + }, + { + "type": "SelectInstance", + "name": "PowerTargetInstance", + "caption": "Instanz für Peakleistung" + }, + { + "type": "ValidationTextBox", + "name": "PowerTargetProperty", + "caption": "Manager Instanz" + } + ] + }, + + { + "type": "ExpansionPanel", + "caption": "Monatswerte", + "items": [ + + { + "type": "Label", + "caption": "Januar" + }, + { + "type": "RowLayout", + "items": [ + { + "type": "NumberSpinner", + "name": "PowerJanuary", + "caption": "Leistung Peakshaving [W]" + }, + { + "type": "NumberSpinner", + "name": "CapacityJanuary", + "caption": "Kapazität [%]" + } + ] + }, + + { + "type": "Label", + "caption": "Februar" + }, + { + "type": "RowLayout", + "items": [ + { + "type": "NumberSpinner", + "name": "PowerFebruary", + "caption": "Leistung Peakshaving [W]" + }, + { + "type": "NumberSpinner", + "name": "CapacityFebruary", + "caption": "Kapazität [%]" + } + ] + }, + + { + "type": "Label", + "caption": "März" + }, + { + "type": "RowLayout", + "items": [ + { + "type": "NumberSpinner", + "name": "PowerMarch", + "caption": "Leistung Peakshaving [W]" + }, + { + "type": "NumberSpinner", + "name": "CapacityMarch", + "caption": "Kapazität [%]" + } + ] + }, + + { + "type": "Label", + "caption": "April" + }, + { + "type": "RowLayout", + "items": [ + { + "type": "NumberSpinner", + "name": "PowerApril", + "caption": "Leistung Peakshaving [W]" + }, + { + "type": "NumberSpinner", + "name": "CapacityApril", + "caption": "Kapazität [%]" + } + ] + }, + + { + "type": "Label", + "caption": "Sommer (Mai–September)" + }, + { + "type": "RowLayout", + "items": [ + { + "type": "NumberSpinner", + "name": "PowerSummer", + "caption": "Leistung Peakshaving [W]" + }, + { + "type": "NumberSpinner", + "name": "CapacitySummer", + "caption": "Kapazität [%]" + } + ] + }, + + { + "type": "Label", + "caption": "Oktober" + }, + { + "type": "RowLayout", + "items": [ + { + "type": "NumberSpinner", + "name": "PowerOctober", + "caption": "Leistung Peakshaving [W]" + }, + { + "type": "NumberSpinner", + "name": "CapacityOctober", + "caption": "Kapazität [%]" + } + ] + }, + + { + "type": "Label", + "caption": "November" + }, + { + "type": "RowLayout", + "items": [ + { + "type": "NumberSpinner", + "name": "PowerNovember", + "caption": "Leistung Peakshaving [W]" + }, + { + "type": "NumberSpinner", + "name": "CapacityNovember", + "caption": "Kapazität [%]" + } + ] + }, + + { + "type": "Label", + "caption": "Dezember" + }, + { + "type": "RowLayout", + "items": [ + { + "type": "NumberSpinner", + "name": "PowerDecember", + "caption": "Leistung Peakshaving [W]" + }, + { + "type": "NumberSpinner", + "name": "CapacityDecember", + "caption": "Kapazität [%]" + } + ] + } + + ] + } + ], + + "actions": [ + { + "type": "Button", + "caption": "Werte sofort übernehmen", + "onClick": "GEF_ApplyCurrentValues($id);" + } + ] +} \ No newline at end of file diff --git a/Peakshaving/module.json b/Peakshaving/module.json new file mode 100644 index 0000000..25bdeb9 --- /dev/null +++ b/Peakshaving/module.json @@ -0,0 +1,12 @@ +{ + "id": "{10371F76-D0A9-80A7-8EA5-43DB636CC5C5}", + "name": "Peakshaving", + "type": 3, + "vendor": "Belevo AG", + "aliases": [], + "parentRequirements": [], + "childRequirements": [], + "implemented": [], + "prefix": "GEF", + "url": "" +} \ No newline at end of file diff --git a/Peakshaving/module.php b/Peakshaving/module.php new file mode 100644 index 0000000..b54249c --- /dev/null +++ b/Peakshaving/module.php @@ -0,0 +1,200 @@ +RegisterPropertyInteger('CapacityTargetInstance', 0); + $this->RegisterPropertyString('CapacityTargetProperty', 'AufdasNachladen'); + + $this->RegisterPropertyInteger('PowerTargetInstance', 0); + $this->RegisterPropertyString('PowerTargetProperty', 'Peakleistung'); + + // Monatswerte + $this->RegisterPropertyFloat('CapacityJanuary', 11); + $this->RegisterPropertyFloat('PowerJanuary', 42000); + + $this->RegisterPropertyFloat('CapacityFebruary', 11); + $this->RegisterPropertyFloat('PowerFebruary', 42000); + + $this->RegisterPropertyFloat('CapacityMarch', 8); + $this->RegisterPropertyFloat('PowerMarch', 43000); + + $this->RegisterPropertyFloat('CapacityApril', 8); + $this->RegisterPropertyFloat('PowerApril', 44000); + + $this->RegisterPropertyFloat('CapacitySummer', 8); + $this->RegisterPropertyFloat('PowerSummer', 44000); + + $this->RegisterPropertyFloat('CapacityOctober', 12); + $this->RegisterPropertyFloat('PowerOctober', 43000); + + $this->RegisterPropertyFloat('CapacityNovember', 12); + $this->RegisterPropertyFloat('PowerNovember', 43000); + + $this->RegisterPropertyFloat('CapacityDecember', 12); + $this->RegisterPropertyFloat('PowerDecember', 43000); + + // Statusvariablen + $this->RegisterVariableFloat('ActiveCapacity', 'Kapazität Peakshaving', '~Intensity.100', 10); + $this->RegisterVariableFloat('ActivePower', 'Leistung Peakshaving', '~Watt', 20); + + $this->EnableAction('ActiveCapacity'); + $this->EnableAction('ActivePower'); + + // Einmal täglich prüfen/übernehmen + $this->RegisterTimer('DailyUpdate', 0, 'GEF_ApplyCurrentValues($_IPS[\'TARGET\']);'); + } + +public function ApplyChanges() +{ + parent::ApplyChanges(); + + $this->SetTimerInterval('DailyUpdate', 24 * 60 * 60 * 1000); + + if (IPS_GetName($this->InstanceID) == '') { + IPS_SetName($this->InstanceID, 'Peakshaving'); + } +} + public function RequestAction($Ident, $Value) + { + switch ($Ident) { + case 'ActiveCapacity': + SetValueFloat($this->GetIDForIdent('ActiveCapacity'), (float)$Value); + $this->ApplyCapacityToTarget((float)$Value); + break; + + case 'ActivePower': + SetValueFloat($this->GetIDForIdent('ActivePower'), (float)$Value); + $this->ApplyPowerToTarget((float)$Value); + break; + + default: + throw new Exception('Ungültiger Ident: ' . $Ident); + } + } + + public function ApplyCurrentValues() + { + $values = $this->GetValuesForCurrentMonth(); + + SetValueFloat($this->GetIDForIdent('ActiveCapacity'), $values['capacity']); + SetValueFloat($this->GetIDForIdent('ActivePower'), $values['power']); + + $this->ApplyCapacityToTarget($values['capacity']); + $this->ApplyPowerToTarget($values['power']); + + return 'Peakshaving Werte wurden übernommen.'; + } + + private function GetValuesForCurrentMonth() + { + $month = (int)date('n'); + + switch ($month) { + case 1: + return [ + 'capacity' => $this->ReadPropertyFloat('CapacityJanuary'), + 'power' => $this->ReadPropertyFloat('PowerJanuary') + ]; + + case 2: + return [ + 'capacity' => $this->ReadPropertyFloat('CapacityFebruary'), + 'power' => $this->ReadPropertyFloat('PowerFebruary') + ]; + + case 3: + return [ + 'capacity' => $this->ReadPropertyFloat('CapacityMarch'), + 'power' => $this->ReadPropertyFloat('PowerMarch') + ]; + + case 4: + return [ + 'capacity' => $this->ReadPropertyFloat('CapacityApril'), + 'power' => $this->ReadPropertyFloat('PowerApril') + ]; + + case 5: + case 6: + case 7: + case 8: + case 9: + return [ + 'capacity' => $this->ReadPropertyFloat('CapacitySummer'), + 'power' => $this->ReadPropertyFloat('PowerSummer') + ]; + + case 10: + return [ + 'capacity' => $this->ReadPropertyFloat('CapacityOctober'), + 'power' => $this->ReadPropertyFloat('PowerOctober') + ]; + + case 11: + return [ + 'capacity' => $this->ReadPropertyFloat('CapacityNovember'), + 'power' => $this->ReadPropertyFloat('PowerNovember') + ]; + + case 12: + return [ + 'capacity' => $this->ReadPropertyFloat('CapacityDecember'), + 'power' => $this->ReadPropertyFloat('PowerDecember') + ]; + } + + return [ + 'capacity' => 0, + 'power' => 0 + ]; + } + + private function ApplyCapacityToTarget(float $value) + { + $instanceID = $this->ReadPropertyInteger('CapacityTargetInstance'); + $property = $this->ReadPropertyString('CapacityTargetProperty'); + + $this->ApplyPropertyToInstance($instanceID, $property, $value); + } + + private function ApplyPowerToTarget(float $value) + { + $instanceID = $this->ReadPropertyInteger('PowerTargetInstance'); + $property = $this->ReadPropertyString('PowerTargetProperty'); + + $this->ApplyPropertyToInstance($instanceID, $property, $value); + } + + private function ApplyPropertyToInstance(int $instanceID, string $property, float $value) + { + if ($instanceID <= 0) { + return; + } + + if (!IPS_InstanceExists($instanceID)) { + $this->SendDebug('Peakshaving', 'Ziel-Instanz existiert nicht: ' . $instanceID, 0); + return; + } + + if ($property === '') { + $this->SendDebug('Peakshaving', 'Kein Property-Name gesetzt.', 0); + return; + } + + IPS_SetProperty($instanceID, $property, $value); + + if (!IPS_ApplyChanges($instanceID)) { + $this->SendDebug( + 'Peakshaving', + 'IPS_ApplyChanges fehlgeschlagen für Instanz ' . $instanceID . ', Property ' . $property, + 0 + ); + } + } +} +?> \ No newline at end of file