From e08470856cf8228a1d974103601a5d28d2ccb682 Mon Sep 17 00:00:00 2001 From: daniel Tartavel Date: Sat, 15 Jan 2022 10:52:03 +0100 Subject: [PATCH] first stable version --- linky2mqtt.php | 203 +++++++++++++++++++++++++++++++++++++++++++++ mqtt_functions.php | 137 ++++++++++++++++++++++++++++++ taglist.php | 41 +++++++++ utils.php | 81 ++++++++++++++++++ 4 files changed, 462 insertions(+) create mode 100644 linky2mqtt.php create mode 100644 mqtt_functions.php create mode 100644 taglist.php create mode 100644 utils.php diff --git a/linky2mqtt.php b/linky2mqtt.php new file mode 100644 index 0000000..72e2c41 --- /dev/null +++ b/linky2mqtt.php @@ -0,0 +1,203 @@ + $baudRate, + 'bits' => $bits, + 'stop' => $stopBit, + 'parity' => 1 +)); + +while(!$bbSerialPort) +{ + logger(ERROR, sprintf(_("Connection to Linky can not be established, retrying in %s seconds"), $reconnectDelay)); + sleep($reconnectDelay); +} +logger(INFO, _("Connected to serial port: " . $portName)); + +$lastToken = array(); + +while(1) +{ + $data = dio_read($bbSerialPort); //this is a blocking call + if ($data) + { + $string = ""; + logger(DEBUG, _("Data Received: ")); + + // add the precedent last incomplete tag + foreach ($lastToken as $lt) + { + if (isset($lt)) + { + $string .= $lt . "\t"; + } + } + $array = explode("\n", $string . $data); + //echo "LastToken " .EOL;print_r($lastToken);echo EOL; + + // loop to analyze tags + foreach ($array as $key => $string) + { + $lastKey = array_key_last($array); + $token = array(); + $token[] = strtok($string, "\t"); + while($token[] = strtok("\t")) + {} + //test if the last tag is completed or not + if ($key === $lastKey) + { + print("repere 1"); + var_dump($token); + if (isset($token[0])) + { + logger(DEBUG, _("ẗoken[0] is set")); + if (array_key_exists($token[0], $taglist)) + { + logger(DEBUG, _("ẗoken[0] exists in taglist")); + if (($taglist[$token[0]] & HORODATAGE) and !isset($token[3])) + { + logger(DEBUG, _("Token[3] not set")); + $lastToken = $token; + break; + }elseif (!isset($token[2]) or !isset($token[1])) + { + logger(DEBUG, _("Token[1] or Token[2] not set")); + $lastToken = $token; + break; + } + }else + { + logger(DEBUG, _("last Token not in taglist")); + $lastToken = $token; + break; + } + }else + { + logger(WARNING, _("Token[0] is not set")); + break; + } + } + array_pop($token); + if (checkCRC($string, end($token))) + { + array_pop($token); + mkLinkyDatas($token); + } + } + } + sleep(1); + /*if ($exit === false) + { + $exit = true; + }else { + exit(); + }*/ + $client->loop(); + +} + +function mkLinkyDatas($data) +{ + static $started = false; + static $linkyDatas; + echo $data[0] . EOL; + logger(DEBUG, _("function mkLinkyDatas")); + if (!$started) + { + logger(DEBUG, _("Array not started")); + echo "is ADSC ?" . $data[0] .EOL; + if ($data[0] == "ADSC") + { + logger(DEBUG, _("ADSC found, i start making array")); + $started = true; + //$linkyDatas[][$data[0]] = $data[1]; + $linkyDatas = "{"; + json_add($data, $linkyDatas); + echo $data[0] . "=>" . $data[1] .EOL; + } + }else + { + logger(DEBUG, _("Array already started")); + if ($data[0] == "ADSC") + { + $linkyDatas .= "}"; + publish($linkyDatas); + logger(DEBUG, _("# Starting new array #")); + $linkyDatas = "{"; //Reinitialisation of array + //$linkyDatas[][$data[0]] = $data[1]; + json_add($data, $linkyDatas); + echo $data[0] . "=>" . $data[1] .EOL; + }else + { + logger(DEBUG, _("Adding data to array")); + //$linkyDatas[][$data[0]] = $data[1]; + $linkyDatas.= ","; + json_add($data, $linkyDatas); + echo $data[0] . "=>" . $data[1] . EOL; + } + } + //echo $linkyDatas[array_key_last($linkyDatas)][$data[0]] ." => " . $linkyDatas[array_key_last($linkyDatas)][$data[1]]; +} + +function json_add($data, &$jsonString) +{ + if (count($data) == 3) + { + $jsonString .= '"' . $data[0] . '":{"' . $data[1] . '":"' . trim($data[2]) . '"}'; + }else + { + $jsonString .= '"' . $data[0] . '":"' . trim($data[1]) . '"'; + } + return $jsonString; +} +?> diff --git a/mqtt_functions.php b/mqtt_functions.php new file mode 100644 index 0000000..67028d3 --- /dev/null +++ b/mqtt_functions.php @@ -0,0 +1,137 @@ + 16 +define( "INFO", $client::LOG_INFO); // => 1 +define( "NOTICE", $client::LOG_NOTICE); // => 2 +define( "WARNING", $client::LOG_WARNING); // => 4 +define( "ERROR", $client::LOG_ERR); // => 8 +define( "ALERT", 32); +define( "ALL", DEBUG | INFO | NOTICE | WARNING | ERROR | ALERT); +$logLevel = ALL ; //INFO | WARNING | ERROR | ALERT; +//$notificationLevel = WARNING | ERROR; // TODO send notification + +logger(DEBUG, _("defining callback functions")); + +// defining callback functions +$client->onConnect('connectResponse'); +$client->onDisconnect('disconnectResponse'); +$client->onSubscribe('subscribeResponse'); +$client->onUnsubscribe('unsubscribeResponse'); +$client->onMessage('messageReceived'); +$client->onLog('logger'); +$client->onPublish('publishResponse'); + +logger(DEBUG, _("connecting to mqtt server")); +$client->connect($mqttServerAddress, $mqttServerPort, 30); +logger(DEBUG, _("subscribing")); +$mid = $client->subscribe($topicName . "/#", 2); + +function messageReceived($message) +{ + global $topicName, $logFh; + $topic = explode ("/", $message->topic); + if($topic[array_key_last($topic)] != "get" and ($topic[array_key_last($topic)]) != "set") + { + $topic = explode ("/", $message->topic, 2); // get topic name + $fnTree = explode ("/" , $topic[1]); // get friendlyname + echo $topic[0] . " => " . $topic[1] . EOL; + logger(INFO, print_r(json_decode($message->payload), true)); + } +} + +// payload is an array : +// $key is property => $value is value of the parameter + +function publish($payload, $commande="") +{ + global $mids, $friendlyName, $topicName, $client, $logFh; + //print_r($payload); + $string = $topicName . "/" . $friendlyName; + $mid = $client->publish($string, $payload , 2); + if (isset($mids[$mid])) + { + //echo "unsetting mids" .EOL; + unset ($mids[$mid]); + }else + { + //echo "setting mids" .EOL; + $mids[$mid] = true; + } + logger(LOG_INFO, $logFh, "Publishing " . $string . " with payload => " . $payload); +} + +function connectResponse($r, $message) +{ + global $connected; + echo sprintf(_("I got code %d and message : '%s'"), $r, $message) . EOL; + switch ($r) + { + case 0: + logger(INFO, _("Successfull connection")); + $connected = true; + break; + case 1: + logger(INFO, _("Connection refused : unacceptable protocol version")); + $connected = false; + break; + case 2: + logger(INFO, _("Connection refused : identifier rejected")); + $connected = false; + break; + case 3: + logger(INFO, _("Connection refused (broker unavailable )")); + $connected = false; + break; + } + return $connected; +} + +function subscribeResponse($mid, $qosCount) +{ + global $topics; + logger(INFO, _("Subscribed")); +} + +function unsubscribeResponse($mid) +{ + global $client; + logger(INFO, _("Unsubscribed")); + $client->disconnect(); +} + +function disconnectResponse($r) +{ + global $connected; + if ($r != 0) + { + $str = _('Badly '); + }else + { + $str = _('Cleanly '); + } + logger(INFO, $str . _("disconnected from server")); + $connected = false; +} + +function publishResponse($mid) +{ + global $mids, $events; + logger(LOG_INFO, "Event with mid = " . $mid . " published by MQTT broker"); + if (isset($mids[$mid])) + { + //echo "unsetting mids" . EOL; + unset ($mids[$mid]); + //print_r($mids); + }else + { + //echo "setting mids" . EOL; + $mids[$mid] = true; + } +} +?> diff --git a/taglist.php b/taglist.php new file mode 100644 index 0000000..e3612a3 --- /dev/null +++ b/taglist.php @@ -0,0 +1,41 @@ + null, + "VTIC" => null, + "DATE" => null, + "NGTF" => null, + "LTARF" => null, + "EAST" => null, + "EASF01" => null, + "EASF02" => null, + "EASF03" => null, + "EASF04" => null, + "EASF05" => null, + "EASF06" => null, + "EASF07" => null, + "EASF08" => null, + "EASF09" => null, + "EASF10" => null, + "EASD01" => null, + "EASD02" => null, + "EASD03" => null, + "EASD04" => null, + "IRMS1" => null, + "URMS1" => null, + "PREF" => null, + "PCOUP" => null, + "SINSTS" => null, + "SMAXSN" => HORODATAGE, + "SMAXSN-1" => HORODATAGE, + "UMOY1" => HORODATAGE, + "STGE" => null, + "MSG1" => null, + "PRM" => null, + "RELAIS" => null, + "NTARF" => null, + "NJOURF" => null, + "NJOURF+1" => null, + "PJOURF+1" => null, + ); diff --git a/utils.php b/utils.php new file mode 100644 index 0000000..4737e8f --- /dev/null +++ b/utils.php @@ -0,0 +1,81 @@ + CRC = %x"), $s1, ord($crc))); + if ($s1 == ord($crc)) + { + return true; + }else + { + return false; + } +} + +function now() +{ + return new DateTime("now"); +} + +function signalHandler($signal) +{ + global $bbSerialPort, $connected, $client, $logFh; + $x = 0; + dio_close($bbSerialPort); + while ($connected) + { + if ( $x++ > 60) + { + $client->disconnect(); + fclose($logFh); + exit (1); + } + $client->loop(); + } + sleep(4); + fclose($logFh); + exit(0); +} + +function logger($level, $log, $notif = false) +{ + global $logFh, $logLevel, $notificationLevel; + //echo "=====>>>> $level => $logLevel => $notificationLevel" . EOL ; + //echo $log .EOL; + //var_dump($level); + //var_dump($log); + if ($level & $logLevel) + { + fwrite($logFh, "$level : $log" . EOL); + print ("$level : $log" . EOL); + } +} + +date_default_timezone_set('Europe/Paris'); + +if (! $logFh = fopen("/var/log/pws2mqtt.log", "w") ) +{ + echo _("error opening log file") . EOL; +}else +{ + echo _("Log file opened") . EOL; +} + +//signal handling +pcntl_signal(SIGTERM, 'signalHandler');// Termination ('kill' was called) +pcntl_signal(SIGHUP, 'signalHandler'); // Terminal log-out +pcntl_signal(SIGINT, 'signalHandler'); +?>