J'utilise la solution libre Domoticz pour orchestrer la domotique à la maison. Domoticz propose une API qui retourne des données au format JSON.
Voyons comment est-il possible d'extraire facliment une valeur provenant d'un fichier au format JSON.
Pistes écartées
Première idée : mais t'as pas besoin d'un script pour faire ça, à grand coup de grep, awk, sed ou cut et c'est plié !
Alors oui c'est possible, mais après réflexion je préfère parser correctement le contenu JSON car j'aurai probablement d'autres utilisations plus tard. Mais si ça peut pimenter un peu vos vacances (ou l'open space) posez votre code en commentaire je l'ajouterai au billet 🙂
jq
De mes recherches ressortent plusieurs scripts et solutions et c'est jq que j'ai choisi. jq est une sorte de sed qui fonctionne avec du JSON.
Installation
Depuis 2018 jq est disponible dans les dépôts
Pour l'installer sur Raspbian :
apt install jq
Utilisation
Il faut ensuite récupérer l'identifiant (idx) du capteur/sonde de Domoticz dans Réglages > Dispositifs > Utilisés. Dans mon cas c'est le numéro 456 qui correspond à une sonde de température / humidité.
Depuis le Raspberry :
curl -s "http://localhost:8080/json.htm?type=devices&rid=456" | jq -r .result[]."Data" 25.7 C, 50 %
Si vous utilisez le nom d'hôte de votre Raspberry Pi plutôt que "localhost" vous pourrez avoir une erreur d'accès, car le flux passera par l'interface physique plutôt que la boucle locale (127.0.0.1).
Si vous lancez ce script depuis une autre machine (Synology, serveur gnu/linux...) alors il faut remplacer localhost par l'IP de votre Raspberry et ajouter user/password :
curl -s "http://utilisateur:password@ip-raspberry:8080/json.htm?type=devices&rid=456" | jq -r .result[]."Data"
Si vous préférez bypasser les identifiants c'est possible en précisant les IP sources des machines qui auront un accès libre, dans Réglages > Paramètres > Réseaux locaux. Cela implique d'être en IP fixe ou dhcp static évidemment sur ces machines.
Isoler température et humidité
Ma sonde renvoie la température et l'humidité sous une seule chaine. Pour extraire séparément ces valeurs il faut utiliser cut.
Pour la température :
curl -s "http://localhost:8080/json.htm?type=devices&rid=456" | jq -r .result[]."Data" | cut -d' ' -f1 exemple de retour (en degrés celcius): 30.4
Pour l'humidité :
curl -s "http://localhost:8080/json.htm?type=devices&rid=456" | jq -r .result[]."Data" | cut -d' ' -f3 exemple de retour (en %): 65
En complément
Voici un exemple d'utilisation de jq chez Easydomoticz pour lire les prévisions de pluie. Et une alternative à jq avec jsawk qui est donc le cousin de jq orienté "awk". Pour tester vos filtres vous pouvez utiliser jqplay (découvert chez lecacheur). Attention à bien respecter la casse !
En bref ça fonctionne, c'est simple et évolutif. J'ai pu intégrer les valeurs de mes capteurs directement dans mon bash_profile que je vous partagerai bientôt.
Auteur : Mr Xhark
Fondateur du blog et passionné par les nouvelles techno, suivez-moi sur twitter
8 commentaires
J'ai un soucis : error 2
pi@RASPBERRYPI:~/jq $ make
make all-recursive
make[1]: Entering directory '/home/pi/jq'
Making all in modules/oniguruma
make[2]: Entering directory '/home/pi/jq/modules/oniguruma'
make[2]: *** No rule to make target 'all'. Arrêt.
make[2]: Leaving directory '/home/pi/jq/modules/oniguruma'
Makefile:1079: recipe for target 'all-recursive' failed
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory '/home/pi/jq'
Makefile:755: recipe for target 'all' failed
make: *** [all] Error 2
@Doudy: n'utilise pas la version make mais le paquet des dépôts
Bonjour,
J'essaie d'extraire la donnée "Counter", 0.247 kWh, d'un compteur virtuel incrémental dans Domoticz avec jq.
Pour utiliser cette donnée dans un script Lua.
Grâce à mon navigateur j'obtiens cette donnée :
{
"AddjMulti" : 1.0,
"AddjMulti2" : 1.0,
"AddjValue" : 0.0,
"AddjValue2" : 0.0,
"BatteryLevel" : 255,
"Counter" : "0.247 kWh",
"CounterToday" : "0.057 kWh",
"CustomImage" : 0,
"Data" : "0.247 kWh",
"Description" : "",
"Favorite" : 0,
"HardwareDisabled" : false,
"HardwareID" : 3,
"HardwareName" : "Dispositifs_Virtuels",
"HardwareType" : "Dummy (Does nothing, use for virtual switches only)",
"HardwareTypeVal" : 15,
"HaveTimeout" : true,
"ID" : "82115",
"LastUpdate" : "2023-02-09 08:03:55",
"Name" : "Compteur",
"Notifications" : "false",
"PlanID" : "0",
"PlanIDs" :
[
Mais la commande curl -s "http://localhost:8080/json.htm?type=devices&rid=115" | jq -r .result[].Counter me renvoie l’erreur :
parse error: Invalid numeric literal at line 1, column 60
Y va-t-il une réponse à ce problème, sinon il-t-il une solution à ce problème ?
Je vous remercie pour vos réponses
@Blueberry: la donnée que tu as retournée est iincomplète, voici : un how-to
Bonjour,
Tout d’abord, je vous remercie de votre réponse et de l’intérêt que vous portez à mon problème.
Vous m’avez orienté vers la page : https://blog.cedrictemple.net/notes-pour-plus-tard/JQ-outil-de-parsing-et-d-analyse-de-json/ que j’ai commencé à déchiffrer avec intérêt.
J’ai compris que la commande : curl -s 'http://localhost:8080/json.htm?type=devices&rid=115' | jq '.'
Me permettrait d’afficher l’ensemble des données de mon dispositif virtuel "Compteur" or j’ai le même message d’erreur que précédemment : parse error: Invalid numeric literal at line 1, column 60
Ma version de jq est jq-1.5-1-a5b5cbe. Les tests que je réalise avec les exemples donnés dans la page de Cédric Temple fonctionnent convenablement.
Je vous livre les données complètes de mon compteur, sachant que je désire récupérer la valeur 0,367 de "Compteur" : "0,367 kWh" et vous remercie à l’avance de toute l’aide que vous pourriez m’apporter:
@Mr Xhark: Rebonjour lorsque je tapais dans le LXTerminal :
curl -s http://localhost:8080/json.htm?type=devices&rid=115
Je n’obtenais pas les données du compteur mais le message suivant :
Unauthorized401 Unauthorized</html
Le problème est un problème d’authentification. Il a fallu que je rajoute l’Identifiant et le Mot de passe tel que :
curl -s "http:// identifiant:mot_de_passe@localhost:8080/json.htm?type=devices&rid=115" | jq -r .result[].Counter
Et maintenant tout marche bien. J’obtiens bien 0.367 kWh
Pourriez-vous me dire s’il existe un moyen de l’identifiant et du Mot de passe que je vais devoir indiquer en clair dans les scripts.
Je vous remercie pour votre réponse.
@Blueberry: Oui il est possible d'ignorer l'authentification pour certaines adresses IP. Vous devez ajouter l'adresse IP de votre raspberry pi et la boucle locale (192.168.x.x, 127.0.0.1) dans menu configuration > paramètres > section Réseaux locaux (pas d'authentification)
192.168.x.x est un exemple il faut remplacer par l'adresse IP de votre Raspberry Pi (ex: 192.168.1.10)
@Mr Xhark: Merci pour tout