Enhance MQTT connection handling and update library version to 3.0 build 4

This commit is contained in:
jhartworks
2026-09-09 11:55:55 +02:00
parent d36c1a8219
commit e2ca524378
2 changed files with 105 additions and 21 deletions
+104 -20
View File
@@ -26,14 +26,78 @@ class MonitoringClient extends IPSModule {
}
// Überschreibt die intere IPS_ApplyChanges($id) Funktion
public function ApplyChanges() {
// Diese Zeile nicht löschen
parent::ApplyChanges();
public function ApplyChanges() {
// Diese Zeile nicht löschen
parent::ApplyChanges();
$this->SetTimerInterval("Update", $this->ReadPropertyInteger("Updatetime") * 1000);
$this->SetTimerInterval("ForceUpdate", $this->ReadPropertyInteger("ForceUpdatetime") * 1000 * 60);
}
}
private function isMqttConnectionReady($instanceId, $logError = true) {
$checked = array();
while ($instanceId > 0) {
if (isset($checked[$instanceId]) || !IPS_InstanceExists($instanceId)) {
return false;
}
$checked[$instanceId] = true;
$instance = IPS_GetInstance($instanceId);
if ($instance["InstanceStatus"] != 102) {
if ($logError) {
IPS_LogMessage("Monitoring Client", "MQTT connection is not ready: " . IPS_GetName($instanceId) . " (Status " . $instance["InstanceStatus"] . ")");
}
return false;
}
$instanceId = isset($instance["ConnectionID"]) ? $instance["ConnectionID"] : 0;
}
return true;
}
private function getMqttClientSocketId($instanceId) {
$checked = array();
while ($instanceId > 0 && !isset($checked[$instanceId]) && IPS_InstanceExists($instanceId)) {
$checked[$instanceId] = true;
$instance = IPS_GetInstance($instanceId);
if (isset($instance["ModuleInfo"]["ModuleName"]) && $instance["ModuleInfo"]["ModuleName"] == "Client Socket") {
return $instanceId;
}
$instanceId = isset($instance["ConnectionID"]) ? $instance["ConnectionID"] : 0;
}
return 0;
}
private function reconnectMqttClientSocket($serverId) {
$socketId = $this->getMqttClientSocketId($serverId);
if ($socketId === 0) {
IPS_LogMessage("Monitoring Client", "No Client Socket found for the configured MQTT Client.");
return false;
}
for ($attempt = 1; $attempt <= 20; $attempt++) {
IPS_SetProperty($socketId, "Open", false);
IPS_ApplyChanges($socketId);
IPS_Sleep(100);
IPS_SetProperty($socketId, "Open", true);
IPS_ApplyChanges($socketId);
IPS_Sleep(500);
if ($this->isMqttConnectionReady($serverId, false)) {
IPS_LogMessage("Monitoring Client", "MQTT Client Socket reconnected on attempt " . $attempt . ".");
return true;
}
}
IPS_LogMessage("Monitoring Client", "MQTT Client Socket could not be reconnected after 20 attempts.");
return false;
}
/**
* Die folgenden Funktionen stehen automatisch zur Verfügung, wenn das Modul über die "Module Control" eingefügt wurden.
* Die Funktionen werden, mit dem selbst eingerichteten Prefix, in PHP und JSON-RPC wiefolgt zur Verfügung gestellt:
@@ -45,10 +109,13 @@ class MonitoringClient extends IPSModule {
a given topic without having to manually create a
MQTT server device */
public function MqttPublish($server_id, $topic, $payload, $retain) {
// ensure server instance exists
if(!IPS_InstanceExists($server_id)) {
return false;
}
// ensure server instance exists
if(!IPS_InstanceExists($server_id)) {
return false;
}
if (!$this->isMqttConnectionReady($server_id)) {
return false;
}
// convert array structure to json string
if(is_array($payload)) $payload = json_encode($payload);
@@ -113,6 +180,9 @@ class MonitoringClient extends IPSModule {
IPS_SetConfiguration($id, $config_str);
IPS_SetHidden($id,true);
IPS_ApplyChanges($id);
if (!$this->isMqttConnectionReady($id)) {
return false;
}
// get Value variable and use it to publish the payload
$var_id = @IPS_GetObjectIDByIdent("Value", $id);
@@ -153,10 +223,13 @@ class MonitoringClient extends IPSModule {
}
// ensure server instance exists
if(!IPS_InstanceExists($server_id)) {
IPS_LogMessage("Monitoring Client", "Server instance does not exist for Setpoint Sync.");
return false;
}
if(!IPS_InstanceExists($server_id)) {
IPS_LogMessage("Monitoring Client", "Server instance does not exist for Setpoint Sync.");
return false;
}
if (!$this->isMqttConnectionReady($server_id)) {
return false;
}
// determine data type
if(is_string($payload)) {
@@ -209,12 +282,15 @@ class MonitoringClient extends IPSModule {
$inst_config = IPS_GetInstance($id);
if($inst_config["ConnectionID"] != $server_id) {
IPS_DisconnectInstance($id);
if(!@IPS_ConnectInstance($id, $server_id)) {
return false;
IPS_LogMessage("Monitoring Client", "Could not connect device to server instance for Setpoint Sync.");
}
}
IPS_LogMessage("Monitoring Client", "Parentid was :".$id);
if(!@IPS_ConnectInstance($id, $server_id)) {
return false;
IPS_LogMessage("Monitoring Client", "Could not connect device to server instance for Setpoint Sync.");
}
}
if (!$this->isMqttConnectionReady($id)) {
return false;
}
IPS_LogMessage("Monitoring Client", "Parentid was :".$id);
$id = IPS_GetChildrenIDs($id)[0];
IPS_LogMessage("Monitoring Client", "ID was :".$id);
@@ -367,6 +443,12 @@ class MonitoringClient extends IPSModule {
$projectname = $this->ReadPropertyString("Projectname");
$ispnumber = $this->ReadPropertyInteger("ISP");
// A manual force update starts with a clean MQTT socket connection.
// Normal timer-driven sends do not interrupt the connection.
if (!$this->reconnectMqttClientSocket($mqttId)) {
return;
}
$catIds = array(
array("id" => $this->ReadPropertyInteger("ParseNotifyCategoryID"), "top" => "Projekte" . $projectyear . "/P" . $projectnumber . "/ISP" . $ispnumber . "/Notify/"),
array("id" => $this->ReadPropertyInteger("ParseAlarmCategoryID"), "top" => "Projekte" . $projectyear . "/P" . $projectnumber . "/ISP" . $ispnumber . "/Alarm/"),
@@ -378,7 +460,9 @@ class MonitoringClient extends IPSModule {
foreach ($this->getCategoryVariables($catId["id"]) as $variable) {
$topic = $this->getTopicForVariable($catId["top"], $variable, true);
$payload = round(GetValue($variable["id"]), 2);
$this->MqttPublish($mqttId, $topic, $payload, false);
if (!$this->MqttPublish($mqttId, $topic, $payload, false)) {
return;
}
}
}
+1 -1
View File
@@ -8,6 +8,6 @@
"date": 1491343200
},
"version": "3.0",
"build": 2,
"build": 4,
"date": 0
}