为Home Assistant添加蓝牙适配器

Linux装驱动初体验

源起

最近整上了Docker版的Home Assistant,寻思把家里的米家温湿度计2接入进来。开始想的是用esp32做蓝牙代理,后来想想,家里才多大点面积,NAS又在客厅,插个USB蓝牙适配器估计就能覆盖到全屋了。

然后着手挑选适配器,淘宝一搜,嘿,9块9包邮到99块的五花八门啥样都有,真是丰俭由人。考虑到NAS是debian系统,华强北三无产品大概率不会管Linux下驱动适配的问题,google英文关键词搜了一下,发现一款MPOW的BH519A,支持到蓝牙5.1,官方明确支持Windows和Linux。淘宝上一搜,居然只有一家店在清库存,好奇的搜了下这个牌子,好家伙,居然是深圳的公司,因为产品被亚马逊下架了,干脆出口转内销,国外售价5-10刀,最终闲鱼到手25元。

开始折磨

东西到手,先插到Win10主力机上看看功能是否正常,结果发现并不是免驱,还是得手动装下驱动。虽然它非常讲究的随包装送了一张驱动光盘,但是今年是2022年,想找一台光驱恐怕不是很现实,打开官网翻了一下,发现下架产品居然官网上居然没有驱动下载地址,惊了。还好可以BH519A+driver关键词google之,果然很快找到了第三方网站备份的驱动。Win10简单测了一下一切ok,拔了插到NAS上,lsusb识别到Realtek Semiconductor Corp. Bluetooth Radio,事先做过功课,主控是Realtek螃蟹厂的RTL8761B,看起来没什么问题,hciconfig -a也能看到有一个名叫hci0的usb蓝牙设备,但是bluetoothctl && scan on显示没有设备可供扫描,想到前面Win10的情况,估计还是得自己打驱动。下好了Linux版驱动,按照国外Linux论坛上的安装办法,把对应主控名的bin文件复制进lib/firmware,再顺便按照Home Assistant官方的蓝牙适配器接入教程,docker容器暴露/run/dbus:/run/dbus:ro然后reboot。兴致满满打开HA管理后台一看,寄,并不能识别到适配器。

反复折磨

反复确认了自己没复制错路径之后,想了下,总觉得哪里不对,难道装驱动不应该有写入模块的操作么?仅仅复制两个文件进去系统真的能加载到么? 于是又打开驱动目录仔细看了看,发现有个安装说明文档,甚至还有一份写好的安装脚本,激动的立刻运行,结果make install报错:找不到/lib/modules/5.16.0-0.bpo.3-amd64/build目录,google之发现需要对应内核版本的linux-headers-<version>包,apt install一下发现并没有5.16版本的包,怪起来了。

陷入僵局之后突然想到,之前为了体验新版smb,好像是自己手动装的5.16内核,这样一看apt里没有这个版本的包好像也确实很合理。但是手动去找这个版本的headers包好像很麻烦的样子,干脆直接把内核升到backdrop源最新版本算了,这样对应的headers肯定也会在apt里有收录。 经过一顿操作,新6.0内核和对应的headers包都顺利装上了,赶紧再重新执行下驱动包里的安装脚本,嘿,这次终于顺利装上了,又看到log里有模块操作的痕迹,信心+5! reboot之后立刻HA后台看一眼,多了一个hci0蓝牙设备,芜湖~再跑一下scan on,开始显示周边蓝牙设备了,折 腾 大 成 功!

补充

中间折磨的时候看了很多国外Linux论坛同款适配器驱动安装问题的反馈,奇怪的是,似乎没有一种通用的、成功率比较高的安装方式。甚至还有一个老哥说全网所有方法他都试过了,最后改了驱动包里源码才成功装上,当时已经走投无路的我也是死马当活马医,按他帖子里的说法也改了源码,不过最后安装成功我也不太确定是不是这个方法救活的。

这里把帖子链接和内容存个档,万一下次…

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
I have the same MPOW adaptor (BH519A) with Realtek chipset RTL8761BU. My kernel version is 5.11 on ubuntu 20.04. Exhausted every solution I can find on the internet and only the one posted by @meavydev worked.

To be precise:
1. Go to the downloaded linux driver folder (20201202_LINUX_BT_DRIVER/usb/bluetooth_usb_driver)
2. edit rtk_misc.c.
3. Look for the code block: static patch_info fw_patch_table[]
4. Add the line: {0x2550, 0x8761, "mp_rtl8761b_fw", "rtl8761bu_fw", "rtl8761b_config", NULL, 0}, /* RTL8761BU only */
5. Save and close the file.
6. Run sudo make install INTERFACE=usb from 20201202_LINUX_BT_DRIVER/usb.
7. hciconfig will now show the device and bluetooth works as intended after that.

2023.05.30 追加

由于换了新内核(6.0.12-with.ntfs3-rt14),蓝牙适配器驱动挂掉了,回头又找出自己这篇记录。 现在看来,自己当时操作真是无头苍蝇,简单梳理一下:

本文开头提到的方法:

按照国外Linux论坛上的安装办法,把对应主控名的bin文件复制进lib/firmware

其实就是使用预编译驱动,根据readme中的说明,预编译驱动可以支持2.6.32-5.7.1的kernel,而当时我已经是5.16.0,所以这种方式失败了。

然后是:

发现有个安装说明文档,甚至还有一份写好的安装脚本…

这里的“安装脚本”实际上是编译驱动的脚本,由于厂商的linux驱动包非常贴心,不仅有编译好的驱动,还有一套完整的源码,所以理论上不管我们使用什么版本的kernel,都能编译出对应的驱动。

显然对于6.0.12内核,只能自行编译。补好对应版本的linux-header包之后,顺利编译好了驱动,结果适配器依旧不能正常工作。 这时看到最后那段,手动给源码rtk_misc.c补上一行,再次编译,重启,果然一切正常了。 看来这个源码确实是有点问题的,上次能成功也是因为改了源码。

现在回想一下,一开始我的选择真是英明啊,如果当时随便找个品牌,贵不说,linux驱动厂商不一定提供,就算提供了,也不见得会给源码,只有预编译驱动的话,也就意味着能使用的内核版本也锁死了,到时候就是新内核feature和适配器驱动两难选择题了。

Licensed under CC BY-NC-SA 4.0
Built with Hugo
主题 StackJimmy 设计