From b50b47e8d8041f45719c9a777264c9c2f2f80acb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=A4fliger?= Date: Fri, 14 Nov 2025 11:16:23 +0100 Subject: [PATCH] no message --- Shelly_Parser_MQTT/module.php | 133 ++++++++++++++++++++++------------ 1 file changed, 88 insertions(+), 45 deletions(-) diff --git a/Shelly_Parser_MQTT/module.php b/Shelly_Parser_MQTT/module.php index 647cff1..34fe893 100644 --- a/Shelly_Parser_MQTT/module.php +++ b/Shelly_Parser_MQTT/module.php @@ -13,9 +13,10 @@ class Shelly_Parser_MQTT extends IPSModule // MQTT-Server verbinden $this->ConnectParent('{C6D2AEB3-6E1F-4B2E-8E69-3A1A00246850}'); - // Auf alle Topics hören + // alle Topics hören $this->Subscribe('#'); + // Debug $this->RegisterPropertyBoolean('Debug', false); } @@ -27,6 +28,19 @@ class Shelly_Parser_MQTT extends IPSModule $this->Subscribe('#'); } + /* --------------------------------------------------------- + * DEBUG WRAPPER + * ---------------------------------------------------------*/ + private function Log($title, $msg) + { + if (!$this->ReadPropertyBoolean('Debug')) { + return; + } + + IPS_LogMessage("ShellyMQTT - $title", $msg); + $this->SendDebug($title, $msg, 0); + } + /* --------------------------------------------------------- * MQTT SUBSCRIBE * ---------------------------------------------------------*/ @@ -43,6 +57,8 @@ class Shelly_Parser_MQTT extends IPSModule $this->SendDataToParent(json_encode([ 'DataID' => '{043EA491-0325-4ADD-8FC2-A30C8EEB4D3F}' ] + $packet)); + + $this->Log("Subscribe", "Topic: $topic"); } /* --------------------------------------------------------- @@ -62,7 +78,7 @@ class Shelly_Parser_MQTT extends IPSModule 'DataID' => '{043EA491-0325-4ADD-8FC2-A30C8EEB4D3F}' ] + $packet)); - $this->SendDebug("Publish", "$topic → $payload", 0); + $this->Log("Publish", "$topic → $payload"); } /* --------------------------------------------------------- @@ -70,7 +86,7 @@ class Shelly_Parser_MQTT extends IPSModule * ---------------------------------------------------------*/ public function RequestAction($Ident, $Value) { - $this->SendDebug('RequestAction', "$Ident → " . json_encode($Value), 0); + $this->Log('RequestAction', "$Ident → " . json_encode($Value)); if (!str_contains($Ident, '_output_')) { throw new Exception("Unknown Ident: " . $Ident); @@ -100,18 +116,18 @@ class Shelly_Parser_MQTT extends IPSModule ] ]); - $this->SendDebug('MQTT SEND', "$topic : $payload", 0); + $this->Log('MQTT SEND', "$topic : $payload"); // absenden $this->Publish($topic, $payload); } /* --------------------------------------------------------- - * RECEIVE MQTT DATA + * MQTT RECEIVE * ---------------------------------------------------------*/ public function ReceiveData($JSONString) { - $this->SendDebug('ReceiveData', $JSONString, 0); + $this->Log('ReceiveData', $JSONString); $data = json_decode($JSONString, true); if (!is_array($data)) { @@ -121,26 +137,24 @@ class Shelly_Parser_MQTT extends IPSModule $topic = $data['Topic'] ?? ''; $payload = $data['Payload'] ?? ''; - if ($topic === '') { - return; - } + if ($topic === '') return; + + $this->Log('ReceiveTopic', "$topic → $payload"); $parts = explode('/', $topic); $deviceID = $parts[0] ?? ''; - if ($deviceID === '') { - return; - } + if ($deviceID === '') return; // /online - if ((isset($parts[1])) && ($parts[1] === 'online')) { + if (($parts[1] ?? '') === 'online') { $this->HandleOnline($deviceID, $payload); return; } // /events/rpc - if ((isset($parts[1]) && $parts[1] === 'events') && - (isset($parts[2]) && $parts[2] === 'rpc')) { + if (($parts[1] ?? '') === 'events' && + ($parts[2] ?? '') === 'rpc') { $this->HandleRPC($deviceID, $payload); return; } @@ -153,24 +167,24 @@ class Shelly_Parser_MQTT extends IPSModule { $value = ($payload === 'true' || $payload === '1'); + $this->Log("DeviceOnline", "$deviceID = " . json_encode($value)); + $varID = $this->EnsureBooleanVariable($deviceID, $deviceID . '_online', 'Online'); SetValue($varID, $value); } /* --------------------------------------------------------- - * RPC-EVENTS VERARBEITEN + * RPC DATA * ---------------------------------------------------------*/ private function HandleRPC(string $deviceID, string $payload): void { + $this->Log("HandleRPC", "$deviceID : $payload"); + $json = json_decode($payload, true); - if (!is_array($json)) { - return; - } + if (!is_array($json)) return; $src = $json['src'] ?? ''; - if (!str_starts_with($src, 'shelly')) { - return; - } + if (!str_starts_with($src, 'shelly')) return; // Gerätetyp merken $type = ShellyParser::ExtractType($src); @@ -186,7 +200,9 @@ class Shelly_Parser_MQTT extends IPSModule * -------------------------*/ foreach ($mapped['outputs'] as $index => $value) { $ident = $deviceID . '_output_' . $index; - $name = 'Output ' . $index; + $name = "Output $index"; + + $this->Log("RPC Output", "$ident = " . json_encode($value)); $varID = $this->EnsureBooleanVariable($deviceID, $ident, $name); SetValue($varID, $value); @@ -197,7 +213,9 @@ class Shelly_Parser_MQTT extends IPSModule * -------------------------*/ foreach ($mapped['inputs'] as $index => $value) { $ident = $deviceID . '_input_' . $index; - $name = 'Input ' . $index; + $name = "Input $index"; + + $this->Log("RPC Input", "$ident = " . json_encode($value)); $varID = $this->EnsureBooleanVariable($deviceID, $ident, $name); SetValue($varID, $value); @@ -207,27 +225,59 @@ class Shelly_Parser_MQTT extends IPSModule * TEMPERATUR * -------------------------*/ if ($mapped['temperature'] !== null) { + $this->Log("RPC Temperature", json_encode($mapped['temperature'])); + $tempID = $this->EnsureFloatVariable($deviceID, $deviceID . '_temperature', 'Temperatur'); SetValue($tempID, $mapped['temperature']); } } /* --------------------------------------------------------- - * HELPER: BOOLEAN VARIABLE + * AUTOMATISCHES ACTION-SCRIPT + * ---------------------------------------------------------*/ + private function EnsureActionScript(): int + { + $scriptName = "ShellyMQTT_Action_" . $this->InstanceID; + + // existiert bereits? + foreach (IPS_GetChildrenIDs($this->InstanceID) as $cid) { + $obj = IPS_GetObject($cid); + if ($obj['ObjectType'] === OBJECTTYPE_SCRIPT && $obj['ObjectName'] === $scriptName) { + return $cid; + } + } + + // neues Script erzeugen + $scriptID = IPS_CreateScript(0); + IPS_SetName($scriptID, $scriptName); + IPS_SetParent($scriptID, $this->InstanceID); + + $php = 'InstanceID . '; +$ident = IPS_GetObject($_IPS["VARIABLE"])["ObjectIdent"]; +$value = $_IPS["VALUE"]; +IPS_RequestAction($inst, $ident, $value); +?>'; + + IPS_SetScriptContent($scriptID, $php); + + return $scriptID; + } + + /* --------------------------------------------------------- + * BOOLEAN VARIABLE * ---------------------------------------------------------*/ private function EnsureBooleanVariable(string $deviceID, string $ident, string $name): int { $folderID = $this->GetDeviceFolder($deviceID); - // bestehende Variable? foreach (IPS_GetChildrenIDs($folderID) as $cid) { - $obj = IPS_GetObject($cid); + $o = IPS_GetObject($cid); + if ($o['ObjectIdent'] === $ident) { - if ($obj['ObjectIdent'] === $ident && $obj['ObjectType'] === OBJECTTYPE_VARIABLE) { - - // OUTPUT → immer CustomAction setzen if (str_contains($ident, '_output_')) { - IPS_SetVariableCustomAction($cid, $this->InstanceID); + $actionScript = $this->EnsureActionScript(); + IPS_SetVariableCustomAction($cid, $actionScript); $var = IPS_GetVariable($cid); if ($var['VariableProfile'] === '' && $var['VariableCustomProfile'] === '') { @@ -239,15 +289,15 @@ class Shelly_Parser_MQTT extends IPSModule } } - // neue Variable + // neu $varID = IPS_CreateVariable(0); IPS_SetIdent($varID, $ident); IPS_SetName($varID, $name); IPS_SetParent($varID, $folderID); - // OUTPUT-Profil + Action if (str_contains($ident, '_output_')) { - IPS_SetVariableCustomAction($varID, $this->InstanceID); + $actionScript = $this->EnsureActionScript(); + IPS_SetVariableCustomAction($varID, $actionScript); IPS_SetVariableCustomProfile($varID, '~Switch'); } @@ -262,10 +312,8 @@ class Shelly_Parser_MQTT extends IPSModule $folderID = $this->GetDeviceFolder($deviceID); foreach (IPS_GetChildrenIDs($folderID) as $cid) { - $obj = IPS_GetObject($cid); - if ($obj['ObjectIdent'] === $ident) { + if (IPS_GetObject($cid)['ObjectIdent'] === $ident) return $cid; - } } $id = $this->RegisterVariableFloat($ident, $name); @@ -281,10 +329,8 @@ class Shelly_Parser_MQTT extends IPSModule $folderID = $this->GetDeviceFolder($deviceID); foreach (IPS_GetChildrenIDs($folderID) as $cid) { - $obj = IPS_GetObject($cid); - if ($obj['ObjectIdent'] === $ident) { + if (IPS_GetObject($cid)['ObjectIdent'] === $ident) return $cid; - } } $id = $this->RegisterVariableString($ident, $name); @@ -300,13 +346,10 @@ class Shelly_Parser_MQTT extends IPSModule $folderIdent = 'folder_' . $deviceID; foreach (IPS_GetChildrenIDs($this->InstanceID) as $cid) { - $obj = IPS_GetObject($cid); - if ($obj['ObjectIdent'] === $folderIdent && $obj['ObjectType'] === OBJECTTYPE_CATEGORY) { + if (IPS_GetObject($cid)['ObjectIdent'] === $folderIdent) return $cid; - } } - // neu anlegen $folderID = IPS_CreateCategory(); IPS_SetParent($folderID, $this->InstanceID); IPS_SetName($folderID, $deviceID); @@ -316,7 +359,7 @@ class Shelly_Parser_MQTT extends IPSModule } /* --------------------------------------------------------- - * HELPER: VARIABLE FINDEN + * VARIABLE FINDEN * ---------------------------------------------------------*/ private function FindVariableByIdent(string $Ident) {