9. Dispositifs Zigbee
Avec zigbee2mqtt
9.1 Démarrage automatique
Important
Si Z2m n’envoie plus de messages à Domoticz ou Home assistant:
le souci vient de Z2M et du driver ember : à la moindre interruption du courter mqtt, il faut redémarrer Z2m
Pour une installation classique node.js
Démarrage auto : avec PM2 , Voir la page domo-site : http://domo-site.fr/accueil/dossiers/74
Pour une installation sous Docker, le démarrage sera automatique.
Pour un démarrage avec systemg zigbee2mqtt.service
[Unit]
Description=zigbee2mqtt
After=network.target
[Service]
Environment=NODE_ENV=production
ExecStart=/usr/bin/pnpm start
WorkingDirectory=/opt/zigbee2mqtt
StandardOutput=inherit
StandardError=inherit
Restart=always
User=root
[Install]
WantedBy=multi-user.target
9.2 Le fronted
Affichage
ajouter une fonction utile: vu pour la derière fois
A parir du frontend:
Note
ISO 8601 c’est la représentation de la date, en format internationalement, exemple : 2023-10-06T17:13:26Z
le payload MQTT:
MQTT publish: topic 'zigbee2mqtt/lampe_jardin', payload '{"last_seen":"2023-10-05T20:52:34.706Z","linkquality":156,"state_l1":"OFF","state_l2":"OFF"}'
La donnée « last_seen » peut être utilisé avec Node , HA (mais pas avec Dz) pour connaitre les dispositifs offline
Note
Voir la page du site consacrée à frontend : http://domo-site.fr/accueil/dossiers/48
9.3 Ajouter le Fronted dans monitor
la page zigbee.php
Le fichier admin/config.php
// Page zigbee2mqtt
define('ON_ZIGBEE',true);// mise en service Zigbee
define('IPZIGBEE', 'http://192.168.1.92:8084');//ip:port
define('URLZIGBEE', 'https://zigbee.<DOMAINE>');//url
Le fichier index_loc.php : pour info, ne pas modifier
if (ON_ZIGBEE==true) include ("include/zigbee.php");// fronted zigbee2mqtt
Les styles CSS
En plus des css pour la page:
/*zigbee2mqtt zwavejs2mqtt & ngiosmobile (----------------*/
#zbmqtt,#zwmqtt {margin-top:-40px;width: 100%;height: 800px;}
zigbee.php
on ajoute une iframe (permet d’obtenir une page HTML intégrée dans la page courante)
<iframe id="zbmqtt" src="<?php echo $lien_zigbee;?>" frameborder="0" ></iframe>
9.4 accès distant HTTPS
Il faut configurer NGINX : - 1.8 Accès distant HTTPS
Exemple de fichier .conf avant de demander un certificat cerbot
server {
listen 80;
server_name zigbee.<DOMAINE>;
#return 301 https://zigbee<DOMAINE>$request_uri;
}
location / {
proxy_pass http://<IP>:<PORT>/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /api {
proxy_pass http://<IP>:<PORT>/api;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Demande de certificat Let’s Encrypt :
sudo cerbot --nginx
Le fichier modifié par cerbot lors de la demande de certificat
Attention
** Pour utiliser auth basic** comme c’est le cas ici
Il faut créer un fichier de mot de passe et ajouter des utilisateurs
https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-http-basic-authentication/
9.5 utilisation directe avec monitor
sans l’intermédiaire de Domoticz, Home Assistant ou Ipbroker
9.5.1 Créer un lien symbolique de state.json
Ce fichier json contient les dernières valeurs de tous les dispositifs. il est mis à jour toutes les 5 minutes.
Note
la mise à jour en temps réel n’est effective que pour les dispositifs affichant un état ON/OFF; en règle général la mise à jour des autres dispositifs s’effectue dans le delai indiqué dans include/admin/config.php TEMPO_DEVICES”, 180000) pour DZ, HA, IOB ; il peut être judicieux , lors de l’utilisation de z2m directement par monitor d’armoniser cette mise à jour: 150 000 , 300 000, 450 000 milli secondes; pour une utilisation de seulement monitor + z2m , régler TEMPO_DEVICES sur 3000000.
ln -s /opt/zigbee2mqtt/data/state.json /opt/zigbee2mqtt/node_modules/zigbee2mqtt-windfront/dist/state.json
9.5.2 Installation de php-mqtt/client coté serveur
https://github.com/php-mqtt/client
Note
Un autre choix existe : mosquitto client; le paquet pour Debian, libmosquitto-dev mais l’installation n’est pas aussi simple qu’avec php-mqtt/client
installé depuis composer; composer ne peut pas être installé en root
cd /www/monitor
sudo apt install composer
composer require php-mqtt/client
9.5.2.1 envoyer et recevoir les messages
Le script est est exécuter dans le répertoire ws_z2m
<?php // PHP-MQTT
require('/www/monitor/vendor/autoload.php');
require('/www/monitor/admin/config.php');
use \PhpMqtt\Client\MqttClient;
use \PhpMqtt\Client\ConnectionSettings;
function id_name($nom_objet) {$rq=[];
$zb_donnees=array();
$zb_donnees = [
'state' => "Data",
'state_l2' => "Data",
'state_l1' => "Data",
'temperature' => "temperature",
'soil_moisture' => "Data",
'humidity' => "humidity",
"contact" => "Data"
];
if ($nom_objet!="") {
$conn = new mysqli(SERVEUR,UTILISATEUR,MOTDEPASSE,DBASE);
$sql="SELECT * FROM ".DISPOSITIFS." WHERE ( nom_objet = '".$nom_objet."' AND Actif = '6' AND maj_js <> 'variable');";
$result = $conn->query($sql);$nb_rows=$result->num_rows;
if ($nb_rows>0) {$i=0;//$row = $result->fetch_assoc();echo $row['ID'];
while($row = $result->fetch_array(MYSQLI_ASSOC)){
$ro=explode(":",$row['param']) ;
$rq[$i]=['ID' => $row['ID'],
'idm' => $row['idm'],
'champ' => $zb_donnees[$ro[1]],
'nb' => $nb_rows,
'json' => $ro[1]
];}
//$rx=json_encode($rq);echo $rx;
}
else { $rq[0]=['ID' => '0'];}}
else { $rq[0]=['ID' => '0'];}
return $rq;}
$server = MQTT_IP;
$port = 1883;
$clientId = rand(5, 15);
$username = MQTT_USER;
$password = MQTT_PASS;
$clean_session = false;
$mqtt_version = MqttClient::MQTT_3_1_1;
$connectionSettings = (new ConnectionSettings)
->setUsername($username)
->setPassword($password)
->setKeepAliveInterval(60)
->setLastWillTopic('monitor/last-will')
->setLastWillMessage('client mqtt déconnecté')
->setLastWillQualityOfService(1)
->setReconnectAutomatically(true)
->setMaxReconnectAttempts(3)
->setDelayBetweenReconnectAttempts(0);
try {
debut:
// Boucle d’attente de connexion
$maxWait = 30; // secondes max d’attente
$start = time();
$mqtt = new MqttClient($server, $port, $clientId, $mqtt_version);
$mqtt->connect($connectionSettings, $clean_session);
printf("client connecté\n");
$mqtt->subscribe('zigbee2mqtt/#', function ($topic, $message) use ($mqtt) {
//if ($topic == "monitor") {sms($message);}
$str=explode("/",$topic);$name=$str[1];$search_id=[];
$search_id=id_name($name);$id=$search_id[0]['ID'];
if ($id!="0") {$n=$search_id[0]['nb'];$i=0;while($i<$n){$search=$search_id[$i];echo "----->".$n." ".$i;
$id=$search['ID'];$idm=$search['idm'];$json=$search['json'];$champ=$search['champ'];$obj = json_decode($message);
if (isset($obj->state) && $obj->state=="offline"){$ob=$obj->state;$msg='{ "id" : "'.$id.'", "objet" : "'.$name.'", "state" : "'.$ob.'" }';maj($id,$ob);}
if (isset($obj->$json)) {$ob=$obj->$json;$msg='{ "id" : "'.$id.'", "objet" : "'.$name.'","state" : "'.$ob.'", "champ1" : "'.$champ.'", "champ2" : "'.$json.'", "idm" : "'.$idm.'"}';
// echo '------------'.$msg;
$mqtt->publish('z1m', $msg, 0,false);$id="0";$str=[];
echo "envoi msg:".$msg;
} $i++;}}} );
$mqtt->loop();
$mqtt->disconnect();
}
catch (\Throwable $e) {
echo 'An exception occured: ' . $e->getMessage() . PHP_EOL;
while (time() - $start <= $maxWait) {
usleep(1000000); // pause 1000ms pour éviter de saturer le CPU
echo ".";}
goto debut;
//$mqtt->disconnect();
}
Note
Ne pas utiliser « z2m » pour le topic à publier car il est utilisé pour publier des erreurs de zigbee2mqtt; j’ai utilisé « z1m »
9.5.2.2 démarrage automatique systemd
le fichier php-mqtt.service
[Unit]
Description=cclient mqtt php
After=multi-user.target
[Service]
Type=idle
ExecStart=php /var/www/monitor/ws_z2m/sub_messages_mqtt.php > /home/michel/sub_mqtt.log 2>&1
[Install]
WantedBy=multi-user.target
Pour activer et démarrer le service :
Systemctl enable php-mqtt
systemctl start php-mqtt.service
9.5.3 Scripts concernés dans monitor
9.5.4 Installation de mqtt.JS coté client
https://github.com/mqttjs/MQTT.js
if (MQTT==true) {echo '<script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>';}
9.5.4.1 Le javascript sur la page html
fichier include/mqtt-js.php
<?php require_once('admin/config.php');
$domaine=$_SESSION["domaine"];
if ($domaine==URLMONITOR) {$lien_mqtt=MQTT_URL;$w='wss://';}
if ($domaine==IPMONITOR) {$lien_mqtt=MQTT_IP;$w='ws://';}
?>
<script>
const clientId = 'mqttjs_' + Math.random().toString(16).substring(2, 8)
const connectUrl = '<?php echo $w.$lien_mqtt.":".MQTT_PORT;?>'
const options = {
keepalive: 60,
clientId: clientId,
clean: true,
connectTimeout: 30 * 1000,
username: '<?php echo MQTT_USER;?>',
password: '<?php echo MQTT_PASS;?>',
reconnectPeriod: 1000,
}
const topic = 'z1m/#'
const payload = ""
const qos = 0
var topic1="z1m"
var state=""
console.log('connecting mqtt client')
const client = mqtt.connect(connectUrl, options)
client.on('error', (err) => {
console.log('Connection error: ', err)
client.end()
})
client.on('reconnect', () => {
console.log('Reconnecting...')
})
client.on('connect', () => {
console.log('Client connected:' + clientId)
client.subscribe(topic, { qos }, (error) => {
if (error) {S
console.log('Subscribe error:', error)
return
}
console.log(`Subscribe to topic ${topic}`);
})
// publish message
client.publish(topic1, payload, { qos }, (error) => {
if (error) {
console.error(error)
}
})
})
client.on('message', (topic, payload) => {if (payload!=""){
console.log('Received Message: ' + payload.toString() + '\nOn topic: ' + topic);
var emsg=document.getElementById('msg_zb').innerText;
document.getElementById('msg_zb1').innerText = emsg;
document.getElementById('msg_zb').innerText=payload;
msg=JSON.parse(payload);var idm=msg.idm;var state=msg.state;var champ=msg.champ1;
var ind=4;if (champ=="Data") {ind=2;}
if (champ=="temp") {ind=3;}
maj_mqtt(idm,state,ind,0,champ) ;// fonction ds footer.php
}
})
</script>
9.5.4.2 envoyer et recevoir les messages
publier
client.publish(topic, msg);} // topic , payload
recevoir et mettre à jour les données
Voir aussi le § 8.1.2.2 Commandes de changement de couleur des lampes
9.5.5 Automatisations
9.5.5.1 Le plugin Zigbee2MQTT-automations
https://github.com/Luligu/zigbee2mqtt-automations
Installation
cd /opt/zigbee2mqtt/data
mkdir external_extensions
cd external_extensions
wget https://github.com/Luligu/zigbee2mqtt-automations/blob/master/dist/automations.js
systemctl stop zigbee2mqtt
systemctl start zigbee2mqtt
Après le redémarrage, automations.js est pris en compte par le fronted
Exemple d’une première automation : dans /opt/zigbee2mqtt/data/automations.yaml
Allumage lampes jardin 2mn depuis contact lampe_ porche:
active: true
trigger:
entity: lampe_terrasse_nord
state: ON
action:
- entity: lampe_jardin
payload:
state_l2: ON
turn_off_after: 120
payload_off:
logger: info
Dans le frontend -> Extensions: Sélectionner automations.js et sauvegarder; automations.yaml et scenes.yaml (si il existe) sont rechargés.
9.5.5.2 Script d’aide pour automations.yaml de monitor
le SCRIPT
UTILISATION:
. pour obtenir de l’aide
. indiquer le nom de l’automation, . choisir de l’activer ou non . choisir un déclenchement
. choisir une condition si il y a lieu, choisir une action
. POUR TERMINER APPUYER sur Envoyer
. et sur COPY pour récupérer le script et l’ajouter à :green:`automations.yaml”
Note
la console est affichée par un textarea html et l’indentation peut être quelquefois modifiée mais la copie crée dans le presse papier est correcte et peut être ajoutée dans automations.yaml.
La copie dans le presse papier est réalisée par clipboard.js : https://clipboardjs.com/












































