【簡単】Home AssistantでSwitchBotの開閉センサーを連携する!

2022年10月22日

2022/9/23 追記
本記事では、自前で開閉センサーのデータを取得できるようにする方法を紹介しています。
現在はSwitchBotインテグレーションで、開閉センサーのデータを取得できるようになっています。
そのため、インテグレーションを使用するのが最も簡単です。

前回、Home AssistantでSwitchBotの温湿度計を扱う方法を紹介しました。

今回はそれを応用して、SwitchBotの開閉センサーを扱えるようにしていきます。

この記事でわかること
  • Home AssistantでSwitchBot開閉センサーを連携する方法

私についてですが、スマートホームにはまってから、今では家中スマートホームデバイスが溢れています。遠隔操作、声で操作、GPSで操作、人が通ったら…などあらゆるシーンをスマート化しています。Home Assistantにも手を出して、色々なデバイスを連携させて、また、自分でコーディングをするくらいハマっています(笑)

そんな私がHome Assistantのノウハウをわかりやすく説明していきます。

Home AssistantとSwitchBot開閉センサーの連携でできること

Home AssistantでSwitchBotの開閉センサーを連携すると開閉センサーのセンサー値を取得できるようになります。

オーバービュー画面にはこのように開閉センサーの開閉状態やボタン押下検知、照度(明るさ)の状態などを表示させることができます。

Home Assistantで開閉センサーのセンサー値を取得できるようになったということは、オートメーションのトリガーとしても使うことができます。

ドアの開閉などを検知して、電気をつけるなどの自動化が可能になります。

SwitchBot開閉センサーを連携する方法

今回の連携のしくみ

前回の記事でSwitchBot温湿度計を連携しました。この時はsbm2mqttを活用させていただきました。

今回はこれを応用して、開閉センサー値を連携できるように改造していきます。

sbm2mqttの使い方や詳細はこちらを参照ください。

基本的な仕組みはsbm2mqttと同じです。

開閉センサーもBLEでセンサー値情報を発信しています。

これをBLEスキャンデバイスでスキャンして取得して、その情報をMQTTでHome Assistantに送ります。

私はBLEスキャンとMQTTの送信、そしてHome AssistantをRaspberry Piで動作させています。

Raspberry PiによるHome Assistantの導入・設定方法などはこちらを読んでみてください。

具体的な連携手順

ここからは早速、具体的な手順を説明していきます。

前提として以下ができているとして説明を進めていきます。

前提
  • Mosquitto brokerが使用できる状態にあること
  • Terminalが使用できる状態にあること
  • File editorが使用できる状態にあること
  • SwitchBotアプリで開閉センサーのデバイス登録が完了していること

特に最初の3つができていない場合は、アドオンのインストールが必要です。インストール方法はこちらを読んでみてください。インストールが終わったら戻ってきてください。

Home AssistantにSwitchBotの開閉センサーを連携する手順をまとめると以下になります。

連携手順
  1. 開閉センサー用のフォルダ作成
  2. sb_open_sensor.pyを作成
  3. sbm2mqtt_config.pyを作成
  4. docker_entrypoint.shの作成
  5. Dockerfileの作成
  6. configuration.yamlの編集

開閉センサー用のフォルダ作成

まずは作業フォルダとして開閉センサー用のソースコードを格納するフォルダを作ります。

Home AssistantのConfigフォルダ内に任意のフォルダを作成します。今回作成するファイルは全てこのフォルダに保存します。

この記事では「sb_open_sensor」というフォルダ名にします。

sb_open_sensor.pyを作成

今回の要となる開閉センサーのデータを取得してHome Assistantに送るソースコードを記述します。

File editor等で新規ファイルを作成します。名前は「sb_open_sensor.py」とします。ファイルの場所は「sb_open_sensor」内です。

そして、下記のソースコードをコピーしてください。

なお、xx:xx:xx:xx:xx:xxの部分はご自身の開閉センサーのMACアドレスを入力してください。

MACアドレスはSwitchBotアプリから、開閉センサーの詳細画面→右上の歯車マーク→デバイス情報から確認することができます。確認方法は以下です。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# sb_open_sensor.py

from bluepy.btle import Scanner, DefaultDelegate, ScanEntry
import datetime
import paho.mqtt.client as mqtt
import json
import time

import binascii
from bluepy.btle import Scanner, DefaultDelegate

# Import configuration variables from sbm2mqtt_config.py file - Must be in the same folder as this script
from sbm2mqtt_config import (
    mqtt_host,
    mqtt_port,
    mqtt_timeout,
    mqtt_client,
    mqtt_user,
    mqtt_pass,
    mqtt_topic,
)

class ScanDelegate( DefaultDelegate ):
    def __init__( self,macaddr ):
        self.macaddr=macaddr
        self.isButton=0
        self.postButtonCount=0
        self.output=[{"isButton":self.isButton}]
        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:] )
                    isIlluminance=servicedata[3] & 0b00000001         #照度取得(明るい/暗い)
                    isOpen=(servicedata[3] & 0b00000010) >> 1         #開閉状態取得
                    isLeaveOpen=(servicedata[3] & 0b00000100) >> 2    #開けっ放し状態取得
                    open_time=servicedata[7]                          #開けっ放しの時間取得
                    buttonCount=servicedata[8] & 0b00001111           #ボタンが押された回数取得

                    if self.postButtonCount==0:
                        self.postButtonCount=buttonCount

                    #ボタンが押されたかどうか判定
                    if (buttonCount>=self.postButtonCount+1) or (buttonCount==1 and self.postButtonCount==15):
                        self.isButton=1
                    elif buttonCount==self.postButtonCount:
                        self.isButton=0

                    if buttonCount!=self.postButtonCount:
                        self.postButtonCount=buttonCount

                    #出力データの整形
                    self.output={"isIlluminance":isIlluminance,"isOpen":isOpen,"isLeaveOpen":isLeaveOpen,"time":open_time,"buttonCount":buttonCount,"isButton":self.isButton}

                    # MQTT publish as JSON
                    msg_data = json.dumps({
                        "isIlluminance": str(isIlluminance),
                        "isOpen": str(isOpen),
                        "isLeaveOpen": str(isLeaveOpen),
                        "time": str(open_time),
                        "buttonCount": str(buttonCount),
                        "isButton": str(self.isButton)
                    })
                    print(
                        "\n  Publishing MQTT payload to "
                        + mqtt_topic
                        + "/"
                        + self.macaddr
                        + " ...\n\n    "
                        + msg_data
                    )
                    mqttc = mqtt.Client(mqtt_client)
                    mqttc.username_pw_set(mqtt_user, mqtt_pass)
                    mqttc.connect(mqtt_host, mqtt_port)
                    mqttc.publish(mqtt_topic + "/" + self.macaddr, msg_data, 1)

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

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

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

    while True:
        try:
            scan.startScan(scan,3)  #スキャン開始 3秒間
        except:
            pass
        time.sleep(5)

sbm2mqtt_config.pyを作成

環境変数を読み込むコードを記述します。

sbm2mqttで使ったファイルをそのまま持ってきても構いません。

一応、コードを書くと以下になります。(ちょっとアレンジ入れています)

#!/usr/bin/env python3
import os

# MQTT settings
mqtt_host = os.environ.get("MQTT_HOST")
mqtt_port = int(os.environ.get("MQTT_PORT"))
mqtt_timeout = int(os.environ.get("MQTT_TIMEOUT", "30"))
mqtt_client = os.environ.get("MQTT_CLIENT")
mqtt_user = os.environ.get("MQTT_USER")
mqtt_pass = os.environ.get("MQTT_PASS")
mqtt_topic = os.environ.get("MQTT_TOPIC")

docker_entrypoint.shの作成

docker_entrypoint.shは実行するときに最初に実行されるスクリプトです。

sbm2mqttも今回のコードもDockerという仮想環境で実行されます。この仮想環境を実行したときにこのスクリプトを実行し、sb_open_sensor.pyを実行するしくみになっています。

あまり詳しいことはわからなくても、とりあえずコピーでOKです。

まずはFile editorで「sb_open_sensor」フォルダ内に「docker_entrypoint.sh」というファイルを作成します。

#!/bin/bash

service dbus start
bluetoothd &

while true ; do
	./sb_open_sensor.py
	sleep $REPORTING_INTERVAL || break
done

Dockerfileの作成

Docker仮想環境のビルド設定ファイルを作成します。これもよくわからなくてもとりあえずコピーでOKです。

まずは、「sb_open_sensor」フォルダ内に「Dockerfile」というファイルを作成します。拡張子はありません。

以下の内容を記載して保存します。

なお、ENV内の内容はご自分のMQTT設定に合わせて書き換えてください。

特に、MQTT_USERとMQTT_PASSはMQTTのユーザー名とパスワードを記入してください。

# docker build . -t sb_open_sensor
# docker run --rm --net=host --privileged -it -e MQTT_HOST=xxx.xxx.xxx.xxx -e MQTT_PORT=xxxx -e MQTT_USER=xxxxxx -e MQTT_PASS=xxxxxx sb_open_sensor
FROM python:3.7
RUN apt-get update && apt-get install -y bluez bluetooth
RUN pip install bluepy paho-mqtt
ENV \
    MQTT_HOST=127.0.0.1 \
    MQTT_PORT=1883 \
    MQTT_USER=mqtt_user \
    MQTT_PASS=xxxxxxxx \
    MQTT_CLIENT=sbo2mqtt \
    MQTT_TOPIC=switchbot_open_sensor \
    REPORTING_INTERVAL=3
      # in seconds
ENTRYPOINT sh docker_entrypoint.sh
COPY . .

configuration.yamlの編集

最後にHome Assistantに開閉センサー情報を表示するためにconfiguration.yamlを編集します。

File editor等でconfiguration.yamlを開き、「sensor:」内に下記を記載してください。

「name:」は表示名です。わかりやすい名前を付けてください。

「state_topic:」のxx:xx:xx:xx:xx:xx(MACアドレス)には先ほど確認した開閉センサーのMACアドレスを入力してください。

sensor:
  - platform: mqtt
    name: '開閉センサーの開閉'
    state_topic: 'switchbot_open_sensor/xx:xx:xx:xx:xx:xx'
    value_template: >-
      {% set values = { '1':'OPEN', '0':'CLOSE'} %}
      {{ values[value_json.isOpen] if value_json.isOpen in values.keys() else 'CLOSE' }}
    icon: mdi:door-open
  - platform: mqtt
    name: '開閉センサーのボタン'
    state_topic: 'switchbot_open_sensor/xx:xx:xx:xx:xx:xx'
    value_template: >-
      {% set values = { '1':'ON', '0':'OFF'} %}
      {{ values[value_json.isButton] if value_json.isButton in values.keys() else 'OFF' }}
    icon: mdi:door-open
  - platform: mqtt
    name: '開閉センサーの照度'
    state_topic: 'switchbot_open_sensor/xx:xx:xx:xx:xx:xx'
    value_template: >-
      {% set values = { '1':'明るい', '0':'暗い'} %}
      {{ values[value_json.isIlluminance] if value_json.isIlluminance in values.keys() else '暗い' }}
    icon: mdi:door-open
  - platform: mqtt
    name: '開閉センサーの開けっ放し状態'
    state_topic: 'switchbot_open_sensor/xx:xx:xx:xx:xx:xx'
    value_template: >-
      {% set values = { '1':'開けっ放し', '0':'CLOSE'} %}
      {{ values[value_json.isLeaveOpen] if value_json.isLeaveOpen in values.keys() else 'CLOSE' }}
    icon: mdi:door-open

sb_open_sensorを実行

お疲れさまでした。ここまでのソースコードが書けたら早速実行します。

まずはDockerのビルドを行います。

Terminalで以下のコマンドを実行してください。

cd config/sb_open_sensor
docker build . -t sb_open_sensor

実行するとこんな感じのログが表示されます。最後にSuccessfullyとなっていることを確認してください。

そして、最後に以下のコマンドで実行します。

docker run --rm --net host --privileged -it sb_open_sensor

成功すれば、このようにログが表示されます。

そして、オーバービュー画面に戻ると以下のように表示されています。

まとめ

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

SwitchBotの開閉センサーの連携ができたと思います。

もしご不明な点があれば、気軽に問い合わせフォームやTwitterでご連絡ください。可能な限り素早く返信します。

問い合わせ

Twitter

SwitchBotに登録したエアコンをコントロールする方法も紹介しています。こちらも読んでみてください。

今回はPythonを使ってコードを書いています。Pythonを知らなくてもほぼコピペするだけで動くように頑張って紹介していくつもりですが、Pythonの基本は知っておくことで、理解も深まりますし、アレンジもできるようになります。少し不安を感じる人は、以下の参考書を使って勉強してみることをおすすめします。

↓超入門書

↓初級本

また、Home Assistantやスマートホーム関連の記事はこちらにまとめていますので、ぜひこちらも読んでみてください。

この記事を書いた人
author

ユキヒト

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