前言

起因是手上刚好有一个15元的京东E卡,想着买点什么,最终没忍住下单了米家智能温度计3(钱包-30),除了温度计也能连接米家,还可以当个小桌面时钟用

mijiatemp3.jpg

但是有个小问题,就是这个温度计是通过蓝牙连接到米家的,而且每次断连以后必须要按一下机身上的一个小按钮来重新连接,如果要保持连接必须要一个带有蓝牙中枢功能的音响或者带屏幕的那个网关……

mijiadisconnect.PNG

掏300多买个网关或者100买个音响是不可能的,这辈子都不可能,而正好我刚刚在一台N5105的小主机上使用docker搭建了Home Assistant智能家居中枢,Home Assistant刚好提供了Bluetooth集成,允许调用小主机自带的蓝牙发现蓝牙相关设备,让我们开始吧

修改设置映射蓝牙

如果你需要使用Bluetooth集成,HomeAssistant对蓝牙设备和系统做出了这些要求

  • 对于在Linux系统上使用蓝牙设备必须满足:

    • Home Assistant必须可访问D-Bus通讯端口

    • 蓝牙适配器必须可访问D-Bus通讯端口且BlueZ 蓝牙协议栈版本必须大于5.43,建议使用5.63或更高版本来避免一些问题

    • 系统的 D-Bus 服务(message bus daemon)应该使用 dbus-broker,而不是传统的 dbus-daemon

    • 宿主系统的Linux内核必须大于5.15.62

如果你的正在使用HAOS,那你只需要将HAOS升级到9.0以上,系统会自动处理好蓝牙部分,你可以跳过这部分直达下一部分:添加智能蓝牙设备

修改宿主系统设置

如果你像我一样在docker上运行home assistant,那么首先你需要对宿主系统做出一些修改,否则即使你映射蓝牙到home assistant的容器里Bluetooth 集成大概也会报错这个:

hci0 (10:6F:D9:31:AF:26): hci0 (10:6F:D9:31:AF:26): Failed to start Bluetooth: passive scanning on Linux requires BlueZ >= 5.56 with --experimental enabled and Linux kernel >= 5.10; Try power cycling the Bluetooth hardware.

首先你需要在宿主系统执行下面这几个命令来检查宿主系统是否满足home assistant的要求:

bluetoothctl --version
uname -r
ps aux | grep bluetoothd

第一行输出的BlueZ版本应该大于5.63,第二行输出的Linux内核应当大于5.15.62 ,如果你的输出不满足这个,请执行sudo apt update && sudo apt dist-upgradesudo pacman -Syu 来更新你的系统

如果没有安装BlueZ,可以使用sudo apt update && sudo apt install bluez来安装

接下来我们看第三行,Home Assistant要求BlueZ必须启用--experimental参数才能成功初始化蓝牙堆栈,如果你的输出像下面这样

╭─[fridayssheep@allinone:~]—{^o^}—(20:49:32)—(4ms) 
╰─$> ps aux | grep bluetoothd 
root 713 0.0 0.0 13120 7084 ? Ss 11:59 0:00 /usr/libexec/bluetooth/bluetoothd 
fridays+ 77866 0.0 0.0 6756 2312 pts/3 S+ 20:49 0:00 grep bluetoothd

可以看到bluetoothd是以默认方式启动的:

/usr/libexec/bluetooth/bluetoothd

我们需要创建bluetoothd的override文件,用我们的设置修改覆盖原有的配置

sudo mkdir -p /etc/systemd/system/bluetooth.service.d
echo -e "[Service]\nExecStart=\nExecStart=/usr/libexec/bluetooth/bluetoothd --experimental" | sudo tee /etc/systemd/system/bluetooth.service.d/override.conf
sudo systemctl daemon-reexec
sudo systemctl daemon-reload
sudo systemctl restart bluetooth

完成后再次检查

╭─[fridayssheep@allinone:~]—{^o^}—(18:37:47)—(5ms)
╰─$> ps aux | grep bluetoothd
root         715  0.2  0.0  13748  7752 ?        Ss   10月29   4:25 /usr/libexec/bluetooth/bluetoothd --experimental
fridays+  476742  0.0  0.0   6756  2340 pts/1    S+   18:37   0:00 grep bluetoothd

修改docker设置

如果你是使用docker compose配置文件,那么你只需要为homeassistant映射/run/dbus 通讯端口并配置NET_ADMINNET_RAW 权限即可

请不要直接将/dev/hci0下的蓝牙直接映射给home assistant!因为蓝牙控制器设备节点只有一个进程(通常是宿主的 bluetoothd)可以独占访问它,这样会导致宿主机丢失对蓝牙的访问!

volumes:
  - /run/dbus:/run/dbus:ro
cap_add:
  - NET_ADMIN
  - NET_RAW

如果在yaml配置文件使用 privileged: true,那就相当于隐含了所有 capabilities,等价于

cap_add:
  - ALL

如果你直接使用docker run命令启动了home assistant,请确保所有容器内文件备份正确以后使用下面的设置创建一个新的容器

docker run --cap-add=NET_ADMIN --cap-add=NET_RAW -v /run/dbus:/run/dbus:ro

添加智能蓝牙设备

在开始前,我们先介绍一下这些传感器类智能家居的连接方式:BLE (Bluetooth Low Energy)Passive / 被动连接

在BLE Passive模式下,Home Assistant或其他的网关设备不主动连接设备,而是监听设备在空气中广播(advertisement)出来的数据包,然后根据对应的协议(比如小米的Mi Beacon)解析出温度、湿度、开关状态等信息

使用Xiaomi BLE集成添加米家蓝牙设备

对于米家的MiBeacon协议,一些米家的智能设备使用AES加密来保护它们正在广播的传感器值。

  • MiBeacon v2/v3使用未认证的AES和24个字符的十六进制(12字节)密钥

  • MiBeacon v4/v5使用经过身份验证的AES,带有32个字符的十六进制(16字节)密钥

这个键被称为bindkey或beaconkey,因此我们需要拿到对应设备的key才能获得他们的传感器数据

在开始之前,请至少保证你的米家蓝牙传感器设备至少在米家添加过一次,之后前往https://github.com/PiotrMachowski/Xiaomi-cloud-tokens-extractor下载对应的key提取工具

运行key提取工具,使用二维码或账号密码登入,登入以后输入cn访问你在国内服务器的设备查询key

usercnserver.webp

记录下蓝牙设备的 MACBLE KEY

extractblekey.webp

然后前往Home Assistant的设置——>集成 ,Home Assistant会自动将扫描到的BLE设备显示在这里,点击添加

getBLEdevice.webp

如果没有弹出key配置界面而是让你等一会,可以按下设备上的按钮尝试让设备广播一次数据,待Xiaomi BLE集成提示需要重新配置时,在弹出的窗口中选择输入key,将你拥有的BLE key输入到对应MAC地址的设备中,完成后稍等五分钟,你就能在主页看到这个设备了

addedBLEdevice.webp

使用Passive BLE集成添加其他品牌的蓝牙设备

设备和集成配置中搜索添加Passive BLE Monitor集成

searchBLEPassive.webp

adddevice.webp

  1. 勾选要使用的蓝牙接口的MAC 地址(宿主上的蓝牙MAC地址,一般不用修改),如果你有开源ESPHome通用蓝牙网关就勾选Don't use Bluetooth adapter让其传入数据.

  2. 勾选自动发现设备及传感器后会自动添加发现的蓝牙传感器设备(只能添加没有加密的设备)

  3. 对于使用加密数据传输数据的设备,还是必须到最下面的设备选择Add devices...

  4. 点击提交按钮.

  5. 如果选择了添加设备,这时候会弹出配置设备对话框

  • 输入蓝牙设备的MAC地址,如果是Beacon输入Beacon的UUID

  • 输入加密密钥,如果有的话

  • 最后点击提交按钮

inputkeyandmac.webp

添加后,同样稍等五分钟,你就能在主页看到这个设备了