MqttthingとZigbee2MQTTプラグインを使い分ける

HomeKitを使う

Homebridgeのプラグインは多数用意されていますが、手元の環境で一番活躍しているのは、

  • Homebridge MQTT-Thing (以下mqttthingプラグイン) と
  • Homebridge Zigbee2MQTT (以下z2mプラグイン)

の2個です。これらを、同じくRaspberry Pi 4で稼働している、MQTTブローカー (Mosquitto)とZigbee2MQTTサーバと組み合わせて使ってます。その構成と使い分けについて説明します。

MQTT関連の構成

Raspberry Piの内部構成を上の図に示しました。Raspberry Pi 4の上では、

  • Homebridge
  • Mosquitto (MQTTブローカー)
  • Zigbee2MQTT

の3個のプログラムが常駐して動いています。これらのインストール方法はこちらで説明しました。

次に、Raspberry Piに接続するアクセサリ類を下の図に示します。Zigbeeデバイスは、Zigbee-USBアダプタ(Zigbee無線の送受信器)を介してZigbee2MQTT (以下Z2M) に接続し、これがMQTTブローカーにメッセージを送ってます。また、ESP32でいろいろDIYしているコントローラは、WiFi経由でMQTTブローカーにメッセージを送ってます。

Homebridgeでは、mqttthingプラグインとz2mプラグインが稼働していて、これらもMQTTブローカーと通信しています。このように、MQTTがこの構成の中核になっています。

mqttthingプラグインの仕事

mqttthingプラグインが有効になっている場合、Homebridgeにmqttthingの設定を記述すると、HomeKitアクセサリを作ってくれます。例えば、ESP32で壁スイッチをDIYして、Mosquittoに接続して、MQTTメッセージを送受信する場合を考えます。このMQTTメッセージをHomeKitに反映させるために、mqttthingプラグインを使います。

この時、例えば、Homebridgeのmqttthing部分の設定として以下を記述したとします。(一覧できるようにテキスト設定を示しましたが、webインタフェースのGUIでも設定できます。)

{
  "type": "switch",
  "name": "Wall Switch",
  "url": "mqtt://localhost",
  "topics": {
    "getOn": "mqttthing/wallswitch/get",
    "setOn": "mqttthing/wallswitch/set"
  },
  "accessory": "mqttthing"
},

この結果、Wall Switchという名前のスイッチアクセサリが、iPhoneやMacのホーム.app画面に表示されるようになります。

このスイッチの動作は、設定で記述したMQTTトピックに連動します。

  • 例えば、ユーザが画面上のGUIスイッチをon/offすると、mqttthing/wallswitch/setトピックにtrue/falseというメッセージが流れ、ESP32に伝達されます。
  • ESP32で実装した物理スイッチをユーザがon/offした場合は、ESP32のプログラムでmqttthing/wallswitch/getトピックにtrue/falseメッセージを流せば、ホーム.app上のこのGUIスイッチがon/offに変化します。

z2mプラグインの仕事

z2mプラグインも、mqttthingプラグインと同様に、MQTTブローカーに接続してメッセージ応答しています。こちらはZ2Mが関係するトピックをモニターし、メッセージを送受信します。

例えば、ZigbeeネットワークにZigbee壁スイッチ製品が接続されたとします。

その情報がZ2MによってMQTTに流されると、z2mプラグインは自動的にスイッチアクセサリを作ります。これはiPhoneやMacのホーム.appにすぐに表示されます。

そしてZ2Mの情報に基づいて、壁スイッチ(実世界のスイッチ)の状態をHomeKitスイッチアクセサリに反映させます。また画面上のスイッチアクセサリがユーザによって操作されると、z2mプラグインはMQTT経由でZ2Mに動作状況を知らせます。これがZigbee無線経由で壁スイッチに伝わります。

mqttthingでZ2Mを使う

Z2MはMosquittoにMQTTメッセージを流していますが、このメッセージはMosquittoに接続できる権限があれば誰でも見られます。なので、z2mプラグインが提供する機能と同じ機能を、mqttthingで実現することも可能です。

例えば壁スイッチの場合、これが操作されるとZ2Mは以下のようなメッセージを流します。

zigbee2mqtt/0x9999999999999999/set {"state":"ON"}

0x9999999999999999の部分はこのデバイスのIDで、これはZ2Mでわかりやすいfriendly nameに変更可能です。以下ではこのまま説明します。このメッセージにmqttthingプラグインが反応するように、以下のようにHomebridgeに設定します。

{
  "type": "switch",
  "name": "Wall Switch",
  "url": "mqtt://localhost",
  "topics": {
    "getOn": "mqttthing/0x9999999999999999/get$.state",
    "setOn": "mqttthing/0x9999999999999999/set$.state"
  },
  "onValue": "ON",
  "offValue": "OFF",
  "accessory": "mqttthing"
},

topicsの指定で、$.を使用すると、json形式のキーを指定できます。今回のメッセージでは、{“state”:”ON”}というjson形式を使っているので、stateの値を取得するために上記のように設定しました。また、mqttthingのデフォルトでは、スイッチon/offの値がtrue/falseですが、Z2Mが送るメッセージではON/OFFです。なので、onValue/offValueで、ON/OFFをスイッチの値とするよう変更してあります。

これで、z2mプラグインを使用しなくても、mqttthingプラグインだけでZ2Mのデバイスにアクセスできます。

z2mプラグインのメリット

このように、mqttthingだけを使ってZigbeeデバイスを使用することもできます。z2mプラグインは、もともとmqttthingプラグインを基礎にして拡張したプラグインなので、同じことができて当然らしいです。

でもmqttthingで設定する場合、Zigbeeデバイスの振る舞いを、一つ一つ手作業で設定ファイルに書き込んでいく必要があります。上記の例では、どのメッセージでon/offになるのか、書き出していく必要がありました。

z2mプラグインは、Z2Mの状況を把握して、Zigbeeデバイスを自動的に検出して、Homebridgeに自動登録してくれます。ZigbeeデバイスをZ2Mにペアリングするだけで、あとは自動的にHomebridgeにアクセサリとして現れるので、とても楽です。なので、Z2MとペアリングしたZigbeeデバイスは、通常はz2mプラグインで使用します。

それでも、mqttthingプラグインを使いたい場面も稀にあります。例えば、mqttthingにだけ用意されているhistory機能を使ってグラフ表示したい場合は、mqttthingプラグインを使います。

HomeKitアクセサリの履歴をグラフ表示する
Eve for HomeKitというiPhoneアプリは、Apple純正のホーム.appに相当するアプリで、HomeKitアクセサリを操作します。純正アプリの機能に加えて、温度センサーなどの履歴をグラフ表示する機能があります。グラフ化はEv...

非対応Zigbeeデバイスを除外する

z2mプラグインがHomeKitアクセサリとして見せてくれるZigbeeデバイスが、「非対応」なアクセサリとして表示されてしまうことがあります。こちらで紹介したZigbee方式の学習リモコンがその一例です。

このリモコンをZ2Mとペアリングすると、次のように学習リモコンのような動作をします。

  1. 学習モードで学習した赤外線リモコンパターンを、MQTTメッセージで伝えてくれます。
  2. 次に、そのパターンをMQTT経由でリモコンに送れば、赤外線パターンを送出します。

Apple HomeKitには、学習リモコンを定義したアクセサリは存在しません。赤外線リモコンでは、機器の現在の状態を取得できないので、スマートホームから排除したいと考えているのかもしれません。z2mプラグインは、定義されていないデバイスもアクセサリとしてHomeKitに伝達するので、このデバイスはホーム.app上では非対応と表示されてしまいます。

無害ですが、表示されるだけで何の操作もできないので邪魔です。この場合、z2mプラグインに、「このデバイスは使わないからHomeKit側に見せないでください」とお願いすることができます。これには、Homebridgeのz2mのプラグイン設定から、IDまたはFriendly nameを指定して、デバイス全体を除外するように設定します。

同じことは、テキスト形式の設定ファイルでも指定できます。

{
  (略)
  "devices": [
  {
    "id": "0x3333333333333333",
    "exclude": true
  },
  (略)
  "platform": "zigbee2mqtt"
},

この結果、該当するデバイスはz2mプラグインの対象から外れて、HomeKitのホーム.appには表示されなくなります。

まとめ

Zigbee2MQTT (Z2M) とペアリングしたZigbeeデバイスは、Homebridge Zigbee2MQTT (z2m)プラグインが適切に判断して、HomeKitアクセサリとして表示してくれます。この時に利用しているMQTTブローカにアクセスすれば、Homebridge Mqttthing (mqttthing)プラグインを使ってHomeKitに表示することも可能です。z2mの対象からデバイスごとに除外設定できるので、デバイスに合わせて2つのプラグインを使い分けることもできます。

コメント

  1. masahiro より:

    こんにちは
    日々こちらの記事で勉強させていただいております。
    実用性があり、自宅のスマート化を楽しんでおります。

    さっそくなのですがこちらの記事で質問がございます。

    MQTTthingとzigbee2MQTTの使い分けなのですが

    コード

    “topics”: {
    “getOn”: “mqttthing/0x9999999999999999/get$.state”,
    “setOn”: “mqttthing/0x9999999999999999/set$.state”
    },

    で情報を取得すると思うのですが

    MQTTエクスプローラで確認すると

    zigbee2mqtt/0x9999999999999999

    mqtthing/0x9999999999999999

    個体識別の番号が一致していればその前の部分はそれぞれzigbee2mqttでもmqtthingでもよいのでしょうか?

    また具体的には

    情報を取得したいほうのvalueには

    {“action”:”wakeup”,”battery”:100,”current”:0,”device_temperature”:24,”linkquality”:123,”power”:159,”power_outage_count”:475,”side”:3,”voltage”:3045}

    このような表示があります。

    その場合、例えば

    “topics”: {
    “getOn”: “mqttthing/0x9999999999999999/get$.action”,
    “setOn”: “mqttthing/0x9999999999999999/set$.action”
    },
    “onValue”: “wakeup”,

    これでactionがwakeupになったときにhomekit側でオンになる

    という認識でした。

    情報の取り方に誤りがありますでしょうか。

    ※端末はZ2Mを利用して登録済みです。

    • diysmartmatter より:

      質問ありがとうございます。

      zigbee2mqtt/0x9999999999999999

      mqtthing/0x9999999999999999
      個体識別の番号が一致していればその前の部分はそれぞれzigbee2mqttでもmqtthingでもよいのでしょうか?

      ベーストピック名は
      /opt/zigbee2mqtt/data/configuration.yaml
      に書いてあるものと同じにします。ここに

      mqtt:
        base_topic: zigbee2mqtt

      と書いてあればzigbee2mqttがベーストピックになります。この場合、mqttthingというベーストピックのメッセージはZ2Mには伝わりません。
      configuration.yamlの記述を変えれば、任意のものにできます。

      ちなみに0x9999999999999999の部分も、configuration.yamlのfriendly_name記述で任意のわかりやすい名前に変更可能です。Z2MのWeb UIの画面からも変更可能です。

      情報を取得したいほうのvalueには

      {“action”:”wakeup”,”battery”:100,”current”:0,”device_temperature”:24,”linkquality”:123,”power”:159,”power_outage_count”:475,”side”:3,”voltage”:3045}

      このような表示があります。

      その場合、例えば

      “topics”: {
      “getOn”: “mqttthing/0x9999999999999999/get$.action”,
      “setOn”: “mqttthing/0x9999999999999999/set$.action”
      },
      “onValue”: “wakeup”,

      これでactionがwakeupになったときにhomekit側でオンになる

      という認識でした。

      mqttthing/0x9999999999999999/setというトピックに、{“action”:”wakeup”}というメッセージを送った場合にOnにできるようでしたら、この設定でokです。ただこの設定だと、Offにする場合はデフォルトのままなので{“action”:”false”}というメッセージが送られてしまいます。これで問題なければ、この設定でokです。

      ちなみにこれはどんなデバイスですか?電力が読めるスマートプラグでしょうか?

  2. Masahiro より:

    ご丁寧にありがとうございます。

    z2m mqttthin設置ファイルを確認しベーストピックを確認してみます!

    デバイスに関してはAwaraのマジックキューブを使用しています。

    get set on value off valueに関しては柔軟にいじってみます!

    まずはz2mとMQTTthingのベーストピック一致を目指します!

  3. masahiro より:

    おかげさまで、ベーストピックを一致させることで思うような挙動になりました!
    ありがとうございます。

    z2mは導入には良いですが、細かいアクションを操作するためにはmqttthingを利用しないとですね。

    記事だけでも生活が豊かになりますが
    細かなサポートいただけるおかげでさらに良い環境が作れました。
    ありがとうございます。

  4. Masahiro より:

    まさに、このデバイスです!

    アクション以外にも、現在どの面が上に向いているかや、キューブの転がし方90度回転180度回転など、細かく設定ができそうなので、幅が広がります。
    我が家では、これをトリガーにして、HomeKitのシーン選択をしようと考えています。

タイトルとURLをコピーしました