Présentation

Il y a quelques jours, j’ai trouvé un détecteur de mouvement avec une batterie rechargeable de chez Calex. Comme la plupart des IOT sur le marché, il fonctionne sur la plate-forme Tuya avec un microcontrôleur TYWE3S. J’ai essayé de le convertir à l’aide du logiciel Tuya-Convert mais j’ai lamentablement échoué, il semble que Tuya ait amélioré son jeu de piratage.

Problème

La détection via le cloud met plusieurs secondes à être acquittée et utilisée par mon serveur homeassistant, cela rend l’automatisation des lumières bizarre à cause du lag.

Solution

J’ai le contrôle du DNS via mon pihole, et j’ai vu que le capteur appelle son serveur “tuya” à chaque fois qu’il y a du mouvement. J’ai décidé de capitaliser sur cette information.

grep -Ea "from 192.168.10.172" /var/log/pihole.log
Jul 16 11:37:58 dnsmasq[242]: query[A] m2.tuyaeu.com from 192.168.10.172
Jul 16 11:37:58 dnsmasq[242]: query[A] a3.tuyaeu.com from 192.168.10.172
Jul 16 13:52:03 dnsmasq[242]: query[A] m2.tuyaeu.com from 192.168.10.172
Jul 16 13:52:03 dnsmasq[242]: query[A] a3.tuyaeu.com from 192.168.10.172

En fait, ce dont j’ai besoin, c’est de l’heure exacte.

grep -Ea "from 192.168.10.172" /var/log/pihole.log | tail -1 | awk '{print $3}'
13:52:03

MQTT

Mqtt-Homeassistant

Avec l’aide de la documentation homeassistant et beaucoup d’essais et d’erreurs, je suis arrivé à cette commande :

mosquitto_pub -h hass.lan -p 1883 -u $user -P $pass -t /pihole/pir/${target_item[i]} -m '{"motion" : "true"}' --qos 0 --retain

Le target_item est le capteur, ils étaient bon marché donc j’en ai acheté 3. Celui-ci communique au Mosquitto Broker l’état du capteur, puis les configurations sur l’assistant domestique aident à un paramétrage plus cohérent et utilisable.

Homeassistant: config/mqtt.yaml

binary_sensor:
- name: "mqtt-pir.atelier"
  state_topic: "/pihole/pir/atelier"
  availability_topic: "/pihole/pir/availability"
  value_template: "{{ 'ON' if value_json.motion == 'true' else 'OFF' }}"
  force_update: true
  off_delay: 15
  qos: 0
  device_class: motion

Le Script

Dans un premier temps je déclare les variables utilisées :

#!/bin/bash

  # Informations d'identification MQTT
  user="mqttuser"
  pass="password"

  # Éléments cibles et leurs adresses IP correspondantes
  target_item=("atelier" "cour_avant" "cour_arriere")
  ip_item=("192.168.10.172" "192.168.10.173" "192.168.10.177")

  # Tableau pour stocker les horodatages de détection
  det_at=()
  # Tableau pour stocker les derniers horodatages de détection
  last_det=()
  # Tableau pour stocker les jours de journalisation
  log_day=()

Ensuite, comme écrit dans la documentation, j’ai paramétré la disponibilité du capteur et mis en place un piège en cas de reboot ou d’erreur.

 # Publier l'état de disponibilité sur MQTT
  mosquitto_pub -h hass.lan -p 1883 -u $user -P $pass -t /pihole/pir/availability -m "online" --qos 0 --retain

  # S'il y a une erreur soudaine ou un redémarrage, changez le statut en hors ligne
  trap 'mosquitto_pub -h hass.lan -p 1883 -u $user -P $pass -t /pihole/pir/availability -m "offline" --qos 0 --retain' EXIT

Ensuite, je démarre la boucle principale qui transformera une deuxième boucle qui parcourt la liste des capteurs à traiter. Et filtre le journal pour les entrées.

 while true; do
      # Parcourir les éléments cibles
      for ((i = 0; i < ${#target_item[@]}; i++ )); do
          # Récupérer le dernier horodatage de détection depuis le journal pour l'élément et l'IP actuels
          det_at[i]=$(grep -Ea "from ${ip_item[i]}" /var/log/pihole.log | tail -1 | awk '{print $3}')
          # Convertir le dernier horodatage de détection en secondes depuis l'époque
          last_item_sec[i]=$(date -d "${last_det[i]}" +%s)
          # Convertir l'horodatage de détection actuel en secondes depuis l'époque
          detected_item_sec[i]=$(date -d "${det_at[i]}" +%s)
          # Récupérer le jour de journalisation pour l'élément et l'IP actuels
          log_day[i]=$(grep -Ea "from ${ip_item[i]}" /var/log/pihole.log | tail -1 | awk '{print $2}')
          # Obtenir le jour actuel
          current_day=$(date -du +%_d)

Ensuite, je vérifie s’il y a une différence entre le dernier horodatage enregistré et les nouvelles entrées, et je mets à jour le registre.


          # Vérifier si une nouvelle détection s'est produite pour l'élément actuel et si c'est le même jour
          if (( ${detected_item_sec[i]} )) && [[ ${log_day[i]} -eq $current_day ]]; then
              # Vérifier si la nouvelle détection s'est produite après la dernière détection
              if (( ${last_item_sec[i]} )) && [[ ${last_item_sec[i]} < ${detected_item_sec[i]} ]]; then
                  # Mettre à jour le dernier horodatage de détection
                  last_det[i]=${det_at[i]}

Voici la commande mosquitto_pub, j’ai également implémenté une commande ’no-motion’ apres le else, mais cela ne semble pas avoir beaucoup d’importance, et cela fait juste du bruit, mais vous pouvez l’activer si vous le souhaitez. Il met également à jour la variable last_det et dort un peu.


                  # Utilisez mosquitto_pub pour publier la charge de détection
                  mosquitto_pub -h hass.lan -p 1883 -u $user -P $pass -t /pihole/pir/${target_item[i]} -m '{"motion" : "true"}' --qos 0 --retain
                  sleep 2
              else
                  # Décommentez la ligne suivante si vous souhaitez exécuter la commande mosquitto_pub et publier la charge "pas de mouvement/clair"
                  # mosquitto_pub -h hass.lan -p 1883 -u $user -P $pass -t /pihole/pir/${target_item[i]} -m '{"motion" : "false"}' --qos 0 --retain
                  # Mettre à jour le dernier horodatage de détection
                  last_det[i]=${det_at[i]}
                  sleep 2
              fi
          else
              sleep 2
          fi
      done
  done

Est-ce que ça marche? Eh bien, si avec la solution cloud, le capteur fonctionne de manière peu fiable avec un décalage compris entre 3 et 10 secondes, j’ai ainsi un temps de réponse fiable de 3 secondes.

Vous pouvez trouver le script à télécharger sur : https://git.cabivr.net/radu/pir-mqtt