【问题标题】:How to use bluetoothctl to report repeated proximity beacons in real time using MQTT如何使用 bluetoothctl 使用 MQTT 实时报告重复的接近信标
【发布时间】:2021-03-09 06:41:13
【问题描述】:

就目前而言,这是一个很好的解决方案:

How to use bluetoothctl like hcitool lescan to report repeated proximity beacons

不过,我想更进一步:我不想将信标检测结果打印到终端,而是将每个检测到的信标的 MAC 地址通过管道传送到将其发布到 Mosquitto 代理的命令。这对于将信标添加到 HomeAssistant 很有用,例如,用于检测连接到一个人的房屋钥匙的密钥卡的存在。我设法通过修改上面脚本的最后两行来实现这个想法,但它只发布了第一个检测......然后就没有了。我猜想通过尝试运行 mosquitto_pub 命令以某种方式关闭或中止扫描。 (与中断线程或子shell有关???)

这是脚本的最后几行,其中我的两个测试信标的 MAC 地址被混淆了。 您可以在上面的链接中看到我修改的完整脚本。

) | sed --unbuffered --quiet --expression 's/^.*Device //p' \
| grep --line-buffered -E 'FF:FF::::|FF:GG::::' \
| stdbuf -oL cut -c 1-17 \
| { read topic; mosquitto_pub -d -u username -P password -m ON -t monitor/$topic; }

注意: | stdbuf -oL cut -c 1-17 \ 将输出修剪为仅 MAC 地址 - 例如FF:GG::::

最后一行将 ON 命令发布到以信标 MAC 地址结尾的唯一状态主题,例如'监视器/FF:GG::::'。

如果我删除最后一行,则随着时间的推移,检测结果会在终端控制台中添加到不断增长的列表中。但是一旦我添加了最后一行,它只能工作一次,然后就死了。

如何使脚本响应每个检测,而不仅仅是第一个检测? 为什么它只响应第一次检测然后挂起?

【问题讨论】:

  • 似乎bluetoothctl 从未设计为以这种方式工作,并且命令管道的深度使得调试和维护变得非常困难。蓝牙信标的扫描可以通过大多数语言的 BlueZ D-Bus API 进行访问。这是python example。还有各种语言的MQTT clients

标签: bluetooth beacon scanning


【解决方案1】:

BlueZ 的命令行工具不是为此目的而设计的,因此很难可靠地管道扫描结果。根据我的经验,进程死亡或挂起,最终导致管道损坏。

BlueZ 的 C API 更加稳定。为此,我用 C 语言编写了一个简单的命令行程序,您可以使用它来代替 bluetoothctl:

https://gist.github.com/davidgyoung/0a18028b4338ff6cb201fba274502662

该程序必须使用cc scanner.c -lbluetooth -o scanner 编译,之后您可以使用scanner 启动扫描程序。程序的输出将是这样的:

B8:27:EB:1F:93:4D -68 02 01 06 11 06 82 75 25 D9 37 9D D7 8F 5F 4A F4 20 00 00 75 30
71:5C:23:9D:BC:7F -68 02 01 1A 02 0A 0C 0B FF 4C 00 10 06 03 1A 3B D4 B2 EB
B8:27:EB:1F:93:4D -68 02 01 06 11 06 82 75 25 D9 37 9D D7 8F 5F 4A F4 20 00 00 75 30
4A:53:7F:64:71:EC -91 03 03 9F FE 17 16 9F FE 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
69:0D:FF:7B:75:65 -73 02 01 1A 02 0A 0C 0A FF 4C 00 10 05 03 1C 27 BB 63
61:39:71:E9:1D:C9 -93 02 01 1A 02 0A 18 0A FF 4C 00 10 05 01 18 3B 24 12
B8:27:EB:1F:93:4D -68 02 01 06 11 06 82 75 25 D9 37 9D D7 8F 5F 4A F4 20 00 00 75 30

上面的每一行显示检测到的蓝牙设备的 MAC 地址,然后是信号强度 RSSI,然后是广告的十六进制字节。

我使用这个程序来管道到其他 shell 脚本,并且发现它在很多天里都是可靠的。如果有帮助,请随意使用。

【讨论】:

  • 感谢您的时间和兴趣。这真是一个棘手的问题!我尝试了您的脚本,它按预期工作,但它似乎在几秒钟到一两分钟后挂起或崩溃。我尝试将结果通过管道传递给 MQTT 发布命令,但同样,它仅适用于第一次检测,然后返回命令提示符,所以我猜它要么崩溃要么挂起?
  • 您需要在命令退出时重复生成命令。它被设计为在固定数量的检测后退出。如果您愿意,您可以修改源代码以使其不那样做——这很简单。
猜你喜欢
  • 2016-08-05
  • 2018-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多