tfohlmeister/berbel-remote

GitHub: tfohlmeister/berbel-remote

基于 ESP32 的 BLE 遥控器模拟器,通过逆向工程 Berbel 抽油烟机协议并桥接 MQTT,实现 Home Assistant 智能家居集成。

Stars: 11 | Forks: 3

# Berbel BFB 6bT - BLE 遥控器模拟器 [![tests](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/b27ffc2388204845.svg)](https://github.com/tfohlmeister/berbel-remote/actions/workflows/test.yml) 基于 ESP32 的 **Berbel BFB 6bT** 遥控器(货号 1090045)模拟器,通过 MQTT 实现完整的 Home Assistant 集成。已通过 Berbel Skyline Frame 抽油烟机测试,但 BFB 6bT 遥控器同样兼容其他 Berbel 抽油烟机。 ## 功能特性 - **BLE 遥控模拟** - 完整模拟原版 Berbel BFB 6bT 遥控器 - **Home Assistant 集成** - 通过 MQTT 自动发现自动创建实体 - **实时状态解码** - 读取来自抽油烟机的 9 字节状态数据包(灯光、风扇、位置、延时运行) - **OTA 更新** - 通过 ArduinoOTA 进行无线固件更新 - **NimBLE 协议栈** - 相比 Arduino BLE (Bluedroid) 节省了约 100KB 的堆内存,为 WiFi + MQTT 留出了空间 ## 兼容的抽油烟机 BFB 6bT 遥控器适用于配备了 **berbel Connect 2.0**,且生产日期在 **2020 年 11 月**之后的 Berbel 抽油烟机。只要支持原版遥控器的抽油烟机,本模拟器应该都能兼容。 **岛式抽油烟机:** Skyline Frame, Skyline Edge, Skyline Curve, Skyline Sound, Skyline Light, Skyline Round, Ergoline, Glassline, Blockline, Smartline **壁挂式抽油烟机:** Glassline, Blockline, Smartline **紧凑型抽油烟机:** Ergoline, Glassline, Formline, Smartline **内置式抽油烟机(2021 年 4 月起):** Glassline, Firstline, Firstline Touch, Firstline Unseen **风机模块(2021 年 4 月起):** Firstline ## 硬件要求 - ESP32 开发板(任何带有 BLE + WiFi 的型号) - 兼容的 Berbel 厨房抽油烟机(见上述列表) - MQTT broker(例如 Mosquitto) - Home Assistant(可选,用于智能家居控制) ## 快速开始 1. **克隆并配置:** git clone https://github.com/tfohlmeister/berbel-remote.git cd berbel-remote/BerbelRemote cp src/config.example.h src/config.h 2. **编辑 `src/config.h`**,填入您的 WiFi 和 MQTT 凭证。如果您的抽油烟机没有伸缩罩(升降功能),请将 `HOOD_HAS_COVER` 设置为 `false`,以禁用 Position、Hochfahren、Herunterfahren 和 Cover State 实体。 3. **构建并烧录:** pio run -t upload # USB(首次烧录) pio run -e ota -t upload # OTA(后续更新) 4. **与抽油烟机配对:** - 使抽油烟机进入配对模式(在 Skyline Frame 上:同时按住机身上的电源键和灯光键 5 秒钟;其他型号可能有所不同) - ESP32 将自动连接 - 连接成功后,板载 LED 将停止闪烁 5. **监控:** pio device monitor ## Home Assistant 实体 所有实体均通过 MQTT 自动发现自动创建。 | 实体 | 类型 | 描述 | |--------|------|-------------| | Oberlicht | Light | 上部/氛围灯开关 | | Unterlicht | Light | 炉灶照明灯开关 | | Lufter | Select | 风扇速度:Aus, Stufe 1-3, Power | | Ausschalten | Button | 关闭电源(启动延时运行计时器) | | Nachlauf | Switch | 切换延时运行计时器 | | Position | Select | Oben(收回) / Unten(展开) *(仅限 `HOOD_HAS_COVER`)* | | Hochfahren | Button | 无条件上升 *(仅限 `HOOD_HAS_COVER`)* | | Herunterfahren | Button | 无条件下降 *(仅限 `HOOD_HAS_COVER`)* | | BLE Verbindung | Binary Sensor | BLE 连接状态(诊断) | | Cover State | Sensor | 盖板位置:up/moving up/moving down/down(诊断) *(仅限 `HOOD_HAS_COVER`)* | | Status Raw | Sensor | 用于调试的原始 9 字节十六进制数据(诊断) | ## 按键代码 BFB 6bT 遥控器上全部 13 个按键的完整映射关系,附带 Berbel 手册中的官方功能名称。 | 代码 | 遥控器标签 | 官方功能(Berbel 手册) | |------|-------------|-----------------------------------| | 0x01 | Power | EIN/AUS | | 0x02 | Fan 1 | Leistungsstufe 1 | | 0x03 | Fan 2 | Leistungsstufe 2 | | 0x04 | Fan 3 | Leistungsstufe 3 | | 0x05 | Fan P | Leistungsstufe POWER | | 0x06 | Cooktop Light | Kochfeld-Beleuchtung | | 0x07 | Sync | Synchronisation | | 0x08 | Recirculation | Umluftbetrieb / Kontrollanzeige Filter | | 0x09 | Raise | Liftfunktion "Heben" | | 0x0A | Effect Light | Effektbeleuchtung | | 0x0B | Multi | Multifunktionstaste | | 0x0C | Afterrun | Nachlauffunktion | | 0x0D | Lower | Liftfunktion "Senken" | 协议:在特征值 `f004f002-...-berbel` 上进行 2 字节通知。按下:`[code, 0x00]`,松开:`[0x00, 0x00]`。 ## 抽油烟机状态字节 抽油烟机会在特征值 `f004f001-...-berbel` 上发送 9 字节的状态数据包。所有值均基于位掩码。 | 字节 | 掩码 | 含义 | |------|------|---------| | [0] | 0x10 | Fan Stufe 1 | | [1] | 0x01 | Fan Stufe 2 | | [1] | 0x10 | Fan Stufe 3 | | [2] | 0x09 | Fan Power | | [2] | 0x10 | Oberlicht(上部灯) | | [4] | 0x10 | Unterlicht(炉灶灯) | | [4] | 0x01 | 盖板正在上升(收回) *(仅限 `HOOD_HAS_COVER`)* | | [5] | 0x90 | Nachlauf(延时运行计时器已激活) | | [6] | 0x01 | 盖板正在下降(展开) *(仅限 `HOOD_HAS_COVER`)* | 在连接时会发送同步数据包(所有字节均为 `0x11`),应将其忽略。 ## BLE 协议摘要 ### MAC 地址 OUI 过滤 抽油烟机仅接受来自具有 Texas Instruments OUI 的设备的连接: - `88:01:F9:xx:xx:xx` - `30:AF:7E:xx:xx:xx` ESP32 的 MAC 地址会在 BLE 初始化之前被伪装: ``` uint8_t ti_mac[6] = {0x88, 0x01, 0xF9, 0xAA, 0xBB, 0xCC}; esp_base_mac_addr_set(ti_mac); // BEFORE NimBLEDevice::init() ``` ### 配对 - 传统配对(无安全连接) - Just Works(无输入,无输出) - 仅 LTK(无 IRK,无 CSRK) - 抽油烟机作为 Central(发起配对) ### GATT 服务顺序 必须严格按照此顺序创建服务(抽油烟机会进行验证): 1. Device Information (0x180A) 2. Battery Service (0x180F) 3. HID Service (0x1812) 4. Berbel Custom Service (`f004f000-...-berbel`) ### 广播 仅使用带有 Flags + Service Data 的原始 `ADV_IND`。没有设备名称,没有 HID UUID,没有外观。Service Data 的值必须为 `0x01`(活动状态)。 ## 逆向工程过程 1. 使用 **nRF52840 Dongle** 作为嗅探器,结合 **Wireshark/nRF Sniffer 插件**,捕获了原装遥控器与抽油烟机之间的 BLE 通信流量 2. 分析了广播数据、GATT 服务结构和 SMP 配对交换过程 3. 通过反复试验发现了 MAC OUI 过滤机制(带有 Espressif OUI 的 ESP32 会被静默拒绝) 4. 通过按下每个按键并记录通知,映射了全部 13 个按键代码 5. 通过系统地切换每个功能,解码了 9 字节的抽油烟机状态数据包 6. 使用另一个遥控器(不同的 TI OUI,但协议完全相同)确认了这些发现 有关完整的协议文档,包括 GATT 服务表、广播数据以及 Wireshark 分析命令,请参阅 [REVERSE_ENGINEERING.md](REVERSE_ENGINEERING.md)。 ## 项目结构 ``` berbel-remote/ ├── BerbelRemote/ # ESP32 firmware (PlatformIO) │ ├── src/ │ │ ├── main.cpp # Firmware: BLE/WiFi/MQTT wiring │ │ ├── berbel_protocol.h # Pure protocol logic (unit-tested) │ │ ├── config.example.h # WiFi/MQTT config template │ │ └── config.h # Your credentials (gitignored) │ ├── test/ │ │ └── test_protocol/ # Host-side unit tests (Unity) │ └── platformio.ini # Build configuration ├── .github/workflows/test.yml # CI: unit tests + firmware build ├── REVERSE_ENGINEERING.md # Full protocol documentation ├── berbel_button_map.json # Button code mapping (machine-readable) ├── LICENSE # MIT License └── README.md ``` ## 测试 逆向工程得出的协议逻辑(状态解码、风扇/盖板状态、JSON 解析)位于 `src/berbel_protocol.h` 中,作为无依赖函数存在,因此 可以在没有 ESP32 的情况下在主机上进行单元测试: ``` cd BerbelRemote pio test -e native ``` CI 会在每次推送时运行这些测试以及完整的固件编译检查(参见 顶部的测试徽章)。硬件 I/O(BLE、WiFi、MQTT、OTA)在 设备上进行测试,而不是在 CI 中。 ## 许可证 本项目采用 [MIT 许可证](LICENSE) 授权。 ## 免责声明 这是一个基于私人逆向工程工作的非官方社区项目。它与 **berbel Ablufttechnik GmbH** 没有任何形式的附属、认可或关联关系。 所有商标,包括 "Berbel",均属于其各自的所有者,此处使用它们仅用于描述兼容性。 对于您的硬件可能受到的任何损坏,作者不承担任何责任。使用风险由您自己承担。
标签:ESP32, Home Assistant, 智能家居, 物联网, 蓝牙低功耗