Smart HomeをDIYする

Apple HomeKit は対応製品が少なくて高価なのでHomebridgeでがんばります

HomeKitでZigbeeを使う:Zigbee2MQTTを導入する

Zigbeeバイスは省電力でメッシュも構成するし応答も早くて、スマートホームに欠かせません。AmazonやAliExpressでは、お値打ちなZigbeeバイスが豊富に揃ってます。今回は、Zigbee機器をHomeKitから使えるようにするため、Zigbee2MQTTなどをインストールして設定しました。

ZigbeeバイスをHomeKitで使う2通りの方法

国内で簡単に入手できて、HomeKitでも使えるZigbee製品として、Philips HueまたはIKEAの製品があります。

Zigbee接続デバイスをLAN側から使う第一の方法は、それぞれの会社が提供するハブを買うことです。Zigbeeハブは、Zigbee無線ネットワークとLANを接続します。さらに、HomeKitに対応したIKEA/Philipsのハブには、ZigbeeバイスをHAP対応デバイスに見せてくれるブリッジ機能が備わってます。これによりHomeKitからZigbeeバイスが使えるようになります。こんな順番の接続です。

[HueとIkeaのデバイス]---[HueとIkeaのハブ]--(HAP)--[HomeKit]

2番目の方法は、メーカが提供しているハブを利用せずに、Zigbee2MQTTとHomebridgeを使う方法です。

[Zigbee]---[Zigbee2MQTT]--[Homebridgeなど]--(HAP)--[HomeKit]

ただ、ZigbeeバイスをHomebridgeで使うためには、プラグインに加えてハードウェア、ソフトウェアが必要です。Zigbeeの側から情報の流れに従って書くと、以下のユニットが必要です。

  1. USB送受信器:Zigbeeバイスと無線送受信するUSBアダプター
  2. Zigbee2MQTT:Zigbeeバイスと通信してMQTTブローカに伝えるデーモン
  3. Mosquitto:MQTTブローカーです
  4. Homebridgeとプラグイン:MQTT経由でZigbee2MQTTとやりとりするプラグイン

1, 2, 3までのユニットは、Home AssistantでZigbeeバイスを制御する場合にも使われるものです。また、2, 3, 4の部分は、WindowsmacOSNASなどでも動かせますが、通常はLinux系のサーバーで動かします。処理能力も要求されないので、Raspberry Piがよく使われます。

下の図に、必要なユニットを信号の流れる順番に示しました。左端のZigbee機器(たとえば電球)を右端のHomeKitに接続するためには、いろいろ用意する必要があります。

このうち、HomebridgeとMosquittoについては、以前の記事で詳しく説明してあります。

diysmarthome.hatenablog.com

diysmarthome.hatenablog.com

これらがすでに設定されている前提で、USBトランシーバ、Zigbee2MQTT、Homebridgeプラグインを追加する方法を説明します。なお、Zigbee2MQTTに関しては、プロジェクトのホームページに詳細な情報があります。これを参考にしました。

www.zigbee2mqtt.io

Zigbee2MQTTを使う理由

上で述べたように、メーカーが用意してくれるハブを買えば、ZigbeeバイスをHomeKitから使えます。しかし、Zigbee2MQTTを使えば、使えるZigbeeバイスが圧倒的に増えます。メーカーハブを買ってくるだけの方法に比べて、いろいろ揃えてインストールする手間は面倒ですが、その価値はあります。

Zigbeeは、情報のやり取りは決まってますが、上位のプロトコルまでは統一されていないようです。なので、たとえば同じ電球でも各社で互換性がありません。メーカのハブは、基本的に自社製品しかサポートしていないので、メーカーごとにハブを用意する必要があります。それに国内で買えるHomeKit対応Zigbeeハブは、IKEAのTRÅDFRIゲートウェイPhilips Hueブリッジだけです。

それに対して、Zigbee2MQTTのコミュニティでは、自分たちが入手したZigbee製品のデータを持ち寄って、対応デバイスを増やし続けています。なので、ある程度知られたデバイスなら、ほぼ使用可能です。もちろんIKEAPhilipsZigbee製品も使えます。またIKEAの場合、Zigbeeスイッチや人感センサは電球とペアリングして使うことになっていて、スイッチ・センサの情報をHomeKit側には公開していません。でもZigbee2MQTTを使えばこれらもHomeKit側から利用可能になります。

Zigbee2MQTTの対応デバイスこちらから確認できます

USBトランシーバ

WiFi, BLEはどのスマホにもノートPCにも搭載されていますが、Zigbeeは搭載されてません。なので、Zigbee電波を送受信するアダプターが必要です。ただそのアダプタも、WiFiやBLEのように豊富には出回ってません。

Zigbee2MQTTで使えるおすすめアダプターはこちらで紹介されてます。それによるとTexas Instruments社のCC2652というチップを使用した製品が推奨されてます。実際に購入して、Raspberry PiUbuntuマシンのUSBポートに挿すだけで、Zigbee2MQTTで使えた製品を2種類ご紹介します。

一つは、こちらの製品です。CC2652Pの方を買いましたが、CC2652Rでも動くのではと思います。検索してみたらPとRの違いはGPIOの数が違うくらいのようです。Zigbee2MQTT対応と書かれてます。

もう一つは、こちらのSonoffの製品です。上の製品よりも造りがしっかりしていて、価格も安くおすすめです。

ただし、Sonoff社には、別のSilicon Labs社チップを使った新製品があり、名前が紛らわしくて注意が必要です。失敗談はこちらをご覧ください。

diysmarthome.hatenablog.com

ちなみにSonoffのアダプタはAmazonでも売っているようですが、価格が高いです。

これらのUSBトランシーバを、Raspberry PiLinuxマシンのUSBポートに差し込むと認識されます。手元のRaspberry Pi 4でlsusbコマンドを発行すると、こんなふうに見えました。

$ lsusb
Bus 001 Device 003: ID 1a86:7523 QinHeng Electronics CH340 serial converter

シリアル変換のチップが入っているのでそれが認識されてます。シリアルチップは、特別にドライバをインストールしなくても、そのまま/dev/tty*に見えました。

$ ls /dev/tty*
/dev/tty    /dev/tty0  /dev/tty1  (略)  /dev/ttyUSB0

今まで使ったところでは、/dev/ttyUSB0もしくは/dev/ttyACM0という名前で現れることが多いです。macOSでもこの名前で現れました。USBトランシーバーを抜き差しすると、消えたり出現したりしますので、その挙動でも確認できます。この名前はZigbee2MQTTの設定で必要なので、メモしておきます。

Mosquittoのインストール

Zigbee2MQTTにはMQTTブローカーが必須なので、簡単に説明しておきます。こちらに書いた手順で、MQTTブローカであるMosquittoをインストールします。

diysmarthome.hatenablog.com

基本的には、aptコマンドでインストールするだけです。

sudo apt install mosquitto mosquitto-clients

また、OS起動時に自動的にMQTTブローカが立ち上がるように以下の設定をしました。

sudo systemctl enable mosquitto.service

Zigbee2MQTTをインストール

ではいよいよ、Zigbee2MQTTを公式ページの手順に従ってインストールします。色々なハードウェアにインストール可能ですが、Raspberry PiLinuxマシンにインストールするには、以下の公式ページのガイドが参考になります。

www.zigbee2mqtt.io

それによると、

# nodejsなどをインストールします。すでに入っているかもしれません。
# 公式ガイドのページではapt-getを使ってますが、aptに統一したいと思っているのでaptでインストールしました

sudo curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -
sudo apt install -y nodejs git make g++ gcc

# nodeとnpmのバージョンを確認します
node --version  # Should output v14.X, V16.x, V17.x or V18.X
npm --version  # Should output 6.X, 7.X or 8.X

# zigbee2mqtt用のディレクトリを作ります
sudo mkdir /opt/zigbee2mqtt
sudo chown -R ${USER}: /opt/zigbee2mqtt

# Zigbee2MQTT リポジトリをクローンします(よくわかってないです)
git clone --depth 1 https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt

# ディペンデンシーをインストールします(同上)
# ユーザを"pi"にしてますが、いつもログインするユーザが良いです
cd /opt/zigbee2mqtt
npm ci

これでエラーらしい表示が出なければokです。

次に設定ファイルを用意します。/opt/zigbee2mqtt/data/configuration.yamlにあるテキストファイルです。公式ページの設定例は以下です。

# MQTTの設定
mqtt:
  # MQTT base topic、なんでも良いです
  base_topic: zigbee2mqtt
  # MQTT server URL、ブローカーのアドレスです
  server: 'mqtt://localhost'
  # MQTT のユーザ、パスワードを設定している場合は以下を記入
  # user: my_user
  # password: my_password

# Serial の設定
serial:
  # USBトランシーバの接続場所です。今までの経験ではttyUSB0かttyACM0です。
  port: /dev/ttyUSB0
  # 以下の設定はおすすめらしいです
  advanced:
    network_key: GENERATE
  # 以下を指定しておくとwebから操作できます。とても簡単なのでお勧めです
  frontend: true

Zigbee2MQTTを起動する

起動させるには、

cd /opt/zigbee2mqtt
npm start

とします。いろいろメッセージが出ますが、エラーらしきものが出なければ成功です。止めるにはコントロールCを押します。

このコマンドで起動すると、自動起動などが面倒なので、systemctlを使います。まずは、/etc/systemd/system/zigbee2mqtt.serviceというファイルを作って、内容を、

[Unit]
Description=zigbee2mqtt
After=network.target

[Service]
ExecStart=/usr/bin/npm start
WorkingDirectory=/opt/zigbee2mqtt
StandardOutput=null
StandardError=inherit
Restart=always
RestartSec=10s
User=pi

[Install]
WantedBy=multi-user.target

とします。ユーザ名piで起動することになってますので、別の名前を使う場合は書き換えます。これで、

sudo systemctl enable zigbee2mqtt.service

とすれば、以後、自動的に起動します。とりあえず起動しておきたいので、

sudo systemctl start zigbee2mqtt.service

としておきます。startの代わりに、stop, restart, statusなどのコマンドが使えます。

プラグインを入れる

ここまでの作業で、

のほとんどが用意できました。Zigbee2MQTTは結果をMosquittoにパブリッシュしますので、HomebridgeはMosquittoとやりとりします。Mosquittoとのやりとりには、以前こちら

diysmarthome.hatenablog.com

で紹介したMqttthingを使うことも可能です。ただ、Zigbee2MQTTが出すMQTTメッセージに特化したプラグインがあるので、それを使ったほうが楽です。Homebridge z2mというプラグインで、Mqttthingを元に、Zigbee2MQTT向けに機能拡張されたプラグインだそうです。

z2m.dev

このプラグインの設定項目はほとんどありません。上で設定したMQTTブローカーのアドレスやbase topicなどを設定するだけです。他は全部未設定でokです。あとはZigbee2MQTTが検出したデバイスが自動的にHomeKitアクセサリとして現れるようになります。

以前に紹介したZigbeeバイスに関しては以下をご覧ください。いずれも今回の設定で、HomeKitから動かしています。

diysmarthome.hatenablog.com

diysmarthome.hatenablog.com

diysmarthome.hatenablog.com

diysmarthome.hatenablog.com

MQTTで設定する

Zigbee2MQTTは、MQTT経由で、いろいろな機能を提供しています。たとえば動作のすべての情報が、MQTTに流されているので、これをmosquitto_subコマンドでサブスクライブすれば確認できます。

mosquitto_sub -h localhost -t zigbee2mqtt/# -v

これにより、Zigbeeバイスをペアリングする場合、Zigbeeスイッチをon/offする場合など、その都度メッセージが表示されるので、動作確認ができます。

Zigbee2MQTTに対する命令も、mosquitto_pubで指示できます。たとえば、とあるidのZigbeeバイスのペアリングを外したい場合は、以下のようにします。

mosquitto_pub -h localhost -t zigbee2mqtt/bridge/request/device/remove -m '{"id":"0x9999999999999999"}'

ただ、次に説明するwebインタフェースの方が簡単です。MQTT経由での確認や操作は、あまり必要ないかもしれません。

Webで設定する

先のconfiguration.yamlファイルでfrontend: trueと設定しました。この設定により、webからの操作が可能になってます。デフォルトではポートが8080です。Webブラウザから、Zigbee2MQTTが稼働しているIPアドレスを指定して、http://192.168.xxx.xxx:8080/でアクセスします。するとZigbee2MQTTの動作確認、操作のためのページが以下のように表示されます。

いろいろな機能がありますが、GUIなので、操作を試して理解できます。

たとえば、上で、MQTT経由で試みたデバイス削除操作は、この画面のゴミ箱ボタンから可能です。ゴミ箱ボタンを押すと、下のようなダイアログパネルが出ます。

オプションのスイッチ、Force removeとBlock from joining againは重要です。まず、Zigbee2MQTTでのデバイス削除操作は、デフォルトでは、デバイスが接続している時のみ可能です。接続していないデバイスも、強制的にペアリング解消するスイッチがForce removeです。Force removeしても、またそのデバイスからの電波が届くと、通常はペアリング再開します。それも阻止するのがBlock from joining againボタンです。これらのスイッチを使ってペアリング解除したデバイスは、デバイスをリセットする操作(ボタンを長押しするとか、何回かon/offを繰り返すなど)をして、ペアリングモードに戻してから、他のシステムで再利用することになります。

また、右上のPermit join (All)のメニューは、ペアリングを開始するメニューです。先のconfiguration.yamlで、permit_join: trueという指定をすると、Zigbee2MQTTが常時ペアリングする設定になります。デフォルトではpermit_join: falseで、ペアリングしません。それを一時的にペアリング可能状態にするのがこのメニューです。クリックすると5分間有効になります。その状態で、ペアリングモードにしたデバイスを近づければ、ペアリングされます。 

Dashboardメニューを選べば、それぞれのデバイスの状態を見て、操作が可能です。

また、Mapメニューを使うとデバイスの接続状態を見ることができます。

この例では、デバイスが少なく、end deviceしかありません。routerになるデバイスがあるとZigbeeのメッシュ接続の様子がわかって面白いです。電球などの消費電力に制約のないデバイスが電波を中継するルータになってくれます。

Zigbee2MQTTを更新する

対応するZigbee製品は増え続けているので、時々アップデートしたいところです。手順は公式ページのここに書いてあります。

# Zigbee2MQTTを停止する
sudo systemctl stop zigbee2mqtt
cd /opt/zigbee2mqtt

# 設定情報をバックアップする
cp -R data data-backup

# 更新する
git pull
npm ci

# 設定情報を復帰する
cp -R data-backup/* data
rm -rf data-backup

# Zigbee2MQTTを始動する
sudo systemctl start zigbee2mqtt

data以下をバックアップしておけば、ペアリング情報や設定状態は保存しておけるようです。

まとめ

Zigbee2MQTTを使って、市販のZigbeeバイスをHomeKitから使うための設定手順をまとめました。これで、市販されている大半のZigbee対応製品を、HomeKitから使用できるようになります。

Zigbeeは、WiFiと比較すると省電力にもかかわらず、メッシュネットワークを構成するので、広い範囲をカバーできます。BLEも似た特徴を持ちますが、安定性や応答速度などでZigbeeの方が優れているような印象があります。これからはZigbeeはThreadに移行していくらしいですが、物理層データリンク層Zigbeeと共通なので、低電力で応答の良いという特長は引き継がれると思います。