diff --git a/VGT_Sub/module.php b/VGT_Sub/module.php index 5a53ea2..fa39dcd 100644 --- a/VGT_Sub/module.php +++ b/VGT_Sub/module.php @@ -4,126 +4,124 @@ declare(strict_types=1); class VGT_Sub extends IPSModule { + private bool $Subscribed = false; + public function Create() { parent::Create(); - $this->RegisterPropertyString("DeviceID", ""); + // MQTT CLIENT – NICHT Splitter! + $this->ConnectParent('{C6D2AEB3-6E1F-4B2E-8E69-3A1A00246850}'); - // --- Variablen für Feedback --- - $this->RegisterVariableFloat("PowerProduction", "Power Production", "", 10); - $this->RegisterVariableBoolean("IsReady", "Is Ready", "", 11); - $this->RegisterVariableBoolean("IsRunning", "Is Running", "", 12); - $this->RegisterVariableFloat("StateOfCharge", "State of Charge", "", 13); - $this->RegisterVariableFloat("MinSOC", "Min SOC", "", 14); - $this->RegisterVariableFloat("MaxSOC", "Max SOC", "", 15); + $this->RegisterPropertyString('DeviceID', ''); - // --- Variablen für Remote Control --- - $this->RegisterVariableFloat("PowerSetpoint", "Power Setpoint", "", 20); - $this->RegisterVariableString("Strategy", "Strategy", "", 21); + // Feedback Variablen + $this->RegisterVariableFloat('PowerProduction', 'Power Production', '', 10); + $this->RegisterVariableFloat('StateOfCharge', 'State of Charge', '', 11); + $this->RegisterVariableBoolean('IsRunning', 'Is Running', '', 12); + $this->RegisterVariableBoolean('IsReady', 'Is Ready', '', 13); + $this->RegisterVariableFloat('MinSOC', 'Min SOC', '', 14); + $this->RegisterVariableFloat('MaxSOC', 'Max SOC', '', 15); - // Debug-Variablen - $this->RegisterVariableString("FeedbackRequestPayload", "Feedback Request", "", 90); - $this->RegisterVariableString("RemoteControlPayload", "Remote Control Request", "", 91); + // Remote Control + $this->RegisterVariableFloat('PowerSetpoint', 'Power Setpoint', '', 20); + $this->RegisterVariableString('Strategy', 'Strategy', '', 21); - // MQTT Splitter (NUR dieser ist korrekt) - $this->ConnectParent("{F7A0DD2E-7684-95C0-64C2-D2A9DC47577B}"); + // Debug + $this->RegisterVariableString('FeedbackRequestPayload', 'Feedback Request', '', 90); + $this->RegisterVariableString('RemoteControlPayload', 'Remote Control', '', 91); } public function ApplyChanges() { parent::ApplyChanges(); - $this->ConnectParent("{F7A0DD2E-7684-95C0-64C2-D2A9DC47577B}"); + $this->ConnectParent('{C6D2AEB3-6E1F-4B2E-8E69-3A1A00246850}'); + $this->Subscribed = false; } - public function RequestAction($Ident, $Value) + private function Log($t, $m) { - SetValue($this->GetIDForIdent($Ident), $Value); + IPS_LogMessage("VGT_Sub/$t", $m); + $this->SendDebug($t, $m, 0); } - - /* ===================================================================================== - * MQTT Funktionen - * ===================================================================================== */ - - private function Subscribe(string $topic) + private function SafeSend(array $p) { - $this->SendDataToParent(json_encode([ - "DataID" => "{F7A0DD2E-7684-95C0-64C2-D2A9DC47577B}", - "Buffer" => [ - "Topic" => $topic, - "QualityOfService" => 0 - ] - ])); + $parent = @IPS_GetInstance($this->InstanceID)['ConnectionID'] ?? 0; + if ($parent === 0) return; + if (IPS_GetInstance($parent)['InstanceStatus'] !== 102) return; + @$this->SendDataToParent(json_encode($p)); + } + + private function EnsureSubscribe() + { + if ($this->Subscribed) return; + $this->Subscribed = true; + + $this->SafeSend([ + 'DataID' => '{043EA491-0325-4ADD-8FC2-A30C8EEB4D3F}', + 'PacketType' => 8, + 'QualityOfService' => 0, + 'Retain' => false, + 'Topic' => '#', + 'Payload' => '' + ]); + + $this->Log("Subscribe", "#"); } private function Publish(string $topic, string $payload) { - $this->SendDataToParent(json_encode([ - "DataID" => "{F7A0DD2E-7684-95C0-64C2-D2A9DC47577B}", - "Buffer" => [ - "Command" => "PUBLISH", - "Topic" => $topic, - "Payload" => $payload, - "Retain" => false, - "QualityOfService" => 0 - ] - ])); + $this->SafeSend([ + 'DataID' => '{043EA491-0325-4ADD-8FC2-A30C8EEB4D3F}', + 'PacketType' => 3, + 'QualityOfService' => 0, + 'Retain' => false, + 'Topic' => $topic, + 'Payload' => $payload + ]); + + $this->Log("Publish", "$topic → $payload"); } - /* ===================================================================================== - * ReceiveData – erkennt NUR das tatsächliche Splitter-Format - * ===================================================================================== */ public function ReceiveData($JSONString) { + $this->EnsureSubscribe(); + $data = json_decode($JSONString, true); - if (!isset($data["Buffer"])) return; + if (!is_array($data)) return; - $buf = $data["Buffer"]; + $topic = $data['Topic'] ?? ''; + $payload = $data['Payload'] ?? ''; - /* CONNECTED? → Dann subscriben */ - if (isset($buf["Message"]) && $buf["Message"] === "MQTT_CONNECTED") { + if ($topic === '') return; - $dev = $this->ReadPropertyString("DeviceID"); - if ($dev) { - $this->Subscribe("feedback-request/$dev"); - $this->Subscribe("remote-control-request/$dev"); - } - return; - } + $this->Log("RX", "$topic → $payload"); - /* Normale MQTT Message */ - if (!isset($buf["Topic"]) || !isset($buf["Payload"])) return; + $device = $this->ReadPropertyString('DeviceID'); - $topic = $buf["Topic"]; - $payload = $buf["Payload"]; + /* ================== FEEDBACK ================== */ - $device = $this->ReadPropertyString("DeviceID"); - - /* ===================================================================================== - * FEEDBACK REQUEST - * ===================================================================================== */ if ($topic === "feedback-request/$device") { - $this->SetValue("FeedbackRequestPayload", $payload); + $this->SetValue('FeedbackRequestPayload', $payload); - $response = [ + $resp = [ "power_production" => GetValueFloat($this->GetIDForIdent("PowerProduction")), "is_ready" => GetValueBoolean($this->GetIDForIdent("IsReady")), "is_running" => GetValueBoolean($this->GetIDForIdent("IsRunning")), "state_of_charge" => GetValueFloat($this->GetIDForIdent("StateOfCharge")), "min_soc" => GetValueFloat($this->GetIDForIdent("MinSOC")), - "max_soc" => GetValueFloat($this->GetIDForIdent("MaxSOC")), + "max_soc" => GetValueFloat($this->GetIDForIdent("MaxSOC")) ]; - $this->Publish("feedback-response/$device", json_encode($response)); + $this->Publish("feedback-response/$device", json_encode($resp)); return; } - /* ===================================================================================== - * REMOTE CONTROL REQUEST - * ===================================================================================== */ + /* ================== REMOTE CONTROL ================== */ + if ($topic === "remote-control-request/$device") { $this->SetValue("RemoteControlPayload", $payload); @@ -131,13 +129,11 @@ class VGT_Sub extends IPSModule $json = json_decode($payload, true); if (!is_array($json)) return; - if (isset($json["power_setpoint"])) { + if (isset($json["power_setpoint"])) SetValueFloat($this->GetIDForIdent("PowerSetpoint"), floatval($json["power_setpoint"])); - } - if (isset($json["strategy"])) { - SetValueString($this->GetIDForIdent("Strategy"), strval($json["strategy"])); - } + if (isset($json["strategy"])) + SetValueString($this->GetIDForIdent("Strategy"), $json["strategy"]); $this->Publish("remote-control-response/$device", json_encode($json)); return;