请选择 进入手机版 | 继续访问电脑版

『瀚思彼岸』» 智能家居技术论坛

 找回密码
 立即注册
查看: 15372|回复: 33

[技术探讨] 【足够强大】ESPHome+ESP32打造通用蓝牙网关,比小米自家的好

  [复制链接]

103

主题

2899

帖子

1万

积分

超级版主

智能家居&单板滑雪痴迷爱好者

Rank: 8Rank: 8

积分
11635
金钱
8671
HASS币
460

教程狂人突出贡献

发表于 2022-5-8 21:22:39 | 显示全部楼层 |阅读模式
本帖最后由 XCray 于 2023-4-26 18:56 编辑

玩ESPHome已经一年多了,碰到了很多问题,有的解决了,有的放弃了,有的耿耿于怀至今。。。

简单小结一下蓝牙通用网关

其实说通用有一点点夸张哈,大部分使用蓝牙广播的设备都可以接入,由于esphome的限制,基于ble_client的还不能与基于广播的用一个esp32搞定。

我自己现在在用的设备可以分为两类:

1. ESPHome内置组件,根据文档直接在yaml里面配置即可:
- 花花草草传感器
- 蓝牙温湿度计2
- 云米燃气灶
2. 自制组件(把ESPHome内置组件拿来修改),把代码保存至指定目录后与前面的设备一起在yaml里配置,即一个esp32即可:
- 榉树门锁
- yeelight调光开关
- 云麦好轻体脂秤
这几个代码之前已经发过帖子,感兴趣的找来看吧。

~~~~~~~~~~~~~~~~~~~~~~~~~
重点说说一个难题,就是广播扫描参数的设置问题。前期试过多种设置,总会偶尔发生收不到设备发出的广播消息的现象

其它设备都还好,或者说偶尔丢一次消息无所谓,最关心的是蓝牙门锁,一次也不想错过。

错过门锁广播消息的现象,大概十几天能观察到一次,而同时在用小米的蓝牙网关却每次都能收到。

这几个组件都是基于 esp32_ble_tracker 的,反复阅读官方文档以及其中提到的TI的文档,可能影响的参数就两个:
扫描间隔和扫描窗口

esphome默认的设置分别时320ms和30ms,丢消息的现象比较明显;目前我在用的是160/120ms,有明显改善,但仍然会丢。

一个极端的想法是把扫描窗口设置为和扫描间隔一样大,但必须把网络连接方式改成以太网,难度太大。

如果继续使用WiFi,那么注定扫描窗口就必须小于扫描间隔(必须为WiFi预留出必要的时间),也就意味着这个简单的思路总会有错过蓝牙广播消息的可能。

小米自己的网关也是用的WiFi,它是怎么设置能够做到不错过广播消息的呢?一直也没有看到有具体的说明,小米设备蓝牙广播的参数设置也没看到过说明

那么我们应该怎么设置才好呢?耗电的事情都可以完全忽视,只求不错过广播消息!
~~~~~~~~~~~~~~~~
根据TI的文档(详见),简单描述一下技术背景:

广播发送设备可以设置使用1~3各广播信道、也可以设置广播间隔(20ms~10.24s),每次在一个信道上的广播最多需要10ms:

                               
登录/注册后可看大图

而广播接收侧不能选择信道,必须3个信道顺序扫描:

                               
登录/注册后可看大图


~~~~~~~~~220621补充~~~~~~~~~
把间隔设置为120ms、窗口设置为100ms,已经观察了两个多月了,未再发生丢消息的现象,wifi连接也没啥问题,感觉基本可以解决之前头疼的问题了。

~~~~~~~~~230426补充~~~~~~~~~
ESPHome自2022.12.x版本开始,存在严重bug,个人能力有限无法判定具体问题,但现象很明确:
运行5个小时左右会出现蓝牙功能失效,就是esp32硬件本身还在运行,但不再接收解析任何蓝牙消息,其他功能正常。只有断电重启才能恢复,然后过几个小时又会出现(2023.3.x~2023.4.x好像若干小时会自行崩溃重启)。


经多次尝试,发现最后一个稳定可靠的版本是2022.11.5。
另外,论坛里有些朋友用于连接LD2410B,也存在非常相像的问题,怀疑根因是一个(帖子)。


供参考。
回复

使用道具 举报

103

主题

2899

帖子

1万

积分

超级版主

智能家居&单板滑雪痴迷爱好者

Rank: 8Rank: 8

积分
11635
金钱
8671
HASS币
460

教程狂人突出贡献

 楼主| 发表于 2022-5-21 17:00:14 | 显示全部楼层
trz0332 发表于 2022-5-15 21:42
其实我也遇到了这个问题,自己diy的蓝牙称的时候也出现了有时候扫描不到蓝牙广播,,一直无解,后来就放弃 ...

我最近在用的配置:
wifi:
  ssid: $wifi_ssid
  password: $wifi_password
  fast_connect: on
  reboot_timeout: 23min
  
esp32_ble_tracker:
  scan_parameters:
   interval: 120ms
   window: 100ms


每次蓝牙广播的时长接近 30ms,我现在只拿出20ms给wifi(只有一个ssid故不用扫描),应该可以达到不错过蓝牙广播的效果,这几天用着还行,wifi没啥异常、也没碰到丢消息的现象,继续观察ing
回复

使用道具 举报

23

主题

137

帖子

712

积分

高级会员

Rank: 4

积分
712
金钱
575
HASS币
0
发表于 2022-5-8 23:52:03 来自手机 | 显示全部楼层
请善用论坛的搜索功能,你的求助一搜就有答案。  可参考下以下这贴:https://bbs.hassbian.com/forum.php?mod=viewthread&tid=16331&highlight=esp32&mobile=2

评分

参与人数 1金钱 +1 收起 理由
XCray + 1 这位好像很厉害的样子啊

查看全部评分

回复

使用道具 举报

103

主题

2899

帖子

1万

积分

超级版主

智能家居&单板滑雪痴迷爱好者

Rank: 8Rank: 8

积分
11635
金钱
8671
HASS币
460

教程狂人突出贡献

 楼主| 发表于 2022-5-9 06:43:47 | 显示全部楼层
本帖最后由 XCray 于 2022-5-9 07:25 编辑

TI的文档中有一段有些参考价值:
Optimizing Scanning: How to get data fast?
In a time-constrained application, when the user needs to receive the data as fast as possible, make sure that scanning window is more than the advertising interval + 10ms to guarantee discovery. (The 10 ms extra account for the 0 ms to 10 ms of pseudo-random delay in between each advertising event, assuming no interference.) Following this rule will increase the chance of receiving the advertising packet on the first scan.

就是扫描窗口要大于发射间隔再加10ms,问题是找不到小米关于广播间隔的说明呀!
回复

使用道具 举报

39

主题

2081

帖子

7814

积分

元老级技术达人

积分
7814
金钱
5718
HASS币
110
发表于 2022-5-9 08:39:32 | 显示全部楼层
XCray 发表于 2022-5-9 06:43
TI的文档中有一段有些参考价值:
就是扫描窗口要大于发射间隔再加10ms,问题是找不到小米关于广播间隔的说 ...

不是很懂
来个不负责的猜测:
小米门锁会强制在扫描窗口发送报文
网关和门锁肯定有授时报文(门锁的远程设置密码就是根据时间来的,指定时间内有有效期)
如果两端能保证时间一致(就算差个几ms)
那么就可以做到门锁在扫描窗口发送报文
回复

使用道具 举报

103

主题

2899

帖子

1万

积分

超级版主

智能家居&单板滑雪痴迷爱好者

Rank: 8Rank: 8

积分
11635
金钱
8671
HASS币
460

教程狂人突出贡献

 楼主| 发表于 2022-5-9 10:00:01 | 显示全部楼层
ghostist 发表于 2022-5-9 08:39
不是很懂
来个不负责的猜测:
小米门锁会强制在扫描窗口发送报文

你把它想的太好了

网关和门锁没有授时机制,甚至网关里根本没有时钟(它当然有晶振但不知道年月日时分秒)。远程临时密码是半小时有效的,对时钟同步的要求很低,并且只是是根据固定算法生成的。

手机app倒是可以校准门锁内的时钟。

让门锁主动在网关的扫描窗口发送报文,这个可以肯定是不可能的
回复

使用道具 举报

19

主题

290

帖子

1508

积分

论坛技术达人

积分
1508
金钱
1203
HASS币
130
发表于 2022-5-9 18:05:54 | 显示全部楼层
很难了,你这个配置已经接近极限了,除非单独WIFI/蓝牙独立通道, 另外小米用的是ESP32芯片么? 在手机/电脑/笔记本/盒子上可以看看会不会漏(非ESP32芯片). 如果ESP32上要作蓝牙持续扫描,除非禁用wifi.

另外那个duration没有搞懂是啥意思. 和wifi啥关系?
回复

使用道具 举报

103

主题

2899

帖子

1万

积分

超级版主

智能家居&单板滑雪痴迷爱好者

Rank: 8Rank: 8

积分
11635
金钱
8671
HASS币
460

教程狂人突出贡献

 楼主| 发表于 2022-5-10 07:41:54 | 显示全部楼层
ryanh7 发表于 2022-5-9 12:59
重发次数和重发间隔定义在小米蓝牙模组,sdk或者基于esp32的蓝牙网关的固件总得搞到一个,或许能从里面提取 ...

逆向难度太大了。

没接触过小米的模组和sdk,现有公开的资料又没有涉及到这么细的细节

不切实际地期待业内人士透露吧。。。
回复

使用道具 举报

103

主题

2899

帖子

1万

积分

超级版主

智能家居&单板滑雪痴迷爱好者

Rank: 8Rank: 8

积分
11635
金钱
8671
HASS币
460

教程狂人突出贡献

 楼主| 发表于 2022-5-10 07:52:35 | 显示全部楼层
riceball 发表于 2022-5-9 18:05
很难了,你这个配置已经接近极限了,除非单独WIFI/蓝牙独立通道, 另外小米用的是ESP32芯片么? 在手机/电脑/笔 ...

是的,除非用以太网,否则wifi和蓝牙公用一个天线,总会有空挡无法进行扫描。在和发射侧无法良好匹配的情况下,错失消息在所难免。

小米有多种型号的蓝牙模组,其中也有esp32,可惜搞不到sdk。

在电脑上搞个程序思路倒是不错,可是实现难度好像更大(编程基础太差),另外漏掉消息的现象几率很低,得长期观察才行。

那个duration根据文档,似乎没有任何实际影响,仅用于蓝牙栈的调试,默认5分钟也很长了。
回复

使用道具 举报

19

主题

290

帖子

1508

积分

论坛技术达人

积分
1508
金钱
1203
HASS币
130
发表于 2022-5-10 09:58:47 | 显示全部楼层
XCray 发表于 2022-5-10 07:52
是的,除非用以太网,否则wifi和蓝牙公用一个天线,总会有空挡无法进行扫描。在和发射侧无法良好匹配的情 ...

电脑上如果测试用 bluetoothctl 即可,写个简单的 bash 脚本 记录下来, 就可进行对比比较. 如果喜欢用python,也有Bluetoothctl wrapper: https://gist.github.com/egorf/66d88056a9d703928f93

另外 可以读读 ble_monitor 的代码, 它使用的是python的异步`aioblescan`蓝牙扫描库,专门用于接收蓝牙广播消息,安装模块后可以直接使用:

```bash
pip3 install aioblescan
aioblescan -h
# or run python3 -m aioblescan
```
回复

使用道具 举报

103

主题

2899

帖子

1万

积分

超级版主

智能家居&单板滑雪痴迷爱好者

Rank: 8Rank: 8

积分
11635
金钱
8671
HASS币
460

教程狂人突出贡献

 楼主| 发表于 2022-5-10 10:44:46 | 显示全部楼层
riceball 发表于 2022-5-10 09:58
电脑上如果测试用 bluetoothctl 即可,写个简单的 bash 脚本 记录下来, 就可进行对比比较. 如果喜欢用pyth ...

翻了翻aioblescan的源码,它考虑的更简单,基本就是 window = interval

对于使用以太网、或者wifi和蓝牙独立天线的情况下当然没问题,但esp32肯定不行,window 太接近 interval 都会导致wifi链接出问题。我现在给wifi留了1/4,感觉再压缩的空间已经不大。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Hassbian

GMT+8, 2024-5-19 13:47 , Processed in 1.969322 second(s), 36 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表