Raspberry PiでSwitchBotの人感センサーの値を取得!

2021年12月19日

今回も少し上級者向けの記事になります。

こんな人におすすめの記事です。

  • SwitchBotの人感センサー値をRaspberry Piで取得する方法を知りたい
  • SwitchBotの人感センサーを取得して、SwitchBot以外の機器を操作したい

前回、開閉センサーのセンサー値取得について書きましたが、今回はそれの人感センサー版です。

前回も似たことを書きましたが、SwitchBotの人感センサーで人を検出して操作できるデバイスはSwichBotデバイスだけです。SwichBotのボットやHub、カーテンなどに限られます。

例えば、個別にGoogle Homeに連携しているルンバなどのスマート家電は、SwitchBotの人感センサーで検知して動作させるということができません。

IFTTTというサービスを利用することで可能ですが、IFTTTも有料化してしまい、使い勝手が悪くなってしまいました。

そこで、人感センサー値を自分で取得して、任意の家電を操作するものを作ってしまおうと思い立ちました。

今回は、まず人感センサーのセンサー値を読み取るところに焦点を当てて説明します。

そんな私は、スマートホームに興味がでて速攻で環境構築しました。今では家中スマートホームデバイスが溢れており、妻には呆れられています(笑)

遠隔操作、声で操作、GPSで操作、人が通ったら…などあらゆるシーンで活用中な私が解説します!

SwitchBotの人感センサー値をRaspberry Piで取得する方法

センサー値を取得するにはこの記事に書かれている手順に沿って進めるだけです。今回の記事では、センサー値取得までを重点的に説明します。

具体的な活用例としては、例えば以下があります。

  • 人の動きを検知して、照明をつける
  • 部屋が暗くて、部屋に人がいない状態が続いたらルンバを起動する

必要なもの

  • スマートフォン ※設定に必要
  • Raspberry Pi
  • SwitchBot人感センサー

前提

前回同様、センサー値を取得するためには事前に人感センサーを使える状態にしておく必要があります。具体的には以下が終わっている状態です。

  • スマートフォンにSwitchBotアプリがインストールされている
  • SwitchBotのアカウントがある
  • SwitchBotアプリと人感センサーの登録設定が済んでいる

要は、SwitchBotの人感センサーを本来の使い道の通りに使える準備ができているということです。

また、Raspberry Piは初期設定が完了していることを前提とします。初期設定についてはGoogleで検索すればいくらでも情報を入手できます。

LXTerminalや他のターミナル(Windowsのコマンドプロンプトでも良い)についても、数度程度は使ったことがあり、なんとなく使い方を知っている前提で書いています。

センサー値を取得する手順

手順は以下の通りになっています。基本の流れは前回と同じですね。

  1. 事前準備(必要なもののインストール)
  2. MACアドレスの確認
  3. センサー値を取得のPythonスクリプトを作成
  4. 実行してみる
  5. センサー値に応じた処理を記述

⓪事前準備

Raspberry Piに事前に設定しておくことがあります。以下の2つをRaspberry Piにインストールします。

前回の開閉センサーの回と同じです。そのため、既にインストールされている場合は、スキップして問題ありません。

  • libglib2.0-dev
  • bluepy

インストールの仕方は前回の記事の⓪事前準備を参考にしてください。全く同じです。

①MACアドレスの確認

まずは人感センサーのMACアドレスを確認します。MACアドレスは機器を識別するために必要です。

スマートフォンのSwichBotアプリを使用します。

下記の手順で該当の人感センサーのMACアドレスを調べておきます。下記は前回の開閉センサーの手順ですが、人感センサーでも基本的には同じ手順です。

②センサー値取得のPythonスクリプトを作成

センサー値を取得するためのスクリプトを作成します。

早い話、テキストエディタを開いて、以下をコピーすればOKです。

保存先はどこでも構いませんが、この記事ではデスクトップに「switchbot」というディレクトリを作成して、そこに保存しています。

そして、ファイル名は「switchbot-human_sensor.py」としています。

import binascii
from bluepy.btle import Scanner, DefaultDelegate

class ScanDelegate( DefaultDelegate ):
    def __init__( self,macaddr ):
        self.macaddr=macaddr
        self.output={}
        DefaultDelegate.__init__( self )

    def handleDiscovery( self, dev, isNewDev, isNewData ):
        if dev.addr == self.macaddr:
            for ( adtype, desc, value ) in dev.getScanData():
                if ( adtype == 22 ):
                    servicedata = bytes.fromhex( value[4:] )
                    isON=(servicedata[1] & 0b01000000) >> 6
                    time=(servicedata[4])
                    isIlluminance=(servicedata[5] & 0b00000011)-1

                    #出力データの整形
                    self.output={"isIlluminance":isIlluminance,"isON":isON,"time":time}

    def startScan(self,scan,time):
        Scanner().withDelegate( self ).scan(time)

if __name__ == '__main__':
    macaddr = 'aa:00:bb:11:cc:22'   #あなたのデバイスのMACアドレスに書き換えてください(アルファベットは小文字) ※左は記入例

    scan=ScanDelegate(macaddr) #BLEスキャンのための初期設定

    while True:
        scan.startScan(scan,3)  #スキャン開始 3秒間隔

        #取得データの出力
        print("isIlluminance:",scan.output["isIlluminance"])    #照度出力 明るい=1 暗い=0
        print("isON:",scan.output["isON"])                      #動体検知状態   検知(動きあり)=1 不検知=0
        print("time:",scan.output["time"])                      #検出してからの経過時間 単位:秒
        print("-----------")

        #取得データによるアクションを以下に記述

そして、①で確認したMACアドレスを以下の部分に記載します。これをしないと正しく動作しません!

macaddr = 'aa:00:bb:11:cc:22'   #あなたのデバイスのMACアドレスに書き換えてください(アルファベットは小文字) ※左は記入例

スキャンの間隔は3秒に設定しています。変更する場合はscan.startScan(scan,3)の"3″の部分の数字を変更してください。例えば、10秒にするには、 scan.startScan(scan,10)です。

③実行してみる

問題なく取得できているか確認するために、実行してみましょう。

「LXTerminal」で実行します。

②で作成したPythonスクリプトを保存したディレクトリまで移動します。

デスクトップのswitchbotというディレクトリであれば、以下を入力すると移動できます。

cd Desktop/switchbot/

そこで、②で作成したPythonスクリプトを実行します。今回のスクリプトで使用しているBLEスキャンを実行するには、sudo権限が必要です。そのため、実行には以下を入力します。

sudo python3 switchbot-sensor.py

これで実行されます。

センサー値がターミナルに表示されれば成功です。

出力の数値の意味は上から、

isIlluminance照度 明るい=1 暗い=0
isON人の検知状態 検知=1 不検知=0
time検知してからの経過時間 単位:秒

④センサー値に応じた処理を記述

センサー値の取得であれば、③までで十分ですが、実際はセンサー値を取得して何かアクションを起こすと思います。

そのアクションをスクリプトに記載する必要があります。

そのアクションは②のスクリプトの最終行以降に記載すればOKです。(#取得データによるアクションを以下に記述というコメントの下に記載)

解説

スキャン生データについて

今回のセンサー値取得の仕組みは前回の開閉センサーと同じです。詳しくはそちらを読んでみてください。

先ほどのPythonスクリプトは取得したデータを加工して、それぞれ動体検知や照度検知を判断しています。

取得した生データ(スクリプト内のvalue[4:])は16進数で表されており、1byte=2桁で区切られています。このvalue[4:]をByte表記に直してservicedataに格納しています。

servicedataのそれぞれのByteが意味を持っています。そして、そのByteをさらにBitで表すと、それぞれ以下のような意味を持っています。全てのByteの意味までは解読できていませんので、わかっている範囲です。

servicedataの配列のインデックスでいう

1番目のビット7桁目・・・動体を検知したかどうかの状態

4番目・・・動体を検出してからの時間

5番目のビット1・2桁目・・・明るい/暗いの照度状態

APIの話

実はSwitchBotにはAPIがあります。しかも、最近、人感センサーもAPIに追加されました。APIを使わない理由も前回の記事と同じです。

まとめ

いかがだったでしょうか?

自前で作ってしまうというちょっと上級編を紹介しました。しかし、この記事の通りに進めれば、センサー値取得まではそこまで難しくはないと思います。取得したセンサー値を使って複雑なアクションを行うことができます。

もし、わからないこと、詰まったところ等ありましたら、遠慮なくお問い合わせください。できる限りサポートさせていただきます。専門家ではないので、完ぺきな回答はできないかもしれませんが、お金はもちろんいただきませんので、気軽に聞いてみてください。何かヒントになるかもしれません。(→Twitter)

お問い合わせフォーム

スマートホーム化に関する記事を他にも書いています。こちらも参考にしてみてください!

この記事を書いた人
author

ユキヒト

家電大好き+子育て真っ只中のブロガーです。
スマートホームを始めとする家電関連の記事や子育て・知育関連の記事を書いています。
質問や相談はいつでも受け付けています。お問い合わせフォームやTwitterからお待ちしております。(もちろん無料です)
どんなことでも構いません。
これまでにあった例としては、
「SwitchBotハブの設定ができないので教えてもらえませんか?」
「ベビーカメラの安いやつないですか?」
などです。全く記事と関係ない質問もOKです。
できる限り答えていきたいと思いますので、お気軽にどうぞ。
お問い合わせ
Twitter