RegisterPropertyInteger("MinLeistung", 3600); $this->RegisterPropertyInteger("MaxLeistung", 11000); $this->RegisterPropertyInteger("MinLeistung_1ph", 1400); $this->RegisterPropertyInteger("MaxLeistung_1ph", 7800); $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 // Ladestationspezifische Variabeln $this->RegisterVariableFloat("Max_Current", 0); $this->RegisterVariableBoolean("Is_1_ph", "Is_1_ph", "", false); $this->RegisterVariableBoolean("Car_Detected", false); $this->RegisterPropertyInteger("Pending_Counter", "Pending_Counter", "", 0); $this->RegisterVariableBoolean("Car_is_full", "Car_is_full", "", false); $this->RegisterVariableBoolean("Ladebereit", "Ladebereit", "~Switch", 1); $this->RegisterVariableBoolean("Solarladen", "Solarladen", "~Switch", 0); $this->RegisterVariableInteger("Fahrzeugstatus", "Fahrzeugstatus", "", 0); $this->RegisterVariableInteger("Lademodus", "Lademodus", "", 0); $this->RegisterVariableFloat("Ladeleistung_Effektiv", "Ladeleistung_Effektiv", "", 0); $this->RegisterVariableBoolean("Peak", "Peak", "", 0); $this->RegisterVariableInteger("Ladestrom", "Ladestrom"); $this->RegisterVariableInteger("Ladeleistung", "Ladeleistung"); // 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->RegisterVariableInteger("Power_Count", "Power_Count", "", 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_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("Power", 0); } break; default: throw new Exception("Invalid Ident"); } } public function Detect_Car(int $carType) { if($this->GetValue("Car_Detected")){ if($this->Get_Car_Status($carType)==true){ $this->SetValue("Car_Detected", true); }else{ $this->SetValue("Car_Detected", false); } } else{ if($this->Get_Car_Status($carType)==true){ $this->sendPowerToStation(32); $counter = $this->GetValue("Pending_Counter"); if($counter>(20/($this->ReadPropertyInteger("Interval")*1000))){ $this->SetValue("Pending_Counter", 0); if($this->GetValue("Ladeleistung_Effektiv")>7500){ $this->SetValue("Is_1_ph", false); } else{ $this->SetValue("Is_1_ph", true); } $this->Calc_Max_Current($this->GetValue("Is_1_ph")); $this->SetValue("Car_Detected", true); } else{ $this->SetValue("Pending_Counter", $counter+1); $this->SetValue("Car_Detected", false); } }else{ $this->SetValue("Car_Detected", false); } } return $this->GetValue("Car_Detected"); } public function Get_Car_Status(int $carType) { $plug_state = false; 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) { $plug_state = true; } $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) { $plug_state = true; } $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["State"] != 1) { $plug_state = true; } $this->SetValue("Ladeleistung_Effektiv", round($data["ActiveChargingPower"]*1000)); $this->SetValue("Fahrzeugstatus", $data["State"]); } break; case 4: $plug_state = true; break; case 5: echo "Fall 5"; break; default: $plug_state = false; $this->SetValue("Fahrzeugstatus", -1); break; } $this->SetValue("Car_detected", $plug_state); return $plug_state; } public function Calc_Max_Current(bool $is_1_ph) { $maxCurrent = 32; if($is_1_ph){ $maxCurrent = 1.1 * ($this->GetValue("Ladeleistung_Effektiv") / 230); } else{ $maxCurrent = 1.1 * ($this->GetValue("Ladeleistung_Effektiv") / (1.71*400)); } if($maxCurrent>32){ $maxCurrent = 32; } $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 = []; 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) { $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 // 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--; 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(Get_Current_From_Power($this->GetValue("Is_1_ph"), $this->GetValue("Max_Current"))); } else { // Ansonsten setze Ladeleistung auf die aktuelle Leistungsvorgabe (Aktuelle_Leistung) $this->sendPowerToStation(Get_Current_From_Power($this->GetValue("Is_1_ph"), $power)); } } // Methode zum Abrufen der aktuellen Daten public function GetCurrentData(bool $Peak) { // 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("Max_Current"))]; } elseif (!$Peak && $solarladen) { $powerSteps = $this->Get_Array_From_Current("Max_Current"); } elseif ($solarladen && $Peak) { $powerSteps = [0]; } else { $powerSteps = [0]; } // PowerSteps in der RegisterVariable speichern SetValue($this->GetIDForIdent("PowerSteps"), json_encode($powerSteps)); // Rückgabe der Powersteps $counter = $this->GetValue("Pending_Counter"); if(max($powerSteps)==$this->GetValue("Aktuelle_Leistung")){ if(max($powerSteps)>(1.11*$this->GetValue("Ladeleistung_Effektiv"))){ $this->SetValue("Pending_Counter", $counter+1); } else{ $this->SetValue("Pending_Counter", 0); } if($counter>(20/($this->ReadPropertyInteger("Interval")*1000))){ $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; } $value = $this->convertPowerToCurrent($value, GetValue($this->GetIDForIdent("Lademodus"))); $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"; 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."; } } } ?>