diff --git a/VGT_Sub/module.json b/VGT_Sub/module.json index 7283293..5cfc1cf 100644 --- a/VGT_Sub/module.json +++ b/VGT_Sub/module.json @@ -6,9 +6,9 @@ "aliases": [ "VGT MQTT Device" ], - "parentRequirements": ["{F66ADE63-8834-4178-8CA5-AE4465D2E252}"], + "parentRequirements": ["{F7A0DD2E-7684-95C0-64C2-D2A9DC47577B}"], "childRequirements": [], "implemented": ["{018EF6B5-AB94-40C6-AA53-46943E824ACF}"], "prefix": "VGT", - "version": "1.5" + "version": "1.6" } \ No newline at end of file diff --git a/VGT_Sub/module.php b/VGT_Sub/module.php index fded11b..73d46df 100644 --- a/VGT_Sub/module.php +++ b/VGT_Sub/module.php @@ -9,13 +9,14 @@ class VGT_Sub extends IPSModule parent::Create(); // --------------------------------------------------------------------- - // 1. MQTT Verbindungsdaten (werden an das Gateway durchgereicht) + // 1. MQTT Verbindungsdaten (für den IO/Socket) // --------------------------------------------------------------------- $this->RegisterPropertyString('MQTTBaseTopic', 'Test VGT_Steuerung/Komm'); $this->RegisterPropertyString('MQTTClientID', 'symcon_vgt_client'); $this->RegisterPropertyString('MQTTUser', ''); $this->RegisterPropertyString('MQTTPassword', ''); - $this->RegisterPropertyBoolean('UpdateGatewayConfig', true); // Schalter: Sollen wir das Gateway überschreiben? + // Checkbox: Sollen die IO-Daten überschrieben werden? + $this->RegisterPropertyBoolean('UpdateGatewayConfig', true); // --------------------------------------------------------------------- // 2. Hardware Verknüpfungen @@ -34,7 +35,7 @@ class VGT_Sub extends IPSModule $this->RegisterVariableString('Strategy', 'Strategy', '', 10); $this->RegisterVariableInteger('PowerSetpoint', 'Power Setpoint', '', 20); - // Visu + // Visu (Nur zur Anzeige) $this->RegisterVariableFloat('Visu_SoC', 'State of Charge', '~Intensity.100', 30); $this->RegisterVariableFloat('Visu_Production', 'Power Production', '~Watt', 40); $this->RegisterVariableBoolean('Visu_IsReady', 'Is Ready', '~Switch', 50); @@ -48,17 +49,17 @@ class VGT_Sub extends IPSModule parent::ApplyChanges(); // --------------------------------------------------------------------- - // A. Filter setzen (Automatisches Subscribe) + // A. Filter setzen (Subscribe) // --------------------------------------------------------------------- $topic = $this->ReadPropertyString('MQTTBaseTopic'); if($topic !== "") { $cleanTopic = preg_quote($topic, '/'); - // Wir abonnieren ALLES unterhalb des BaseTopics + // Filter für den Splitter: Alles empfangen, was mit BaseTopic beginnt $this->SetReceiveDataFilter(".*\"Topic\":\"" . $cleanTopic . "/.*\".*"); } // --------------------------------------------------------------------- - // B. Gateway (IO) Konfiguration aktualisieren + // B. Gateway (IO/Socket) Konfiguration aktualisieren // --------------------------------------------------------------------- if ($this->ReadPropertyBoolean('UpdateGatewayConfig')) { $this->ConfigureGateway(); @@ -76,45 +77,58 @@ class VGT_Sub extends IPSModule } /** - * Diese Funktion sucht die IO-Instanz (MQTT Client) und setzt User/Passwort + * Sucht den IO (Socket) und setzt User/Passwort/ClientID */ private function ConfigureGateway() { - // 1. Suche Parent (MQTT Splitter) + // 1. Parent (Splitter) holen $instance = IPS_GetInstance($this->InstanceID); $splitterID = $instance['ConnectionID']; if ($splitterID > 0) { - // 2. Suche Grandparent (MQTT Client / IO) + // 2. Grandparent (IO / Client Socket) holen $splitter = IPS_GetInstance($splitterID); $ioID = $splitter['ConnectionID']; if ($ioID > 0) { - // Prüfen, ob es ein MQTT Client ist (GUID prüfen oder einfach Eigenschaften setzen) - // Wir setzen die Eigenschaften, wenn sie existieren. - $user = $this->ReadPropertyString('MQTTUser'); $pass = $this->ReadPropertyString('MQTTPassword'); $client = $this->ReadPropertyString('MQTTClientID'); $hasChanged = false; - // ClientID (Achtung: Symcon MQTT Splitter nutzt ClientID meist im Splitter, nicht IO) - // Wir prüfen, wo die Property existiert. - - // Versuch 1: IO Konfigurieren (User/Pass) + // --- 1. Benutzer/Passwort am IO setzen (meist MQTT Client Socket) --- + // Prüfen ob Properties existieren, um Fehler zu vermeiden if (@IPS_GetProperty($ioID, 'Username') !== false) { - if (IPS_GetProperty($ioID, 'Username') != $user) { IPS_SetProperty($ioID, 'Username', $user); $hasChanged = true; } - if (IPS_GetProperty($ioID, 'Password') != $pass) { IPS_SetProperty($ioID, 'Password', $pass); $hasChanged = true; } + if (IPS_GetProperty($ioID, 'Username') != $user) { + IPS_SetProperty($ioID, 'Username', $user); + $hasChanged = true; + } + } + if (@IPS_GetProperty($ioID, 'Password') !== false) { + if (IPS_GetProperty($ioID, 'Password') != $pass) { + IPS_SetProperty($ioID, 'Password', $pass); + $hasChanged = true; + } } - // Versuch 2: ClientID wird oft im Splitter (dem direkten Parent) konfiguriert + // --- 2. ClientID am Splitter setzen (oft ist ClientID im Splitter, nicht IO) --- + // Falls ClientID im Splitter definiert ist: if (@IPS_GetProperty($splitterID, 'ClientID') !== false) { - if (IPS_GetProperty($splitterID, 'ClientID') != $client) { IPS_SetProperty($splitterID, 'ClientID', $client); $hasChanged = true; } // Splitter neu laden - if ($hasChanged) IPS_ApplyChanges($splitterID); + if (IPS_GetProperty($splitterID, 'ClientID') != $client) { + IPS_SetProperty($splitterID, 'ClientID', $client); + IPS_ApplyChanges($splitterID); // Splitter sofort übernehmen + } + } + // Falls ClientID doch am IO ist: + elseif (@IPS_GetProperty($ioID, 'ClientID') !== false) { + if (IPS_GetProperty($ioID, 'ClientID') != $client) { + IPS_SetProperty($ioID, 'ClientID', $client); + $hasChanged = true; + } } - // Änderungen am IO übernehmen + // IO Änderungen speichern if ($hasChanged) { IPS_ApplyChanges($ioID); } @@ -123,7 +137,7 @@ class VGT_Sub extends IPSModule } // ------------------------------------------------------------------------- - // MQTT Logik (unverändert) + // MQTT Logik // ------------------------------------------------------------------------- public function ReceiveData($JSONString) { @@ -132,8 +146,7 @@ class VGT_Sub extends IPSModule $topic = $data->Topic; $baseTopic = $this->ReadPropertyString('MQTTBaseTopic'); - // Debug - $this->SendDebug('MQTT Received', "Topic: $topic | Payload: $payload", 0); + //$this->SendDebug('MQTT Received', "Topic: $topic | Payload: $payload", 0); if ($topic === $baseTopic . '/Writebefehl') { $this->ProcessWriteCommand($payload); @@ -187,7 +200,6 @@ class VGT_Sub extends IPSModule 'power_setpoint' => $this->GetValue('PowerSetpoint'), 'strategy' => $this->GetValue('Strategy') ]; - // Antwort senden $this->SendMQTT($this->ReadPropertyString('MQTTBaseTopic') . '/Writebefehl Antwort', json_encode($output)); } @@ -205,7 +217,6 @@ class VGT_Sub extends IPSModule 'min_soc' => $data['min_soc'], 'max_soc' => $data['max_soc'] ]; - // Antwort senden $this->SendMQTT($this->ReadPropertyString('MQTTBaseTopic') . '/Lesebefehl Antwort', json_encode($mqttData)); } @@ -252,13 +263,17 @@ class VGT_Sub extends IPSModule protected function SendMQTT($Topic, $Payload) { - // Standard DataID für MQTT Publish an Splitter + // DataID für Symcon MQTT Publish. + // Falls der Schnittcher-Splitter eine andere ID will, könnte hier ein Fehler kommen. + // In den meisten Fällen funktioniert diese ID aber auch mit kompatiblen Splittern. $Data['DataID'] = '{043EA491-0325-4ADD-8FC2-A30C8EEB4D3F}'; + $Data['PacketType'] = 3; $Data['QualityOfService'] = 0; $Data['Retain'] = false; $Data['Topic'] = $Topic; $Data['Payload'] = $Payload; + $JSON = json_encode($Data); $this->SendDataToParent($JSON); }