Govee H5074, H5075, H5100, H5101, H5104, H5105, H5174, H5177 et H5179 Enregistreur de température et d'humidité Bluetooth à faible consommation d'énergie, et thermomètres à viande intelligents Govee H5181, H5182 et H5183
Chacun de ces appareils coûte actuellement moins de 15 $ sur Amazon et utilise BLE pour la communication, il n'est donc pas nécessaire de créer un compte fabricant pour suivre les données.
GoveeBTTempLogger a été initialement construit à l'aide de Microsoft Visual Studio 2017, ciblant le processeur ARM fonctionnant sous Linux. J'utilise un Raspberry Pi 4 comme hôte Linux. J'ai vérifié que le même code fonctionne sur un Raspbery Pi ZeroW, un Raspberry Pi Zero2W, un Raspberry Pi 3b et un Raspberry Pi 5.
GoveeBTTempLogger crée un fichier journal, si spécifié par l'option -l ou --log, pour chacun des appareils à partir desquels il reçoit des données diffusées en utilisant un simple format séparé par des tabulations compatible avec le chargement dans Microsoft Excel. Chaque ligne du fichier journal contient la date (enregistrée en UTC), la température, l'humidité relative et le pourcentage de batterie. Le format de dénomination du fichier journal inclut le nom unique de l'appareil Govee, l'année et le mois en cours. Un nouveau fichier journal est créé mensuellement.
Ajout de l'option --index pour créer un fichier d'index HTML basé sur les fichiers journaux existants. Cette option crée un fichier d'index et se termine sans exécuter aucun code Bluetooth. Il peut être exécuté sans affecter une instance en cours d'exécution du programme écoutant les publicités Bluetooth. Exemple de commande pour créer un index :
sudo /usr/local/bin/goveebttemplogger --log /var/log/goveebttemplogger/ --index index.html
Conversion vers Bluetooth en utilisant BlueZ sur DBus ! DBus est la méthode approuvée de communication Bluetooth. Il semble utiliser plus de CPU que le code HCI pur. Lorsque j'ai essayé de construire ceci sur une machine exécutant Raspbian GNU/Linux 10 (buster), le système se construit mais les routines BlueZ DBus pour trouver l'adaptateur Bluetooth échouent. Pour cette raison, j'ai laissé les anciennes commandes HCI dans le code et j'ai recours à l'exécution de HCI en cas d'échec de DBus.
J'ai ajouté une option --HCI pour permettre à l'utilisateur de le forcer à exécuter les commandes HCI au lieu d'utiliser l'interface DBus.
Lors de l'exécution de DBus, il n'est pas possible de l'exécuter en mode d'analyse passive. L'option --passive est ignorée.
Lors de l'exécution du mode HCI, la liste blanche créée avec l'option --only est envoyée au matériel Bluetooth et seuls ces appareils sont envoyés du matériel au logiciel. En mode DBus, la liste blanche ne semble pas être disponible. En mode DBus, je filtre la sortie en fonction de la liste blanche.
Le code a été légèrement réorganisé pour plus de clarté, déplaçant tout le code d'accès HCI dans des blocs #ifdef. Le fichier CMakeLists.txt définit _BLUEZ_HCI_ pour conserver le code dans l'application. Supprimer ou commenter la ligne add_compile_definitions( BLUEZ_HCI ) compilera sans les bibliothèques Bluetooth HCI. Je devrais également pouvoir ignorer les fichiers att-types.h, uuid.c et uuid.h. Je maîtrise déjà CMake pour le faire.
Le code HCI utilise la fonctionnalité libbluetooth de BlueZ sur Linux pour ouvrir le périphérique Bluetooth par défaut et écouter les publicités à faible consommation d'énergie des thermomètres Govee.
Mise à jour du script d'installation Debian postinst pour ajouter un utilisateur goveebttemplogger et apporter les modifications appropriées aux autorisations sur les répertoires par défaut. Modification du fichier de service pour spécifier l'exécution du programme en tant qu'utilisateur goveebttemplogger. Ceci est possible car l'accès à BlueZ via DBus ne nécessite pas d'accès root.
Ajout de la fonction de sortie SVG, créant directement des graphiques SVG à partir de données internes dans un répertoire spécifié. Cela rend le démarrage du programme plus long, car il tentera de lire toutes les anciennes données enregistrées dans une structure de mémoire interne lors de son démarrage. Une fois que le programme est entré dans l'état d'exécution normal, il écrit quatre fichiers SVG par périphérique dans le répertoire spécifié toutes les cinq minutes.
Voici un exemple de nom de fichier : gvh-E35ECC215C0F-day.svg
La température et l'humidité les plus récentes sont affichées sur l'échelle verticale de gauche. L'échelle de température est affichée à gauche du graphique, l'échelle d'humidité à droite. Les données temporelles les plus récentes sont affichées en haut à droite, avec un titre en haut à gauche du graphique.
Des données de température et d'humidité minimales et maximales, selon la granularité du graphique, peuvent être affichées. Ceci est particulièrement utile dans les graphiques annuels, où la granularité est d'un jour. Voici le graphique annuel correspondant au graphique journalier précédent : gvh-E35ECC215C0F-year.svg
L'humidité et l'échelle d'humidité à droite sont automatiquement omises si les données actuelles indiquent une humidité de zéro. Le thermomètre à viande indique sa température actuelle et sa température de consigne d'alarme mais aucune mesure d'humidité.
Un simple fichier texte mappant les adresses Bluetooth aux titres sera lu à partir du nom de fichier gvh-titlemap.txt dans le répertoire de sortie svg. Chaque ligne du fichier doit contenir l'adresse Bluetooth (au format hexadécimal avec ( :
) entre les octets), des espaces et le titre. Voir gvh-titlemap.txt pour un exemple. S'il n'existe aucun mappage de titre, l'adresse Bluetooth est utilisée pour le titre du graphique.
Si l'option --svg n'est pas ajoutée à la ligne de commande, le programme devrait continuer à fonctionner exactement de la même manière qu'auparavant.
libbluetooth-dev
libdbus-1-dev
Cela semble mieux construire le paquet Debian avec la taille installée, les dépendances et les détails md5sums corrects. J'apprends encore CMake, il peut donc y avoir des mises à jour régulières pendant un certain temps.
sudo apt install build-essential cmake git libbluetooth-dev libdbus-1-dev
git clone https://github.com/wcbonner/GoveeBTTempLogger.git
cmake -S GoveeBTTempLogger -B GoveeBTTempLogger/build
cmake --build GoveeBTTempLogger/build
pushd GoveeBTTempLogger/build && cpack . && popd
Le package d'installation créera une unité systemd goveebttemplogger.service
qui démarrera automatiquement GoveeBTTempLogger. Le service peut être configuré via la commande systemctl edit goveebttemplogger.service
. Par défaut, il écrit les journaux dans /var/log/goveebttemplogger
et écrit les fichiers SVG dans /var/www/html/goveebttemplogger
.
La routine d'installation postinst crée un utilisateur et trois répertoires. Cela modifiera également les autorisations sur ces répertoires pour qu'ils appartiennent et soient accessibles en écriture par l'utilisateur nouvellement créé.
adduser --system --ingroup www-data goveebttemplogger
mkdir --verbose --mode 0755 --parents /var/log/goveebttemplogger /var/cache/goveebttemplogger /var/www/html/goveebttemplogger
chown --changes --recursive goveebttemplogger:www-data /var/log/goveebttemplogger /var/cache/goveebttemplogger /var/www/html/goveebttemplogger
chmod --changes --recursive 0644 /var/log/goveebttemplogger/* /var/cache/goveebttemplogger/* /var/www/html/goveebttemplogger/*
sudo setcap 'cap_net_raw,cap_net_admin+eip' /usr/local/bin/goveebttemplogger
La section du fichier d'unité systemd ExecStart
pour démarrer le service a été divisée en plusieurs lignes pour plus de clarté.
[Service]
Type=simple
Restart=always
RestartSec=30
User=goveebttemplogger
Group=www-data
ExecStart=/usr/local/bin/goveebttemplogger
--verbose 0
--log /var/log/goveebttemplogger
--time 60
--svg /var/www/html/goveebttemplogger --battery 8 --minmax 8
--cache /var/cache/goveebttemplogger
KillSignal=SIGINT
À titre d'exemple, pour désactiver les fichiers SVG, augmenter la verbosité et modifier le répertoire dans lequel les fichiers journaux sont écrits, utilisez sudo systemctl edit --full goveebttemplogger.service
et saisissez le fichier suivant dans l'éditeur :
[Service]
Type=simple
Restart=always
RestartSec=5
ExecStartPre=/bin/mkdir -p /var/log/gvh
ExecStart=/usr/local/bin/goveebttemplogger
--verbose 1
--log /var/log/gvh
--time 60
--download
KillSignal=SIGINT
Utilisez ensuite sudo systemctl restart goveebttemplogger
pour redémarrer GoveeBTTempLogger.
Les deux premières commandes ci-dessous configurent l'environnement requis pour que Visual Studio 2022 puisse créer le projet. La troisième commande a ajouté les bibliothèques requises pour créer des projets Bluetooth.
sudo apt-get update
sudo apt install g++ gdb make ninja-build rsync zip -y
sudo apt install bluetooth bluez libbluetooth-dev -y
Le format du fichier journal est stable depuis longtemps sous la forme d'un simple fichier texte séparé par des tabulations avec un nombre défini de colonnes : Date (UTC), Température (C), Humidité, Batterie.
Avec l'ajout de la prise en charge des lectures multiples de température des thermomètres à viande, j'ai légèrement modifié le format de manière à ce qu'il soit rétrocompatible avec la plupart des programmes lisant les journaux existants. Après les colonnes existantes Date, Température, Humidité, Batterie, j'ai ajouté des colonnes facultatives Modèle, Température, Température, Température.
J'ai changé le nom du fichier journal par défaut pour commencer par gvh-
au lieu de gvh507x_
. Le code lira toujours les anciens fichiers journaux et renommera le fichier journal du mois en cours au nouveau format. J'ai utilisé la commande shell Linux for f in gvh507x_*.txt; do sudo mv "${f}" "${f//gvh507x_/gvh-}"; done
dans le répertoire des fichiers journaux pour renommer tous les anciens fichiers au nouveau format sur ma machine.
Les unités 5074, 5075, 5174 et 5177 diffusent toutes un UUID de 88EC. Malheureusement, le 5074 n'inclut pas l'UUID dans la même publicité que les températures.
Les unités H5181, 5182 et 5183 diffusent respectivement l'UUID de 5182 et 5183 dans chacun de leurs messages diffusés incluant les températures.
(Flags) 06 (UUID) 5182 (Manu) 3013270100010164018007D0FFFF860708FFFF (Temp) 20°C (Temp) -0.01°C (Temp) 18°C (Temp) -0.01°C (Battery) 0%
(UUID) 5183 (Flags) 05 (Manu) 5DA1B401000101E40186076C2F660000 (Temp) 19°C (Temp) 121.34°C (Battery) 0% (Other: 00) (Other: 00) (Other: 00) (Other: 00) (Other: 00) (Other: CB)
Il m'a fallu beaucoup de temps pour télécharger directement les données des appareils au lieu de simplement écouter les publicités. La méthode de téléchargement direct est intéressante car elle peut récupérer les données accumulées lorsque l'auditeur était hors ligne.
Il semble que les données diffusées H5105 soient automatiquement reconnues comme un thermomètre Govee et que les données soient stockées, mais le téléchargement ne fonctionne pas. Le H5105 dispose d'un bouton d'appairage sur le dessus de l'appareil. J'ai remarqué que l'appareil H5100 ne semble pas non plus télécharger les données historiques. Ils peuvent utiliser le même protocole, différent des anciens thermomètres.
J'ai réalisé quelques hacks pour faire fonctionner les deux appareils que j'ai chez moi. L'appareil H5100 que je possède a une adresse Bluetooth qui commence par un C, l'appareil H5105 commence par un D. Le très gros problème est que pour communiquer avec eux, le protocole doit déclarer qu'il parle avec LE_RANDOM_ADDRESS par opposition à LE_PUBLIC_ADDRESS que l'autre les appareils que j'ai utilisés nécessitent. Cela entre également en jeu si un filtre Bluetooth est configuré pour n'écouter que certains appareils. Je ne comprends pas cette configuration car d'après ce que j'ai lu, si les bits les plus significatifs de l'adresse Bluetooth 48 bits sont définis sur un, cela définit l'adresse comme ALÉATOIRE, ce qui signifierait qu'un C, D, E, ou F dans le premier chiffre de l'adresse devraient tous nécessiter RANDOM.
J'ai rencontré des problèmes pour reconnaître les publicités. Cela a conduit à trop de temps à expérimenter la méthode d'analyse des publicités Bluetooth, principalement avec les paramètres de ScanWindow et ScanInterval, mais également avec la différence entre l'analyse active et l'analyse passive.
Dans ce mode, ce programme fait exactement ce à quoi vous vous attendez, en écoutant les publicités.
Dans ce mode, la pile Bluetooth elle-même tentera de se connecter aux appareils dont elle reçoit des publicités et de récupérer plus d'informations.
Pendant très longtemps, des valeurs fixes ont été définies dans mon code pour la fenêtre d'analyse et l'intervalle d'analyse, rapidement définies sur bt_ScanInterval(0x0012) bt_ScanWindow(0x0012) suivi de bt_ScanInterval(0x1f40) bt_ScanWindow(0x1f40). Les valeurs sont par incréments de 0,625 ms. La première valeur était de 11,25 ms et la deuxième valeur était de (5 000 ms). En faisant beaucoup de lectures, je suis tombé sur des recommandations d'utilisation de 40 ms et 30 ms, j'ai donc essayé bt_ScanInterval(64) et bt_ScanWindow(48). Lorsqu'il est configuré de cette façon, j'ai l'impression de recevoir des publicités, mais je ne parviens pas à me connecter et à télécharger.
J'ai inclus il y a quelque temps un hack lié au filtrage Bluetooth pour filtrer facilement sur les appareils déjà connectés. Si un filtre est spécifié avec tous les bits définis, le programme soumettra un filtre d'adresses connues à la pile au démarrage de l'analyse. Cela désactive la découverte de nouveaux périphériques, mais peut améliorer les performances dans certaines situations.
Les connexions sur les appareils Bluetooth sont toutes basées sur des identifiants et des UUID. Il existe certains UUID définis que chaque appareil Bluetooth doit prendre en charge, puis il existe des UUID personnalisés. Cette annonce provient d'un GVH5177.
[-------------------] Service Handles: 0x0001..0x0007 UUID: 1800 (Generic Access)
[ ] Characteristic Handles: 0x0002..0x0003 Properties: 0x12 UUID: 2a00 (Device Name)
[ ] Characteristic Handles: 0x0004..0x0005 Properties: 0x02 UUID: 2a01 (Appearance)
[ ] Characteristic Handles: 0x0006..0x0007 Properties: 0x02 UUID: 2a04 (Peripheral Preferred Connection Parameters)
[-------------------] Service Handles: 0x0008..0x000b UUID: 1801 (Generic Attribute)
[ ] Characteristic Handles: 0x0009..0x000a Properties: 0x20 UUID: 2a05 (Service Changed)
[-------------------] Service Handles: 0x000c..0x000e UUID: 180a (Device Information)
[ ] Characteristic Handles: 0x000d..0x000e Properties: 0x02 UUID: 2a50 (PnP ID)
[-------------------] Service Handles: 0x000f..0x001b UUID: 57485f53-4b43-4f52-5f49-4c4c45544e49
[ ] Characteristic Handles: 0x0010..0x0011 Properties: 0x1a UUID: 11205f53-4b43-4f52-5f49-4c4c45544e49
[ ] Characteristic Handles: 0x0014..0x0015 Properties: 0x1a UUID: 12205f53-4b43-4f52-5f49-4c4c45544e49
[ ] Characteristic Handles: 0x0018..0x0019 Properties: 0x12 UUID: 13205f53-4b43-4f52-5f49-4c4c45544e49
[-------------------] Service Handles: 0x001c..0x001f UUID: 12190d0c-0b0a-0908-0706-050403020100
[ ] Characteristic Handles: 0x001d..0x001e Properties: 0x06 UUID: 122b0d0c-0b0a-0908-0706-050403020100
57485f53-4b43-4f52-5f49-4c4c45544e49 est l'UUID personnalisé de 128 bits que tous les thermomètres Govee semblent utiliser pour leur service principal. S'il est imprimé sous forme de chaîne ascii, il ressemble à ce texte à l'envers INTELLI_ROCKS_HW . ( WH_SKCOR_ILLETNI )
12205f53-4b43-4f52-5f49-4c4c45544e49 est l'UUID 128 bits de la caractéristique de service que j'écris pour permettre le téléchargement de données. Il ressemble à l'UUID principal, sauf que les deux premiers octets sont différents. INTELLI_ROCKS_ . ( _SKCOR_ILLETNI )
La plupart des appareils disposent d’un historique de 20 jours. Les appareils GVH5177 et GVH5174 contiennent un mois de données.
Download from device: [A4:C1:38:DC:CC:3D] 2023-02-03 13:52:00 2023-02-23 13:52:00 (28800)
Download from device: [A4:C1:38:EC:0B:03] 2023-02-03 13:51:00 2023-02-23 13:52:00 (28801)
Download from device: [E3:5E:CC:21:5C:0F] 2023-02-03 13:53:00 2023-02-23 13:53:00 (28800)
Download from device: [A4:C1:38:0D:3B:10] 2023-01-24 13:50:00 2023-02-23 13:53:00 (43203)
Download from device: [A4:C1:38:D5:A3:3B] 2023-02-03 13:54:00 2023-02-23 13:54:00 (28800)
Download from device: [A4:C1:38:65:A2:6A] 2023-02-03 13:52:00 2023-02-23 13:55:00 (28803)
Download from device: [A4:C1:38:05:C7:A1] 2023-02-03 13:53:00 2023-02-23 13:56:00 (28803)
Download from device: [A4:C1:38:13:AE:36] 2023-02-03 13:54:00 2023-02-23 13:57:00 (28803)
Download from device: [C2:35:33:30:25:50] 2024-01-15 22:19:00 2024-02-03 20:01:00 (27222)
Download from device: [D0:35:33:33:44:03] 2024-01-14 20:00:00 2024-02-03 20:00:00 (28800)
[2024-02-04T04:01:41] 46 [C2:35:33:30:25:50] (Flags) 06 (Name) GVH5100_2550 (UUID) 88EC (Manu) 010001010276EF55 (Temp) 16.1519°C (Humidity) 51.9% (Battery) 85% (GVH5100)
[-------------------] Service Handles: 0x0001..0x0009 UUID: 1800 (Generic Access)
[ ] Characteristic Handles: 0x0002..0x0003 Properties: 0x0a UUID: 2a00 (Device Name)
[ ] Characteristic Handles: 0x0004..0x0005 Properties: 0x0a UUID: 2a01 (Appearance)
[ ] Characteristic Handles: 0x0006..0x0007 Properties: 0x02 UUID: 2a04 (Peripheral Preferred Connection Parameters)
[ ] Characteristic Handles: 0x0008..0x0009 Properties: 0x02 UUID: 2ac9
[-------------------] Service Handles: 0x000a..0x000d UUID: 1801 (Generic Attribute)
[ ] Characteristic Handles: 0x000b..0x000c Properties: 0x22 UUID: 2a05 (Service Changed)
[-------------------] Service Handles: 0x000e..0x001a UUID: 57485f53-4b43-4f52-5f49-4c4c45544e49
[ ] Characteristic Handles: 0x000f..0x0010 Properties: 0x1a UUID: 11205f53-4b43-4f52-5f49-4c4c45544e49
[ ] Characteristic Handles: 0x0013..0x0014 Properties: 0x1a UUID: 12205f53-4b43-4f52-5f49-4c4c45544e49
[ ] Characteristic Handles: 0x0017..0x0018 Properties: 0x12 UUID: 13205f53-4b43-4f52-5f49-4c4c45544e49
[-------------------] Service Handles: 0x001b..0x0025 UUID: 00fe0000-0000-0000-0000-00000000f002
[ ] Characteristic Handles: 0x001c..0x001d Properties: 0x02 UUID: 03ff0000-0000-0000-0000-00000000f002
[ ] Characteristic Handles: 0x001e..0x001f Properties: 0x12 UUID: 02ff0000-0000-0000-0000-00000000f002
[ ] Characteristic Handles: 0x0022..0x0023 Properties: 0x02 UUID: 00ff0000-0000-0000-0000-00000000f002
[ ] Characteristic Handles: 0x0024..0x0025 Properties: 0x0c UUID: 01ff0000-0000-0000-0000-00000000f002
[2024-02-04T04:03:05] [C2:35:33:30:25:50] Download from device. 2024-01-15 22:19:00 2024-02-03 20:01:00 (27222)
[2024-02-04T04:00:25] 46 [D0:35:33:33:44:03] (Flags) 06 (Name) GVH5105_4403 (UUID) 88EC (Manu) 0100010102868262 (Temp) 16.5506°C (Humidity) 50.6% (Battery) 98% (GVH5105)
[-------------------] Service Handles: 0x0001..0x0009 UUID: 1800 (Generic Access)
[ ] Characteristic Handles: 0x0002..0x0003 Properties: 0x0a UUID: 2a00 (Device Name)
[ ] Characteristic Handles: 0x0004..0x0005 Properties: 0x0a UUID: 2a01 (Appearance)
[ ] Characteristic Handles: 0x0006..0x0007 Properties: 0x02 UUID: 2a04 (Peripheral Preferred Connection Parameters)
[ ] Characteristic Handles: 0x0008..0x0009 Properties: 0x02 UUID: 2ac9
[-------------------] Service Handles: 0x000a..0x000d UUID: 1801 (Generic Attribute)
[ ] Characteristic Handles: 0x000b..0x000c Properties: 0x22 UUID: 2a05 (Service Changed)
[-------------------] Service Handles: 0x000e..0x001a UUID: 57485f53-4b43-4f52-5f49-4c4c45544e49
[ ] Characteristic Handles: 0x000f..0x0010 Properties: 0x1a UUID: 11205f53-4b43-4f52-5f49-4c4c45544e49
[ ] Characteristic Handles: 0x0013..0x0014 Properties: 0x1a UUID: 12205f53-4b43-4f52-5f49-4c4c45544e49
[ ] Characteristic Handles: 0x0017..0x0018 Properties: 0x12 UUID: 13205f53-4b43-4f52-5f49-4c4c45544e49
[-------------------] Service Handles: 0x001b..0x0025 UUID: 00fe0000-0000-0000-0000-00000000f002
[ ] Characteristic Handles: 0x001c..0x001d Properties: 0x02 UUID: 03ff0000-0000-0000-0000-00000000f002
[ ] Characteristic Handles: 0x001e..0x001f Properties: 0x12 UUID: 02ff0000-0000-0000-0000-00000000f002
[ ] Characteristic Handles: 0x0022..0x0023 Properties: 0x02 UUID: 00ff0000-0000-0000-0000-00000000f002
[ ] Characteristic Handles: 0x0024..0x0025 Properties: 0x0c UUID: 01ff0000-0000-0000-0000-00000000f002
[2024-02-04T04:01:31] [D0:35:33:33:44:03] Download from device. 2024-01-14 20:00:00 2024-02-03 20:00:00 (28800)
Le fichier btsnoop_hci.log est un journal de surveillance Bluetooth hci provenant d'un appareil Google Nexus 7 exécutant Android et l'application Govee Home.