Files
Symcon_Belevo_Energiemanage…/Shelly_Parser_MQTT/module.php
2025-11-14 08:42:38 +01:00

223 lines
6.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
require_once __DIR__ . "/libs/ShellyParser.php";
class Shelly_Parser_MQTT extends IPSModule
{
public function Create()
{
parent::Create();
$this->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)
{
$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)
{
$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"]);
}
}
public function ShellyScanDevices()
{
// Diese Funktion kann später echte Scan-Logik erhalten.
// Jetzt nur Dummy, damit das Modul geladen wird.
IPS_LogMessage("Shelly_Parser_MQTT", "ShellyScanDevices() aufgerufen");
// Optional: spätere Erweiterung bekannte Devices ausgeben
$devices = json_decode($this->ReadPropertyString("Devices"), true);
if (is_array($devices)) {
IPS_LogMessage("Shelly_Parser_MQTT", "Aktuell gespeicherte Geräte: " . json_encode($devices));
}
}
/* ------------------------------------------------------------------
* Helper → Child-Instanzen erzeugen
* ------------------------------------------------------------------*/
private function GetOrCreateDeviceInstance(string $deviceID)
{
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;
}
}
?>