破解我的云控吊扇的射频遥控

Hacker News Top 新闻

摘要

一位开发者对Dreo云控吊扇的射频遥控器进行逆向工程,以实现通过Home Assistant的本地控制,从而绕过云依赖,并记录了解码和重放命令的过程。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/06/30 21:39

# RF破解我的云控吊扇 · Sam Wilkinson 来源:https://samwilkinson.io/posts/2026-06-24-rf-hacking-dreo ## RF破解我的云控吊扇 2026年6月24日 · 8分钟阅读 搬进现在的住处后,我们很快就想换掉卧室的吊扇。那家伙几乎占了天花板四分之一,晃得厉害,而且我根本搞不清那三根(!)拉绳分别控制什么。必须换掉。 一番搜索后,Dreo 的这款吊扇(型号 CLF513S)看起来不错。价格合理,外观漂亮,最重要的是尺寸正常。 过去几年我一直热衷于智能家居,以 Home Assistant 为核心平台,所以希望能把新风扇加入我的系统。遗憾的是,Dreo 的智能家居集成默认仅支持云端。不过,他们维护了一个官方的 Home Assistant 集成,这点值得加分。 我尽可能避免使用基于云的智能家居控制,原因如下: - 网络中断会导致设备无法工作。 - 你常常会被锁定在充满广告的专用应用中,而绕过这些应用的集成可能不稳定。 - 让外部服务器控制家里的实物,感觉总有点不对劲。 风扇外观时尚且价格实惠,我忍了忍还是买下了,希望安装后能找到本地控制的方法。 ## 选择本地控制的路径 在探索本地控制的选项时,我发现了 GitHub 上 `ouaibe` 的出色项目,他们通过令人印象深刻的固件逆向工程,在另一款 Dreo 风扇上成功运行了 ESPHome。 虽然我可以尝试跟着他们的步骤,在我的吊扇上复制他们的方法,但一想到可能把直连在天花板上的东西变砖,就打了退堂鼓。 风扇唯一的本地控制方式就是遥控器,所以我打算走“万能遥控器”路线:解码遥控器的指令并重放它们。万能遥控器是出了名的可靠产品,显然我没走错路。 Dreo 遥控器 遥控器不需要视线对准,所以不像电视遥控器那样使用红外线。查阅背面标注的 FCC ID 后确认它是一个射频发射器。 为了实现通过 Home Assistant 进行本地控制,我需要完成三步: 1. 解码遥控器的 RF 指令。 2. 构建一个能重放这些指令的设备。 3. 让 Home Assistant 触发这些重放。 确定了方法后,第一步是弄清楚遥控器到底发送了什么信号。 ## 解码指令 要解码一个(简单的)RF 控制方案,你需要确定三件事: 1. **载波频率**:用于通信的基础频率。 2. **调制方式**:如何通过载波频率传输 1 和 0。 3. **有效载荷**:遥控器发送的实际 1 和 0 比特序列。 根据制造商 FCC 文档找到载波频率(433.92 MHz,遥控器常用频率)后,下一步是弄清楚调制方式。 遥控器常用的两种数字调制方式是: - **幅移键控 (ASK)**:发射机通过升高和降低载波振幅来表示 1 和 0。一种简单形式是**开关键控 (OOK)**,即载波直接打开和关闭。 - **频移键控 (FSK)**:发射机将信号频率略微高于和低于载波频率,以表示 1 和 0。 这跟 AM 与 FM 收音机的基本概念相同,但处理的是数字信号而非模拟音频。FCC 文档 *声称* 遥控器使用 FSK,但我想实际验证信号,而不是盲目相信文档。通常这些文档会使用通用值,所以它们并不是最可靠的来源。 我使用 RTL-SDR(配合 gqrx)在按下遥控器按钮时捕获 RF 频谱数据。结果清楚地表明遥控器使用的是 ASK(具体来说是 OOK):在载波频率上出现高振幅脉冲,中间是静默。下面是水平旋转的水声图,显示了按下风扇开/关按钮两次时捕获的频谱。 水声图 通过下方的图表更详细地查看捕获数据,信号似乎使用短脉冲和长脉冲的振幅变化,有点像摩斯电码的点与划。 OOK 比特 放大一次按钮按下,我发现一个特定模式在快速连续重复五次。下面的图表显示了一次重复,然后我可以将其解码为逻辑 1 和 0。对每个我想复制的按钮(风扇开/关、风扇速度预设、灯光开/关、亮度升/降)重复这个过程。 开/关指令解码 每个指令的结构相同,单个数据包重复五次,重复间隔为 8.8 毫秒: - **前导码**:8 个逻辑 0。 - 共享的 **20 位同步** 短语。 - 唯一的 **13 位有效载荷**,指定指令。 例如,风扇开/关按钮的有效载荷是: `0111110010000` 如上所述,逻辑位被编码为短的 OOK 脉冲模式,其中 `1000` 代表逻辑 `0`,`1110` 代表逻辑 `1`。这些模式中的每个脉冲持续 300 微秒,因此每个逻辑位(四个脉冲)需要 1.2 毫秒传输。 这意味着上面的风扇开/关有效载荷被传输为: `1000 1110 1110 1110 1110 1110 1000 1000 1110 1000 1000 1000 1000` 所有解码后的指令都可以在项目的仓库中找到。 ## 重放指令 为了重放这些指令,我将 Xiao ESP32-C6 板连接到 RFM69HCW 433 MHz RF 收发器。我最近经常使用 Seeed Studio 的 Xiao 板,它们非常小巧,非常适合保持项目紧凑。ESP32 完全被收发器分线板覆盖。 开放式外壳中的 RFAN 电路 据我所知,我解码的数据包结构是专有的,不受 RadioHead 等现有库支持。我没有让射频库来理解协议,而是使用收发器的原始发送模式,并手动根据从原始遥控器解码的脉冲时序切换其数据引脚。 要重放指令,微控制器需要: 1. 通过 SPI 配置射频模块:频率、调制方式、功率设置等。 2. 将射频模块置于发送模式。 3. 根据指令的脉冲时序切换射频模块的数据引脚。 4. 将射频模块恢复至休眠状态,直到再次需要。 这里 RTL-SDR 再次发挥了作用。没有它,调试主要就是刷固件、走进卧室看看风扇有没有反应。有了 SDR,我可以实际比较生成的信号和原始遥控器捕获的信号。 最烦人的问题是时序。风扇相当挑剔:一个在代码中看起来正确的指令,如果脉冲时序或数据包间间隔稍有偏差,就可能被忽略。 最后一个障碍是我在射频/SPI 处理中引入的一个 bug,导致 ESP32 断开 Wi-Fi 连接。修复后,经过多次在办公室和卧室之间来回测试命令,ESP32 终于能够可靠地重放与原始遥控器相同的指令了! ## 连接到 Home Assistant 现在我已经能够重放想要的指令,我需要一种从 Home Assistant 触发它们的方法。一个简单的解决方案是 MQTT,这是一种轻量级的消息协议,广泛应用于智能家居设备。MQTT 的工作原理是:设备向命名主题发布消息,而其他设备订阅这些主题,并在消息到达时做出响应。 MQTT 图示 我将 ESP32 配置为订阅一组 MQTT 主题,每个主题对应一个特定的风扇或灯光指令。Home Assistant 可以在用户操作仪表板上的风扇控制时,向这些主题发布消息。当 ESP32 收到消息时,它会重放相应的 RF 指令。 由于风扇不会向发射器发送任何反馈,ESP32 无法知道风扇的实际状态。为解决这个问题,设备首次通电时会假设一个默认状态:灯光关闭、中等亮度、风扇关闭。当它发送指令时,会相应地更新这个内部状态。状态会保存到持久存储中,因此默认状态仅在首次启动时需要。 偶尔状态会与风扇不同步,例如在墙壁开关关闭风扇时发送指令。发生这种情况时,我只需使用遥控器将风扇恢复到 Home Assistant 期望的状态即可。 ## 总结 外壳中的 RFAN 为发射器打印了一个小外壳,并给天线添上标志性的强调色后,终于可以投入使用了。 这种项目成功的最好标志就是没人再需要想着它。这个小发射器在我的办公室架子上放了将近一年,我和伴侣每天都用 Siri 愉快地控制我们的风扇。 如果你有兴趣复现这个方法,请查看项目的仓库。

相似文章

一款由iroh驱动的智能风扇

Hacker News Top

本文演示了如何使用ESP32微控制器和iroh网络库构建智能风扇,实现无需云服务的点对点控制。

逆向工程如今变得廉价

Simon Willison's Blog

本文讨论了编程代理如何大幅降低逆向工程家用设备的成本和精力,使自动化项目更易实现且风险更低。

无需触碰,通过音箱入侵你的电脑

Hacker News Top

一位安全研究人员对 Creative Sound Blaster Katana V2X 的固件进行了逆向工程,发现了漏洞,攻击者可在15米范围内将音箱变成隐蔽的窃听工具和无需物理接触的 Rubber Ducky。

逆向工程Creative Katana音箱以从Linux控制

Hacker News Top

一位开发者逆向工程了专有的Creative Sound Blaster Katana V2X音箱的USB协议,以便从Linux控制它,记录了捕获流量、去混淆固件和分析命令的过程。