りなっくすとらずぱい!

Raspberry Pi初心者に向けた各コマンドの説明、プログラムの作り方について紹介しています!

Raspberry Pi + SwitchBotで風呂を沸かす

f:id:ibuquicallig:20200227170849p:plain

この記事ではRaspberry PiSwitchBotを連携させて、動作させるための環境作成、設定方法やコマンドなどについて解説しています。

この記事でできること

  • 動作に必要な環境を作成する
  • Raspberry PiとSwitchBotをBluetoothで接続する
  • Raspberry PiからSwitchBotを動作させる

※公式のアプリを使用する場合やIFTTTなどのWEBサービスを使用する場合は各使用方法を参考としてください。

SwitchBot

概要

SwitchBotとはBluetoothで接続できる無線接続の、物理ボタンを押すためだけの装置というような感じです。ボタンを押すという小さな動作しかできませんが、IoTに対応していない家電を基板をハッキングすることなく、操作することができるようになります。詳細やイメージは以下の公式サイトをご覧ください。

専用のスマホアプリから設定・操作することができますが、Raspberry Piから操作することができるライブラリも公開されています。これにより、より柔軟な分岐処理を追加することができ、外部から家庭内のRaspberry Piに接続できる状態であればSwitchBotハブなしで操作することもできます。(専用アプリで家の外から操作するには、SwitchBotハブが必要になるみたいです。)

外観・内容

外箱。結構しっかりしたパッケージです。ベルクロでくっついている扉をぱかっと開いて本体を確認することができる凝った作り。

f:id:ibuquicallig:20200227170043p:plain

内容物はこんな感じです。

f:id:ibuquicallig:20200227170206p:plain

  • 本体
  • 説明書
  • 替えの両面テープ
  • トグルスイッチ用のフープ
  • 電池(CR2)(本体に内蔵)

トグルスイッチは押し込むと、逆方向が出っ張るタイプのスイッチに使用します。実家の各部屋の電気のスイッチはこの形式でしたね(笑)

電池は本体にセットされていますが、絶縁テープが挟まっていますので動かす前に取り外してください。SwitchBotと書いてある面は蓋となっていて簡単に取り外すことができます。

f:id:ibuquicallig:20200227170242p:plain

処理

バージョン

$ lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description:    Raspbian GNU/Linux 10 (buster)
Release:        10
Codename:       buster

$ python3 --version
Python 3.7.3

GitHubからリポジトリをクローンする

今回は以下のスクリプトを使用します。

Pythonで書かれているスクリプトで、バージョンが2系と3系のスクリプトがそれぞれ存在しています。2系のほうが簡単そうだったので少し試してみたのですが、私の環境ではうまくいきませんでした。ので今回は3系のほうを使用します。(コマンド引数は同じです)

以下のコマンドでリポジトリをクローンします。gitコマンドが使用できない場合は、sudo apt-get install gitをまず実行してください。

$ git clone https://github.com/OpenWonderLabs/python-host.git

必要なライブラリをRaspberry Piにインストール

公式のREADMEにある手順に従ってインストールしていきますが、2系と間違えないようにしてください!

3系を使用するには以下のコマンドを実行して必要なライブラリをインストールします。本家のREADMEにある内容に数点追加してインストールします。(こっちだけでいいかと思っていましたが、別途2系で使用しているライブラリも必要なようです。。)

$ sudo apt-get install python3-pip libboost-python-dev libboost-thread-dev
$ sudo apt-get install libbluetooth-dev # READMEにはないがこれも必要
$ sudo pip3 install pybluez
# $ sudo pip3 install gattlib 後でインストールします

最後のコメントアウトしているライブラリ(gattlib)は後で手動でインストールします。




2つ目のライブラリ(libbluetooth-dev)をインストールしないと、pip3 install pybluezを実行したときに以下のようなエラーが発生し、インストールできません。

bluez/btmodule.h:5:10: fatal error: bluetooth/bluetooth.h: No such file or directory
  #include <bluetooth/bluetooth.h>
          ^~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
error: command 'arm-linux-gnueabihf-gcc' failed with exit status 1




pipでそのままgattlibをインストールしようとすると以下のようなエラーが表示されると思います。表示されずにインストールが完了した場合はこの章内の残りの内容は無視してOKです。

/usr/bin/ld: cannot find -lboost_python-py34
  collect2: error: ld returned 1 exit status
  error: command 'arm-linux-gnueabihf-g++' failed with exit status 1

boost_python-py34というライブラリが存在していないためエラーとなっています。Raspberry Piの場合、/usr/lib/arm-linux-gnueabihf/内にlibboost_python*というファイルがいくつか存在しているはずなので、そのファイル名に合わせて以下のコマンドを実行します。gattlibの更新が2015年を最後にメンテナンスされていない(もしくは、別ライブラリに統合・名称変更)のが理由かと思います。

$ cd /usr/lib/arm-linux-gnueabihf/
$ ls *libboost_python*
libboost_python27.a          libboost_python3.a
libboost_python27.so         libboost_python3-py37.a
libboost_python27.so.1.67.0  libboost_python3-py37.so
libboost_python37.a          libboost_python3.so
libboost_python37.so         libboost_python.a
libboost_python37.so.1.67.0  libboost_python.so

以下のコマンドを実行して、pipでインストールするためのファイル群をいったんRaspberry Piに保存します。さっきクローンしたところにとりあえず保存します。

$ cd python-host
$ pip3 download gattlib

# ダウンロードしたファイル名はおそらくgattlib-0.20150805.tar.gzですが、
# 異なっている場合は、以下のコマンドを適宜読み替えてください。
$ tar xvzf ./gattlib-0.20150805.tar.gz # 解凍
$ cd gattlib-0.20150805/

私の環境の場合はlibboost_python37がRaspberry Piに存在していたので以下のようインストール用のファイルを書き換えました。boost_python37の部分を適宜、より新しいバージョンに変更してください。

# 以下のコマンドで、setup.py内のboost_python-py34をboost_python37に置換します。
$ sed -ie 's/boost_python-py34/boost_python37/' setup.py

# インストール(2-3分かかります)
$ sudo pip3 install .

すべてインストールが完了したら次に進みます。

SwitchBotを探す

これで必要なものはそろったのでスクリプトを実行していきます。まずはSwitchBotのMACアドレスを調べます。MACアドレスはSwitchBot(だけでなくすべてのネットワークに接続できる端末)に一意に振られている値です。もちろんRaspberry Piにも振られています!これによりコマンドを送信する端末を決定することができます。

以下のコマンドでMACアドレスを調べ、動作確認します。まだSwitchBotの通電防止フィルムを取っていない人は実行前にとっておきましょう😉

$ cd python-host
$ sudo python3 switchbot_py3.py --scan
Found 2 devices: ['69:7F:74:xx:xx:xx', 'EC:C3:A6:xx:xx:xx'] # スキャンできたBluetooth端末
Enter the number of the device you want to control:
        0       69:7F:74:xx:xx:xx
        1       EC:C3:A6:xx:xx:xx
1 # SwitchBotっぽい方のMACアドレスを入力してEnter

Connected!  # 接続成功!実際にSwitchBotが動きます!
Command execution successful

実行するとRaspberry Piが接続することのできるBluetooth端末のMACアドレス一覧が表示されます。

総当たりで実行していってもいいのですが、MACアドレスの前半3つの部分は企業によって固定されています。私のSwitchBotはEC:C3:A6で始まっているのでおそらく皆さんのものも同じと思われます。もし全然違う場合は総当たりで試していきましょう!(笑)

コマンドを実行してSwitchBot出ない場合は、処理が途中で止まるのでCtrl + Cで中断します。

Enter the number of the device you want to control:
        0       69:7F:74:xx:xx:xx
0

# 処理が終わらないのでCtrl + Cで中断

どれを実行してもSwitchBotが動作しない場合は、SwitchBotの表面の蓋を開けて左上にある再起動ボタンを押して再起動してみてください。もしくは電池を入れ直してLEDが光るのを確認してください。




余談ですがRaspberry PiのMACアドレスはB8:27:EBから始まります。これらは以下のようなサイトで検索できます。(のでその辺でBluetooth接続受付状態の端末のおおよそのメーカーを調べることができます。)

ワンラインで実行

MACアドレスがわかったので、これでコマンドライン上から一発で動作させることができます。以下のコマンドでボタンを押して離す動作が実行できます。

$ sudo python3 switchbot_py3.py --device EC:C3:A6:xx:xx:xx Press

これで一行で実行できるようになりました。sudo不要でBluetoothモジュールを使用するようにすることもできるようですが、sudo実行時にパスワード不要にするほうが容易に実装できます。が、不要にsudo権限を与えるのはセキュリティリスクの高い行為になりますので外部公開しているような環境では注意してください。

$ sudo visudo
username ALL=(root) NOPASSWD:/usr/bin/python3 switchbot_py3.py

usernameの部分はスクリプトを実行するユーザー名に適宜置き換えてください。追記場所がよくわからない場合は末尾に追加しておけばOKです。(visudosudoersに関しては追記予定です。)

Node.jsから実行する

先ほどのワンライン処理をNode.jsから実行します。下記のようにすると実行することができます。Linuxコマンドを実行できる汎用的な処理ですね。適当にファイル名はindex.jsとでもして、python-host内に作成します。このディレクトリ外に作成する場合はswitchbot_py3.pyへのパスを適切に設定してあげる必要があります。(もしくはindex.jsと同じ場所にシンボリックリンクを作成する)

const { exec } = require('child_process')

const mac_address = 'EC:C3:A6:22:A7:3B'

const command = 'sudo python3 switchbot_py3.py --device ' + mac_address + ' Press'

exec(command, (error, stdout, stderr) => {
  if (error) return false
})

node index.jsで実行して動作することを確認してください。これでWEBアプリからのAPI処理時にボタンを押すことができます。

とりあえず適当にフロントページを作って風呂の給湯ボタンをオスページを作ってみました。このページを外部公開すれば家の外からでも風呂を沸かすことができますね!

最後に

以上でRaspberry PiとSwitchBotを接続して動作させることができました。NodeJSで処理を実行するようにするとExpress.jsなどから動作させることができるようになるのでフロントエンドとの連携もOKですね。

正直1個5000円ほどはちょっと高いかもしれませんが、家に帰って即風呂にはいれるようになったのでよしとしましょう。。。(笑)♨

参考

以下のサイトの情報を引用・参考にしました。

bluetooth.hのエラー

/usr/bin/idのエラー