「Alexaを呼ぶの面倒じゃない?」自撮り棒のBluetoothボタンでSwitchBotを動かす快適IoTボタン化計画

みなさん、こんにちは。

私は自宅のインターホンにSwitchBot Botを設置して、Alexa経由で「アレクサ、オートロックを開いて」と声で制御できるようにしています。

当初は「声で操作できるなんて未来的!」と満足していたのですが、実際に運用してみると意外な盲点が……。
急な来訪者が来たとき、焦ってAlexaを呼び出すのが意外と面倒だったり、うまく聞き取ってもらえなかったり……。

「やっぱり、手元に物理ボタンが欲しい……!」

そう思い立ち、手元にあった自撮り棒付属のBluetoothボタン(TAWARON製)を使って、SwitchBotを制御するシステムを構築することにしました。

ただ、Bluetoothボタンの宿命で、よくあるのが接続失敗。毎回、「本当に動いたかな?」と不安になるのは嫌ですよね。
そこで今回は、SwitchBotの操作に加えて、Google Home Notifierを使ってスマートスピーカーから「解錠しました」と音声フィードバックを返す仕組みも組み込むことにしました。

今回は、GitHub Copilotという最強の相棒と一緒に、古いRaspberry Pi(Python 3.5環境)向けにシステムを実装した過程をご紹介します!

 


 

事前準備

 

今回のシステムは、過去の記事で紹介したツールを組み合わせています。以下のセットアップが終わっている前提で進めますので、未読の方はチェックしてみてくださいね。

  • google-home-notifierの設定(Google Homeに喋らせる用)
  • switchbot.pyの設定(SwitchBotをPythonから叩く用)

 

Bluetoothボタン(TAWARON)のペアリング

まずはRaspberry Piとボタンをペアリングします。bluetoothctlを使いましょう。

# bluetoothctlを起動
sudo bluetoothctl

# スキャン開始
scan on

# 「TAWARON」が見つかったらペアリング!
pair XX:XX:XX:XX:XX:XX
connect XX:XX:XX:XX:XX:XX
trust XX:XX:XX:XX:XX:XX
exit

 

権限設定

プログラムからBluetoothデバイス(inputデバイス)を叩けるよう、ユーザーをinputグループに追加しておきます。

sudo usermod -a -G input $USER
# 一度ログアウトしてログインし直すと反映されます

以上で、事前準備は完了です!

 


 

いざ開発 – こだわり&改修ポイント

 

開発を始めるにあたって、まずは先人の知恵を借りようとGitHubで見つけた既存のリポジトリ(300yen-iot-button)をベースにしようと考えました。

しかし、実際に手元の環境で動かしてみると課題が山積みで……。

  • evdevライブラリの依存関係が古い
  • MACアドレスベースの検出がTAWARONでは動かない
  • 最新のPython機能が使われており、Raspbian Stretch(Python 3.5)でエラーが出る

「これ、ほぼ作り直した方が早いのでは……?」と思い、GitHub Copilotをフル活用して大幅な書き換えを行いました。

 

1. evdevを廃止し、低レベルイベント監視へ

古いライブラリへの依存を避けるため、/sys/class/input/event* から直接バイナリデータを読み取る方式に変更しました。Copilotに「Linuxのinput_event構造体をPythonのstructモジュールで解析するコードを書いて」と頼んで、サクッと実装。

# Copilotと一緒に書いた binary unpack ロジック
# Linuxの timeval (32bit) フォーマットに対応
tv_sec, tv_usec, evt_type, code, value = struct.unpack('IIHHi', data)

 

2. デバイス検出を「名前ベース」に

TAWARONは内部に複数のサブデバイスを持っており、MACアドレスベースの検出が不安定でした。そこで、「”Keyboard” という文字列を含むデバイスパスを探す」というロジックにCopilotと相談しながらリライト。これで確実にキー入力イベントをキャッチできるようになりました。

 

3. Python 3.5 互換性への執念(f-stringよ、さらば)

今回の環境はPython 3.5.3。モダンなf-stringsubprocess.runの便利な引数が使えません。Copilotに「このコードをPython 3.5でも動くように書き換えて」と指示し、すべてのf-stringを.format()へ、subprocessをPopenベースのレガシーな書き方へ修正しました。

 

4. 堅牢な再接続&連打防止

Bluetoothボタンはすぐスリープに入るため、エラーハンドリングが重要です。

  • デバイスが外れてもループで再検索し続けるロジック
  • 1秒以内のチャタリングを無視するガード

これらを追加し、実用性を高めました。

 


 

設定ファイルでメンテナンスしやすく

 

設定はconfig.pyに外だしして、一箇所で管理できるようにしました。MACアドレスやIPアドレスなど、環境依存の設定を簡単に変更できます。

CONFIG = {
    "BUTTON_DEVICE_NAME": "TAWARON",
    "SWITCHBOT_MAC_ADDRESS": "**:**:**:**:**:**", 
    "IP_ADDRESS": "192.168.**.**", # Google HomeのIP
    "NOTIFIER_PORT": 8091,
    "NOTIFICATION_TEXT": "ドアを解錠しました",
    "MULTIPLE_PRESS_THRESHOLD": 1.0, # 連打防止(秒)
    "PYTHON_HOST_PATH": "/path/to/switchbot.py",
}

 


 

systemdに登録して自動起動を仕込む

 

24時間365日動いてほしいので、systemdに登録します。bt-button.service というUnitファイルを作成します。

[Service]
ExecStart=/usr/bin/python3 /path/to/bt_button.py
Restart=always
RestartSec=10

これを /etc/systemd/system/ に放り込んで sudo systemctl enable すれば、ラズパイ起動時に自動で立ち上がります。

 


 

まとめ

 

既存コードの課題をGitHub Copilotと一緒に乗り越えることで、以下のメリットが得られました!

  • 環境を選ばない:ライブラリ依存を減らし、古いOSでも動作。
  • 安定した検知:デバイス名ベースの柔軟なフィルタリング。
  • 運用性:音声通知によるフィードバックと、systemdによる常駐化。

今回開発したソースコードはGitHubで公開しています。環境依存が強い部分もありますが、普段Pythonを触っているエンジニアならきっと「いい感じ」に調整して使えるはず。ぜひ試してみてください!

🔗 GitHubリポジトリ:bt_button_for_switchbot

 

本日も最後までお読みいただきありがとうございました。

それでは、よいIoTライフを!

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール