no message
This commit is contained in:
0
Batterie_Deye/README.md
Normal file
0
Batterie_Deye/README.md
Normal file
91
Batterie_Deye/form.json
Normal file
91
Batterie_Deye/form.json
Normal file
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"elements": [
|
||||
{
|
||||
"type": "Label",
|
||||
"caption": "Konfiguration der Batterie für Peakshaving"
|
||||
},
|
||||
{
|
||||
"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": "MaxBatterieleistung",
|
||||
"caption": "Maximale Batterieleistung",
|
||||
"suffix": ""
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "MaxNachladen",
|
||||
"caption": "Maximum Nachladen",
|
||||
"suffix": ""
|
||||
},
|
||||
{
|
||||
"type": "Label",
|
||||
"caption": "Bei Deye wird vorerst der Ladezustand in V angegeben."
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "AufdasNachladen",
|
||||
"caption": "Auf so viel Spannung nachladen",
|
||||
"suffix": "V",
|
||||
"minimum": 49,
|
||||
"maximum": 56,
|
||||
"step": 0.1
|
||||
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "MinimumEntladen",
|
||||
"caption": "Minimumspannung des Batterieladezustand",
|
||||
"suffix": "V",
|
||||
"minimum": 49,
|
||||
"maximum": 56,
|
||||
"step": 0.1
|
||||
},
|
||||
{
|
||||
"type":"Select",
|
||||
"name":"Batteriemanagement",
|
||||
"caption":"Batteriemanagement",
|
||||
"options":[
|
||||
{
|
||||
"caption":"Durch Wechselrichter",
|
||||
"value":2
|
||||
},
|
||||
{
|
||||
"caption":"Durch EMS Symcon",
|
||||
"value":0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
"name": "Batterieladezustand",
|
||||
"caption": "Batterieladezustand",
|
||||
"test": true
|
||||
},
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
"name": "Netzbezug",
|
||||
"caption": "Variable mit dem zu regelnden Netzbezug"
|
||||
},
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
"name": "Kotnrolle_TOU_Spannung",
|
||||
"caption": "Kontrollvariabel Spannung TOU1"
|
||||
},
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
"name": "Kotnrolle_Selling_CT",
|
||||
"caption": "Kontrollvariabel Selling First/Zero Export to CT"
|
||||
}
|
||||
]
|
||||
}
|
||||
12
Batterie_Deye/module.json
Normal file
12
Batterie_Deye/module.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"id": "{76529CAE-191C-41BF-5FDE-EF4A4FE25651}",
|
||||
"name": "Batterie_Deye",
|
||||
"type": 3,
|
||||
"vendor": "Belevo AG",
|
||||
"aliases": [],
|
||||
"parentRequirements": [],
|
||||
"childRequirements": [],
|
||||
"implemented": [],
|
||||
"prefix": "GEF",
|
||||
"url": ""
|
||||
}
|
||||
370
Batterie_Deye/module.php
Normal file
370
Batterie_Deye/module.php
Normal file
@@ -0,0 +1,370 @@
|
||||
<?php
|
||||
|
||||
|
||||
|
||||
class Batterie_Deye extends IPSModule
|
||||
{
|
||||
public function Create()
|
||||
{
|
||||
parent::Create();
|
||||
|
||||
// Batterie spezifische Eigenschaften
|
||||
$this->RegisterPropertyInteger("MaxBatterieleistung", 0);
|
||||
$this->RegisterPropertyInteger("Batteriespannung", 50);
|
||||
$this->RegisterPropertyInteger("AufdasNachladen",0);
|
||||
$this->RegisterPropertyInteger("MinimumEntladen",0);
|
||||
$this->RegisterPropertyInteger("Batterieladezustand",0);
|
||||
$this->RegisterPropertyInteger("Batteriemanagement", 1);
|
||||
$this->RegisterPropertyInteger("Kotnrolle_TOU_Spannung", 0);
|
||||
$this->RegisterPropertyInteger("Kotnrolle_Selling_CT", 0);
|
||||
$this->RegisterPropertyInteger("MaxNachladen",0);
|
||||
$this->RegisterPropertyInteger("Netzbezug", 0); // Initialisierung mit 0
|
||||
$this->RegisterPropertyInteger("Interval", 2); // Recheninterval
|
||||
|
||||
// Variabeln für Kommunkation mit Manager
|
||||
$this->RegisterVariableFloat("Entladeleistung","Entladeleistung", "",0);
|
||||
$this->RegisterVariableInteger("Laden3_Entladen4","Laden3_Entladen4", "",3);
|
||||
$this->RegisterVariableFloat("Ladeleistung","Ladeleistung", "",0);
|
||||
|
||||
$this->RegisterVariableInteger("Batteriemanagement_Variabel","Batteriemanagement_Variabel", "",0);
|
||||
$this->RegisterVariableFloat("Ladestrom","Ladestrom", "",0);
|
||||
$this->RegisterVariableFloat("Entladestrom","Entladestrom", "",0);
|
||||
$this->RegisterVariableFloat("Batteriespannung_laden_entladen",0);
|
||||
|
||||
$this->RegisterVariableInteger("Aktuelle_Leistung", "Aktuelle_Leistung", "", 0);
|
||||
$this->RegisterVariableString("PowerSteps", "PowerSteps");
|
||||
$this->RegisterVariableBoolean("Idle", "Idle", "", 0);
|
||||
$this->RegisterVariableInteger("Sperre_Prio", "Sperre_Prio");
|
||||
$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->RegisterVariableBoolean("Schreibkontrolle", "Schreibkontrolle","",false);
|
||||
|
||||
|
||||
$this->RegisterVariableFloat("Bezogene_Energie", "Bezogene_Energie", "", 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_Battery",$this->ReadPropertyInteger("Interval")*1000,"IPS_RequestAction(" .$this->InstanceID .', "Do_UserCalc", "");');
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function ApplyChanges()
|
||||
{
|
||||
parent::ApplyChanges();
|
||||
|
||||
$batterieManagement = $this->ReadPropertyInteger("Batteriemanagement");
|
||||
$this->SetValue("Batteriemanagement_Variabel", $batterieManagement);
|
||||
$this->SetTimerInterval("Timer_Do_UserCalc_Battery",$this->ReadPropertyInteger("Interval")*1000);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
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 SetAktuelle_Leistung(int $power)
|
||||
{
|
||||
|
||||
if ($power < 0) {
|
||||
|
||||
// Laden
|
||||
$lade_strom = abs($power) / GetValue($this->ReadPropertyInteger("Batteriespannung"));
|
||||
$this->SetValue("Ladestrom", $lade_strom);
|
||||
$this->SetValue("Entladestrom", 0);
|
||||
$this->SetValue("Batteriespannung_laden_entladen", 56);
|
||||
|
||||
} elseif ($power > 0) {
|
||||
|
||||
// Entladen
|
||||
$entlade_strom = $power / GetValue($this->ReadPropertyInteger("Batteriespannung"));
|
||||
$this->SetValue("Entladestrom", $entlade_strom);
|
||||
$this->SetValue("Ladestrom", 0);
|
||||
$this->SetValue("Batteriespannung_laden_entladen", 49);
|
||||
|
||||
} else {
|
||||
|
||||
// Kein Stromfluss (Leistung = 0)
|
||||
$this->SetValue("Ladestrom", 0);
|
||||
$this->SetValue("Entladestrom", 0);
|
||||
// Optional: Spannung neutral setzen, falls gewünscht
|
||||
$this->SetValue("Batteriespannung_laden_entladen", 52);
|
||||
}
|
||||
|
||||
|
||||
$batterieManagement = $this->ReadPropertyInteger("Batteriemanagement");
|
||||
// Wechselrichter steuert das Laden/Entladen der Batterie
|
||||
if ($batterieManagement == 2) {
|
||||
$this->SetValue("Ladestrom", 0);
|
||||
$this->SetValue("Entladedestrom", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Prüfe auf Änderung der Leistung 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 GetCurrentData(bool $Peak)
|
||||
{
|
||||
|
||||
|
||||
$ct = GetValue($this->ReadPropertyInteger("Kotnrolle_Selling_CT"));
|
||||
$sell_Ct = $this->GetValue("Batteriemanagement_Variabel");
|
||||
|
||||
|
||||
$V_Tou = GetValue($this->ReadPropertyInteger("Kotnrolle_TOU_Spannung"));
|
||||
$V_lad_ent = $this->GetValue("Batteriespannung_laden_entladen");
|
||||
|
||||
if ($ct != $sell_Ct || $V_Tou != $V_lad_ent) {
|
||||
$this->SetValue("Schreibkontrolle", false);
|
||||
} else {
|
||||
$this->SetValue("Schreibkontrolle", true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//$a = 2.54 * pow($V, 2) - 252 * $V + 6255.4;
|
||||
|
||||
if ($this->GetValue("Ladestrom") > 0 ) {
|
||||
$V = GetValue($this->ReadPropertyInteger("Batteriespannung")) + 1;
|
||||
}elseif ($this->GetValue("Entladedestrom") > 0) {
|
||||
$V = GetValue($this->ReadPropertyInteger("Batteriespannung")) - 1;
|
||||
} else {
|
||||
|
||||
$V = GetValue($this->ReadPropertyInteger("Batteriespannung"));
|
||||
}
|
||||
|
||||
IPS_LogMessage("Batterie", "Currentdata");
|
||||
|
||||
$array_powersteps = $this->GeneratePowerSteps($this->GetValue("Aktuelle_Leistung"));
|
||||
$aufdasnachladen = $this->ReadPropertyInteger("AufdasNachladen");
|
||||
$minimumentladen = $this->ReadPropertyInteger("MinimumEntladen");
|
||||
$maxleistung = $this->ReadPropertyInteger("MaxBatterieleistung");
|
||||
$dummy_array = [];
|
||||
|
||||
|
||||
$batterieladezustand = $V;
|
||||
|
||||
|
||||
|
||||
$filtered_powersteps_entladen = [];
|
||||
if ($this->ReadPropertyInteger("Batteriemanagement") == 2) {
|
||||
$dummy_array[] = 0;
|
||||
return $this->SetValue("PowerSteps", json_encode($dummy_array));
|
||||
}
|
||||
|
||||
$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));
|
||||
|
||||
}elseif($batterieladezustand>$minimumentladen){
|
||||
|
||||
$this->SetValue("PowerSteps", json_encode($array_powersteps));
|
||||
}
|
||||
else{
|
||||
|
||||
$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));
|
||||
}
|
||||
|
||||
}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");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
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 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user