Deep Sleep et OTA Update : réflexions…

Posted by

Aujourd’hui, j’ai 3 sondes domotiques DIY qui tournent comme des charmes dans la maison…

Basées sur du Wemos D1 Mini, une sonde DHT22, un shield batterie TP4056 et une Li-Ion 18650, le tout sur un firmware 100% fait maison, j’vous raconte pas comment qu’j’en suis fier de celles-là… 😀

Ceci dit, aujourd’hui, j’ai un soucis : y a bien longtemps, j’ai mis en place l’OTA dans le code ; comme je suis fainéant je vais pas me lancer dans un tuto sur le sujet, mais vous pouvez trouver pleins d’infos sur le sujet, par exemple ici… En gros, ça veut dire qu’en théorie, je pourrais envoyer un nouveau firmware par le wifi, au lieu de connecter mon Wemos en USB sur l’ordi. Super pratique, pour pas aller cavaler partout dans la maison quand il s’agit de mettre à jour les capteurs !

Sauf que maintenant, mon Wemos fonctionne selon une boucle qui fait :

  1. Wake Up feignasse !!
  2. Y a un update OTA ? non ? je continue…
  3. Mesure des données du sensor
  4. Connexion Wifi
  5. Connexion au serveur MQTT
  6. Publication MQTT des données
  7. Déconnexion du MQTT (on fait les choses proprement…)
  8. Deep Sleep !

Cette boucle, de 1 à 8, se passe en quelques secondes… toutes les minutes pour l’instant, et à terme toutes les 10 minutes.

Ca veut dire que pendant 9 minutes et des brouettes, sur 10 minutes, mon module, ben y roupille… pas de wifi, pas d’attente OTA… donc théoriquement, j’ai une fenêtre de quelques secondes (voire moins !!) pour lancer mon update dans les airs (OTA = Over The Air, hein… bon je sors). Impossible.

J’ai donc pensé à la solution suivante :

Mon module étant un publisher MQTT, pourquoi ne pas en faire un subscriber, qui écouterait un topic spécifique qui, quand il le choppe, se dit « ah ok, j’arrête ma boucle classique de deepsleep, et je me mets dans un mode « attente d’update » ?

Ni une ni, je prototype le truc.

Résultat : Ah oui. L’étape 7 : déconnexion du MQTT… accessoirement, ça arrête tout simplement la souscription au fameux topic… et un topic envoyé lorsque je n’y suis pas abonné, je ne le verrai jamais. Raté.

Du coup, je cherche une idée…

Et comme je la trouve pas, je poste cet article qui ressemble à un échec, mais qui me permet de verbaliser le truc et, peut-être, faire de ce blog un canard en plastique, pour une fois…

?

… non. ça vient pas.

Bon, ben je continue la réflexion, et si je trouve qqchose, je mettrai ce post à jour !

Stay safe…

Edit 02.01.2021

En fait, j’ai trouvé quelques temps après la publication de cet article…

Passons quelques secondes sur MQTT et le flag « retain » : lorsqu’un message est publié sans flag « retain« , le serveur MQTT vérifie, dès qu’il arrive, s’il y a des subscribers à celui-ci : s’il n’en trouve aucun, le message est benné direct. C’est la situation toute logique que j’ai rencontrée en faisant mes premiers tests, tels que présentés plus haut. Par contre, si « retain » est passé à True lors de la publication du message, alors le message est conservé sur le serveur, qu’il y ait un abonné ou non. Pratique : si un abonné se connecte après la publication, c’est parfait, il le trouve, et l’utilise…

… Sauf que oui mais non !

Et oui : ok, c’est top, mon abonné trouve le message. Mais la contrepartie du mode retain, c’est que, contrairement au mode pas-retain, le message n’est pas supprimé par le serveur MQTT lorsque le dernier abonné l’a reçu. Du coup, si l’abonné, ou un autre, se déconnecte, puis revient, il va le retrouver, et potentiellement le traiter inutilement ; dans notre cas, ça va vouloir dire : « remets toi en mode OTA » indéfiniment… Il va donc falloir trouver un moyen de le supprimer, ce message !

Ah oui, mais … j’avais jamais réfléchi à ça : ça s’efface, un message MQTT ?

Et bien oui ! Et, alors que je m’en faisais toute une montagne, je vais pulvériser vite-fait le mythe : effacer un message MQTT, c’est aussi simple que de publier un topic avec une payload vide ! Point. Rien de plus…

Du coup, on a trouvé la solution… et je vous confirme, tout ça fonctionne comme un charme 😉