Compare commits

..
14 Commits
Author SHA1 Message Date
jhartworks 646ebbafc1 Enhance MQTT message handling with semaphore control and update library build to 5 2026-09-14 10:22:59 +02:00
jhartworks e2ca524378 Enhance MQTT connection handling and update library version to 3.0 build 4 2026-09-09 11:55:55 +02:00
jhartworks d36c1a8219 Enhance category validation in getCategoryVariables to handle unconfigured client categories 2026-09-09 11:48:21 +02:00
jhartworks 2d337c6308 Improve category checks in MonitoringServer for robustness and clarity 2026-09-09 11:35:48 +02:00
jhartworks 8719dec2de Swap SetpointVarCount and AnalogVarCount assignments for correct value tracking 2026-04-23 08:27:23 +02:00
jhartworks 5deebeffd5 Refactor MqttSync method to use global GetValue function for value retrieval 2026-04-22 13:17:46 +02:00
jhartworks 4f7a2b8199 Fix incorrect method call for retrieving child IDs in MqttSync method 2026-04-22 13:16:47 +02:00
jhartworks 1855868435 Add logging for ID and value retrieval in MqttSync method to enhance traceability 2026-04-22 13:15:07 +02:00
jhartworks 9bb1636ddf Add retrieval of child IDs in MqttSync method to improve value synchronization 2026-04-22 13:12:18 +02:00
jhartworks d17e81a5ab Add detailed logging for MqttSync method to enhance debugging and traceability 2026-04-22 13:07:31 +02:00
jhartworks 444b6a2a8d Update ParseSetpointCategoryID and ParseSetpointCacheCategoryID to default to -1; improve validation checks in MqttSync method 2026-04-22 13:01:52 +02:00
jhartworks 1bb10e2bc7 Add logging for cache category and source variable checks in MqttSync method 2026-04-22 12:56:14 +02:00
jhartworks 1cd8bb5547 Add logging for setpoint synchronization in MqttSync method 2026-04-22 12:50:31 +02:00
jhartworks 08e55c604c Enhance MqttSync call in MonitoringClient to improve setpoint synchronization and logging 2026-04-22 12:45:41 +02:00
3 changed files with 382 additions and 282 deletions
+352 -262
View File
@@ -9,8 +9,8 @@ class MonitoringClient extends IPSModule {
$this->RegisterPropertyInteger("ParseNotifyCategoryID","0");
$this->RegisterPropertyInteger("ParseAlarmCategoryID","0");
$this->RegisterPropertyInteger("ParseAnalogCategoryID","0");
$this->RegisterPropertyInteger("ParseSetpointCategoryID","0");
$this->RegisterPropertyInteger("ParseSetpointCacheCategoryID","0");
$this->RegisterPropertyInteger("ParseSetpointCategoryID",-1);
$this->RegisterPropertyInteger("ParseSetpointCacheCategoryID",-1);
$this->RegisterPropertyInteger("MqttCLientID","0");
$this->RegisterPropertyInteger("Projectnumber","230001");
@@ -26,14 +26,82 @@ 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;
}
private function getSendSemaphore() {
return "MonitoringClientSend_" . $this->InstanceID;
}
/**
* 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 +113,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);
@@ -67,81 +138,102 @@ class MonitoringClient extends IPSModule {
}
$module_id = "{01C00ADD-D04E-452E-B66A-D253278743FE}" /* Module ID of MQTT Server Device */;
$ident = "TempMQTTDevice";
// enter semaphore to ensure the temporary device gets used by one thread at a time
if(IPS_SemaphoreEnter($ident, 100)) {
// get temporary MQTT Server Device or create if needed
$id = @IPS_GetObjectIDByIdent($ident, $_IPS['SELF']);
if($id === false) {
$id = @IPS_CreateInstance($module_id);
if($id === false) {
return false;
}
IPS_SetParent($id, $_IPS['SELF']);
IPS_SetIdent($id, $ident);
}
// ensure the specified server instance is actually compatible
if(!IPS_IsInstanceCompatible($id, $server_id)) {
return false;
}
// ensure that the temporary device is actually connected to the correct server instance
$inst_config = IPS_GetInstance($id);
if($inst_config["ConnectionID"] != $server_id) {
IPS_DisconnectInstance($id);
if(!@IPS_ConnectInstance($id, $server_id)) {
return false;
}
}
// name object to help with debugging
IPS_SetName($id, "Temporary MQTT Device for: " . $topic);
// configure temporary device
$config_arr = array(
"Retain" => $retain,
"Topic" => $topic,
"Type" => $ips_var_type
);
$config_str = json_encode($config_arr);
IPS_SetConfiguration($id, $config_str);
IPS_SetHidden($id,true);
IPS_ApplyChanges($id);
// get Value variable and use it to publish the payload
$var_id = @IPS_GetObjectIDByIdent("Value", $id);
RequestAction($var_id, $payload);
IPS_SemaphoreLeave($ident);
} else { // semaphore timeout
return false;
}
return true;
} // MQTT_Publish
$ident = "TempMQTTDevice";
// Each client instance owns its temporary device. Do not let different
// Monitoring Client instances block each other during a force update.
$semaphore = $ident . "_" . $this->InstanceID;
// enter semaphore to ensure the temporary device gets used by one thread at a time
if(IPS_SemaphoreEnter($semaphore, 5000)) {
try {
// get temporary MQTT Server Device or create if needed
$id = @IPS_GetObjectIDByIdent($ident, $this->InstanceID);
if($id === false) {
$id = @IPS_CreateInstance($module_id);
if($id === false) {
return false;
}
IPS_SetParent($id, $this->InstanceID);
IPS_SetIdent($id, $ident);
}
// ensure the specified server instance is actually compatible
if(!IPS_IsInstanceCompatible($id, $server_id)) {
return false;
}
// ensure that the temporary device is actually connected to the correct server instance
$inst_config = IPS_GetInstance($id);
if($inst_config["ConnectionID"] != $server_id) {
IPS_DisconnectInstance($id);
if(!@IPS_ConnectInstance($id, $server_id)) {
return false;
}
}
// name object to help with debugging
IPS_SetName($id, "Temporary MQTT Device for: " . $topic);
// configure temporary device
$config_arr = array(
"Retain" => $retain,
"Topic" => $topic,
"Type" => $ips_var_type
);
$config_str = json_encode($config_arr);
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);
if ($var_id === false) {
IPS_LogMessage("Monitoring Client", "MQTT device has no Value variable for topic: " . $topic);
return false;
}
RequestAction($var_id, $payload);
return true;
} finally {
IPS_SemaphoreLeave($semaphore);
}
} else { // semaphore timeout
IPS_LogMessage("Monitoring Client", "MQTT publish timed out waiting for topic: " . $topic);
return false;
}
} // MQTT_Publish
public function MqttSync($server_id, $topic, $payload, $retain, $ident, $source) {
IPS_LogMessage("Monitoring Client", "MQTT Sync called with Topic: " . $topic . " Payload: " . $payload. " Source: " . $source . " Ident: " . $ident);
$cacheCat = $this->ReadPropertyInteger("ParseSetpointCacheCategoryID");
if ($cacheCat == 0){
if ($cacheCat < 1){
IPS_LogMessage("Monitoring Client", "No Cache Category defined for Setpoint Sync. Please define a Cache Category to use this feature.");
return false;
}
if (IPS_CategoryExists($cacheCat) == false){
IPS_LogMessage("Monitoring Client", "Cache Category does not exist for Setpoint Sync.");
return false;
}
if (IPS_VariableExists($source) == false){
IPS_LogMessage("Monitoring Client", "Source variable does not exist for Setpoint Sync.");
return false;
}
// ensure server instance exists
if(!IPS_InstanceExists($server_id)) {
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)) {
@@ -155,7 +247,9 @@ class MonitoringClient extends IPSModule {
$ips_var_type = 0;
} else { // unsupported
return false;
IPS_LogMessage("Monitoring Client", "Unsupported data type for Setpoint Sync.");
}
IPS_LogMessage("Monitoring Client", "Data type for Setpoint Sync determined as: " . $ips_var_type);
$module_id = "{01C00ADD-D04E-452E-B66A-D253278743FE}" /* Module ID of MQTT Server Device */;
@@ -169,7 +263,7 @@ class MonitoringClient extends IPSModule {
IPS_SetParent($id, $cacheCat);
IPS_SetIdent($id, $ident);
// name object to help with debugging
IPS_SetName($id, "CS_" . $name);
IPS_SetName($id, "CS_" . $ident);
// configure temporary device
$config_arr = array(
@@ -186,18 +280,28 @@ class MonitoringClient extends IPSModule {
// ensure the specified server instance is actually compatible
if(!IPS_IsInstanceCompatible($id, $server_id)) {
return false;
IPS_LogMessage("Monitoring Client", "Device is not compatible with server instance for Setpoint Sync.");
}
$inst_config = IPS_GetInstance($id);
if($inst_config["ConnectionID"] != $server_id) {
IPS_DisconnectInstance($id);
if(!@IPS_ConnectInstance($id, $server_id)) {
return false;
}
}
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);
$valSelf = $this->GetValue($id);
$valSource = $this->GetValue($source);
$valSelf = GetValue($id);
$valSource = GetValue($source);
IPS_LogMessage("Monitoring Client", "Self value: " . $valSelf . " Source value: " . $valSource);
$varInfoSelf = IPS_GetVariable($id);
$changedtimeSelf = $varInfoSelf["VariableChanged"];
@@ -210,11 +314,13 @@ class MonitoringClient extends IPSModule {
//self is newer than source, so update source with self value
if ($changedtimeSelf > $changedtimeSource) {
RequestAction($source, $valSelf);
IPS_LogMessage("Monitoring Client", "Source variable updated with self value for Setpoint Sync. Source: " . $source . " Value: " . $valSelf);
}
//source is newer than self, so update self with source value
if ($changedtimeSource > $changedtimeSelf) {
RequestAction($id, $valSource);
IPS_LogMessage("Monitoring Client", "Self variable updated with source value for Setpoint Sync. Self: " . $id . " Value: " . $valSource);
}
}
@@ -224,191 +330,175 @@ class MonitoringClient extends IPSModule {
return true;
} // MQTT_Sync
public function SendTopic() {
$mqttId = $this->ReadPropertyInteger("MqttCLientID");
$projectyear = $this->ReadPropertyInteger("Projectyear");
$projectnumber = $this->ReadPropertyInteger("Projectnumber");
$projectname = $this->ReadPropertyString("Projectname");
$ispnumber = $this->ReadPropertyInteger("ISP");
$updatetime = $this->ReadPropertyInteger("Updatetime");
$catIds[0]["id"] = $this->ReadPropertyInteger("ParseNotifyCategoryID");
$catIds[0]["top"] = "Projekte". $projectyear."/P".$projectnumber. "/ISP" .$ispnumber. "/Notify/";
$catIds[1]["id"] = $this->ReadPropertyInteger("ParseAlarmCategoryID");
$catIds[1]["top"] = "Projekte". $projectyear."/P".$projectnumber. "/ISP" .$ispnumber. "/Alarm/";
$catIds[2]["id"] = $this->ReadPropertyInteger("ParseAnalogCategoryID");
$catIds[2]["top"] = "Projekte". $projectyear."/P".$projectnumber. "/ISP" .$ispnumber. "/Analog/";
$catIds[3]["id"] = $this->ReadPropertyInteger("ParseSetpointCategoryID");
$catIds[3]["top"] = "Projekte". $projectyear."/P".$projectnumber. "/ISP" .$ispnumber. "/Setpoint/";
$catIds[3]["setpoint"] = true;
foreach ($catIds as $catId){
$catChilds = IPS_GetChildrenIDs($catId["id"]);
foreach ($catChilds as $catChild) {
$childids = IPS_GetChildrenIDs($catChild);
$parname = IPS_GetName($catChild);
if (IPS_VariableExists($catChild) != 1 && IPS_LinkExists($catChild) != 1){
foreach ($childids as $childid){
foreach ($childids as $childid){
if (IPS_VariableExists($childid) != 1){
if(IPS_LinkExists($childid) == 1){
$linkInfo = IPS_GetLink($childid);
$linkTarget = $linkInfo["TargetID"];
$childid = $linkTarget;
$varInfo = IPS_GetVariable($childid);
}
}
$varInfo = IPS_GetVariable($childid);
$changedtime = $varInfo["VariableChanged"];
$varname = IPS_GetName($childid);
$topic = $catId["top"]. $parname."_".$varname;
$payload = round(getvalue($childid), 2);
$time = time();
$isSetpoint = isset($catId["setpoint"]) ? $catId["setpoint"] : false;
if ($isSetpoint == true){
$this->MqttSync($mqttId, $topic, $payload, false, $parname."_".$varname, $childid);
}else{
if($changedtime > $time - $updatetime){
$this->MqttPublish($mqttId, $topic, $payload, false);
}
}
}
}
}else{
$childid = $catChild;
if (IPS_VariableExists($childid) != 1){
if(IPS_LinkExists($childid) == 1){
$linkInfo = IPS_GetLink($childid);
$linkTarget = $linkInfo["TargetID"];
$childid = $linkTarget;
$varInfo = IPS_GetVariable($childid);
}
}
$varInfo = IPS_GetVariable($childid);
$changedtime = $varInfo["VariableChanged"];
$varname = IPS_GetName($childid);
$topic = $catId["top"]. $parname."_".$varname;
$payload = round(getvalue($childid), 2);
$time = time();
$isSetpoint = isset($catId["setpoint"]) ? $catId["setpoint"] : false;
if ($isSetpoint == true){
$this->MqttSync($mqttId, $topic, $payload, false, $parname."_".$varname, $childid);
}else{
if($changedtime > $time - $updatetime){
$this->MqttPublish($mqttId, $topic, $payload, false);
}
}
}
}
}
$topic = "Projekte". $projectyear."/".$projectnumber. "/ISP" .$ispnumber. "/Name";
$this->MqttPublish($mqttId, $topic, $projectname, false);
}
public function ForceSendTopic() {
$mqttId = $this->ReadPropertyInteger("MqttCLientID");
$projectyear = $this->ReadPropertyInteger("Projectyear");
$projectnumber = $this->ReadPropertyInteger("Projectnumber");
$projectname = $this->ReadPropertyString("Projectname");
$ispnumber = $this->ReadPropertyInteger("ISP");
$updatetime = $this->ReadPropertyInteger("Updatetime");
$catIds[0]["id"] = $this->ReadPropertyInteger("ParseNotifyCategoryID");
$catIds[0]["top"] = "Projekte". $projectyear."/P".$projectnumber. "/ISP" .$ispnumber. "/Notify/";
$catIds[1]["id"] = $this->ReadPropertyInteger("ParseAlarmCategoryID");
$catIds[1]["top"] = "Projekte". $projectyear."/P".$projectnumber. "/ISP" .$ispnumber. "/Alarm/";
$catIds[2]["id"] = $this->ReadPropertyInteger("ParseAnalogCategoryID");
$catIds[2]["top"] = "Projekte". $projectyear."/P".$projectnumber. "/ISP" .$ispnumber. "/Analog/";
foreach ($catIds as $catId){
$catChilds = IPS_GetChildrenIDs($catId["id"]);
foreach ($catChilds as $catChild) {
$childids = IPS_GetChildrenIDs($catChild);
$parname = IPS_GetName($catChild);
if (IPS_VariableExists($catChild) != 1 && IPS_LinkExists($catChild) != 1){
foreach ($childids as $childid){
foreach ($childids as $childid){
if (IPS_VariableExists($childid) != 1){
if(IPS_LinkExists($childid) == 1){
$linkInfo = IPS_GetLink($childid);
$linkTarget = $linkInfo["TargetID"];
$childid = $linkTarget;
$varInfo = IPS_GetVariable($childid);
}
}
$varInfo = IPS_GetVariable($childid);
$varname = IPS_GetName($childid);
$topic = $catId["top"]. $parname."_".$varname;
$payload = round(getvalue($childid), 2);
$this->MqttPublish($mqttId, $topic, $payload, false);
// IPS_LogMessage("Monitoring Client", "Force Update with Parent: " . $topic . " mit Payload: " . $payload);
}
}
}else{
$childid = $catChild;
if (IPS_VariableExists($childid) != 1){
if(IPS_LinkExists($childid) == 1){
$linkInfo = IPS_GetLink($childid);
$linkTarget = $linkInfo["TargetID"];
$childid = $linkTarget;
$varInfo = IPS_GetVariable($childid);
}
}
$varInfo = IPS_GetVariable($childid);
$varname = IPS_GetName($childid);
$topic = $catId["top"].$varname;
$payload = round(getvalue($childid), 2);
$this->MqttPublish($mqttId, $topic, $payload, false);
// IPS_LogMessage("Monitoring Client", "Force Update none Parent: " . $topic . " mit Payload: " . $payload);
}
}
}
$topic = "Projekte". $projectyear."/".$projectnumber. "/ISP" .$ispnumber. "/Name";
$this->MqttPublish($mqttId, $topic, $projectname, false);
}
private function resolveLinkTarget($objectId) {
$visited = array();
while ($objectId > 0 && IPS_LinkExists($objectId)) {
if (isset($visited[$objectId])) {
return 0;
}
$visited[$objectId] = true;
$objectId = IPS_GetLink($objectId)["TargetID"];
}
return $objectId;
}
/*
* Return every variable directly represented by a monitoring category.
* The parent name is deliberately kept from the visible object/link in the
* configured tree, so existing MQTT topic names remain unchanged.
*/
private function getCategoryVariables($categoryId) {
$variables = array();
// Unconfigured client categories use -1. IPS_CategoryExists() rejects
// negative IDs before it can return false.
if ($categoryId < 1 || !IPS_CategoryExists($categoryId)) {
return $variables;
}
foreach (IPS_GetChildrenIDs($categoryId) as $entryId) {
$entryName = IPS_GetName($entryId);
$targetId = $this->resolveLinkTarget($entryId);
if ($targetId <= 0 || !IPS_ObjectExists($targetId)) {
continue;
}
// A variable or a link to a variable is located directly in the category.
if (IPS_VariableExists($targetId)) {
$variables[] = array(
"id" => $targetId,
"parent" => $entryName,
"name" => IPS_GetName($targetId),
"direct" => true
);
continue;
}
// An object (or a link to an object) may contain one or several values.
foreach (IPS_GetChildrenIDs($targetId) as $childId) {
$variableId = $this->resolveLinkTarget($childId);
if ($variableId <= 0 || !IPS_VariableExists($variableId)) {
continue;
}
$variables[] = array(
"id" => $variableId,
"parent" => $entryName,
"name" => IPS_GetName($variableId),
"direct" => false
);
}
}
return $variables;
}
private function getTopicForVariable($top, $variable, $force) {
// The old force path used the bare variable name for values directly in
// the category. Keep that legacy topic spelling intact.
if ($force && $variable["direct"]) {
return $top . $variable["name"];
}
return $top . $variable["parent"] . "_" . $variable["name"];
}
public function SendTopic() {
// Do not send regular updates while a complete force send is running.
if (!IPS_SemaphoreEnter($this->getSendSemaphore(), 0)) {
return;
}
try {
$mqttId = $this->ReadPropertyInteger("MqttCLientID");
$projectyear = $this->ReadPropertyInteger("Projectyear");
$projectnumber = $this->ReadPropertyInteger("Projectnumber");
$projectname = $this->ReadPropertyString("Projectname");
$ispnumber = $this->ReadPropertyInteger("ISP");
$updatetime = $this->ReadPropertyInteger("Updatetime");
$catIds = array(
array("id" => $this->ReadPropertyInteger("ParseNotifyCategoryID"), "top" => "Projekte" . $projectyear . "/P" . $projectnumber . "/ISP" . $ispnumber . "/Notify/", "setpoint" => false),
array("id" => $this->ReadPropertyInteger("ParseAlarmCategoryID"), "top" => "Projekte" . $projectyear . "/P" . $projectnumber . "/ISP" . $ispnumber . "/Alarm/", "setpoint" => false),
array("id" => $this->ReadPropertyInteger("ParseAnalogCategoryID"), "top" => "Projekte" . $projectyear . "/P" . $projectnumber . "/ISP" . $ispnumber . "/Analog/", "setpoint" => false),
array("id" => $this->ReadPropertyInteger("ParseSetpointCategoryID"), "top" => "Projekte" . $projectyear . "/P" . $projectnumber . "/ISP" . $ispnumber . "/Setpoint/", "setpoint" => true)
);
foreach ($catIds as $catId) {
foreach ($this->getCategoryVariables($catId["id"]) as $variable) {
$varInfo = IPS_GetVariable($variable["id"]);
$changedtime = $varInfo["VariableChanged"];
$topic = $this->getTopicForVariable($catId["top"], $variable, false);
$payload = round(GetValue($variable["id"]), 2);
if ($catId["setpoint"]) {
$syncname = $variable["parent"] . "_" . $variable["name"];
IPS_LogMessage("Monitoring Client", "Sync Setpoint: " . $topic . " mit Payload: " . $payload . " und Source: " . $variable["id"] . " und Ident: " . $syncname);
$this->MqttSync($mqttId, $topic, $payload, false, $syncname, $variable["id"]);
} elseif ($changedtime > time() - $updatetime) {
$this->MqttPublish($mqttId, $topic, $payload, false);
}
}
}
$topic = "Projekte" . $projectyear . "/" . $projectnumber . "/ISP" . $ispnumber . "/Name";
$this->MqttPublish($mqttId, $topic, $projectname, false);
} finally {
IPS_SemaphoreLeave($this->getSendSemaphore());
}
}
public function ForceSendTopic() {
// Wait briefly for a currently running regular update. Further regular
// updates skip their run until this complete force send has finished.
if (!IPS_SemaphoreEnter($this->getSendSemaphore(), 5000)) {
IPS_LogMessage("Monitoring Client", "Force Send skipped because another send is still running.");
return;
}
try {
$mqttId = $this->ReadPropertyInteger("MqttCLientID");
$projectyear = $this->ReadPropertyInteger("Projectyear");
$projectnumber = $this->ReadPropertyInteger("Projectnumber");
$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/"),
array("id" => $this->ReadPropertyInteger("ParseAnalogCategoryID"), "top" => "Projekte" . $projectyear . "/P" . $projectnumber . "/ISP" . $ispnumber . "/Analog/"),
array("id" => $this->ReadPropertyInteger("ParseSetpointCategoryID"), "top" => "Projekte" . $projectyear . "/P" . $projectnumber . "/ISP" . $ispnumber . "/Setpoint/")
);
foreach ($catIds as $catId) {
foreach ($this->getCategoryVariables($catId["id"]) as $variable) {
$topic = $this->getTopicForVariable($catId["top"], $variable, true);
$payload = round(GetValue($variable["id"]), 2);
if (!$this->MqttPublish($mqttId, $topic, $payload, false)) {
return;
}
// Limit manual/full transfers to ten MQTT messages per second.
// This gives the subscribed client socket time to process its
// own echoed publications before the next one is sent.
IPS_Sleep(100);
}
}
$topic = "Projekte" . $projectyear . "/" . $projectnumber . "/ISP" . $ispnumber . "/Name";
$this->MqttPublish($mqttId, $topic, $projectname, false);
} finally {
IPS_SemaphoreLeave($this->getSendSemaphore());
}
}
}
?>
?>
+28 -18
View File
@@ -182,9 +182,8 @@ class MonitoringServer extends IPSModule {
$inalarmcount = 0;
$alarmvalues = 0;
$catChilds = IPS_GetChildrenIDs($catAlarmId);
if ($catAlarmId > 0){
if (IPS_CategoryExists($catAlarmId)){
$catChilds = IPS_GetChildrenIDs($catAlarmId);
foreach ($catChilds as $catChild) {
@@ -192,6 +191,9 @@ class MonitoringServer extends IPSModule {
$parname = IPS_GetName($catChild);
foreach ($childids as $childid){
if (!IPS_VariableExists($childid)) {
continue;
}
$varInfo = IPS_GetVariable($childid);
$changedtime = $varInfo["VariableChanged"];
@@ -212,11 +214,13 @@ class MonitoringServer extends IPSModule {
}
SetValueInteger($this->GetIDForIdent("AlarmVarCount"),$alarmvalues);
SetValueInteger($this->GetIDForIdent("AlarmActiveCount"),$inalarmcount);
$rootcat = IPS_GetParent($catAlarmId);
if ($inalarmcount > 0 && $rootcat >0){
IPS_SetIcon($rootcat,"Alert");
}else{
IPS_SetIcon($rootcat,"");
if (IPS_CategoryExists($catAlarmId)) {
$rootcat = IPS_GetParent($catAlarmId);
if ($inalarmcount > 0 && $rootcat >0){
IPS_SetIcon($rootcat,"Alert");
}else{
IPS_SetIcon($rootcat,"");
}
}
}
@@ -256,6 +260,7 @@ class MonitoringServer extends IPSModule {
$catNotifyId = $this->ReadPropertyInteger("ParseNotifyCategoryID");
$catAnalogId = $this->ReadPropertyInteger("ParseAnalogCategoryID");
$catSetpointId = $this->ReadPropertyInteger("ParseSetpointCategoryID");
$projectnumber = $this->ReadPropertyInteger("Projectnumber");
$projectname = $this->ReadPropertyString("Projectname");
@@ -274,7 +279,7 @@ class MonitoringServer extends IPSModule {
if ($catAnalogId > 0){
if (IPS_CategoryExists($catAnalogId)){
$catChilds = IPS_GetChildrenIDs($catAnalogId);
@@ -285,6 +290,9 @@ class MonitoringServer extends IPSModule {
$parname = IPS_GetName($catChild);
foreach ($objchildids as $objchildid){
if (!IPS_VariableExists($objchildid)) {
continue;
}
$varInfo = IPS_GetVariable($objchildid);
$changedtime = $varInfo["VariableChanged"];
@@ -345,10 +353,10 @@ class MonitoringServer extends IPSModule {
}
}
SetValueInteger($this->GetIDForIdent("SetpointVarCount"),$numberofvalues);
SetValueInteger($this->GetIDForIdent("AnalogVarCount"),$numberofvalues);
$numberofvalues = 0;
if ($catSetpointId > 0){
if (IPS_CategoryExists($catSetpointId)){
$catChilds = IPS_GetChildrenIDs($catSetpointId);
@@ -366,11 +374,10 @@ class MonitoringServer extends IPSModule {
}
}
SetValueInteger($this->GetIDForIdent("AnalogVarCount"),$numberofvalues);
SetValueInteger($this->GetIDForIdent("SetpointVarCount"),$numberofvalues);
$numberofvalues = 0;
if ($catNotifyId > 0){
if (IPS_CategoryExists($catNotifyId)){
$catChilds = IPS_GetChildrenIDs($catNotifyId);
@@ -381,6 +388,9 @@ class MonitoringServer extends IPSModule {
$parname = IPS_GetName($catChild);
foreach ($objchildids as $objchildid){
if (!IPS_VariableExists($objchildid)) {
continue;
}
$varInfo = IPS_GetVariable($objchildid);
$changedtime = $varInfo["VariableChanged"];
@@ -709,7 +719,7 @@ class MonitoringServer extends IPSModule {
$catAnalogId = $this->ReadPropertyInteger("ParseAnalogCategoryID");
$catAlarmId = $this->ReadPropertyInteger("ParseAlarmCategoryID");
if ($catNotifyId > 0){
if (IPS_CategoryExists($catNotifyId)){
$catChilds = IPS_GetChildrenIDs($catNotifyId);
@@ -723,7 +733,7 @@ class MonitoringServer extends IPSModule {
}
}
if ($catAnalogId > 0){
if (IPS_CategoryExists($catAnalogId)){
$catChilds = IPS_GetChildrenIDs($catAnalogId);
@@ -737,7 +747,7 @@ class MonitoringServer extends IPSModule {
}
}
if ($catAlarmId > 0){
if (IPS_CategoryExists($catAlarmId)){
$catChilds = IPS_GetChildrenIDs($catAlarmId);
@@ -879,4 +889,4 @@ private function generateAndUploadCsv($catId, $ftp, $remotePath, $localPath) {
}
?>
?>
+2 -2
View File
@@ -8,6 +8,6 @@
"date": 1491343200
},
"version": "3.0",
"build": 1,
"build": 5,
"date": 0
}
}