HAAを使って超簡単にHomeKitデバイスを作る

スマートホームデバイスは、Apple のホームアプリで使える HomeKit や Matter に対応したものは、しばしば高価で、メーカー独自のサーバーを経由して通信するため、セキュリティ上の懸念がつきものです。 そんな理由から、多くのユーザーが自分でスマートホームデバイスを作ろうと試みています。たとえば、有名な Homebridge もその一例ですが、Raspberry Pi などのコンソールが必要で、コマンドラインとの対決も避けられません。 かつて私も Homebridge での構築を試みましたが、頻繁な接続の切断に悩まされ、結局使用しなくなりました。

さらに、ESP32-Arduino 用の Matter ライブラリや MQTT を使用してブリッジを介して通信する方法も存在しますが、これらはプロトコル的に一工程を必要とし、安定性の確保が難しかったです。というかほぼ使い物になりません。

そこで、今回はあまり知られていないかもしれませんが、 すぐに構築でき、(現時点では)安定性が確保されている HAA+ESP32 を使用したスマートホームデバイスの作成方法をご紹介します。

HAA とは

HAA – Home Accessory Architect

RavenSystemさんのオープンソースプロジェクトで、ESP チップにファームウェアを書き込み、HomeKit デバイスを作ることができます。HomeKit へのサポートはネイティヴ(!)であり、ブリッジを必要としません。 センサーやスイッチなどを繋げることができたり、UART や HTTP リクエストを送ることもできます。そしてそれらの設定はMEPLHAA スクリプトと呼ばれる JSON な独自構文をデバイスにアップすることで完了します。

MEPLHAA スクリプトを使い、HomeKitアクセサリを構築し、それをサービスとして使います。

今回行うこと

今回は、基本的な HAA のセットアップを行い、 次に湿度・温度センサー(DHT22)とリレーを接続し、温度や湿度をモニターしファンを回す簡単なスマートデバイスを作ろうと思います。

必要な材料

  • ESP32 / ESP8266 が乗ったボード
  • PC または Mac(esptool.py が利用可能である必要があります)
  • 湿度温度センサー(DHT22)
  • リレーなどの部品

使えるチップ

ESP32 や ESP8266 に対応していますので、余っているやつでトライしてみてください。

  • ESP8266
  • ESP32
  • ESP32 1-Core
  • ESP32 C2
  • ESP32 C2
  • ESP32 C3
  • ESP32 C6
  • ESP32 S2
  • ESP32 S3

ESP32 が乗った DevKitやNodeMCU は Amazon などでかなり安い価格で販売されています。メジャーなやつを買いましょう。

また、小型化を目指すなら Seeed Studio XIAO ESP32-C3 もいいかもしれません。

注意なんですが、HAA はカメラやディスプレイには対応しないと明言されています。 つまり、Seeed XIAO ESP32-S3 をドアカメラにしたり、M5Stack をモニター端末として使うことができません。

センサーとリレー

センサーはメジャーなDHT22を使います。

リレーは、3.3Vで動くやつを使います。古典的なやつです。ACも使えるので照明の操作とかもできます。

ソリッドステートリレーの名で、フォトカプラが安価で売ってますが電流値が低く照明や動力にはほぼ使えません。古典的なやつを買いましょう。

インストール手順

ファームウェアの準備

[Release ページ][https://github.com/RavenSystem/haa/releases] から自分のボードにあった bin ファイルをダウンロードします。 自分の持っているボードに乗っているチップがわからない場合は、以下を参考にして下さい。 メジャーなものを取り上げました。

ボード bin ファイル
ESP32-WROOM-32, NodeMCU-32, ESP32 DEVKIT V1 fullhaaboot_esp32.bin
ESP-WROOM-02,Wemos D1, D1 mini fullhaaboot.bin
Seeed XIAO ESP32C3 fullhaaboot_esp32c3.bin
ESP32-C6-WROOM-1,ESP32-C6-DevKitC fullhaaboot_esp32c6.bin
Seeed XIAO ESP32S3 fullhaaboot_esp32s3.bin

ダウンロードしたら、わかりやすいところに置いておきます。

esptool.py (オプション)

この記事をここまで読める人には関係ないと思いますが、ESP ファミリーにファームウェアを書き込むためにesptool.pyを使います。 つまり、Python も必要です。 Python 2.7 か 3.4 以上をインストールし、esptool.pyをインストールしましょう。 (Python3 推奨です)

$ pip install esptool

ファームウェアの書き込み

  • esptool.pyを使いフラッシュを消去します。繋がっているボードを勝手に認識するので、書き込むボードのみを PC に接続して下さい。
python3 -m esptool erase_flash
  • ファームウェアの書き込みをしますが、ESP32 と 8266 でコマンドが違うので、以下を参考にして下さい。
  • (ESP32)ファームウェアの書き込み
python3 -m esptool -b 460800 --before=default_reset --after=hard_reset write_flash -fs 2MB -fm dio 0x0 <さっきのbinファイル>
  • (ESP8266)ファームウェアの書き込み
python3 -m esptool -b 115200 --before=default_reset --after=hard_reset write_flash -fs 1MB -fm dout 0x0 <さっきのbinファイル>

Mac なら、<さっきのbinファイル>以前までをコピペして、bin ファイルをターミナルにドラッグ&ドロップすれば、bin ファイルの場所が入ります。

  • これでファームウェアの書き込みができました。ボードの起動を待ちます。

HAA BOOT モードでボードを WiFi に繋ぐ

  • まず、アドホックで PC や Mac や iPhone からボードに繋ぎます。 デバイス本体設定の WiFi 設定で、HAA-xxxxxxという WiFi を探します。 (例えば以下のように WiFi 一覧に現れます)

この WiFi に接続します。

次に、Web ブラウザ(Safari など)を開き、設定用の URL にアクセスします。


http://192.168.4.1:4567
  • すると、次のような画面が出ます

MEPLHAA スクリプトが準備できているなら、この画面で入れることができます。あとで説明します。

  • Search WiFi」ボタンを押して、家の中の WiFi を探し選びます。
  • Password」 というところにパスワードを入れて、上にある緑の「Save」ボタンを押します。
  • 「OK」(渋いセリフフォント)と潔く小さく表示されるので、ページを閉じて家の WiFi に繋ぎます。(iPhone なら勝手に切り替わりました)

ちなみに、”HAA BOOT”モードというのは、さっきのオレンジの画面のことを指します。

ホームに追加する

これは別にいつのタイミングでも良いんですが、iPhone のホームアプリからデバイスをホームに追加します。 ここから QR コードを見つけ出して、ホームのアクセス追加から読み取ります。

なお、HAA の HomeKit コードを手動で入力することもできます。

0218-2017

我が家にはたくさんの HAA デバイスがありますが、1 回登録すればデバイスが変わろうともペアリングの必要はありません。

HAA デバイスを探す

これが結構難儀です。 HAA と化した ESP32/8266 ボードの IP アドレスを探して、アクセスしないといけません。 以下のような方法があります。

  • Fing のようなローカルネットワーク検索アプリを使う
  • ルーターにアクセスして IP アドレスを探す
  • シリアルモニターに帰ってくる IP アドレスを見る

これがちょっと一手間なんですが、一番早く確認できる方法でやってみましょう。

Arduino IDE や PlatformIO を持っている人は、ESP32/8266 ボードのポートを選択して、シリアルモニターを開きます。

Arduino IDE を持っていないという素人か玄人は、screen/dev/tty.usbxxxxをモニターします。

ボーレートを合わせて(普通は 115200 です)、ボードをリセットします。 すると、ゴチャゴチャと色々帰ってきますが、その中で以下の様な部分を見つけます。


Connected (繋がっているWiFiの名前) DHCP start IP:192.168.11.37/255.255.255.0 GW:192.168.11.1

この中の、IP:192.168.11.37というのが今回作ったデバイスの IP アドレスになります。

HAA MAIN  モードにアクセスする

Mac や PC の Web ブラウザから、

http://192.168.11.37:4567

にアクセスします。さっきのオレンジの画面みたいな白い画面が出ます。 ちなみに、”HAA MAIN”モードというのは、この白いの画面のことを指します。

いよいよここに、MEPLHAA スクリプトというものを書き込んで、HomeKit アクセサリ化します。

MEPLHAA スクリプト

MEPLHAA スクリプトは形は JSON なのですが、アクセサリの指定や設定等、非常に単純化されており、シンプルに書くことができます。でもリファレンスがないとサッパリです。

以下に、今回構築するスクリプトを置いておきます。 1つのセンサーと 2 つの GPIO 出力を備えたデバイス


    {
        "c": {
            "n": "HAA-XXX1",
            "sn": "XXXXXX-AAA",
            "tz": "JST-9",
            "o": 1,
            "r": [
                {
                    "n": 0,
                    "s": 115200,
                    "p": 0,
                    "b": 0,
                    "g": [1]
                }
            ],
            "io": [[[12], 2], [4]],
            "l": 13,
            "b": [[0, 5]],
            "f": 1
        },
        "a": [
            {
                "t": 24,
                "n": 2,
                "g": 4,
                "k": 10,
                "j": 30
            },
            {
                "0": {
                    "r": [[12, 0]]
                },
                "1": {
                    "r": [[12, 1]]
                },
                "t": 1,
                "d": 3600,
                "s": 5,
                "b": [[0]]
            }
        ]
    }

簡単に説明します。

“c”

"c" は Config、つまり設定ブロックを表します。この中には、

コマンド 意味
"n" デバイスの名前 "HAA-XXXXXX"
"sn" シリアルナンバー "XXXXXX-<Acc#>"
"tz" タイムゾーン "JST-9"

というかんじにデバイス固有のものを記載しますが、正直なくても動作します。

"io" には、使用するボードの GPIO ナンバーを入れて宣言します。 これがなければ、一切の GPIO 操作ができません。 僕は一回ここで詰みました。必ず入れる様にしましょう。

[[GPIOナンバー] , 引数]

のように指定している部分がありますが、以下の様になってます。

モード 説明
0 無効 (デフォルト)
1 入力のみ
2 出力のみ
3 オープンドレイン付きの出力のみ
4 * 出力および入力、オープンドレイン付き
5 * 出力および入力
6 入力のみ、バイナリ入力(ボタン/スイッチ)サポート付き
7 ソフトウェア PWM、出力のみ
8 ソフトウェア PWM、オープンドレイン付きの出力のみ
9 * ハードウェア PWM、出力のみ
10 * ADC 入力

ちなみに、なくても Arduino でいうpinMode()が無い状態なので別に動きます。

GPIO の設定はここに詳しく書いてあります。

他の部分もさらっと説明します。

"o" は、ログの残し方

"r" は、UART の設定。使わなければ必要ありません。

"l" には、ステータス LEDの設定。

"b" には、セットアップモードに入るためのボタン GPIO 設定。

"f" には、ボタン入力のデバウンス設定

この辺は、僕もよくわからず入れております。このほかにも使えるコマンドがあり、かなり高機能です。 General Configurationを参考にしてみて下さい。

“a”

"a"には、アクセサリの設定が入り、{ }で区切られます。 HomeKitで対応されているアクセサリなら、ある程度再現できる様です。 Service Typesを参考にして下さい。

ここでは、今回使うアクセサリ設定を書きます。

温度・湿度センサー


{
    "t": 24,
    "n": 2,
    "g": 4,
    "k": 10,
    "j": 30
}
セクション キー 説明
Actions “t” アクセサリの種類
Sensor GPIO “g” 接続されているGPIOラインのセンサー
Sensor Type “n” センサータイプ
Sensor Polling Time “j” センサーの読み取り頻度(秒)
Humidity Offset “k” 適用する補正オフセット(湿度)
Temperature Offset “z” 適用する補正オフセット(温度)
Sensor Index “u” 同じGPIOに複数のセンサーが接続されている場合に使用するセンサー。DS18B20のみ

アクセサリの種類には、

タイプ アクセサリの種類
22 温度センサー
23 湿度センサー
24 温度および湿度センサー

センサータイプ には、

タイプ アクセサリの種類 説明
1 22, 23 & 24 DHT11 温度および湿度センサー
2 22, 23 & 24 DHT22 Type 1 (デフォルト) 温度および湿度センサー
3 22 DS18B20 温度センサー
4 22, 23 & 24 Si7021 1-Wire バージョン 温度および湿度センサー
5 22 ADC NTC サーミスタ
6 22 ADC PTC サーミスタ
7 22 Raw ADC NTC サーミスタ
8 22 Raw ADC PTC サーミスタ
9 23 Raw ADC 湿度センサー
10 23 Raw ADC 湿度センサー (反転ロジック)
100 22 ビルトインチップ温度センサー (ESP32-C および ESP32-Sのみ)

とあります。 今回はDHT22を使いますので、"2"を選んでいます。

また、DHT22は温度が10℃ほど低く出る様でしたので、"k" 温度オフセットを使っています。

GPIO出力(スイッチ、LED、ファン)


{
    "0": {
        "r": [[12, 0]]
    },
    "1": {
        "r": [[12, 1]]
    },
    "t": 1,
    "d": 3600,
    "s": 5,
    "b": [[0]]
}

"0"でオフの状態のGPIOのステートを、 "1"でオンの状態のGPIOのステートを設定します。

セクション キー 説明
Actions “0”, “1” など サービスが実行するアクション
Binary Inputs “b” 特定のアクションを呼び出すGPIO
Inching Time “i” サービスをオフ状態に戻すまでの時間
State & Status Inputs “f[n]” & “g[n]” サービスの状態を管理する入力
ICMP Ping Inputs “q[n]” & “p[n]” サービスの状態を管理するPing入力
Service Notifications “m” 他のサービスから送信される通知
Initial Lock State “ks” 起動時のロック状態
Initial State “s” 起動時にサービスが入る状態
Maximum Use Time “d” サービスがオンになれる最大時間
Actions on Boot “xa” 起動時のサービスアクションの実行を有効/無効にする
スイッチサービスについては、Switchesに詳しくあります。

というふうに項目がありすぎて書くのがめんどくさいんですが、MEPLHAA スクリプトを使って任意のアクセサリを作ることができます。

ハードを接続する

この時点でホームアプリにはHomeKitアクセサリとして表示されると思いますが、虚無を操作することしかできないので、センサーとリレーを接続します。 さっきのMEPLHAA スクリプトを使って、DHT22から温度と湿度を取得し、ホームアプリのオートメーションからファンを回せる様にします。

ESP32 DevKitV1を使ってます。GPIO番号などは使っているボードやセンサーなどによって都度読み替えて下さい。 さっきのスクリプトの通りに行くならこれで動きます。 MEPLHAA スクリプトを書く前にArduinoでテストコードを書いて、ハードウェアでチェックしても良いかもしれませんね。

ちなみに、ホームアプリからはこんな感じに見ることができます。
 dro

熱帯ドロセラ(食虫植物)を栽培している温室水槽に丸ごと入れてます。 また、オートメーションを使って、温度や時間によってファンを回す様にしています。


くぅ~疲れましたw これにて完結です!

実は、GitHubでたまたまプロジェクトを見つけたのが始まりでした

本当はブログに書こうとは思わなかったのですが←

やってみたらクッソ意味わからず、他に挑もうとする日本人のガイドになろうと思った所存ですw

🛠Makeの最新記事