Mes passions, le boulots, mes coups de gueule...




Xiaomi Mijia LYWSD03MMC : Récupérer les données du capteur sur un Raspberry Pi avec gatttool

Catégories : Domotique, Geek, Informatique, Linux, Raspberry Pi · par 16 Avr 2020

Introduction

Depuis quelques temps, j’utilise différents types de capteurs Bluetooth pour effectuer des mesures de température, d’humidité, d’éclairement, de fertilité du sol, …

Aujourd’hui, je vais détailler la procédure pour récupérer les données en provenance d’un capteur de température et d’humidité Xiaomi Mijia LYWSD03MMC.

Le capteur a une taille très modeste puisqu’il ne mesure que 4.30 x 4.30 x 1.25 cm et ne pèse pas plus de 60g.

Il est alimenté par une pile classique CR 2032.

Il est muni d’un petit écran LCD qui affiche la température, le pourcentage d’hygrométrie et un petit smiley qui détermine si la combinaison des deux premières valeurs est confortable.

On le trouve facilement sur Amazon pour moins d’une dizaine d’euros.


N.B. : Seule la version destinée au marché chinois est actuellement en vente. Vous devrez donc localiser l’App iOS « Xiaomi Home » en Chine pour pouvoir appairer un nouveau Mijia LYWSD03MMC, sans quoi il n’apparaîtra pas dans la liste des accessoires Xiaomi.

Appairage avec un iPhone

Importer les données

Installation du Bluetooth

En principe, si vous utilisez un RPi avec Jessie, Stretch ou Buster, les outils gatttool et hcitool que nous allons utiliser plus loin devraient déjà être installés.

Si ce n’est pas le cas, je vous renvoie vers cet article : https://fr.tipsandtrics.com

$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install bluetooth bluez-utils blueman bluez

Déterminer l’adresse MAC du Mijia LYWSD03MMC

Pour déterminer cette adresse, nous allons utiliser l’outil hcitool.

$ sudo hcitool lescan

Ce qui devrait nous retourner la liste des périphérique Bluetooth LE (Low Energy) qui se trouvent à proximité :

LE Scan …
90:03:B7:E7:DC:6C (unknown)
90:03:B7:E7:DC:6C Parrot
4E:BD:77:42:D1:B5 (unknown)
4E:BD:77:42:D1:B5 (unknown)
C4:7C:8D:62:83:C9 (unknown)
C4:7C:8D:62:83:C9 Flower care
4E:94:AD:DE:80:33 (unknown)
4E:94:AD:DE:80:33 (unknown)
A4:C1:38:9D:D1:8F (unknown)
A4:C1:38:9D:D1:8F LYWSD03MMC
4B:13:13:68:2D:F7 (unknown)
4B:13:13:68:2D:F7 (unknown)

Le Mijia LYWSD03MMC a donc la MAC Address suivante : A4:C1:38:9D:D1:8F

Importer les données avec gatttool

gatttool en mode interactif

Premiers pas

Pour commencer, nous allons nous connecter en mode interactif ( -I ) avec cette commande :

$ sudo gatttool --device=A4:C1:38:9D:D1:8F -I

Une fois démarré, l’outil est prêt à recevoir des commandes et ceci devrait apparaitre à l’écran :

[A4:C1:38:9D:D1:8F][LE]>

On va se connecter avec cette commande :

connect

L’outil devrait répondre quelque chose comme ceci et l’adresse MAC devrait passer en bleu lorsque la connexion est établie :

[A4:C1:38:9D:D1:8F][LE]> connect
Attempting to connect to A4:C1:38:9D:D1:8F
Connection successful
Notification handle = 0x0036 value: ce 08 2a 0f 0c
Notification handle = 0x0036 value: d0 08 2a 0f 0c
Notification handle = 0x0036 value: d0 08 2a 0f 0c
Notification handle = 0x0036 value: d0 08 2a 0f 0c
[A4:C1:38:9D:D1:8F][LE]>

À intervalles réguliers de quelques secondes, on voit s’ajouter des lignes de « Notification handle« . Ce sont les données de température, d’hygrométrie et de tension de la batterie qui sont envoyées par le petit boîtier.

Mais avant d’analyser ces valeures retournées, nous allons regarder s’il est possible d’obtenir d’autres informations sur le Mijia LYWSD03MMC.

Un petit help va nous retourner toutes les commandes disponibles :

[C4:7C:8D:63:85:B1][LE]> help
help                                          Show this help
exit                                          Exit interactive mode
quit                                          Exit interactive mode
connect [address [address type]]              Connect to a remote device
disconnect                                    Disconnect from a remote device
primary [UUID]                                Primary Service Discovery
included [start hnd [end hnd]]                Find Included Services
characteristics [start hnd [end hnd [UUID]]]  Characteristics Discovery
char-desc [start hnd] [end hnd]               Characteristics Descriptor Discovery
char-read-hnd <handle>                        Characteristics Value/Descriptor Read by handle
char-read-uuid <UUID> [start hnd] [end hnd]   Characteristics Value/Descriptor Read by UUID
char-write-req <handle> <new value>           Characteristic Value Write (Write Request)
char-write-cmd <handle> <new value>           Characteristic Value Write (No response)
sec-level [low | medium | high]               Set security level. Default: low
mtu <value>                                   Exchange MTU for GATT/ATT

La commande primary va explorer les handles des services primaires :

[A4:C1:38:9D:D1:8F][LE]> primary
attr handle: 0x0001, end grp handle: 0x0007 uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle: 0x0008, end grp handle: 0x000b uuid: 00001801-0000-1000-8000-00805f9b34fb
attr handle: 0x000c, end grp handle: 0x0018 uuid: 0000180a-0000-1000-8000-00805f9b34fb
attr handle: 0x0019, end grp handle: 0x001c uuid: 0000180f-0000-1000-8000-00805f9b34fb
attr handle: 0x001d, end grp handle: 0x0020 uuid: 00010203-0405-0607-0809-0a0b0c0d1912
attr handle: 0x0021, end grp handle: 0x004b uuid: ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6
attr handle: 0x004c, end grp handle: 0x005f uuid: 0000fe95-0000-1000-8000-00805f9b34fb
attr handle: 0x0060, end grp handle: 0x0068 uuid: 00000100-0065-6c62-2e74-6f696d2e696d

La commande char-desc va explorer les descripteurs de caractéristiques et nous retourner tous les handle disponibles avec leurs numéros et leurs uuid :

[A4:C1:38:9D:D1:8F][LE]> char-desc
handle: 0x0001, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0002, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb
...
handle: 0x0012, uuid: 00002a26-0000-1000-8000-00805f9b34fb
...
handle: 0x0014, uuid: 00002a27-0000-1000-8000-00805f9b34fb
...
handle: 0x001b, uuid: 00002a19-0000-1000-8000-00805f9b34fb
...
handle: 0x0068, uuid: 00002902-0000-1000-8000-00805f9b34fb

En comparant certains de ces uuid avec la nomenclature standardisée Bluetooth sur ce site https://www.bluetooth.com, nous pouvons en déduire ceci :

https://www.bluetooth.com/

Grâce à ce tableau, nous apprenons que :

  • handle 0x0003 : 2A00 => Device Name
  • handle 0x0012 : 2A26 => Firmware Revision String
  • handle 0x0014 : 2A27 => Hardware Revision String
  • handle 0x001b : 2A19 => Battery Level

Lire un handle

Pour lire le contenu d’un handle, on utilise la commande char-read-hnd suivie du n° du handle qui nous intéresse :

[A4:C1:38:9D:D1:8F][LE]> char-read-hnd 0x0003
Characteristic value/descriptor: 4c 59 57 53 44 30 33 4d 4d 43 00
[A4:C1:38:9D:D1:8F][LE]> char-read-hnd 0x0012
Characteristic value/descriptor: 31 2e 30 2e 30 5f 30 31 30 36 00
[A4:C1:38:9D:D1:8F][LE]> char-read-hnd 0x0014
Characteristic value/descriptor: 42 31 2e 34
[A4:C1:38:9D:D1:8F][LE]> char-read-hnd 0x001b
Characteristic value/descriptor: 63

gatttool en ligne de commande

Lire un handle

Pour lire un handle en ligne de commande, nous utiliserons :

$ sudo gatttool --device=A4:C1:38:9D:D1:8F --char-read -a 0x03

Et ainsi de suite pour tous les handles à lire, en veillant à utiliser le numéro correspondant à la fin ( 0x03 ).

Écouter les Notification handle

Dans le cas qui nous occupe, pour lire la température et l’hygrométrie, il n’est pas possible de lire directement le handle 36.

Voici les valeurs qui seraient retournées :

$ sudo gatttool --device=A4:C1:38:9D:D1:8F --char-read -a 0x36
Characteristic value/descriptor: 00 00 00

Pour obtenir les données, nous allons inscrire une valeur arbitraire dans le handle 38 qui permet l’écriture et écouter tout ce qui se passe ensuite ( --listen ):

$ sudo gatttool -b A4:C1:38:9D:D1:8F --char-write-req --handle=0x0038 --value=0100 --listen
Characteristic value was written successfully
Notification handle = 0x0036 value: f7 08 2c 05 0c
Notification handle = 0x0036 value: fa 08 2c 05 0c
Notification handle = 0x0036 value: f8 08 2c 05 0c
Notification handle = 0x0036 value: f8 08 2c 05 0c
Notification handle = 0x0036 value: fa 08 2c 05 0c
^C

Une fois la valeur inscrite avec succès, la commande va continuer à recevoir les notifications du boîtier jusqu’à interruption avec [ctrl] C.

Pour éviter ce blocage, on va restreindre le temps d’exécution à 15 secondes ( timeout 15 ) et ne récupérer qu’une seule ligne des notifications ( grep ) :

$ sudo timeout 15 gatttool -b A4:C1:38:9D:D1:8F --char-write-req --handle=0x0038 --value=0100 --listen | grep --max-count=1 "Notification handle"

Et voici la réponse retournée après 15 secondes :

Notification handle = 0x0036 value: fa 08 2c 05 0c

Structure des données

Table ASCII

Pour les handle 0x0003, 0x0012, 0x0014, 0x001b, il suffit d’utiliser une table ASCII pour convertir les Hex en Char

Wikimedia Foundation

0x0003Device Name : 4c 59 57 53 44 30 33 4d 4d 43

4c5957534430334d4d43
LYWSD03MMC

Il s’agit du nom qui apparaît lorsqu’on liste les périphériques BT avec la commande hcitool lescan vue au début.


0x0012Firmware Revision String : 31 2e 30 2e 30 5f 30 31 30 36

312e302e305f30313036
1.0.0_0106

0x0014Hardware Revision String : 42 31 2e 34

42312e34
B1.4

On peut le vérifier dans l’App Xiaomi Home :


0x001bBattery Level : 63

63
99

Ici, on va prendre la valeur décimale de celle en hexadécimale : 63. C’est un pourcentage.


Little endian

Dans le handle de notification 0x0036, lorsque les nombres entiers sont codés sur plusieurs octets, il sont présentés en Little endian. C.-à-d. avec l’octet de poids le plus faible en premier.

Pour comprendre la représentation des nombres entiers sur plusieurs octets, vous pouvez consulter cette page Wikipedia : https://fr.wikipedia.org/wiki/Endianness

Notification handle = 0x0036 value: fa 08 2c 05 0c
fa082c050c
2298443077
Température * 100 (°C)Hygrométrie (%)Tension de batterie * 1000 (Volts)
  • Bytes 1 & 2 : Température : Hex 08 fa : 2298 = 22,98 °C

Attention !
Lorsque la température est négative, les 2 premiers bytes affichent :
FF FF pour -0.1 °C / F6 FF pour -1.0 °C / 9C FF pour -10.0 °C
Soit la formule : Température = -65536 + Température

  • Byte 3 : Hygrométrie : Hex 2c : 44 = 44 %
  • Bytes 4 et 5 : Tension de la batterie en Volts : Hex 0c 05 : 3077 = 3,077 V

Concernant le niveau de la batterie, voici ce qu’indique jaggil sur le forum GitHub : https://github.com/JsBergbau/MiTemperature2/issues/1

Dans mes tests de batterie, j’ai utilisé une alimentation électrique réglable, et le résumé est le suivant :

1. La plage de fonctionnement est comprise entre 2,1v et 3v.

2. Lorsque 2,1 v est atteint, l’icône de la batterie vide est activée sur l’écran LCD.

3. Lorsqu’il atteint 2,09v, le capteur s’éteint.

Ma conclusion est que la plage de 0 à 100% de la batterie correspond à 2,1v à 3v

https://github.com/JsBergbau/MiTemperature2/issues/1

Script

En ligne de commande

Update 24/10/2020 :
Mise à jour du script suite au commentaire de David Auvré afin d’éviter l’erreur : « linux avertissement : substitution de commande: octet nul ignoré en entrée ».
Lignes 52, 60 et 68.

#!/bin/bash

# Vérifie que l'on est en Root
if [[ $EUID -ne 0 ]];
then
	echo "Ce script doit être exécuté avec les privilèges administrateur"
   	exit 1
fi

MACadd="A4:C1:38:9D:D1:8F"


hciconfig hci0 down
hciconfig hci0 up

hnd38=$(timeout 15 gatttool -b $MACadd --char-write-req --handle='0x0038' --value="0100" --listen | grep --max-count=1 "Notification handle")
# Notification handle = 0x0036 value: 7c 08 2a 97 0c


if !([ -z "$hnd38" ])
then

	temperature=${hnd38:39:2}${hnd38:36:2}
	temperature=$((16#$temperature))
	if [ "$temperature" -gt "10000" ];
	then
		temperature=$((-65536 + $temperature))
	fi	
	temperature=$(echo "scale=2;$temperature/100" | bc)

	humidity=${hnd38:42:2}
	humidity=$((16#$humidity))

	voltage=${hnd38:48:2}${hnd38:45:2}
	voltage=$((16#$voltage))
	voltage=$(echo "scale=3;$voltage/1000" | bc)


	# Battery Level : 0x2A19
	# handle = 0x001b, uuid = 00002a19-0000-1000-8000-00805f9b34fb

		hnd1b=$(gatttool --device=$MACadd --char-read -a 0x1b)
		# Characteristic value/descriptor: 63
		battery=${hnd1b:33:2}
		battery=$((16#$battery))

	# Firmware Revision String : 0x2A26
	# handle = 0x0012, uuid = 00002a26-0000-1000-8000-00805f9b34fb

		hnd12=$(gatttool --device=$MACadd --char-read -a 0x12)
		# Characteristic value/descriptor: 31 2e 30 2e 30 5f 30 31 30 36 00
		firmware=$(echo "'$hnd12'" | cut -c34-65 | xxd -r -p)


	# Device Name : 0x2A00
	# handle = 0x0003, uuid = 00002a00-0000-1000-8000-00805f9b34fb

		hnd03=$(gatttool --device=$MACadd --char-read -a 0x03)
		# Characteristic value/descriptor: 4c 59 57 53 44 30 33 4d 4d 43 00
		name=$(echo "'$hnd03'" | cut -c34-65 | xxd -r -p)


	# Hardware Revision String : 0x2A27
	# handle = 0x0014, uuid = 00002a27-0000-1000-8000-00805f9b34fb

		hnd14=$(gatttool --device=$MACadd --char-read -a 0x14)
		# Characteristic value/descriptor: 42 31 2e 34
		revision=$(echo "'$hnd14'" | cut -c34-45 | xxd -r -p)

	# Affichage des données

		echo "Reading Mijia..."
		echo "Hardware: {Firmware Version:$firmware / Hardware Revision:$revision / BT Name:$name / Battery Level:$battery}"
		echo "Sensors: {Temperature:$temperature / Humidity:$humidity / Voltage:$voltage}"

else

	echo "Mijia error"

fi

Voici ce que ce script devrait retourner :

Reading Mijia…
Hardware: {Firmware Version:1.0.0_0106 / Hardware Revision:B1.4 / BT Name:LYWSD03MMC / Battery Level:99}
Sensors: {Temperature:22.00 / Humidity:47 / Voltage:3.060}

Domoticz

Édité le 07 juillet 2020 :

À la demande d’un lecteur de ce blog, j’ai demandé à Pierre, qui a indiqué dans les commentaires avoir adapté ce script à Domoticz, de me l’envoyer pour le publier ci-dessous.

Le voici tel qu’il me l’a transmis :

#!/bin/bash
#chcp 65001 > nul
# récupération de la date et l'heure du jour ; on obtient ici une valeur telle que "mercredi 31 décembre 2014, 00:15:01"
DATE=`date +"%A %d %B %Y, %H:%M:%S"`
 
# récupération de la date et l'heure du jour sous un autre format ; on obtient ici un résultat sous la forme suivante : XX-YY-ZZZZ (ex: 31-12-2014)
DATE2=`date +"%d-%m-%Y"`
 
# définition du chemin du répertoire à créer ; ce chemin sera /home/pi/Script/Capteur_Salon/
REP=/home/pi/Script/Capteur_Salon/
 
# définition du chemin du répertoire à créer ; ce chemin sera /media/Capteur_Salon/XX-YY-ZZ
REP1=$REP/$DATE2
 
# le fichier à créer dans ce répertoire est "Capteur_Salon_??_??_????"
FICHIER=$REP1/Capteur_Salon_$DATE2.xlsx
 
# Si le REP n'existe pas on le crée
if [ ! -d $REP ];then
mkdir $REP
fi
 
# Si le REP1 n'existe pas on le crée
if [ ! -d $REP1 ];then
mkdir $REP1
fi
 
# Si le fichier n'existe pas on le crée et on y injecte le l'entête
if [ ! -f $FICHIER ];then
touch $FICHIER
# echo "Mode Date Heure temperature temperature_haute" > $FICHIER
echo "Date Heure temperature Date Heure Humidity Date Heure voltage" > $FICHIER
fi

date="$(date "+%d-%m-%Y")"
heure="$(date "+%H:%M:%S")"
# Vérifie que l'on est en Root
if [[ $EUID -ne 0 ]];
then
    echo "Ce script doit être exécuté avec les privilèges administrateur"
    exit 1
fi
MACadd="A4:C1:38:61:9B:41"
 
hciconfig hci0 down
hciconfig hci0 up
hnd38=$(timeout 15 gatttool -b $MACadd --char-write-req --handle='0x0038' --value="0100" --listen | grep --max-count=1 "Notification handle")
# Notification handle = 0x0036 value: 7c 08 2a 97 0c
 
if !([ -z "$hnd38" ])
then
    temperature=${hnd38:39:2}${hnd38:36:2}
    temperature=$((16#$temperature))
    if [ "$temperature" -gt "10000" ];
    then
        temperature=$((-65536 + $temperature))
    fi
    temperature=$(echo "scale=2;$temperature/100" | bc)
   
    humidity=${hnd38:42:2}
    humidity=$((16#$humidity))
    voltage=${hnd38:48:2}${hnd38:45:2}
    voltage=$((16#$voltage))
    voltage=$(echo "scale=3;$voltage/1000" | bc)
   
    # Battery Level : 0x2A19
    # handle = 0x001b, uuid = 00002a19-0000-1000-8000-00805f9b34fb
        hnd1b=$(gatttool --device=$MACadd --char-read -a 0x1b)
        # Characteristic value/descriptor: 63
        battery=${hnd1b:33:2}
        battery=$((16#$battery))
    # Firmware Revision String : 0x2A26
    # handle = 0x0012, uuid = 00002a26-0000-1000-8000-00805f9b34fb
        hnd12=$(gatttool --device=$MACadd --char-read -a 0x12)
        # Characteristic value/descriptor: 31 2e 30 2e 30 5f 30 31 30 36 00
        firmware=$(echo "$hnd12" | cut -c34-65 | xxd -r -p)
 
    # Device Name : 0x2A00
    # handle = 0x0003, uuid = 00002a00-0000-1000-8000-00805f9b34fb
        hnd03=$(gatttool --device=$MACadd --char-read -a 0x03)
        # Characteristic value/descriptor: 4c 59 57 53 44 30 33 4d 4d 43 00
        name=$(echo "$hnd03" | cut -c34-65 | xxd -r -p)
 
    # Hardware Revision String : 0x2A27
    # handle = 0x0014, uuid = 00002a27-0000-1000-8000-00805f9b34fb
        hnd14=$(gatttool --device=$MACadd --char-read -a 0x14)
        # Characteristic value/descriptor: 42 31 2e 34
        revision=$(echo "$hnd14" | cut -c34-45 | xxd -r -p)
    # Affichage des données
        echo "Reading Mijia..."
        echo "Hardware: {Firmware Version:$firmware / Hardware Revision:$revision / BT Name:$name / Battery Level:$battery}"
        echo "Sensors: {Temperature:$temperature / Humidity:$humidity / Voltage:$voltage}"
        echo "$date $heure $temperature $date $heure $humidity $date $heure $voltage" >> /home/pi/Script/Capteur_Salon/$DATE2/Capteur_Salon_$DATE2.xlsx
 
#humidity=80
 
if [ $humidity -ge 0 ]&&[ $humidity -le 39 ]
then
         HUM=2
elif [ $humidity -ge 60 ]&&[ $humidity -le 79 ]
then
         HUM=1
elif [ $humidity -ge 40 ]&&[ $humidity -le 59 ]
then
         HUM=0
elif [ $humidity -ge 80 ]&&[ $humidity -le 100 ]
then
         HUM=3
fi  
 
echo $HUM 
 
#Création d'une variable contenant url en y incluant la valeur de la température
url1="http://192.168.1.69:8087/json.htm?type=command&param=udevice&idx=11&nvalue=0&svalue=$temperature"
url2="http://192.168.1.69:8087/json.htm?type=command&param=udevice&idx=11&nvalue=$humidity"
url3="http://192.168.1.69:8087/json.htm?type=command&param=udevice&idx=9&svalue=$temperature;$humidity;$HUM"
 
 
#Requête vers domoticz pour mise à jour  de la température en mode silencieux
curl -s  $url1 > /dev/null
curl -s  $url2 > /dev/null
curl -s  $url3 > /dev/null
 
else
    echo "Mijia error"
fi

Grand merci à Pierre pour ce partage.

Edit : 01 octobre 2020 :

Suite au commentaire de fp, la déclaration de l’interpréteur a été corrigée (première ligne du script de Pierre) pour résoudre le problème de « Bad substitution ». La ligne 35 a été supprimée car redondante.

Edit : 24 janvier 2021 :

Un lecteur, David Smhosy, a adapté ce script pour remplir une base de données SQLITE3 : https://smhosy.blogspot.com/

(56) comments

Pierre PERNO
4 ans ago · Répondre

Bonjour, merci beaucoup pour votre script, mais j’ai un souci:

capteur.sh: ligne 29: bc : commande introuvable
capteur.sh: ligne 36: bc : commande introuvable
capteur.sh: ligne 51: avertissement :substitution de commande: octet nul ignoré en entrée
capteur.sh: ligne 59: avertissement :substitution de commande: octet nul ignoré en entrée
Reading Mijia…
Hardware: {Firmware Version:1.0.0_0106 / Hardware Revision:B1.4 / BT Name:LYWSD03MMC / Battery Level:99}
Sensors: {Temperature: / Humidity:62 / Voltage:}

voilà le retour qu’il me fait, je n’arrive pas à trouver le souci!

Pourriez-vous m’aider?

    fanjoe
    4 ans ago · Répondre

    Bonjour,

    BC est une calculatrice en ligne de commande.
    https://fr.wikipedia.org/wiki/Bc_(Unix)

    Il suffit de l’installer :
    $ sudo apt-get update
    $ sudo apt-get install bc

    Sans la calculatrice, les valeurs ne peuvent pas être calculées et sont absentes à la fin.

    Didier.

Pierre
4 ans ago · Répondre

Bonjour, merci beaucoup ça fonctionne niquel, avec un petit plus, affichage dans Domoticz…

Pierre

Julien
4 ans ago · Répondre

Bonjour,

Merci pour le script, j’ai adapté ton bout de code afin d’alimenter influxDB.

En outre il est possible de bypasser la limitation du timeout en passant par un fichier intermédiaire.

Une chose aussi importante est de bien mettre à jour le raspberry, aussi bien le firmware que la distribution, chez moi, c’est du raspbian.

Mes sources : https://github.com/jbsky/MijiaV2

Julien

    fanjoe
    4 ans ago · Répondre

    Merci pour ton commentaire.

    Didier.

Rio
4 ans ago · Répondre

Merci pour ce travail, Fanjoe ! Est-ce que c’est possible de publier le code pour envoyer les résultats à Domoticz ?

    fanjoe
    4 ans ago · Répondre

    Bonjour,

    Je n’utilise pas Domoticz, mais Pierre (ci-dessus) a sans doute adapté le script à cet usage.
    Comme il a laissé son mail, je vais le contacter et voir s’il m’autorise à publier son code.

    Didier.

      Rio
      4 ans ago ·

      Merci beaucoup, Fanjoe !

Pierre
4 ans ago · Répondre

Bonjour, j’ai envoyé le code par mail à Fanjoe!!

Cordialement

    Rio
    4 ans ago · Répondre

    Merci, Pierre ! Je l’attends alors.

      fanjoe
      4 ans ago ·

      Il est déjà en ligne en bas de l’article… 😉

Nicobsa
4 ans ago · Répondre

Merci pour ce super driver !!! (je vais donc acheter pleins d’autres petites sondes comme celles-ci !!)

freeman37
4 ans ago · Répondre

Merci beaucoup pour cette page, tout est super là dedans !
Je ne sais pas bien comment fonctionnent ces capteurs mais j’ai remarqué qu’avec xiaomi home ont est capable d’avoir des données sur toute a journée, un peu comme ci le capteur stockait un jeu de données par heure. C’est possible de récupérer tout ça afin de réduire la fréquence d’accès au capteur (et économiser un peu les piles !) ?

    fanjoe
    4 ans ago · Répondre

    Bonjour,

    Oui, ça semble possible, mais il faut pouvoir interpréter le volume des données récupérées.
    C’est sans doute un poil plus complexe à gérer.

    Didier.

fredclo
4 ans ago · Répondre

Bonjour et merci pour ce travail et partage.
Je suis sous domoticz et ce script m’intéresse beaucoup.
Mais j’ai 2 erreurs :
– 39: ….sh: [[: not found
Et en mettant tout en commentaire j’arrive sur l’erreur suivante
– 53:….sh: Bad substitution

Si vous aviez des idées ca serait cool. Merci
fred

    fanjoe
    4 ans ago · Répondre

    Bonjour,

    La vérification Root en ligne 39 peut être commentée pour l’instant.
    La MacAddress en ligne 44 est-elle bien celle de votre capteur ?
    Quelle est la valeur de $hnd38 après lecture en ligne 48 ?
    Si la lecture s’est mal passée, la conversion des données va buguer.

    Didier.

fredclo
4 ans ago · Répondre

merci.
Oui en ligne 44 j’ai mis la bonne mac (et j’ai aussi mis les N° de device à la fin pour domoticz).
En ligne de command voilà ce que j’ai :
timeout 15 gatttool -b A4:C1:38:48:D0:9C –char-write-req –handle=’0x0038′ –value= »0100″ –listen | grep –max-count=1 « Notification handle »

me répond : Notification handle = 0x0036 value: c3 09 3c 78 0c

fredclo
4 ans ago · Répondre

Je ne suis pas informaticien, et c trop compliqué pour moi. Le listing est identique, et je ne comprends pas non plus. Je suis sous RPI3B et buster avec un upgrade de ce matin.
Dommage ca avait l’air bien. Bizarre que je soit le seul à avoir ce problème.

Sinon, à moins que je ne fasse erreur, il faut corriger le listing d’un malheureux copier/coller :
tous les amp;amp; sont des « double et » des lignes 98 à 107 (le signe ne passe pas dans le message – problème de token)
Est-ce le cas dans les url de la fin entre  » : j’en suis moins sûr

    fanjoe
    4 ans ago · Répondre

    Merci pour les remarques concernant les &.
    C’est un bug dans SyntaxHighlighter de l’interface Gutenberg de WordPress.
    C’est corrigé.
    Le détail est ici : https://github.com/Automattic/syntaxhighlighter/issues/98

    Pour ton problème de substitution, je te dirais de continuer de chercher.
    Le résultat en vaut la chandelle.

    Didier.

Micka1er
4 ans ago · Répondre

Bonjour,

Ce travail a l’air formidable !!
Seulement, je ne comprend pas comment faire le lien entre le script et Domoticz.

D’autre part quand j’exécute le script, j’ai simplement l’erreur « Mijia error »

J’utilise raspbian10 sur raspberry 4b.

J’ai l’impression d’être au bout mais un « truc » coince. Si vous savez quoi m’ndiquer merci d’avance.

Je ne suis pas un fou du dev loin de la mais je peux comprendre ce qu’on me dit.

Meric

    fanjoe
    4 ans ago · Répondre

    Bonjour,

    « Mijia error » est la réponse si la valeur de $hnd38 est vide à la ligne 20 du premier script ou 51 du deuxième.
    Je vous conseille d’utiliser le premier script pour comprendre ce qui cloche.
    Si $hnd 38 est vide, c’est que la ligne 16 n’a pas rapporté la réponse escomptée.
    Essayez ceci en ligne de commande en remplaçant la MACaddress par la vôtre :

    gatttool -b A4:C1:38:9D:D1:8F --char-write-req --handle='0x0038' --value="0100" --listen

    Qu’obtenez-vous ?

    Didier.

      Micka1er
      4 ans ago ·

      Bonjour,

      Merci de cette réponse extrêmement rapide !!

      Voici le résultat de la commande :

      pi@domoticz:~ $ gatttool -b A4:C1:38:2C:4C:34 –char-write-req –handle=’0x0038′ –value= »0100″ –listen
      Characteristic value was written successfully
      Notification handle = 0x0036 value: 39 0a 42 f2 0a
      Notification handle = 0x0036 value: 3b 0a 42 f2 0a
      Notification handle = 0x0036 value: 3c 0a 42 f2 0a
      Notification handle = 0x0036 value: 3f 0a 42 f2 0a
      ^C
      pi@domoticz:~ $

      Cdt
      Mickael

      fanjoe
      4 ans ago ·

      Et que se passe-t-il si vous exécutez le premier script en utilisant la bonne MACaddress à la ligne 10 ?
      Vous pouvez aussi ajouter echo $hnd38 en ligne 18 pour voir si la valeur est correctement extraite en ligne 16.

      Didier.

      Micka1er
      4 ans ago ·

      Je continuerai mes tests dimanche ou lundi. Merci pour ce suivi impeccable ! À très très vite pour la suite !

      Micka1er
      4 ans ago ·

      Bonjour,

      Me voici de retour, voici ce que j’ai avec le echo en plus :

      Notification handle = 0x0036 value: 2b 0a 3b 41 0b
      TestFanJeowithoutdomoticz: ligne 52: avertissement :substitution de commande: octet nul ignoré en entrée
      TestFanJeowithoutdomoticz: ligne 60: avertissement :substitution de commande: octet nul ignoré en entrée
      Reading Mijia…
      Hardware: {Firmware Version:1.0.0_0106 / Hardware Revision:B1.4 / BT Name:LYWSD03MMC / Battery Level:99}
      Sensors: {Temperature:26.03 / Humidity:59 / Voltage:2.881}

      fanjoe
      4 ans ago ·

      Tout semble correctement fonctionner.
      Vous avez juste un avertissement indiquant que $hnd 12 et $hnd03 ont des octets null (00 dans la chaîne) qui ne peuvent pas être convertis en ASCII. Sans doute le dernier octet.
      Pour résoudre ce problème, on pourrait tronquer la chaîne de 3 caractères avec cut c34-62.

      Didier.

      Micka1er
      4 ans ago ·

      Mille merci, j’arrive maintenant bien a tout afficher !!
      …et sans erreur et ça c’est quand même bien !

      Il me reste encore un truc que je ne sais pas, mais la question irai plutôt à Pierre je pense.

      Ca concerne la création des URL et l’envoi vers Domoticz, je ne comprend pas bien comment ça marche.

      – Est-ce qu’on peut remplacer l’@IP par un élément du type « localhost »
      – Je ne vois pas bien comment faire remonter les informations dans Domoticz, en fait je comprends pas :

      curl -s $url1 > /dev/null
      curl -s $url2 > /dev/null
      curl -s $url3 > /dev/null

      Encore merci pour ta disponibilité, tu as du aider pas mal de monde avec ce petit script qui fait plaisir !

      Mickaël

fredclo
4 ans ago · Répondre

comme je n’ai pas trouvé d’issue à mon problème, j’utilise https://github.com/JsBergbau/MiTemperature2 qui a fonctionné du 1er coup.
J’aurai préféré le prog présenté ici qui est tout en 1, mais cette erreur de bad substitution, je ne comprends pas.

    fanjoe
    4 ans ago · Répondre

    Bonjour,

    Merci pour le lien vers le projet GitHub.

    Didier.

Pierre
4 ans ago · Répondre

Bonjour à tous, Micka1er, je ne sais pas si on peut remplacer l’IP par le localhost. A voir si cela fonctionne!
Ensuite pour ton souci d’incompréhension, voici un site qui explique comment fonctionne l’envoi de données dans Domoticz!

https://projetsdiy.fr/esp8266-client-web-envoyer-donnees-domoticz-tcpip-api-json/

Bien Cordialement

    Micka1er
    4 ans ago · Répondre

    Bonjour,

    Merci beaucoup !

    J’arrive maintenant à faire remonter les données dans domoticz, je suis super content et vous remercie tous de votre aide.

    Pour info il est tout a fait possible de mettre 127.0.0.1 dans l’url, ça fonctionne (pratique quand on fait la config pas toujours au même endroit)

    J’ai aussi remplacé les 3 URL par la suivante, ce qui me permets d’avoir tout dans le même capteur virtuel dans domoticz :

    url1= »http://127.0.0.1:8080/json.htm?type=command&param=udevice&idx=1&nvalue=0&svalue=$temperature;$humidity;$HUM »

    Voilà.

    Il me reste à comprendre comment faire pour exécuter le script en boucle pour récupérer les info régulièrement (et oui je n’ai quasiment aucune base en linux mais ça va venir), mais je vais trouver, notre Google national va m’aider !

    Je vais me permettre de partager cette page qui est forte utile, sauf avis contraire de votre part.

    Merci encore Pierre et Didier !

Pierre
4 ans ago · Répondre

De rien!

Pour le faire tourner en boucle ou du moins automatiquement. J’utilise Crontab…

Cordialement

fp
3 ans ago · Répondre

Salut,

Merci pour ce tutoriel.

J’ai aussi rencontré le problème de « Bad substitution » en lançant le script pour domoticz en tâche cron, et j’ai réussi à le contourner en corrigeant la première ligne du script fourni, il faut déclarer l’interpréteur avec un  » #!/bin/bash  » et non un  » #/bin/bash  » … si ça peut servir à quelqu’un 😉

Cordialement,

    fanjoe
    3 ans ago · Répondre

    Bonjour,

    C’est corrigé dans le script.

    Merci pour cette remontée constructive,
    Didier.

david auvré
3 ans ago · Répondre

Bonjour,

super tout bien détailler ça fonctionne parfaitement

j’ai juste une petite modification ligne 52 « $hnd12 » remplacé par « ‘$hnd12′ »
firmware=$(echo « ‘$hnd12′ » | cut -c34-65 | xxd -r -p)

et ligne 60 « $hnd03 » remplacé par ‘ »$hnd12″‘
name=$(echo « ‘$hnd03′ » | cut -c34-65 | xxd -r -p)

afin d’évité les erreur > linux avertissement : substitution de commande: octet nul ignoré en entrée

    fanjoe
    3 ans ago · Répondre

    Bonjour,

    C’est modifié dans le script.

    Merci pour cette correction,
    Didier.

      david auvré
      3 ans ago ·

      quelle réactivité
      concernant la consommation de la pile qu’elle fréquence d’interrogation est le meilleur compromis celons vous
      avez vous du recul sur la consommation

      fanjoe
      3 ans ago ·

      Bonjour,

      La pile a tenu 5 mois avec une interrogation toutes les minutes.

      Le graph du pourcentage de batterie se maintient à 99% puis s’effondre rapidement les quelques derniers jours.

      Didier.

david auvré
3 ans ago · Répondre

Merci pour la réponse
Je pensais faire une interrogation tpute les 15 minutes j’ai peut être vu large 5 minutes serais pas mal je pense pour les piles
5 mois c’est deja pas mal pour une interrogation presque permanente

Armand
3 ans ago · Répondre

Bonsoir à tous. Merci beaucoup pour ce script. J’utilise la version de Pierre pour faire le lien avec Domoticz, dupliqué et adapté trois fois pour gérer trois capteurs, avec trois cron jobs pour mettre à jour. J’ai choisi un intervalle de 5 minutes, à voir si cela suffit mais ça me paraît bien.
Ça fonctionne parfaitement, une fois toutes les modifications en commentaires prises en compte.
Merci à tous pour le boulot réalisé.
Armand

Pierre
3 ans ago · Répondre

Bonjour,
J’ai essayé de suivre la procédure pour le modèle inférieur (LYWSD02MMC) et je n’arrive pas au même résultat.
Tout d’abord, certains UUID ne sont pas formatés de la même manière. Par exemple :
> char-desc
handle: 0x0036, uuid: 2b43ccc4-2506-415c-a16c-e4cc5f52ef78
Comment savoir à quoi correspond cet UUID ?

Ensuite, beaucoup d’UUID contiennent « 0x2803 » qui, d’après les specs Bluetooth, signifie « Characteristic » ; c’est un peu vague, non ? Comment savoir à quoi correspondent les données associées ?

Dans votre tuto, vous dîtes : « Dans le cas qui nous occupe, pour lire la température et l’hygrométrie, il n’est pas possible de lire directement le handle 36. » Comment avez-vous su qu’il fallait utiliser ce handle ?

En ce qui me concerne, quand j’essaie de le lire, je n’obtiens pas la valeur « 00 00 00 » mais un message d’erreur :
> char-read-hnd 36
Error: Characteristic value/descriptor read failed: Attribute can’t be read
Comment rendre accessible en lecture ce handle ?

Ensuite, vous dîtes : « Pour obtenir les données, nous allons inscrire une valeur arbitraire dans le handle 38 qui permet l’écriture ». D’où viennent ces informations ? Pourquoi le handle 38 et pourquoi la valeur « 0100 » ? En ce qui me concerne, je ne peux pas écrire sur ce handle :
> char-write-req 38 0100
Error: Characteristic Write Request failed: Attribute can’t be written

Merci pour votre retour.

    fanjoe
    3 ans ago · Répondre

    Bonjour,

    Votre modèle est totalement différent de celui présenté sur cette page, même si les numéros sont proches.

    Pour retrouver les handles utiles, listez-les tous avec la commande char-desc. Comparez ensuite les uuid un à un avec la nomenclature standardisée du Bluetooth. Vous trouverez probablement le niveau de batterie, la version du firmware, le nom du device, … À chaque uuid correspondra un handle spécifique à votre appareil qu’il faudra lire ensuite.

    Il est probable que les données principales ne soient pas stockées de manière standardisée. Il faudra alors effectuer des recherches sur internet et explorer le code d’applications tierces (GitHub, …) adaptées à votre modèle.

    Une fois le handle identifié, vous devrez analyser les données (comme expliqué en fin d’article) pour en comprendre la structure et le découpage.

    Un exemple de recherche sur un Flower Power : https://www.fanjoe.be/?p=3520

    Didier.

Lecocqe
3 ans ago · Répondre

Bonjour, comment utilisez ceci dans Home Assistant ?

Philippe
3 ans ago · Répondre

Bonjour,
merci à tous pour votre super travail, j’ai réussi à afficher mon thermomètre dans domoticz sans trop de soucis 🙂
J’aimerais en plus de tout ça, afficher le niveau de la batterie de l’appareil dans la page des dispositifs ou dans la page des capteurs (si possible) malheureusement je ne trouve pas le format pour l’insérer de l’URL json.htm du script de Pierre.

Avez-vous réussi à faire ceci ?
Merci d’avance.
Bonne journée.
Philippe

david auvré
3 ans ago · Répondre

bonjour,
je n’ai pas domoticz mais dans la doc il y a

—————————————————————————————————————————
Paramètres additionnels (signal level & battery level)
Il y deux paramètres supplémentaires pour toutes les commandes ci dessus pour préciser la qualité de réception (radio) et le niveau de batterie.

Par défaut le niveau de signal est à 12 et le niveau de la batterie est à 255 (pas de batterie) sinon le niveau est entre 0 et 100.

Il faut ajouter ces lignes tout au bout de la chaine

exemple: &rssi=10&battery=89

—————————————————————————————————————————

voici le lien
https://easydomoticz.com/traduction-francais-de-lapi-json-domoticz/#addpar

je pense que en faisant dans le script de pierre modifier
String url = « /json.htm?type=command&param=udevice&idx=12&nvalue=0&svalue= »;
url += String(t); url += « ; »;
url += String(h); url += « ; »;
url += String(hum_stat); url += « ; »;
url += String(pa);url += « ; »;
url += String(bar_for);
url += « &battery= » + String(val_bat)

à tester

david auvré
3 ans ago · Répondre

Bonjour,

j’ai repris votre script afin dans faire une fonction permettant de lire une base de donnée SQLite3 contenant une table avec la liste des module et une autre pour enregistrer les valeur

plus de détail disponible ici : https://smhosy.blogspot.com/2021/01/quelle-temperature-et-hydrometrie-dans.html

un grand merci pour les détail de cette article qui mon permis d’arriver a réaliser ce script lié a ma domotique

    fanjoe
    3 ans ago · Répondre

    Bonjour,

    Le lien vers votre blog a été ajouté en note de fin d’article.
    Merci pour vos retours. 🙂

    Didier.

Sean
3 ans ago · Répondre

Bonjour, Je suis en train d’essayer d’intégrer une sonde de température bluetooth sur Domiticz en suivant votre post. mon problème étant que je n’utilise pas la même sonde que la votre et que lorsque je me connecte dessus, je n’ai aucun retour.

58:2D:34:11:CE:7D Qingping Temp & RH Lite

pi@Rpi-Domoticz:~ $ sudo gatttool –device=58:2D:34:11:CE:7D -I
[58:2D:34:11:CE:7D][LE]> connect
Attempting to connect to 58:2D:34:11:CE:7D
Connection successful
[58:2D:34:11:CE:7D][LE]>

Après cela, rien ne se passe. auriez-vous une idée de pourquoi je n’ai aucun retour.

En vous remerciant par avance.

    fanjoe
    3 ans ago · Répondre

    Bonjour,

    C’est assez normal que le script s’arrête après la connexion.
    Chaque fabricant va décider de comment et où stocker les données dans la mémoire du capteur.

    Il faut faire quelques recherches sur internet pour trouver dans quel handle se trouvent les données et sous quelle forme elles sont inscrites.

    Didier.

david auvré
3 ans ago · Répondre

bonjour,

merci fanjoe

après plusieurs année de bidouille je me lance dans le partage

david

david auvré
3 ans ago · Répondre

Bonjour sean

une piste ici http://www.d0wn.com/qingping-cleargrass-cgdk2-factory-reset/
apparemment les data son cryptée

SEAN
3 ans ago · Répondre

Bonjour,

Merci à vous pour votre réactivité.

J’ai suivi cette piste et j’ai réussi à capter la clé de 32 caractères. Mais je ne sais pas où la rentrer lorsque je suis dans putty

Ce que j’ai oublié de préciser, c’est que j’arrive à ire les handles sans PB et que je peux également écrire sur le Handles 0x0038 (par exemple) lorsque je suis connecté sur ma sonde

Je vais encore chercher sur internet voir quel Handles peux contenir les informations dont j’ai besoin.

Merci à tous

Sean

Christobald
2 ans ago · Répondre

Merci Bien !

Grâce à vous, un rPi 4 alimente ma box eedomus toutes les 10mn. J’ai quelques échecs mais c’est pas grave (c’est similaire avec l’appli IPhone)

J’ai utilisé CronTab pour lancer un petit shell qui lui même exécute 6 fois un dérivé de vos exemples de shell pour mes 6 capteurs (j’ai 7 arguments à mon bash !)

Ça fonctionne plutôt bien depuis hier, en firmware standard 1.0.0.109 et 1.0.0.130 (avec une préférence pour le vieux).

Adecy
2 ans ago · Répondre

Merci Fanjoe,

J’ai créé une petite application basé sur Zephyr RTOS pour une board nrf52840dk afin de collecter les mesures de mes devices Xiaomi et les transmettre à un second microcontrôleur IoT. Ton guide ma grandement aidé pour réaliser les measures, donc merci !

Repo: https://github.com/lucasdietrich/zephyr-nrf52840-ble-dev/tree/ble_xiaomi_mijia_collector

Répondre à Micka1erAnnuler la réponse.

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.