Govee H5074, H5075, H5100, H5101, H5104, H5105, H5174, H5177 e H5179 Registrador de temperatura e umidade Bluetooth de baixa energia e termômetros inteligentes de carne Govee H5181, H5182 e H5183
Cada um desses dispositivos custa atualmente menos de US$ 15 na Amazon e usa BLE para comunicação, portanto, não é necessário configurar uma conta de fabricante para rastrear os dados.
GoveeBTTempLogger foi inicialmente construído usando Microsoft Visual Studio 2017, visando processador ARM rodando em Linux. Estou usando um Raspberry Pi 4 como meu host Linux. Verifiquei que o mesmo código funciona em Raspbery Pi ZeroW, Raspberry Pi Zero2W, Raspberry Pi 3b e Raspberry Pi 5.
GoveeBTTempLogger cria um arquivo de log, se especificado pela opção -l ou --log, para cada um dos dispositivos dos quais recebe dados transmitidos usando um formato simples separado por tabulações que é compatível com o carregamento no Microsoft Excel. Cada linha no arquivo de log possui data (registrada em UTC), temperatura, umidade relativa e porcentagem da bateria. O formato de nomenclatura do arquivo de log inclui o nome exclusivo do dispositivo Govee, o ano e o mês atuais. Um novo arquivo de log é criado mensalmente.
Adicionada a opção --index para criar um arquivo de índice HTML baseado nos arquivos de log existentes. Esta opção cria um arquivo de índice e sai sem executar nenhum código bluetooth. Ele pode ser executado sem afetar uma instância em execução do programa que escuta anúncios de Bluetooth. Comando de exemplo para criar índice:
sudo /usr/local/bin/goveebttemplogger --log /var/log/goveebttemplogger/ --index index.html
Conversão para Bluetooth usando BlueZ sobre DBus! DBus é o método aprovado de comunicação Bluetooth. Parece usar mais CPU do que o código HCI puro. Quando tentei construir isso em uma máquina rodando Raspbian GNU/Linux 10 (buster), o sistema foi compilado, mas as rotinas BlueZ DBus para encontrar o adaptador bluetooth falharam. Por esse motivo, deixei os antigos comandos HCI no código e voltei a executar o HCI se o DBus falhar.
Adicionei uma opção --HCI para permitir que o usuário o force a executar os comandos HCI em vez de usar a interface DBus.
Ao executar o DBus, não há como executar no modo de varredura passiva. A opção --passive é ignorada.
Ao executar o modo HCI, a lista de permissões criada com a opção --only é enviada para o hardware bluetooth e apenas esses dispositivos são enviados do hardware para o software. No modo DBus, a lista de permissões não parece estar disponível. No modo DBus, estou filtrando a saída com base na lista de permissões.
O código foi ligeiramente reorganizado para maior clareza, movendo todo o código de acesso HCI para blocos #ifdef. O arquivo CMakeLists.txt define _BLUEZ_HCI_ para manter o código no aplicativo. Remover ou comentar a linha add_compile_definitions( BLUEZ_HCI ) irá compilar sem as bibliotecas Bluetooth HCI. Eu também deveria ser capaz de ignorar os arquivos att-types.h, uuid.c e uuid.h. Sou proficiente no CMake para fazer isso ainda.
O código HCI usa a funcionalidade libbluetooth do BlueZ no Linux para abrir o dispositivo Bluetooth padrão e ouvir anúncios de baixo consumo de energia dos termômetros Govee.
Atualizado o script de instalação postinst debian para adicionar um usuário goveebttemplogger e fazer alterações nas permissões nos diretórios padrão de forma adequada. Alterado o arquivo de serviço para especificar a execução do programa como usuário goveebttemplogger. Isso é possível porque acessar o BlueZ via DBus não requer acesso root.
Adicionada a função de saída SVG, criando gráficos SVG diretamente a partir de dados internos em um diretório especificado. Isso faz com que o programa demore mais para inicializar, pois tentará ler todos os dados antigos registrados em uma estrutura de memória interna ao iniciar. Depois que o programa entra no estado normal de execução, ele grava quatro arquivos SVG por dispositivo no diretório especificado a cada cinco minutos.
Aqui está um exemplo de nome de arquivo: gvh-E35ECC215C0F-day.svg
A temperatura e a umidade mais recentes são exibidas na escala vertical à esquerda. A escala de temperatura é exibida no lado esquerdo do gráfico, a escala de umidade no lado direito. Os dados de tempo mais recentes são exibidos no canto superior direito, com um título no canto superior esquerdo do gráfico.
Podem ser exibidos dados mínimos e máximos de temperatura e umidade, na granularidade do gráfico. Isto é mais útil em gráficos anuais, onde a granularidade é de um dia. Aqui está o gráfico anual correspondente ao gráfico diário anterior: gvh-E35ECC215C0F-year.svg
A umidade e a escala de umidade à direita serão automaticamente omitidas se os dados atuais reportarem uma umidade zero. O termômetro de carne informa a temperatura atual e a temperatura definida pelo alarme, mas não mede a umidade.
Um arquivo de texto simples mapeando endereços Bluetooth para títulos será lido a partir do nome de arquivo gvh-titlemap.txt no diretório de saída svg. Cada linha do arquivo deve consistir no endereço do bluetooth (em formato hexadecimal com ( :
) entre octetos), espaço em branco e o título. Veja gvh-titlemap.txt para ver um exemplo. Se não existir nenhum mapeamento de título, o endereço Bluetooth será usado para o título do gráfico.
Se a opção --svg não for adicionada à linha de comando, o programa deverá continuar a operar exatamente da mesma forma que antes.
libbluetooth-dev
libdbus-1-dev
Isso parece construir melhor o pacote debian com o tamanho correto de instalação, dependências e detalhes de md5sums. Ainda estou aprendendo o CMake, então pode haver atualizações regulares por um tempo.
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
O pacote de instalação criará uma unidade systemd goveebttemplogger.service
que iniciará automaticamente o GoveeBTTempLogger. O serviço pode ser configurado por meio do comando systemctl edit goveebttemplogger.service
. Por padrão, ele grava logs em /var/log/goveebttemplogger
e grava arquivos SVG em /var/www/html/goveebttemplogger
.
A rotina de instalação postinst cria um usuário e três diretórios. Ele também alterará as permissões nesses diretórios para serem de propriedade e graváveis pelo usuário recém-criado.
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
A seção ExecStart
do arquivo da unidade systemd para iniciar o serviço foi dividida em várias linhas para maior clareza.
[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
Por exemplo, para desabilitar arquivos SVG, aumentar o detalhamento e alterar o diretório em que os arquivos de log são gravados, use sudo systemctl edit --full goveebttemplogger.service
e insira o seguinte arquivo no 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
Em seguida, use sudo systemctl restart goveebttemplogger
para reiniciar o GoveeBTTempLogger.
Os dois primeiros comandos abaixo configuram o ambiente necessário para o Visual Studio 2022 construir o projeto. O terceiro comando adicionou as bibliotecas necessárias para construir projetos bluetooth.
sudo apt-get update
sudo apt install g++ gdb make ninja-build rsync zip -y
sudo apt install bluetooth bluez libbluetooth-dev -y
O formato do arquivo de log é estável há muito tempo como um simples arquivo de texto separado por tabulações com um número definido de colunas: Data (UTC), Temperatura (C), Umidade, Bateria.
Com a adição do suporte para leituras múltiplas de temperatura dos termômetros de carne, alterei ligeiramente o formato de uma forma que deve ser compatível com versões anteriores da maioria dos programas que leem registros existentes. Após as colunas existentes de Data, Temperatura, Umidade, Bateria, adicionei colunas opcionais de Modelo, Temperatura, Temperatura, Temperatura
Alterei o nome do arquivo de log padrão para começar com gvh-
em vez de gvh507x_
. O código ainda lerá os arquivos de log antigos e renomeará o arquivo de log dos meses atuais para o novo formato. Usei o comando shell do Linux for f in gvh507x_*.txt; do sudo mv "${f}" "${f//gvh507x_/gvh-}"; done
no diretório do arquivo de log para renomear todos os arquivos antigos para o novo formato na minha máquina.
Todas as unidades 5074, 5075, 5174 e 5177 transmitem um UUID de 88EC. Infelizmente, o 5074 não inclui o UUID no mesmo anúncio que as temperaturas.
As unidades H5181, 5182 e 5183 transmitem UUID de 5182 e 5183 respectivamente em cada uma de suas mensagens de transmissão, incluindo as 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)
Levei muito tempo para baixar dados diretamente dos dispositivos, em vez de apenas ouvir os anúncios. O método de download direto é bom porque pode recuperar dados acumulados enquanto o ouvinte estava offline.
Parece que os dados de transmissão do H5105 são automaticamente reconhecidos como um termômetro Govee e os dados armazenados, mas o download não está funcionando. O H5105 possui um botão de emparelhamento na parte superior do dispositivo. Percebi que o dispositivo H5100 também não parece estar baixando dados históricos. Eles podem utilizar o mesmo protocolo, diferente dos termômetros mais antigos.
Fiz alguns hacks para fazer com que os dois dispositivos que tenho em meu local funcionassem. O dispositivo H5100 que tenho tem um endereço bluetooth que começa com C, o dispositivo H5105 começa com D. O grande problema é que para se comunicar com eles, o protocolo deve declarar que está falando com LE_RANDOM_ADDRESS em oposição a LE_PUBLIC_ADDRESS que o outro dispositivos que usei exigem. Isso também entra em ação se um filtro Bluetooth estiver configurado para ouvir apenas determinados dispositivos. Não entendo essa configuração, de acordo com o que li, se os bits mais significativos do endereço bluetooth de 48 bits forem definidos como um, isso define o endereço como RANDOM, o que significaria que C, D, E, ou F no dígito inicial do endereço devem exigir RANDOM.
Tive problemas para reconhecer anúncios. Isso levou muito tempo experimentando o método de verificação de anúncios Bluetooth, principalmente com as configurações de ScanWindow e ScanInterval, mas também com a diferença entre verificação ativa e verificação passiva.
Neste modo esse programa está fazendo exatamente o que você espera, ouvindo anúncios.
Neste modo, a própria pilha bluetooth tentará se conectar aos dispositivos dos quais recebe anúncios e recuperar mais informações.
Por muito tempo, tive valores fixos definidos em meu código para Scan Window e Scan Interval sendo rapidamente definidos como bt_ScanInterval(0x0012) bt_ScanWindow(0x0012) seguido por bt_ScanInterval(0x1f40) bt_ScanWindow(0x1f40). Os valores estão em incrementos de 0,625 ms. O primeiro valor foi 11,25 ms e o segundo valor foi (5.000 ms). Lendo bastante, encontrei recomendações para usar 40 ms e 30 ms, então tentei bt_ScanInterval(64) e bt_ScanWindow(48). Quando configurado dessa forma, parece que recebo anúncios, mas não consigo conectar e fazer download.
Incluí um hack há algum tempo relacionado à filtragem de bluetooth para filtrar facilmente dispositivos que já foram logados. Se um filtro for especificado com todos os bits definidos, o programa enviará um filtro de endereços conhecidos para a pilha quando a varredura for iniciada. Isso desativa a descoberta de novos dispositivos, mas pode melhorar o desempenho em algumas situações.
As conexões em dispositivos Bluetooth são todas baseadas em identificadores e UUIDs. Existem alguns UUIDs definidos que todos os dispositivos Bluetooth devem suportar e, em seguida, existem UUIDs personalizados. Esta listagem veio de um 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 é o UUID personalizado de 128 bits que todos os termômetros Govee parecem usar em seu serviço principal. Se impresso como uma string ascii, terá a aparência deste texto invertido INTELLI_ROCKS_HW . ( WH_SKCOR_ILLETNI )
12205f53-4b43-4f52-5f49-4c4c45544e49 é o UUID de 128 bits da característica de serviço que escrevo para permitir o download de dados. Parece o UUID primário, exceto que os dois primeiros bytes são diferentes. INTELLI_ROCKS_ . ( _SKCOR_ILLETNI )
A maioria dos dispositivos contém 20 dias de histórico. Os dispositivos GVH5177 e GVH5174 mantiveram um mês de dados.
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)
O arquivo btsnoop_hci.log é um log de rastreamento Bluetooth hci de um dispositivo Google Nexus 7 executando Android e o aplicativo Govee Home.