Rebounder Tech Blog

運用している当事者が書く、本番システムの記録。

SwitchBot 人感センサを Hub なしで BLE 直読みする

公開 読了時間 約2分執筆: Rebounder 開発チーム(当該システムの運用当事者)

※本記事にはアフィリエイトリンクを含む場合があります。内容は広告の有無に影響されません。

結論

SwitchBot の人感センサは BLE アドバタイズを直接受信すれば、Hub もクラウドも介さずローカルだけで人感トリガーとして使える。

普通の構成と、直接読む構成の違い

SwitchBot の人感センサは、通常「センサ → Hub → クラウド → アプリ/連携」という経路で使います。手軽ですが、Hub が要り、クラウドが前提になります。

一方、センサは常時 BLE のアドバタイズを送出しています。これを自分のプログラムで受信して解析すれば、Hub もクラウドも挟まずにローカルで完結します。遅延も小さくなります。

既存の通知や連携で用が足りるなら前者で十分です。自作システムに人感を差し込みたい場合だけ、後者を選ぶ意味があります。

必要なもの

  • SwitchBot 人感センサ
  • BLE を受信できるコンピュータ(Raspberry Pi でも Android でも可)

追加のゲートウェイは要りません。

やっていること

BLE のアドバタイズには、メーカー独自のデータ(Service Data / Manufacturer Data)が乗っています。ここに検知/未検知が入っているので、解析して取り出します。データ形式は有志の解析(pySwitchbot 等)が公開されているので、それを頼りにしました。

実装の要点は3つです。

  1. 対象センサの MAC だけをフィルタして拾う
  2. 常駐して受信し続ける
  3. 取りこぼしても大丈夫なように、いったんローカルに貯めて後から送る

3つ目が特に重要です。BLE アドバタイズは届かないことがあるので、オフライン耐性を前提に組みます。

詰まった点

① BLE スキャンに位置情報権限が要る(Android)

Android では BLE スキャンに位置情報の許可が必要で、これが無いとエラーも出さずに検知0件になります。

ログにも出ません。原因が見えないまま、いちばん時間を溶かした箇所です。

② 放っておくとスキャンが止まる

常駐サービスにして、電池最適化からも除外しないと、OS の都合でいつのまにか受信が止まります。

③ 取りこぼしは前提

前述のとおりです。ローカルにバッファして再送する設計にしておかないと、記録が歯抜けになります。

3つに共通していること

並べると、どれも「止まったことが分からない」形をしています。①はエラーが出ず、②はいつのまにか止まり、③は歯抜けになったことに後から気づく。

BLE を扱うときに時間を取られるのは、たいてい解析そのものではなく、この沈黙する失敗のほうでした。受信が生きていることを外から確認できる仕組みを先に作っておくと、後の調査がまるで違います。

よくある質問

Q1Hub を買わなくても本当に動きますか?

動きます。センサは常時 BLE のアドバタイズを送出しているので、BLE を受信できるコンピュータがあれば直接解析できます。追加のゲートウェイは不要です。ただし SwitchBot アプリの通知や既存の連携で用が足りるなら、素直に Hub を買うほうが圧倒的に楽です。

Q2検知が0件のまま何も起きません。どこを見ればいいですか?

Android の場合は位置情報権限を確認してください。BLE スキャンは位置情報の許可が無いとエラーも例外も出さずに0件を返します。ログにも出ないため、原因が分からないまま時間を溶かしやすい箇所です。

Q3取りこぼしはどう扱えばいいですか?

BLE アドバタイズは届かないことがある前提で設計します。受信した値をいったんローカルに貯めて後から送る形にしておかないと、記録が歯抜けになります。