
2026/06/24 23:13
クラウド制御の天井ファンへの無線通信妨害(RFハッキング)
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
最も重要な点は、Dreo の天井扇を完全なローカル制御とプライバシーを実現でき、メーカーのクラウド依存型エコシステム全体を迂回してそれを得られるということです。専用アプリへの依存や継続的なインターネット接続に頼るのではなく、この DIY プロジェクトでは元のハードウェアを置き換え、Home Assistant および Siri によるローカル管理が可能なカスタムシステムを導入しています。ソリューションは ESP32-C6 Xiao ボードと 433.92 MHz RF トランシーバーを組み合わせて構成し、特定の無線信号を直接デコードして再送します。技術的な詳細の一つとして、FCC ドキュメントでは周波数シフトキーイング(FSK)変調が示唆されていましたが、実際の信号解析の結果、データを送信するために周波数を切換えるのではなく、ラジオをオン・オフする単純な伝送方法である Ask(オンスイッチキーイング)が使われていることが明らかになりました。システムは 8 ビットのプレアミブル、20 ビットのシンクフレーズ、および元のリモートコマンドを正確に模倣するために必要なユニークなペイロードからなる構造化されたメッセージをデコードします。RadioHead などの標準ライブラリを使用せず SPI ラインを手動で切り替えながら、MQTT を Home Assistant トピックのトリガー用ブリッジとして活用することで、ハードウェアリバースエンジニアリングに関連するセキュリティリスクを排除しています。カスタム 3D 印刷ケース内でのほぼ 1 年にわたる安定動作を経て、本プロジェクトはソフトウェアアップデートを待ったりクラウドベースの脆弱性に晒されたりすることなく、ハードウェアによるイノベーションを通じてレガシー機能を維持することを示す証例となっています。
本文
天井扇風機の無線制御を実現:Dreo のハッキングとローカル制御構築記
プロジェクトの背景と動機
- 新居での課題: 新しい住居の寝室に設置された大型天井扇風機(Dreo CLF513S)が、振動や使い方の謎など不満足だった。
- スマートホームへの要望: 従来の Home Assistant 環境との統合を強く希望したが、公式対応はクラウド依存型であることがわかった。
- クラウド回避の理由:
- インターネット切断時に機能停止する。
- プロプライエタリーアプリによるロックインと不安定なインテグレーションリスク。
- 「外部サーバーが自宅機器を制御している」という感覚的不快感。
- 決定: 手頃な価格・デザインに惹かれ購入したが、設置後は**ローカル制御(オフラインでも動作)**の実現を目指した。
ローカル制御へのアプローチ選定
- 既存ソリューションの評価: GitHub の「ouaibe」による ESPHome 化プロジェクトは技術的に魅力的だが、高層天井の固定式機器を破壊して実装するリスクが高すぎた。
- 採用戦略: 「汎用リモコン」アプローチを選択。
- 既存のリモコントランスシーター送信コマンドを復号化し、それを再発射する方式。
- 赤外線(IR)ではなく、**RF(無線周波数)**通信であることが確認された(背面の FCC ID から判明)。
- 実装ステップ:
- リモコンから RF コマンドの内容を復号化。
- そのコマンドを再発射できる送信機を構築。
- Home Assistant よりトリガー信号を送る仕組みを確立。
RF コマンドの復号化プロセス
- 解析対象: 433.92 MHz(一般的なリモコン周波数)帯域での通信。
- 変調方式の確認:
- FCC ドキュメントでは「FSK」と記載されていたが、実際の信号を測定したところ、ASK(振幅シフトキーイング)、具体的には**OOK(オングオフキーイング)**であることが判明。
- 搬送波の有無で「1」と「0」を表現する方式。
- 信号分析(RTL-SDR/gqrx 使用):
- スペクトラムデータから、短いパルスと長いパルスの組み合わせ(モールス符号様)を用いていることが確認。
- 「ファンオン/オフ」ボタンの拡大図では、特定パターンが5 回繰り返される構造が明確になった。
- コマンド構造の解明:
- 単一パケットは 5 回の繰り返しで構成され、各反復間には8.8 ms のギャップがある。
- ビット構成:
- イントロダクション(プレアンプル): 8 ビット(論理「0」)。
- システム同期フレーズ: 20 ビット(共有)。
- ユニークなペイロード: 13 ビット。
- 符号化ルール:
- 論理ビットは 4 つの OOK パルスの組み合わせで表現される。
- 送信時間:1 ピルス 300 μs / 1 ロジカルビッ トあたり 1.2 ms。
- 例示(ファンオン/オフコマンド):
論理パターン: 0111110010000 パルス展開: 1000 1110 1110 1110 1110 1110 1000 1000 1110 1000 1000 1000
RF 送信機の構築と再発射
- ハードウェア構成:
- マイクロコントローラー:Xiao ESP32-C6。
- RF 送信機:RFM69HCW(433 MHz)。
- セットの特徴: Seeed Studio の Xiao シリーズを用いたため、小型でコンパクトな設計が可能。
- ソフトウェア実装:
- 既存ライブラリ(RadioHead など)では非対応の独自プロトコルのため、「生(raw)」送信モードを採用。
- コード上で論理ビットを生成し、RFM69HCW のデータピンを手動でパルス制御する方式。
- 動作手順:
- SPI を介して無線機構成設定(周波数・出力電力等)。
- 送信モードへの移行。
- 復号化データに基づき、パルスタイミングの制御をピンで実行。
- 処理終了後のスリープ状態へ移行。
- 開発上の難所と解決:
- タイミング精度: ファン側は非常に感度が高く、パルスやギャップのわずかなズレで無視されるため、厳密な同期が必要だった。
- バグ修正: ESP32 の Wi-Fi 接続による SPI 処理の不具合を解消し、安定してコマンド再発射する状態へ到達した(RTL-SDR によるリアルタイムスペクトラム解析がデバッグに大活躍)。
Home Assistant との連携設計
- 通信プロトコル: MQTTを採用。軽量なメッセージングにより、ローカルネットワーク内で安定動作。
- 動作フロー:
- ESP32 が対応する MQTT トピックを購読開始。
- Home Assistant のダッシュボード操作で特定トピックへメッセージ公開。
- ESP32 がメッセージ受信→RF コマンド再発射。
- 状態同期の仕組み:
- ファン側はレスポンスを返さないため、ESP32 は機器の状態を直接把握できない。
- 解決策: デバイス起動時にデフォルト状態(ライト OFF・中 brightness・ファン OFF)に強制し、コマンド送信ごとに内部状態を更新・永続化ストレージへ保存する方式。
- 例外ケースへの対応:
- 稀に実際の機器状態と ESP32 の認識がズレる場合がある(例:壁スイッチを切ったままの操作)。
- その際は、物理的なリモコンを使って Home Assistant が想定する状態へ手動復帰させることで問題ない。
プロジェクトの完遂と結論
- 筐体加工: 3D プリンタで送信機のカバーを作成し、アンテナ部分にアクセントカラー(オレンジ)を施して完成。
- 成功の指標:
- 1 ヶ月以上の放置実験において、パートナーに意識させることなくSiri を介した快適な操作が可能に。
- インターネット接続がない環境下でもローカル制御が維持され、クラウド依存からの脱却を実現。
- 公開情報: 本プロジェクトの詳細とコードは GitHub リポジトリにて共有可能(記事内でリンク参照)。