Notre librairie en ligne de commande permet d'utiliser tous nos modules depuis un terminal ou dans un shell script.
Nous avons plusieurs fois utilisé cette librairie pour configurer un module ou effectuer une tâche ponctuelle, mais nous avons remarqué que nous n'avons pas encore parlé d'un autre type d'utilisation: la surveillance des valeurs mesurées dans un shell script.
Si l'on désire surveiller la valeur d'un capteur, il est possible d’utiliser les commandes traditionnelles get_XXXX en boucle à l'aide d'un shell script ou de l'utilitaire UNIX watch.
Toutefois, cette approche n'est pas efficace. D'une part, à chaque appel l'utilitaire YSensor doit initialiser la connexion avec le module, ce qui peut prendre un certain temps. D'autre part, cette approche ne permet d'obtenir qu'une mesure ponctuelle toutes les X secondes. Les mesures entre chaque appel à YSensor sont ignorées.
Dans nos librairies de programmation, la solution correcte pour surveiller la valeur d'un capteur est d'utiliser les callbacks: Comment lire efficacement un capteur.
Pour la librairie en ligne de commande, il n'y a pas à strictement parler de callback, mais deux fonctions qui permettent de lire efficacement et en continu la valeur d'un capteur.
get_valueChange
La commande get_valueChange est le pendant des callbacks de valeurs dans les librairies de programmation. C'est-à-dire que cette fonction permet d'obtenir la valeur propagée de manière efficace.
Dès que le capteur du module détecte un changement du signal mesuré, il transmet la nouvelle valeur à la librairie en ligne de commande qui l'affiche immédiatement. La commande ne rend pas la main et continue à afficher sur la sortie standard les nouvelles valeurs qu'elle reçoit des capteurs. Il n'y a pas de latence liée à une attente externe, et les mesures ne sont pas perdues.
Un exemple sur une machine avec un Yocto-Meteo connecté par USB:
OK: METEOMK2-120582.pressure.valueChange = 972.02.
OK: METEOMK2-120582.humidity.valueChange = 46.7.
OK: METEOMK2-120582.humidity.valueChange = 46.6.
Notez, il est possible de configurer la commande pour quelle rende la main après le premier changement de valeur à l'aide des deux paramètres optionnel suivants:
- minWait: le temps minimum pour attendre une valeur, zéro pour attendre au moins la première valeur.
- maxWait: le délai maximal d'attente pour une valeur, zéro pour ne pas attendre plus longtemps que la première valeur.
get_timedReport
La commande get_timedReport est le pendant des callbacks periodiques dans les librairies de programmation Yoctopuce. C'est-à-dire que cette fonction permet d'obtenir à intervalle fixe la valeur minimal, moyenne et maximale d'un capteur. Tout comme get_valueChange, les valeurs sont affichées sur la sortie standard immédiatement.
Pour utiliser cette fonctionnalité, il faut auparavant que le l'attribut reportFrequency du module ait été configuré. Comme c'est le module qui en interne calcule la valeur minimale, moyenne et maximale et qui transmet de manière périodique à la librairie ces informations, si l'attribut reportFrequency n'est pas configuré, il n'enverra jamais de notification périodique. Il est possible de configurer cet attribut avec le VirtualHub ou, comme nous le verrons plus bas, directement avec la librairie ligne de commande.
Un exemple sur une machine avec un Yocto-Meteo connecté par USB:
OK: METEOMK2-120582.humidity.timedReport = 1572482454;46.590;46.647;46.670.
OK: METEOMK2-120582.pressure.timedReport = 1572482454;971.840;971.845;971.851.
OK: METEOMK2-120582.temperature.timedReport = 1572482454;23.513;23.522;23.534.
OK: METEOMK2-120582.humidity.timedReport = 1572482456;46.590;46.6470;46.6700.
OK: METEOMK2-120582.pressure.timedReport = 1572482456;971.839;971.845;971.853.
OK: METEOMK2-120582.temperature.timedReport = 1572482456;23.520;23.523;23.534.
OK: METEOMK2-120582.humidity.timedReport = 1572482458;46.630;46.655;46.680.
OK: METEOMK2-120582.pressure.timedReport = 1572482458;971.839;971.844;971.849.
OK: METEOMK2-120582.temperature.timedReport = 1572482458;23.517;23.519;23.523.
OK: METEOMK2-120582.humidity.timedReport = 1572482460;46.600;46.626;46.670.
OK: METEOMK2-120582.pressure.timedReport = 1572482460;971.837;971.845;971.850.
OK: METEOMK2-120582.temperature.timedReport = 1572482460;23.510;23.517;23.523.
Tout comme la commande get_valueChange, il est possible de spécifier un minWait et un maxWait pour rendre la main après la première mesure.
Exemple concret
Pour illustrer l'utilisation de ces commandes, nous allons écrire un micro script d'une seule ligne qui récupère la température d'un Yocto-Meteo et si la température dépasse 25° au cours des dernières 5 minutes une entrée est ajoutée dans les logs système de Linux.
Installer la librairie
La première chose à faire est d'installer la dernière version de notre librairie "Ligne de commande" à l'aide d'apt-get.
Si ce n'est pas déjà fait, il faut ajouter notre repository APT au système à l'aide des commandes suivantes:
wget -qO - https://www.yoctopuce.com/apt/KEY.gpg | sudo apt-key add - echo "deb https://www.yoctopuce.com/ apt/stable/" | sudo tee /etc/apt/sources.list.d/yoctopuce.list
On peut ensuite installer la librairie à l'aide de l'utilitaire apt-get
sudo apt-get update sudo apt-get install yoctolib-cmdlines
Configurer le module
Il faut ensuite configurer la fréquence de notification périodique du capteur de température du Yocto-Meteo. Pour cet exemple, nous allons utiliser une fréquence de 12 fois par heure, ce qui fait un intervalle de 5 minutes. Notez l'option -s qui sauvegarde ce paramètre dans la mémoire flash du Yocto-Meteo. De cette manière, même si le module est débranché puis rebranché, il enverra toujours une notification toutes les 5 minutes.
yocto@linux-laptop:~$ YTemperature -s all set_reportFrequency 12/h OK: METEOMK2-120582.temperature.set_reportFrequency = 12/h. OK: METEOMK2-120582.module.saveToFlash executed.
Lire la température en continu
Ensuite, pour récupérer ces notifications de manière efficace, on utilise la commande get_timedReport. Pour simplifier le parsing des données affichées, on utilise l'option --csv qui formate les résultats dans un format CSV.
Concrètement, l'utilitaire YTemperature va afficher les informations suivantes séparées par un ";" sur une seule ligne toutes les 5 minutes:
- le hardware ID du senseur
- la date de la mesure
- la valeur minimal durant les 5 minutes
- la valeur moyenne durant les 5 minutes
- la valeur maximale durant les 5 minutes
Avant continuer on peux vérifier que tout fonctionne comme prévu.
yocto@linux-laptop:~$ YTemperature --csv all get_timedReport METEOMK2-120582.temperature;2019-10-31 00:45:00.00;23.579;23.593;23.608 METEOMK2-120582.temperature;2019-10-31 00:50:00.00;23.568;23.598;23.632 METEOMK2-120582.temperature;2019-10-31 00:55:00.00;23.582;23.606;23.632 METEOMK2-120582.temperature;2019-10-31 01:00:00.00;23.542;23.572;23.600 METEOMK2-120582.temperature;2019-10-31 01:05:00.00;23.546;23.570;23.596
La dernière étape consiste à rediriger la sortie de YTemperature sur l’utilitaire awk pour parser chaque ligne et en faire quelque chose d'intéressant. Dans notre cas, on veut appeler la commande logger si la température dépasse 25°.
La commande awk qui permet de parser la sortie est la suivante:
L'option -F\; indique à awk que chaque champ est séparé par un ";".
Dans le script, les variables $1, $2, $3, $4 et $5 correspondent respectivement au hardware ID, la date de la mesure, la temperature min, la temperature moyenne et la température max.
La partie "$4>25" indique à awk qu'il ne faut exécuter la suite que si la temperature moyenne ($3) dépasse 25. La suite justement effectue un appel à l'utilitaire logger qui ajoute une entrée dans les logs système.
La commande complète est donc :
yocto@linux-laptop:~$ YTemperature --csv all get_timedReport | awk -F\; '$4>25 {system("logger -s \"Température élevée : \""$1"="$4 "°")}' <13>Oct 31 17:58:12 yocto: Température élevée : METEOMK2-120582.temperature=25.3190°
Conclusion
Comme nous venons de le voir, il est possible de surveiller efficacement un capteur Yoctopuce avec notre API en ligne de commande. Cette fonctionnalité plaira certainement aux gourous du shell script. Toutefois, à notre avis dans 99% des cas il est plus simple d'écrire un petit programme dans un langage comme Python.