ConnectParent('{C6D2AEB3-6E1F-4B2E-8E69-3A1A00246850}'); $this->Subscribe("#"); $this->RegisterPropertyString("Devices", "[]"); $this->RegisterPropertyBoolean("Debug", false); } public function ApplyChanges() { parent::ApplyChanges(); $this->ConnectParent('{C6D2AEB3-6E1F-4B2E-8E69-3A1A00246850}'); $this->Subscribe("#"); } /* ------------------------------------------------------------------ * MQTT SUBSCRIBE * ------------------------------------------------------------------*/ private function Subscribe(string $topic): void { $packet = [ "PacketType" => 8, "QualityOfService" => 0, "Retain" => false, "Topic" => $topic, "Payload" => "" ]; $this->SendDataToParent(json_encode([ "DataID" => "{043EA491-0325-4ADD-8FC2-A30C8EEB4D3F}" ] + $packet)); } /* ------------------------------------------------------------------ * MQTT PUBLISH * ------------------------------------------------------------------*/ private function Publish(string $topic, string $payload): void { $packet = [ "PacketType" => 3, "QualityOfService" => 0, "Retain" => false, "Topic" => $topic, "Payload" => $payload ]; $this->SendDataToParent(json_encode([ "DataID" => "{043EA491-0325-4ADD-8FC2-A30C8EEB4D3F}" ] + $packet)); } /* ------------------------------------------------------------------ * RequestAction → Schalten des Outputs * ------------------------------------------------------------------*/ public function RequestAction($Ident, $Value) { $iid = IPS_GetParent($this->InstanceID); $this->SetValue($Ident, $Value); // output? if ($Ident === "output") { $deviceID = IPS_GetName($iid); $topic = $deviceID . "/rpc/Switch.Set"; $payload = json_encode([ "id" => 0, "on" => (bool)$Value ]); $this->Publish($topic, $payload); } } /* ------------------------------------------------------------------ * RECEIVE MQTT * ------------------------------------------------------------------*/ public function ReceiveData($JSONString) { $data = json_decode($JSONString, true); $topic = $data["Topic"] ?? ""; $payload = $data["Payload"] ?? ""; if ($topic === "") { return; } $parts = explode("/", $topic); $deviceID = $parts[0] ?? ""; if ($deviceID === "") { return; } // ONLINE if (isset($parts[1]) && $parts[1] === "online") { $this->HandleOnline($deviceID, $payload); return; } // RPC if ((($parts[1] ?? "") === "events") && (($parts[2] ?? "") === "rpc")) { $this->HandleRPC($deviceID, $payload); return; } } /* ------------------------------------------------------------------ * ONLINE * ------------------------------------------------------------------*/ private function HandleOnline(string $deviceID, string $payload) { $iid = $this->GetOrCreateDeviceInstance($deviceID); $onlineID = @$this->GetIDForIdentEx("online", $iid); if (!$onlineID) { $this->RegisterVariableBoolean("online", "Online"); } $this->SetValue("online", $payload === "true"); } /* ------------------------------------------------------------------ * RPC * ------------------------------------------------------------------*/ private function HandleRPC(string $deviceID, string $payload) { $json = json_decode($payload, true); if (!is_array($json)) { return; } $src = $json["src"] ?? ""; if (!str_starts_with($src, "shelly")) { return; } // Modell ermitteln $type = ShellyParser::ExtractType($src); $iid = $this->GetOrCreateDeviceInstance($deviceID); // Typ speichern $this->RegisterVariableString("type", "Geräte-Typ"); $this->SetValue("type", $type); // Parameter extrahieren $mapped = ShellyParser::MapParams($json["params"] ?? []); // Variablen anlegen if (isset($mapped["input"])) { $this->RegisterVariableBoolean("input", "Input"); $this->SetValue("input", $mapped["input"]); } if (isset($mapped["output"])) { $this->RegisterVariableBoolean("output", "Output"); $this->EnableAction("output"); $this->SetValue("output", $mapped["output"]); } if (isset($mapped["temperature"])) { $this->RegisterVariableFloat("temperature", "Temperatur"); $this->SetValue("temperature", $mapped["temperature"]); } } /* ------------------------------------------------------------------ * Helper → Child-Instanzen erzeugen * ------------------------------------------------------------------*/ private function GetOrCreateDeviceInstance(string $deviceID): int { foreach (IPS_GetInstanceListByModuleID("{ED0ED0AC-3843-0888-DF27-FA45435BCEF3}") as $id) { if (IPS_GetName($id) === $deviceID) { return $id; } } // neue Instanz $iid = IPS_CreateInstance("{ED0ED0AC-3843-0888-DF27-FA45435BCEF3}"); IPS_SetName($iid, $deviceID); IPS_SetParent($iid, $this->InstanceID); return $iid; } }