Govee H5074、H5075、H5100、H5101、H5104、H5105、H5174、H5177 和 H5179 蓝牙低功耗温度和湿度记录仪,以及 Govee H5181、H5182 和 H5183 智能肉类温度计
目前,这些设备在亚马逊上的售价均低于 15 美元,并使用 BLE 进行通信,因此不需要设置制造商帐户来跟踪数据。
GoveeBTTempLogger 最初使用 Microsoft Visual Studio 2017 构建,针对在 Linux 上运行的 ARM 处理器。我使用 Raspberry Pi 4 作为我的 Linux 主机。我已经验证了相同的代码可以在 Raspbery Pi ZeroW、Raspberry Pi Zero2W、Raspberry Pi 3b 和 Raspberry Pi 5 上运行。
如果通过 -l 或 --log 选项指定,GoveeBTTempLogger 将使用与在 Microsoft Excel 中加载兼容的简单制表符分隔格式为其接收广播数据的每个设备创建一个日志文件。日志文件中的每一行都包含日期(以 UTC 格式记录)、温度、相对湿度和电池百分比。日志文件命名格式包括唯一的 Govee 设备名称、当前年份和月份。每月创建一个新的日志文件。
添加了选项 --index 以根据现有日志文件创建 html 索引文件。此选项创建索引文件并退出而不运行任何蓝牙代码。它可以在不影响监听蓝牙广告的程序的运行实例的情况下运行。创建索引的示例命令:
sudo /usr/local/bin/goveebttemplogger --log /var/log/goveebttemplogger/ --index index.html
使用 BlueZ 通过 DBus 转换为蓝牙! DBus 是经过批准的蓝牙通信方法。它似乎比纯 HCI 代码使用更多的 CPU。当我尝试在运行 Raspbian GNU/Linux 10 (buster) 的计算机上构建此系统时,系统可以构建,但用于查找蓝牙适配器的 BlueZ DBus 例程失败。因此,我在代码中保留了旧的 HCI 命令,并在 DBus 失败时回退到运行 HCI。
我添加了一个 --HCI 选项,以允许用户强制它运行 HCI 命令,而不是使用 DBus 接口。
运行DBus时,没有办法以被动扫描模式运行。 --passive 选项被忽略。
运行 HCI 模式时,使用 --only 选项创建的白名单将发送到蓝牙硬件,并且只有那些设备从硬件发送到软件。在 DBus 模式下,白名单似乎不可用。在 DBus 模式下,我根据白名单过滤输出。
为了清晰起见,代码已稍微重新排列,将所有 HCI 访问代码移至 #ifdef 块中。 CMakeLists.txt 文件定义 _BLUEZ_HCI_ 以将代码保留在应用程序中。删除或注释掉 add_compile_definitions( BLUEZ_HCI ) 行将在没有蓝牙 HCI 库的情况下进行编译。我还应该能够忽略文件 att-types.h、uuid.c 和 uuid.h。我已经精通 CMake 来做到这一点。
HCI 代码使用 Linux 上 BlueZ 的 libbluetooth 功能来打开默认蓝牙设备并监听来自 Govee 温度计的低能耗广告。
更新了 postinst debian 安装脚本以添加用户 goveebttemplogger 并相应地更改默认目录的权限。更改了服务文件以指定以用户 goveebttemplogger 身份运行程序。这是可能的,因为通过 DBus 访问 BlueZ 不需要 root 访问权限。
新增SVG输出功能,直接将指定目录下的内部数据创建SVG图形。这会导致程序需要更长的时间来启动,因为它会在启动时尝试将所有旧的记录数据读入内部内存结构。一旦程序进入正常运行状态,它每五分钟就会将每个设备的四个 SVG 文件写入指定目录。
以下是文件名示例:gvh-E35ECC215C0F-day.svg
最近的温度和湿度显示在左侧的垂直刻度中。温度标度显示在图表的左侧,湿度标度显示在右侧。最近的时间数据显示在右上角,标题位于图表的左上角。
可以以图表的粒度显示最小和最大温度和湿度数据。这在年度图表中最有用,其中粒度为一天。以下是之前每日图表对应的年度图表:gvh-E35ECC215C0F-year.svg
如果当前数据报告的湿度为零,则湿度和右侧的湿度刻度将自动省略。肉类温度计报告其当前温度和警报设定温度,但不报告湿度测量。
将从 svg 输出目录中的文件名 gvh-titlemap.txt 读取将蓝牙地址映射到标题的简单文本文件。文件中的每一行应包含蓝牙地址(采用十六进制格式,八位位组之间使用 ( :
)、空格和标题。有关示例,请参阅 gvh-titlemap.txt。如果不存在标题映射,则蓝牙地址将用作图形标题。
如果 --svg 选项未添加到命令行中,程序应该继续像以前一样运行。
libbluetooth-dev
libdbus-1-dev
这似乎可以更好地构建具有正确安装大小、依赖项和 md5sums 详细信息的 debian 软件包。我仍在学习 CMake,因此可能会定期更新一段时间。
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
安装包将创建一个 systemd 单元goveebttemplogger.service
,它将自动启动 GoveeBTTempLogger。可以通过systemctl edit goveebttemplogger.service
命令配置该服务。默认情况下,它将日志写入/var/log/goveebttemplogger
并将 SVG 文件写入/var/www/html/goveebttemplogger
。
postinst 安装例程创建一个用户和三个目录。它还会将这些目录的权限更改为新创建的用户所拥有和可写。
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
为了清楚起见,用于启动服务的 systemd 单元文件部分ExecStart
已分为几行。
[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
例如,要禁用 SVG 文件、增加详细程度并更改日志文件写入的目录,请使用sudo systemctl edit --full goveebttemplogger.service
并在编辑器中输入以下文件:
[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
然后使用sudo systemctl restart goveebttemplogger
重新启动 GoveeBTTempLogger。
下面的前两个命令设置 Visual Studio 2022 构建项目所需的环境。第三个命令添加了构建蓝牙项目所需的库。
sudo apt-get update
sudo apt install g++ gdb make ninja-build rsync zip -y
sudo apt install bluetooth bluez libbluetooth-dev -y
日志文件格式长期以来一直保持稳定,是一个简单的制表符分隔文本文件,具有一定数量的列:日期 (UTC)、温度 (C)、湿度、电池。
由于增加了对肉类温度计多个温度读数的支持,我稍微改变了格式,以便与大多数读取现有日志的程序向后兼容。在现有的日期、温度、湿度、电池列之后,我添加了型号、温度、温度、温度的可选列
我将默认日志文件名更改为以gvh-
而不是gvh507x_
。该代码仍将读取旧的日志文件,并将当前月份的日志文件重命名为新格式。我for f in gvh507x_*.txt; do sudo mv "${f}" "${f//gvh507x_/gvh-}"; done
在日志文件目录中for f in gvh507x_*.txt; do sudo mv "${f}" "${f//gvh507x_/gvh-}"; done
,将我的计算机上的所有旧文件重命名为新格式。
5074、5075、5174 和 5177 设备均广播 UUID 88EC。不幸的是,5074 在与温度相同的广告中不包含 UUID。
H5181、5182 和 5183 单元在其每个广播消息(包括温度)中分别广播 UUID 5182 和 5183。
(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)
我花了很长时间才开始从设备上直接下载数据,而不是纯粹听广告。直接下载方法很好,因为它可以检索侦听器离线时积累的数据。
看来H5105广播数据会自动识别为Govee温度计并存储数据,但下载不工作。 H5105 的设备顶部有一个配对按钮。我注意到H5100设备似乎也没有下载历史数据。他们可能使用与旧温度计不同的相同协议。
我进行了一些修改,以使我所在位置的两台设备能够正常工作。我的 H5100 设备有一个以 C 开头的蓝牙地址,H5105 设备以 D 开头。真正的大问题是,要与它们通信,协议必须声明它正在与 LE_RANDOM_ADDRESS 进行通信,而不是与其他设备的 LE_PUBLIC_ADDRESS 进行通信。我使用过的设备需要。如果蓝牙过滤器配置为仅侦听某些设备,这也会发挥作用。我不明白这个设置,因为根据我读到的内容,如果 48 位蓝牙地址的最高有效位设置为 1,则将地址定义为随机,这意味着 C、D、E、地址前导数字中的 F 或 F 都应要求 RANDOM。
我在识别广告时遇到了问题。这就导致我们花了太多的时间去尝试扫描蓝牙广告的方法,主要是ScanWindow和ScanInterval的设置,还有主动扫描和被动扫描的区别。
在这种模式下,该程序将完全按照您的预期进行操作,即监听广告。
在此模式下,蓝牙堆栈本身将尝试连接到从中接收广告的设备并检索更多信息。
最长的时间里,我在代码中为扫描窗口和扫描间隔设置了固定值,很快被设置为 bt_ScanInterval(0x0012) bt_ScanWindow(0x0012),然后是 bt_ScanInterval(0x1f40) bt_ScanWindow(0x1f40)。这些值的增量为 0.625 毫秒。第一个值为 11.25 毫秒,第二个值为 (5000 毫秒)。经过大量阅读后,我发现建议使用 40 毫秒和 30 毫秒,因此我尝试了 bt_ScanInterval(64) 和 bt_ScanWindow(48)。当这样设置时,我似乎收到广告,但无法连接和下载。
我前段时间加入了一个与蓝牙过滤相关的黑客攻击,可以轻松过滤已记录的设备。如果指定了过滤器并设置了所有位,则程序将在扫描开始时向堆栈提交已知地址的过滤器。这会禁用新设备发现,但在某些情况下可能会提高性能。
蓝牙设备上的连接都是基于句柄和UUID。每个蓝牙设备都需要支持一些定义的 UUID,还有自定义的 UUID。此列表来自 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是自定义 128 位 UUID,所有 Govee 温度计似乎都将其用于其主要服务。如果打印为 ascii 字符串,则该文本看起来像是向后的INTELLI_ROCKS_HW 。 ( WH_SKCOR_ILLETNI )
12205f53-4b43-4f52-5f49-4c4c45544e49是我编写的用于启用数据下载的服务特征的 128 位 UUID。它看起来像主 UUID,只是前两个字节不同。 INTELLI_ROCKS_ 。 ( _SKCOR_ILLETNI )
大多数设备都保存 20 天的历史记录。 GVH5177 和 GVH5174 设备保存一个月的数据。
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)
文件 btsnoop_hci.log 是来自运行 Android 和 Govee Home 应用程序的 Google Nexus 7 设备的蓝牙 hci 监听日志。