no message

This commit is contained in:
2026-02-10 15:09:06 +01:00
parent ccb068dd5d
commit 851dc7d70e
2 changed files with 53 additions and 28 deletions

View File

@@ -7,11 +7,11 @@
"VGT MQTT Device" "VGT MQTT Device"
], ],
"parentRequirements": [ "parentRequirements": [
"{F7A0DD2E-7684-95C0-64C2-D2A9DC47577B}", "{F66ADE63-8834-4178-8CA5-AE4465D2E252}",
"{F66ADE63-8834-4178-8CA5-AE4465D2E252}" "{F7A0DD2E-7684-95C0-64C2-D2A9DC47577B}"
], ],
"childRequirements": [], "childRequirements": [],
"implemented": ["{018EF6B5-AB94-40C6-AA53-46943E824ACF}"], "implemented": ["{018EF6B5-AB94-40C6-AA53-46943E824ACF}"],
"prefix": "VGT", "prefix": "VGT",
"version": "2.1" "version": "3.0"
} }

View File

@@ -4,6 +4,10 @@ declare(strict_types=1);
class VGT_Sub extends IPSModule class VGT_Sub extends IPSModule
{ {
// GUIDs für den offiziellen IP-Symcon Datenfluss (MQTT)
const MQTT_TX_GUID = '{043EA491-0325-4ADD-8FC2-A30C8EEB4D3F}'; // Wir senden das an den Splitter
const MQTT_RX_GUID = '{018EF6B5-AB94-40C6-AA53-46943E824ACF}'; // Wir empfangen das (implemented)
public function Create() public function Create()
{ {
parent::Create(); parent::Create();
@@ -11,7 +15,7 @@ class VGT_Sub extends IPSModule
// --- Konfiguration --- // --- Konfiguration ---
$this->RegisterPropertyString('MQTTBaseTopic', 'Test VGT_Steuerung/Komm'); $this->RegisterPropertyString('MQTTBaseTopic', 'Test VGT_Steuerung/Komm');
// --- Optionale Gateway-Konfig (Nur für IO/Socket relevant) --- // Gateway-Konfig (Optional für Komfort)
$this->RegisterPropertyString('MQTTUser', ''); $this->RegisterPropertyString('MQTTUser', '');
$this->RegisterPropertyString('MQTTPassword', ''); $this->RegisterPropertyString('MQTTPassword', '');
$this->RegisterPropertyBoolean('UpdateGatewayConfig', false); $this->RegisterPropertyBoolean('UpdateGatewayConfig', false);
@@ -37,36 +41,49 @@ class VGT_Sub extends IPSModule
{ {
parent::ApplyChanges(); parent::ApplyChanges();
// 1. Filter setzen (Abonnieren) // ---------------------------------------------------------------------
// DATENFLUSS: Filter setzen
// ---------------------------------------------------------------------
// Wir teilen dem Splitter mit: "Schick mir nur Daten für mein Topic"
// Das entlastet das System massiv.
$topic = $this->ReadPropertyString('MQTTBaseTopic'); $topic = $this->ReadPropertyString('MQTTBaseTopic');
if($topic !== "") { if($topic !== "") {
$cleanTopic = preg_quote($topic, '/'); $cleanTopic = preg_quote($topic, '/');
// Dieser Filter funktioniert für beide Splitter-Varianten // Regex Filter auf das Feld "Topic" im JSON Datensatz
$this->SetReceiveDataFilter(".*\"Topic\":\"" . $cleanTopic . "/.*\".*"); $this->SetReceiveDataFilter(".*\"Topic\":\"" . $cleanTopic . "/.*\".*");
} }
// 2. Gateway Config (Optional) // ---------------------------------------------------------------------
// Komfort: Gateway Konfiguration durchreichen
// ---------------------------------------------------------------------
if ($this->ReadPropertyBoolean('UpdateGatewayConfig')) { if ($this->ReadPropertyBoolean('UpdateGatewayConfig')) {
$this->ConfigureGateway(); $this->ConfigureGateway();
} }
// 3. Events registrieren // ---------------------------------------------------------------------
// Events
// ---------------------------------------------------------------------
$socID = $this->ReadPropertyInteger('SourceSoC'); $socID = $this->ReadPropertyInteger('SourceSoC');
if (IPS_VariableExists($socID)) $this->RegisterMessage($socID, VM_UPDATE); if (IPS_VariableExists($socID)) $this->RegisterMessage($socID, VM_UPDATE);
$this->RegisterMessage($this->GetIDForIdent('Strategy'), VM_UPDATE); $this->RegisterMessage($this->GetIDForIdent('Strategy'), VM_UPDATE);
$this->RegisterMessage($this->GetIDForIdent('PowerSetpoint'), VM_UPDATE); $this->RegisterMessage($this->GetIDForIdent('PowerSetpoint'), VM_UPDATE);
} }
// -------------------------------------------------------------------------
// DATENFLUSS: Empfang (ReceiveData)
// -------------------------------------------------------------------------
// Wird automatisch aufgerufen, wenn der Splitter Daten hat, die zum Filter passen.
public function ReceiveData($JSONString) public function ReceiveData($JSONString)
{ {
$data = json_decode($JSONString); $data = json_decode($JSONString);
// Payload Dekodierung // Daten aus dem JSON extrahieren (Standard Symcon Format)
$payload = utf8_decode($data->Payload); $payload = utf8_decode($data->Payload);
$topic = $data->Topic; $topic = $data->Topic;
$baseTopic = $this->ReadPropertyString('MQTTBaseTopic'); $baseTopic = $this->ReadPropertyString('MQTTBaseTopic');
// Routing
if ($topic === $baseTopic . '/Writebefehl') { if ($topic === $baseTopic . '/Writebefehl') {
$this->ProcessWriteCommand($payload); $this->ProcessWriteCommand($payload);
} }
@@ -75,6 +92,28 @@ class VGT_Sub extends IPSModule
} }
} }
// -------------------------------------------------------------------------
// DATENFLUSS: Senden (SendDataToParent)
// -------------------------------------------------------------------------
protected function SendMQTT($Topic, $Payload)
{
// Wir bauen das JSON Paket exakt so, wie der MQTT Splitter es erwartet
$Data = [
'DataID' => self::MQTT_TX_GUID, // Die ID für "MQTT Publish"
'PacketType' => 3, // 3 = Publish
'QualityOfService' => 0,
'Retain' => false,
'Topic' => $Topic,
'Payload' => $Payload
];
// Ab an den Parent (Splitter)
$this->SendDataToParent(json_encode($Data));
}
// -------------------------------------------------------------------------
// Interne Logik
// -------------------------------------------------------------------------
private function ProcessWriteCommand($jsonInput) private function ProcessWriteCommand($jsonInput)
{ {
$data = json_decode($jsonInput, true); $data = json_decode($jsonInput, true);
@@ -130,33 +169,18 @@ class VGT_Sub extends IPSModule
else RequestAction($targetID, -2500); else RequestAction($targetID, -2500);
} }
} }
protected function SendMQTT($Topic, $Payload)
{
// Standard DataID für MQTT. Funktioniert meistens auch mit dem 77B-Modul.
$Data['DataID'] = '{043EA491-0325-4ADD-8FC2-A30C8EEB4D3F}';
$Data['PacketType'] = 3;
$Data['QualityOfService'] = 0;
$Data['Retain'] = false;
$Data['Topic'] = $Topic;
$Data['Payload'] = $Payload;
$this->SendDataToParent(json_encode($Data));
}
// Automatische Konfiguration des Parents (falls aktiviert) // Hilfsfunktion: IO Konfigurieren
private function ConfigureGateway() private function ConfigureGateway()
{ {
$instance = IPS_GetInstance($this->InstanceID); $instance = IPS_GetInstance($this->InstanceID);
$parentId = $instance['ConnectionID']; // Das ist dein 77B Modul oder der native Splitter $parentId = $instance['ConnectionID'];
if ($parentId > 0) { if ($parentId > 0) {
// Wir versuchen, User/Pass auf dem Parent zu setzen (manche Module haben das direkt)
// Oder wir suchen den IO darunter.
$user = $this->ReadPropertyString('MQTTUser'); $user = $this->ReadPropertyString('MQTTUser');
$pass = $this->ReadPropertyString('MQTTPassword'); $pass = $this->ReadPropertyString('MQTTPassword');
// Check: Hat der Parent direkt Username/Password? (Schnittcher Modul hat das oft) // Versuch 1: Parent ist direkt konfigurierbar (z.B. Schnittcher Splitter)
if (@IPS_GetProperty($parentId, 'Username') !== false) { if (@IPS_GetProperty($parentId, 'Username') !== false) {
IPS_SetProperty($parentId, 'Username', $user); IPS_SetProperty($parentId, 'Username', $user);
IPS_SetProperty($parentId, 'Password', $pass); IPS_SetProperty($parentId, 'Password', $pass);
@@ -164,7 +188,8 @@ class VGT_Sub extends IPSModule
return; return;
} }
// Wenn nicht, suchen wir den IO darunter (Native Symcon Logik) // Versuch 2: Standard Symcon Weg (Device -> Splitter -> IO)
// Wir müssen den IO unter dem Splitter finden
$parentInfo = IPS_GetInstance($parentId); $parentInfo = IPS_GetInstance($parentId);
$ioID = $parentInfo['ConnectionID']; $ioID = $parentInfo['ConnectionID'];
if ($ioID > 0) { if ($ioID > 0) {