From 57390d099bcd96057fd0a7c815fdc0c010f96c77 Mon Sep 17 00:00:00 2001 From: daniel Tartavel Date: Fri, 31 Dec 2021 14:34:20 +0100 Subject: [PATCH] making compatibility with mqtt's friendly names --- db_functions.php | 96 ++++++++++++++++++++++++++++++--------- events.php | 19 ++++---- moha.php | 44 ++++++++++++------ mqtt_functions.php | 34 ++++++++++---- scripts/panneau_salon.php | 19 ++++---- 5 files changed, 151 insertions(+), 61 deletions(-) diff --git a/db_functions.php b/db_functions.php index 4b281b6..9f73cd3 100644 --- a/db_functions.php +++ b/db_functions.php @@ -8,37 +8,63 @@ function storeDB($db, $filepath) fclose($fp); } -function mkDevicesDB($topic, $json) +function deviceTree(string $topic, array $fnTree, array &$device) +{ + +} + +function mkDevicesDB($topic, $json, $group=false) { global $devices, $listProperties, $indexDevices, $dbInit, $logFh; - foreach ($json as $device) + if (!isset($devices[$topic])) $devices[$topic]= array(); + foreach ($json as $jsonDevice) { //print_r($device); - $fn = $device->friendly_name; - $devices[$topic][$fn] = new device; - $devices[$topic][$fn]->topic = $topic; - $devices[$topic][$fn]->device = $device; - $devices[$topic][$fn]->type = $device->type; - $devices[$topic][$fn]->ieeeAddress = $device->ieee_address; - $devices[$topic][$fn]->friendlyName = $device->friendly_name; - if ( !empty($devices[$topic][$fn]->powerSource ) ) + $fn = $jsonDevice->friendly_name; + $fnTree = explode("/", $fn); + $device = & $devices[$topic]; + foreach($fnTree as $fnPart) { - $devices[$topic][$fn]->powerSource = $device->power_source; + $device[$fnPart] = array(); + $device = & $device[$fnPart]; } - if ($device->definition != null) + + $device["device"] = new device; + $device["device"]->topic = $topic; + //$device["device"]->device = $jsonDevice; + $device["device"]->friendlyName = $jsonDevice->friendly_name; + if ($group) { - $devices[$topic][$fn]->description = $device->definition->description; + //print_r($device); + $device["device"]->groupID = $jsonDevice->id; + $indexDevices[$device["device"]->groupID] = $jsonDevice->friendly_name; + }else + { + $device["device"]->type = $jsonDevice->type; + $device["device"]->ieeeAddress = $jsonDevice->ieee_address; + if ( !empty($jsonDevice->power_source ) ) + { + $device["device"]->powerSource = $jsonDevice->power_source; + } + if ($jsonDevice->definition != null) + { + $device["device"]->description = $jsonDevice->definition->description; + } + //searchProperty($fn, $device["device"], $jsonDevice, $listProperties); + $indexDevices[$device["device"]->ieeeAddress] = & $device["device"]; + //print_r($device); } - searchProperty($fn, $devices[$topic][$fn], $device, $listProperties); - $indexDevices[$device->ieee_address] = $device->friendly_name; } $dbInit = true; + fwrite($logFh, "################################START##################################################"); fwrite($logFh, print_r($devices, true)); + fwrite($logFh, "################################END##################################################"); + echo "Devices DB made" .EOL; //print_r($devices); } -function searchProperty($fn, $device, $object, $listProperties) +function searchProperty($fn, &$device, $object, $listProperties) { $objectArray = (array)$object; foreach($listProperties as $key => $value) @@ -52,17 +78,43 @@ function searchProperty($fn, $device, $object, $listProperties) } } -function changeDevice($topic, $fn, $device) +function changeDevice($topic, $fn, &$device, $json) { //print_r($device); - iterateDevice($topic, $fn, $device, $device->json); + /*foreach($fnTree as $fn) + { + //print_r($device); + if (!isset($device[$fn])) + { + + } + $device = & $device[$fn]; + }*/ + + //print_r($json); + $fnTree = explode("/", $fn); + print_r($json); + if ( ($jsonDevice = json_decode($json)) === null ) + { + echo "json ========>>>>>>> " . print_r($json,true) . EOL; + if (!isset($device->value)) + { + $device->{"value"} = $json; + $device->type = true; //set this as parameter and not device + } + print_r($device); + }else + { + iterateDevice($topic, $fn, $device, $jsonDevice); + } } -function iterateDevice($topic, $fn, $device, $object) +function iterateDevice($topic, $fn, &$device, $json) { global $changed; + //echo "device =>";print_r($device);echo EOL; - foreach($object as $key => $value) + foreach($json as $key => $value) { $oldValue = 0; //echo "key =>"; print_r($key); echo EOL; @@ -95,14 +147,14 @@ function iterateDevice($topic, $fn, $device, $object) $changed[$fn]["value"] = $value; //echo "oldvalue => " . print_r($oldValue, true) . EOL; - if (empty($oldValue)) + /*if (empty($oldValue)) { echo "Initializing " . $key; }else { echo "changed " . $key . " value " . $oldValue;; } - echo " to " . $value . EOL; + echo " to " . $value . EOL;*/ } //print_r($device->functions); if (!empty($device->functions)) diff --git a/events.php b/events.php index d943a65..51e034c 100644 --- a/events.php +++ b/events.php @@ -3,15 +3,16 @@ function checkEvents() { global $events, $indexDevices, $devices; - echo "===========> checking events" . EOL; + //echo "===========> checking events" . EOL; foreach ($events as $key => $event) { - if ($event->dateTimeEvent <= now()) + if (!empty($event->dateTimeEvent) and $event->dateTimeEvent <= now()) { - echo "---->sending command" . EOL; + //echo "---->sending command" . EOL; publish($devices[$event->topic][$indexDevices[$event->ieeeAddress]], array($event->param => $event->value), "set", $key); //$event->published = now(); - unset($key); + //echo "#################################\nUnsetting event $key \n###########################" . EOL; + unset($events[$key]); } } //print_r($events); @@ -69,15 +70,15 @@ function searchEvent($device, $param , $value) global $events; echo "searching event" . EOL; //$keys = array_keys($events, $device->ieeeAddress); - echo "ieee_address =>" . $device->ieeeAddress . EOL; - print_r($events); + //echo "ieee_address =>" . $device->ieeeAddress . EOL; + //print_r($events); foreach($events as $key => $event) { //echo "Event : $event => $value" . EOL; - echo "===>";print_r($event); echo EOL; + //echo "===>";print_r($event); echo EOL; if($event->topic == $device->topic and $event->param == $param and $event->value == $value and $event->ieeeAddress == $device->ieeeAddress) { - echo "==============================\nfound " . $key . "\n=================================" . EOL; + //echo "==============================\nfound " . $key . "\n=================================" . EOL; return $key; } } @@ -87,7 +88,7 @@ function deleteEvent($eventKey) { global $events; unset ($events[$eventKey]); - echo "delete event " . $eventKey . EOL; + //echo "delete event " . $eventKey . EOL; } diff --git a/moha.php b/moha.php index 98192c4..12d02a9 100644 --- a/moha.php +++ b/moha.php @@ -35,12 +35,13 @@ class topic { class device { + public $method; //auto or manual public $topic; public $device; - public $json; public $ieeeAddress; + public $groupID; public $friendlyName; - public $type; + public $type; // if true then not a device but parameter of device(eg. topic/FRIENDLYNAME/PARAMETER public $powerSource; public $description; public $functions; @@ -50,6 +51,11 @@ class device { publish($this, $this->payload, "set", $event); } + + public function get() + { + publish($this, $this->payload, "get", $event); + } } class event @@ -136,15 +142,14 @@ $topics["zigbee2mqtt"] = new topic; bindtextdomain("moha", "./locale"); textdomain("moha"); -//signal handling -pcntl_signal(SIGTERM, 'signalHandler');// Termination ('kill' was called) -pcntl_signal(SIGHUP, 'signalHandler'); // Terminal log-out -pcntl_signal(SIGINT, 'signalHandler'); - +if (!init()) exit(1); +require "mqtt_functions.php"; +require "utils.php"; +require "events.php"; +require "db_functions.php"; $client = new Mosquitto\Client(); -if (!init()) exit(1); $client->onConnect('connectResponse'); $client->onDisconnect('disconnectResponse'); $client->onSubscribe('subscribeResponse'); @@ -152,8 +157,16 @@ $client->onMessage('message'); $client->onLog('logger'); $client->onPublish('publishResponse'); -$include 'mqtt_functions.php'; +//signal handling +pcntl_signal(SIGTERM, 'signalHandler');// Termination ('kill' was called) +pcntl_signal(SIGHUP, 'signalHandler'); // Terminal log-out +pcntl_signal(SIGINT, 'signalHandler'); + +// Program start + + +$client->connect("192.168.1.253", 1883, 5); foreach($topics as $name => $topic) { //echo $name; @@ -178,6 +191,10 @@ while (true) }elseif($dbInit and $included) { checkEvents(); + if (empty($flag)) + { + $flag = true; + } } } @@ -187,7 +204,7 @@ function init() { global $logFh, $client; date_default_timezone_set('Europe/Paris'); - $client->connect("192.168.1.253", 1883, 5); + if (! $logFh = fopen("moha.log", "w") ) { echo _("error opening log file"); @@ -211,7 +228,7 @@ function loadHooks($dir) if (is_dir($file)) { //echo "directory" . EOL; - listHooks($dir . '/' . $file); + loadHooks($dir . '/' . $file); }else { //echo "file" . EOL; @@ -234,14 +251,15 @@ function endMoha() { if ($object->status) { - $client->unsubscribe($topic); + $mid = $client->unsubscribe($topic); + $mids[$mid] = $topic; } } while ($nSubscribed != 0) { //echo $nSubscribed;0x00124b0022ebac5c - if ( $x++ > 30) exit (0); + if ( $x++ > 60) exit (0); $client->loop(); } $client->disconnect(); diff --git a/mqtt_functions.php b/mqtt_functions.php index c984cec..7365f7a 100644 --- a/mqtt_functions.php +++ b/mqtt_functions.php @@ -13,12 +13,12 @@ function message($message) break; case "devices": $topics[$topic[0]]->devices = json_decode($message->payload); - mkDevicesDB($topic[0], $topics[$topic[0]]->devices); fwrite($logFh, print_r($topics[$topic[0]]->devices, true)); + mkDevicesDB($topic[0], $topics[$topic[0]]->devices); break; case "groups": $topics[$topic[0]]->groups = json_decode($message->payload); - mkDevicesDB($topic[0], $topics[$topic[0]]->groups); + mkDevicesDB($topic[0], $topics[$topic[0]]->groups, true); break; case "extensions": $topics[$topic[0]]->extensions = json_decode($message->payload); @@ -37,11 +37,23 @@ function message($message) }; }elseif (($topic[array_key_last($topic)]) != "get" and ($topic[array_key_last($topic)]) != "set") { - $topic = explode ("/", $message->topic, 2); - + $topic = explode ("/", $message->topic, 2); // get topic name + $fnTree = explode ("/" , $topic[1]); // get friendlyname echo $topic[0] . " => " . $topic[1] . EOL; - $devices[$topic[0]][$topic[1]]->json = json_decode($message->payload); - changeDevice($topic[0], $topic[1], $devices[$topic[0]][$topic[1]]); + //$devices[$topic[0]][$fnTree[0]]->json = json_decode($message->payload); + $device = & $devices[$topic[0]]; + foreach($fnTree as $fn) + { + //print_r($device) ; + if (!isset($device[$fn])) + { + logger(LOG_INFO, $logFh, "init of " . $fn .EOL); + $device[$fn] = array(); + $device[$fn]["device"] = new device; + } + $device = & $device[$fn]; + } + changeDevice($topic[0], $topic[1], $device["device"], $message->payload); //fwrite($logFh, print_r($msg, true)); } } @@ -52,17 +64,19 @@ function message($message) function publish($device, $payload, $commande="set", $eventKey) { global $client, $mids, $logFh; - print_r($payload); + //print_r($payload); $string = $device->topic . "/" . $device->friendlyName . "/" . $commande; $mid = $client->publish($string, json_encode($payload) , 2); - if ($mids[$mid]) + if (isset($mids[$mid])) { + //echo "unsetting mids" .EOL; unset ($mids[$mid]); }else { + //echo "setting mids" .EOL; $mids[$mid] = true; } - echo $string . " =>>>>>> " . json_encode($payload) . EOL; + //echo $string . " =>>>>>> " . json_encode($payload) . EOL; logger(LOG_INFO, $logFh, "Publishing " . $string . " with payload => " . json_encode($payload)); } @@ -127,9 +141,11 @@ function publishResponse($mid) logger(LOG_INFO, "Event with mid = " . $mid . " published by MQTT broker"); if (isset($mids[$mid])) { + //echo "unsetting mids" . EOL; unset ($mids[$mid]); }else { + //echo "setting mids" . EOL; $mids[$mid] = true; } } diff --git a/scripts/panneau_salon.php b/scripts/panneau_salon.php index bc8f173..b617bd5 100644 --- a/scripts/panneau_salon.php +++ b/scripts/panneau_salon.php @@ -5,8 +5,8 @@ $rdcPanneau = function($topic, $fn, $param, $value) { global $devices, $indexDevices; - $delay = 20; - $timeUnit = "sec"; + $delay = 3; + $timeUnit = "min"; switch($param) { case "occupancy": @@ -14,16 +14,19 @@ { $msg = array("state" => "ON"); $device = $devices[Z2M][$indexDevices["0x588e81fffe343e8f"]]; - $device->set($msg); - setDelay($device, $delay, $timeUnit, $param, "OFF", true); + $device->payload = $msg; + $device->set(null); + setDelay($device, $delay, $timeUnit, "state", "OFF", true); } break; } echo _("notification received from MQTT") . EOL; - echo $param . "=> " . $value . EOL; + //echo $param . "=> " . $value . EOL; }; - //assignation of the function to the devices - $devices[Z2M][$indexDevices["0x00124b0022ebac5c"]]->functions[] = $rdcPanneau; - $devices[Z2M][$indexDevices["0x588e81fffe2cf695"]]->functions[] = $rdcPanneau; + //assignation of the function to the sensors devices + $indexDevices["0x00124b0022ebac5c"]->functions[] = $rdcPanneau; + $indexDevices["0x588e81fffe2cf695"]->functions[] = $rdcPanneau; + $indexDevices["0x04cf8cdf3c78aff0"]->functions[] = $rdcPanneau; + ?>