Enhance MQTT connection handling and update library version to 3.0 build 4
This commit is contained in:
+104
-20
@@ -26,14 +26,78 @@ class MonitoringClient extends IPSModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Überschreibt die intere IPS_ApplyChanges($id) Funktion
|
// Überschreibt die intere IPS_ApplyChanges($id) Funktion
|
||||||
public function ApplyChanges() {
|
public function ApplyChanges() {
|
||||||
// Diese Zeile nicht löschen
|
// Diese Zeile nicht löschen
|
||||||
parent::ApplyChanges();
|
parent::ApplyChanges();
|
||||||
|
|
||||||
$this->SetTimerInterval("Update", $this->ReadPropertyInteger("Updatetime") * 1000);
|
$this->SetTimerInterval("Update", $this->ReadPropertyInteger("Updatetime") * 1000);
|
||||||
$this->SetTimerInterval("ForceUpdate", $this->ReadPropertyInteger("ForceUpdatetime") * 1000 * 60);
|
$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 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:
|
* 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
|
a given topic without having to manually create a
|
||||||
MQTT server device */
|
MQTT server device */
|
||||||
public function MqttPublish($server_id, $topic, $payload, $retain) {
|
public function MqttPublish($server_id, $topic, $payload, $retain) {
|
||||||
// ensure server instance exists
|
// ensure server instance exists
|
||||||
if(!IPS_InstanceExists($server_id)) {
|
if(!IPS_InstanceExists($server_id)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!$this->isMqttConnectionReady($server_id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// convert array structure to json string
|
// convert array structure to json string
|
||||||
if(is_array($payload)) $payload = json_encode($payload);
|
if(is_array($payload)) $payload = json_encode($payload);
|
||||||
@@ -113,6 +180,9 @@ class MonitoringClient extends IPSModule {
|
|||||||
IPS_SetConfiguration($id, $config_str);
|
IPS_SetConfiguration($id, $config_str);
|
||||||
IPS_SetHidden($id,true);
|
IPS_SetHidden($id,true);
|
||||||
IPS_ApplyChanges($id);
|
IPS_ApplyChanges($id);
|
||||||
|
if (!$this->isMqttConnectionReady($id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// get Value variable and use it to publish the payload
|
// get Value variable and use it to publish the payload
|
||||||
$var_id = @IPS_GetObjectIDByIdent("Value", $id);
|
$var_id = @IPS_GetObjectIDByIdent("Value", $id);
|
||||||
@@ -153,10 +223,13 @@ class MonitoringClient extends IPSModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ensure server instance exists
|
// ensure server instance exists
|
||||||
if(!IPS_InstanceExists($server_id)) {
|
if(!IPS_InstanceExists($server_id)) {
|
||||||
IPS_LogMessage("Monitoring Client", "Server instance does not exist for Setpoint Sync.");
|
IPS_LogMessage("Monitoring Client", "Server instance does not exist for Setpoint Sync.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!$this->isMqttConnectionReady($server_id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// determine data type
|
// determine data type
|
||||||
if(is_string($payload)) {
|
if(is_string($payload)) {
|
||||||
@@ -209,12 +282,15 @@ class MonitoringClient extends IPSModule {
|
|||||||
$inst_config = IPS_GetInstance($id);
|
$inst_config = IPS_GetInstance($id);
|
||||||
if($inst_config["ConnectionID"] != $server_id) {
|
if($inst_config["ConnectionID"] != $server_id) {
|
||||||
IPS_DisconnectInstance($id);
|
IPS_DisconnectInstance($id);
|
||||||
if(!@IPS_ConnectInstance($id, $server_id)) {
|
if(!@IPS_ConnectInstance($id, $server_id)) {
|
||||||
return false;
|
return false;
|
||||||
IPS_LogMessage("Monitoring Client", "Could not connect device to server instance for Setpoint Sync.");
|
IPS_LogMessage("Monitoring Client", "Could not connect device to server instance for Setpoint Sync.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IPS_LogMessage("Monitoring Client", "Parentid was :".$id);
|
if (!$this->isMqttConnectionReady($id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
IPS_LogMessage("Monitoring Client", "Parentid was :".$id);
|
||||||
$id = IPS_GetChildrenIDs($id)[0];
|
$id = IPS_GetChildrenIDs($id)[0];
|
||||||
IPS_LogMessage("Monitoring Client", "ID was :".$id);
|
IPS_LogMessage("Monitoring Client", "ID was :".$id);
|
||||||
|
|
||||||
@@ -367,6 +443,12 @@ class MonitoringClient extends IPSModule {
|
|||||||
$projectname = $this->ReadPropertyString("Projectname");
|
$projectname = $this->ReadPropertyString("Projectname");
|
||||||
$ispnumber = $this->ReadPropertyInteger("ISP");
|
$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(
|
$catIds = array(
|
||||||
array("id" => $this->ReadPropertyInteger("ParseNotifyCategoryID"), "top" => "Projekte" . $projectyear . "/P" . $projectnumber . "/ISP" . $ispnumber . "/Notify/"),
|
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/"),
|
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) {
|
foreach ($this->getCategoryVariables($catId["id"]) as $variable) {
|
||||||
$topic = $this->getTopicForVariable($catId["top"], $variable, true);
|
$topic = $this->getTopicForVariable($catId["top"], $variable, true);
|
||||||
$payload = round(GetValue($variable["id"]), 2);
|
$payload = round(GetValue($variable["id"]), 2);
|
||||||
$this->MqttPublish($mqttId, $topic, $payload, false);
|
if (!$this->MqttPublish($mqttId, $topic, $payload, false)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -8,6 +8,6 @@
|
|||||||
"date": 1491343200
|
"date": 1491343200
|
||||||
},
|
},
|
||||||
"version": "3.0",
|
"version": "3.0",
|
||||||
"build": 2,
|
"build": 4,
|
||||||
"date": 0
|
"date": 0
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user