Registrador de temperatura y humedad Bluetooth de bajo consumo Govee H5074, H5075, H5100, H5101, H5104, H5105, H5174, H5177 y H5179, y termómetros inteligentes para carne Govee H5181, H5182 y H5183
Cada uno de estos dispositivos cuesta actualmente menos de $15 en Amazon y usa BLE para la comunicación, por lo que no es necesario configurar una cuenta de fabricante para rastrear los datos.
GoveeBTTempLogger se creó inicialmente con Microsoft Visual Studio 2017, dirigido al procesador ARM que se ejecuta en Linux. Estoy usando una Raspberry Pi 4 como mi host de Linux. Verifiqué que el mismo código funciona en Raspbery Pi ZeroW, Raspberry Pi Zero2W, Raspberry Pi 3b y Raspberry Pi 5.
GoveeBTTempLogger crea un archivo de registro, si se especifica mediante la opción -l o --log, para cada uno de los dispositivos de los que recibe datos transmitidos utilizando un formato simple separado por tabulaciones que es compatible con la carga en Microsoft Excel. Cada línea del archivo de registro tiene fecha (registrada en UTC), temperatura, humedad relativa y porcentaje de batería. El formato de denominación del archivo de registro incluye el nombre exclusivo del dispositivo Govee, el año y el mes actuales. Mensualmente se crea un nuevo archivo de registro.
Se agregó la opción --index para crear un archivo de índice html basado en los archivos de registro existentes. Esta opción crea un archivo de índice y sale sin ejecutar ningún código de Bluetooth. Se puede ejecutar sin afectar una instancia en ejecución del programa que escucha anuncios de Bluetooth. Comando de ejemplo para crear índice:
sudo /usr/local/bin/goveebttemplogger --log /var/log/goveebttemplogger/ --index index.html
¡Conversión a Bluetooth usando BlueZ sobre DBus! DBus es el método aprobado de comunicación Bluetooth. Parece utilizar más CPU que el código HCI puro. Cuando intenté construir esto en una máquina que ejecuta Raspbian GNU/Linux 10 (buster), el sistema se construye pero las rutinas BlueZ DBus para encontrar el adaptador bluetooth fallan. Por esta razón, dejé los antiguos comandos de HCI en el código y recurrí a ejecutar HCI si DBus falla.
Agregué una opción --HCI para permitir al usuario forzarlo a ejecutar los comandos HCI en lugar de usar la interfaz DBus.
Cuando se ejecuta DBus, no hay forma de ejecutarlo en modo de escaneo pasivo. La opción --passive se ignora.
Cuando se ejecuta el modo HCI, la lista blanca creada con la opción --only se envía al hardware bluetooth y solo esos dispositivos se envían desde el hardware al software. En el modo DBus, la lista blanca no parece estar disponible. En el modo DBus, estoy filtrando la salida según la lista blanca.
El código se ha reorganizado ligeramente para mayor claridad, moviendo todo el código de acceso a HCI a bloques #ifdef. El archivo CMakeLists.txt define _BLUEZ_HCI_ para mantener el código en la aplicación. Eliminar o comentar la línea add_compile_definitions( BLUEZ_HCI ) se compilará sin las bibliotecas de Bluetooth HCI. También debería poder ignorar los archivos att-types.h, uuid.c y uuid.h. Todavía soy competente en CMake para hacer esto.
El código HCI utiliza la funcionalidad libbluetooth de BlueZ en Linux para abrir el dispositivo Bluetooth predeterminado y escuchar anuncios de baja energía de los termómetros Govee.
Se actualizó el script de instalación de Debian postinst para agregar un usuario goveebtteplogger y realizar cambios apropiados en los permisos en los directorios predeterminados. Se modificó el archivo de servicio para especificar la ejecución del programa como usuario goveebtteplogger. Esto es posible porque acceder a BlueZ a través de DBus no requiere acceso de root.
Se agregó la función de salida SVG, creando directamente gráficos SVG a partir de datos internos en un directorio específico. Esto hace que el programa tarde más en iniciarse, ya que intentará leer todos los datos registrados antiguos en una estructura de memoria interna a medida que se inicia. Una vez que el programa ha entrado en el estado de ejecución normal, escribe cuatro archivos SVG por dispositivo en el directorio especificado cada cinco minutos.
Aquí hay un nombre de archivo de ejemplo: gvh-E35ECC215C0F-day.svg
La temperatura y la humedad más recientes se muestran en la escala vertical de la izquierda. La escala de temperatura se muestra en el lado izquierdo del gráfico, la escala de humedad en el derecho. Los datos de tiempo más recientes se muestran en la parte superior derecha, con un título en la parte superior izquierda del gráfico.
Se pueden mostrar datos mínimos y máximos de temperatura y humedad, en la granularidad del gráfico. Esto es más útil en gráficos anuales, donde la granularidad es de un día. Aquí está el gráfico anual correspondiente al gráfico diario anterior: gvh-E35ECC215C0F-year.svg
La humedad y la escala de humedad de la derecha se omiten automáticamente si los datos actuales informan una humedad de cero. El termómetro para carne informa su temperatura actual y la temperatura establecida de alarma, pero no mide la humedad.
Se leerá un archivo de texto simple que asigna direcciones Bluetooth a títulos desde el nombre de archivo gvh-titlemap.txt en el directorio de salida svg. Cada línea del archivo debe constar de la dirección de bluetooth (en formato hexadecimal con ( :
) entre octetos), espacios en blanco y el título. Consulte gvh-titlemap.txt para ver un ejemplo. Si no existe ninguna asignación de títulos, se utiliza la dirección Bluetooth para el título del gráfico.
Si la opción --svg no se agrega a la línea de comando, el programa debería continuar funcionando exactamente igual que antes.
libbluetooth-dev
libdbus-1-dev
Esto parece construir mejor el paquete Debian con el tamaño de instalación correcto, las dependencias y los detalles de md5sums. Todavía estoy aprendiendo CMake, por lo que es posible que haya actualizaciones periódicas durante un tiempo.
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
El paquete de instalación creará una unidad systemd goveebttemplogger.service
que iniciará automáticamente GoveeBTTempLogger. El servicio se puede configurar mediante el comando systemctl edit goveebttemplogger.service
. De forma predeterminada, escribe registros en /var/log/goveebttemplogger
y escribe archivos SVG en /var/www/html/goveebttemplogger
.
La rutina de instalación postinst crea un usuario y tres directorios. También cambiará los permisos en esos directorios para que sean propiedad del usuario recién creado y pueda escribirlos.
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 sección del archivo de unidad systemd ExecStart
para iniciar el servicio se ha dividido en varias líneas para mayor claridad.
[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
Como ejemplo, para deshabilitar los archivos SVG, aumentar la detalle y cambiar el directorio en el que se escriben los archivos de registro, use sudo systemctl edit --full goveebttemplogger.service
e ingrese el siguiente archivo en el editor:
[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
Luego use sudo systemctl restart goveebttemplogger
para reiniciar GoveeBTTempLogger.
Los dos primeros comandos siguientes configuran el entorno necesario para que Visual Studio 2022 cree el proyecto. El tercer comando agregó las bibliotecas necesarias para crear proyectos de bluetooth.
sudo apt-get update
sudo apt install g++ gdb make ninja-build rsync zip -y
sudo apt install bluetooth bluez libbluetooth-dev -y
El formato del archivo de registro se ha mantenido estable durante mucho tiempo como un simple archivo de texto separado por tabulaciones con un número determinado de columnas: Fecha (UTC), Temperatura (C), Humedad, Batería.
Con la adición de soporte para las múltiples lecturas de temperatura de los termómetros para carne, cambié ligeramente el formato de una manera que debería ser compatible con la mayoría de los programas que leen registros existentes. Después de las columnas existentes de Fecha, Temperatura, Humedad, Batería, agregué columnas opcionales de Modelo, Temperatura, Temperatura, Temperatura
Cambié el nombre del archivo de registro predeterminado para que comenzara con gvh-
en lugar de gvh507x_
. El código seguirá leyendo los archivos de registro antiguos y cambiará el nombre del archivo de registro de los meses actuales al nuevo formato. Utilicé el comando de shell de Linux for f in gvh507x_*.txt; do sudo mv "${f}" "${f//gvh507x_/gvh-}"; done
en el directorio de archivos de registro para cambiar el nombre de todos los archivos antiguos al nuevo formato en mi máquina.
Las unidades 5074, 5075, 5174 y 5177 transmiten un UUID de 88EC. Desafortunadamente, el 5074 no incluye el UUID en el mismo anuncio que las temperaturas.
Las unidades H5181, 5182 y 5183 transmiten UUID de 5182 y 5183 respectivamente en cada uno de sus mensajes de transmisión, incluidas las temperaturas.
(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)
Me ha llevado mucho tiempo empezar a descargar datos directamente desde los dispositivos en lugar de limitarme a escuchar anuncios. El método de descarga directa es bueno porque puede recuperar datos acumulados mientras el oyente estaba desconectado.
Parece que los datos transmitidos por el H5105 se reconocen automáticamente como un termómetro Govee y los datos se almacenan, pero la descarga no funciona. El H5105 tiene un botón de emparejamiento en la parte superior del dispositivo. He notado que el dispositivo H5100 tampoco parece estar descargando datos históricos. Es posible que utilicen el mismo protocolo, diferente al de los termómetros más antiguos.
Hice un par de trucos para que funcionen los dos dispositivos que tengo en mi ubicación. El dispositivo H5100 que tengo tiene una dirección bluetooth que comienza con C, el dispositivo H5105 comienza con D. El gran problema es que para comunicarse con ellos, el protocolo debe declarar que está hablando con LE_RANDOM_ADDRESS en lugar de LE_PUBLIC_ADDRESS que el otro Los dispositivos que he usado requieren. Esto también entra en juego si se configura un filtro bluetooth para escuchar solo ciertos dispositivos. No entiendo esta configuración, según lo que he leído, si los bits más significativos de la dirección bluetooth de 48 bits se configuran en uno, eso define la dirección como ALEATORIA, lo que significaría que C, D, E, o F en el primer dígito de la dirección deberían requerir ALEATORIO.
He tenido problemas para reconocer anuncios. Esto ha llevado a pasar demasiado tiempo experimentando con el método de escaneo en busca de anuncios de bluetooth, principalmente con las configuraciones de ScanWindow y ScanInterval, pero también con la diferencia entre escaneo activo y escaneo pasivo.
En este modo, ese programa hace exactamente lo que usted esperaría: escuchar anuncios.
En este modo, la pila Bluetooth intentará conectarse a los dispositivos de los que recibe anuncios y recuperar más información.
Durante mucho tiempo, he configurado valores fijos en mi código para la ventana de escaneo y el intervalo de escaneo que se configuran rápidamente en bt_ScanInterval(0x0012) bt_ScanWindow(0x0012) seguido de bt_ScanInterval(0x1f40) bt_ScanWindow(0x1f40). Los valores están en incrementos de 0,625 ms. El primer valor fue 11,25 ms y el segundo valor fue (5000 ms). Al leer mucho, encontré recomendaciones para usar 40 ms y 30 ms, así que probé bt_ScanInterval(64) y bt_ScanWindow(48). Cuando está configurado de esta manera, parece que recibo anuncios, pero no puedo conectarme ni descargar.
Hace algún tiempo incluí un truco relacionado con el filtrado de bluetooth para filtrar fácilmente en dispositivos que ya han sido registrados. Si se especifica un filtro con todos los bits configurados, el programa enviará un filtro de direcciones conocidas a la pila cuando se inicie el escaneo. Esto desactiva la detección de nuevos dispositivos, pero puede mejorar el rendimiento en algunas situaciones.
Todas las conexiones en dispositivos bluetooth se basan en identificadores y UUID. Hay algunos UUID definidos que todos los dispositivos Bluetooth deben admitir, y luego están los UUID personalizados. Este listado proviene de 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 es el UUID personalizado de 128 bits que todos los termómetros Govee parecen utilizar para su servicio principal. Si se imprime como una cadena ASCII, se parecerá a este texto al revés INTELLI_ROCKS_HW . ( WH_SKCOR_ILLETNI )
12205f53-4b43-4f52-5f49-4c4c45544e49 es el UUID de 128 bits de la característica de servicio que escribo para permitir la descarga de datos. Parece el UUID principal excepto que los dos primeros bytes son diferentes. INTELLI_ROCAS_ . ( _SKCOR_ILLETNI )
La mayoría de los dispositivos tienen 20 días de historial. Los dispositivos GVH5177 y GVH5174 tuvieron un mes de datos.
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)
El archivo btsnoop_hci.log es un registro de vigilancia hci de Bluetooth de un dispositivo Google Nexus 7 que ejecuta Android y la aplicación Govee Home.