HomeKitオートメーションをホーム.appとEveで作る

Apple対応品を使う

HomeKitの仕様では、例えばアクセサリA, B, Cがあった場合に、

「AがOnになったときに、BがOnならば、CをOnにする」

というオートメーションを実行できます。しかし、ホーム.appにはこれをストレートに記述する方法がありません。でもサードパーティのアプリEve for Matter & HomeKit(以下Eve)を使うと、作成できます。

この記事では、HomeKitで実行可能なオートメーションのタイプについて調べました。そして、ホーム.appでも作れるオートメーションと、Eveでしか作れないオートメーションを紹介します。Eveで作ったオートメーションは、ホーム.appで閲覧したり手直しできるので、両方の長所を組み合わせたオートメーションを作れます。

HomeKitのオートメーション

HomeKitが提供するオートメーションを説明します。

用語の説明

まずは用語の説明です。HomeKit APIでの名称が、プログラマ向けで、一般の感覚とズレているためか、ホーム.appやEveでは色々な用語が使われてます。この記事では、HomeKit APIの考え方に沿って、オートメーション、イベント、条件、アクションセットという用語を使うことにします。それぞれの用語の対応を下の表に示します。用語のバリエーションから、意味を汲み取れるかと思います。

記事での用語 HomeKit API ホーム.appの画面 Eveの画面
オートメーション Trigger(HMEventTrigger) オートメーション ルール
イベント Event(HMEvent) 「いつ」 トリガ
条件 Predicate 「〜の場合のみ」 条件
アクションセット Action Set(HMActionSet) シーン、またはアクセサリの指定(アクション) シーン

オートメーション:HomeKit APIでは、自動化のルールのことをTriggerと呼んでいます。ここでは、ホーム.appの用語に従って、引き続きオートメーションと呼ぶことにします。

オートメーションは、イベント、条件、アクションの3つのパートから構成されます。

イベント:HomeKit APIでもEventです。オートメーションを開始するきっかけにあたる部分です。「いつ」開始するかを決める内容です。

条件:HomeKit APIでは、Predicateというプログラマ向けの分かりにくい用語を使ってます。英語としては「述語」という意味ですが、プログラムでは「条件関数」と訳されてます。その名のとおり、イベントで開始したオートメーションを、実行するかどうかの条件です。「〜の場合にのみ」実行するという、条件を決める部分です。

アクションセット:HomeKit APIの用語であるaction setに合わせました。アクセサリの値を変更する(プラグをOnにするなど)操作をアクションと呼び、それを複数まとめたものがアクションセットです。イベントで開始され、条件を満たした場合に、一つまたは複数のアクションを実行します。アクションセットのうち、名前がついてシーンの一覧に表示されるセットが、シーンです。シーン一覧をユーザがタップすると、指定された一連のアクションが実行されます。名前が無く、シーン一覧に表示されず、ユーザが実行できない、アクションセットもあります。そのようなアクションセットは、オートメーションだけが使います。後述のように、Eveでは、名前が無いアクションセットをカスタムシーンと呼んでます。

ということで、オートメーションの流れは、

  1. イベントで以下を開始する:
  2. 条件が成立したときに、
  3. アクションセットを実行する。

の3ステップで動作します。

オートメーションの例

最も単純なオートメーションとして、条件のないパターンが考えられます。例えば、

  1. イベント:スイッチがOnになったら、
  2. 条件:(なし)
  3. アクションセット:照明を点灯する。

のようなオートメーションです。また、イベントや条件には、アクセサリの値(電源のオン・オフや、人を検知したかどうかなど。HomeKitでは特性=characteristic の値)のほかに、時刻、家族の在宅/不在/出発/到着などを指定できます。例えば、

  1. イベント:人感センサーが人を検知し、
  2. 条件:時刻が夜間なら、
  3. アクションセット:照明を点灯する。

のようなオートメーションです。また、イベントや条件には、複数の項目を指定できます。例えば、

  1. イベント:人感センサーA、またはB、またはCのいずれかが人を検知し、
  2. 条件:壁スイッチがOnで、かつ光センサーの照度値が小さかったら、
  3. アクションセット:照明を点灯する。

のようなオートメーションです。アクションセットの実行に関して、イベントの項目はORで寄与します。条件 (Predicate) に関しては、HomeKit APIの仕様ではORを含む複雑な条件も表現できるようですが、ホーム.appとEveでは、条件はANDで組み合わされます。

ホーム.appで作れるオートメーション

HomeKitの仕様では、上記のように様々なオートメーションを作れます。しかし、ホーム.appでは、すべてのオートメーションには対応していません。対応しているのは、

  1. イベント:アクセサリの値、もしくは時刻/家族の移動などの状況を、1個のみ
  2. 条件:時刻/在宅などの複数の状況(アクセサリの値は使えない)
  3. アクションセット:複数のシーンとアクセサリの操作(組み合わせ可)、またはショートカット1個

のようなオートメーションです。イベントに書ける項目は1個のみで、条件にはアクセサリの値を使用できません。かなり制限されています。

その代わり、アクションセットに、ショートカットを記述できます。これにより実行できる内容が大幅に広がります。アプリケーション間通信を利用して、様々なアプリケーションの機能を利用できます。大半は、どう使うのか不明なものが多いですが、中には、URLの内容を取得する機能もあります。これでWeb APIが呼べるようならば、色々対応できそうです。

ショートカットを使えば、「条件」にアクセサリの値を使えない点も、ある程度克服できます。ショートカットからホーム.appにアクセスして、アクセサリの値を得て、それを元にスクリプトを書けるからです。

次の節では、ホーム.appで作れないオートメーション例を紹介して、ショートカットで解決する方法と、Eveで解決する方法を示します。

警報器オートメーション

この先では、ホーム.appが不得手とするタイプのオートメーションを、どう作成するかについて説明します。

そのようなオートメーションの実例として、不審者が来たら警報ブザーを鳴らすオートメーションを作りたいとします。使うアクセサリは、

  • 人感センサー:IKEA MYGGSPRAYのようなスマートセンサーで、人を検知します。
  • 警戒中ランプ:IKEA KAJPLATSのようなスマート電球が、「警戒中」と印字された半透明のケースに入ってます。これが点灯していると、センサーが稼働して、警報ブザーを鳴らす状態にあることを示します。
  • 警報ブザー:IKEA GRILLPLATSのようなスマートプラグに接続された警報ブザーで、プラグの電源が入ると、大音量でブザーが鳴動します。

の3点です。ここで、単純に、

「人感センサーがOnならば、警報ブザーをOnにする」

というオートメーションを作ると、常時作動中になり、そこで生活している人を検知してもブザーが鳴ってしまいます。そこで、

  1. イベント:人感センサーがOnになったときに、
  2. 条件:警戒中ランプがOnならば、
  3. アクションセット:警報ブザーをOnにする。

というオートメーションを作ることにします。

これならば、警戒中ランプを、スマホ経由や、別のスイッチからOn/Offすることで、必要な時だけ、警報器を作動させることができます。

ちなみに、HomeKitでは、セキュリティシステムというアクセサリが、まさにこの用途のために用意されています。これを使えば、警報ブザーが動作したときに、iPhoneに警報音を伴った通知が届きます。また、留守、就眠中、在宅などの警戒モードを用意することもできます。以前、DIYで作成しましたので、実装したい方はそちらを参考にしてください。

ESP-01を使ってセキュリティシステムを作る
以前の記事で、AliExpressで安価に販売されているESP-01リレーモジュールを買って、Arduino IDEでプログラムして、HomeKitから使いました。ただこの時は、リレーを動作させただけで、実際に役立つ工作は行いませんでした。...

ホーム.appで作る

ここで作ろうとしている、

  1. イベント:人感センサーがOnになったときに、
  2. 条件:警戒中ランプがOnならば、
  3. アクションセット:警報ブザーをOnにする。

というオートメーションは、ホーム.appでは作れません。条件に、アクセサリの値を指定できないからです。なので代わりに、

  1. イベント:人感センサーがOnになったときに、
  2. 条件:(なし)
  3. アクションセット:「警戒中ランプがOnならば警報ブザーをOnにする」ショートカットを実行する。

ことにします。

まずは、「人感センサーがOnになったとき」というイベント部分を作ります。

人感センサーがOnになったとき」というイベント部分を作ります。

次へ、を選び、ショートカットに変換を選びます。これでショートカットエディタが現れますので、ここで以下のようなスクリプトを書きます。

スクリプトを書きます

これで、「警戒中ランプがOnならば警報ブザーをOnにする」部分を、ショートカットで実現できました。この結果、

「人感センサーがOnになったときに、警戒中ランプがOnならば警報ブザーをOnにする」

オートメーションが完成しました。実際にセンサーを反応させて試したところ、意図通りに動作しました。

Eveで作る

Eveならば、

  1. イベント:人感センサーがOnになったときに、
  2. 条件:警戒中ランプがOnならば、
  3. アクションセット:警報ブザーをOnにする。

というオートメーションを、ほぼそのまま実装できます。ただし、アクションセットには、シーンだけが記述できます。なので、「警報ブザーをOnにするシーン」を作って、それを実行します。なので、実際には、

  1. イベント:人感センサーがOnになったときに、
  2. 条件:警戒中ランプがOnならば、
  3. アクションセット:「警報ブザーをOnにする」シーンを実行する。

というオートメーションになります。

ちなみに、Eveは、iOSのアプリですが、Apple SiliconのMacならば、macOSでも動作します。素晴らしいです。以後では、MacでEveを操作した際のスクリーンショットを示します。

まずは、「警報ブザーをOnにする」シーンを作っておきます。

警報ブザーをOnにする」シーンを作っておきます。

次に、オートメーションを追加します。Eveでは、オートメーションのことをルールと呼んでいます。ルールを追加するには、トリガ、条件、シーンを組み合わせるとの指示があります。トリガが、ここでのイベントに相当します。

オートメーションを追加します。

ダイアログパネルの案内に従って、トリガ、条件、シーンの順に作っていきます。結果、以下のオートメーション(名前を警報器オートメーションとしました)が完成しました。

オートメーションが完成しました。

イベント(ここではトリガ)、条件、アクションセット(ここではシーン)が、完成していることがわかります。

実際にセンサーを反応させて試したところ、ホーム.appで作ったオートメーションと同様に、正しく動作することを確認できました。ただ、ホーム.app版より、応答が早いです。ホーム.app版は、1秒くらいの遅延がありますが、Eve版は瞬時に応答します。ショートカット呼び出しのオーバーヘッドと思われます。

Eve版オートメーションをホーム.appで修正する

次に、この記事で紹介されているホーム.appとEveを組み合わせる手法を使います。

Manual overrides for HomeKit automations
Smart home automations are cool, but sometimes go off when they’re not wanted. See how to use conditions to create a kin...

Eve版のオートメーションは、HomeKit本来の性能を活かし、ショートカットの力を借りずにスマートに実装できました。応答速度も速いです。でも欠点が一つだけあります。それは、オートメーションで実行する対象がシーンなので、オートメーション1つに、シーンが1つできてしまうことです。今回も、「警報ブザーをOnにする」というシーンができてしまい、ホーム.appの画面に表示されてしまいました。

「警報ブザーをOnにする」というシーン

そこで、Eveで作ったオートメーションを、ホーム.appで開き、シーンを実行する方式(下図左)から、アクセサリを直接操作する方法(下図右)に書き換えます。

Eveで作ったオートメーションを、ホーム.appで開く   

上のスクリーンショットでわかるように、「オフィスの警戒中ランプがオンの場合のみ」という注釈が追加されています。Eveで行った作業が、ここに表示されているのです。この部分は、ホーム.appでは削除も変更もできません。

ホーム.appでシーン操作を、アクセサリ操作に書き換えた後、Eveで確認してみます。すると、シーン名のところに、「カスタム(ホームApp)」と表示されます。先のステップで、ホーム.appで作ったアクセサリの操作が、カスタムシーンという名前になっています。無名の特製シーンという意味のようです。

カスタムシーンは、シーン一覧に現れず、ユーザ操作もできません。オートメーションだけに使われるアクションセットです。カスタムシーンは、HomeKit APIではトリガー専用のアクションセット(trigger-owned action set)と呼ばれるものです。これを作成する方法はサードパーティのアプリに公開されていないので、Eveからは作成できないらしいです。

これで、「警報ブザーをOnにする」というシーンは使われなくなりました。ホーム.appの画面から削除しても大丈夫です。今まで通り動作します。

もう少しだけ改良します。通常のシーンではなく、アクセサリを個別に操作するカスタムシーンに変更したことで、Onにした後、自動的にOffに戻す操作を指定できるようになりました。Onにした後に、例えば5分後にOffにする設定が可能になります。警報装置を実際に作るとしたら、警報が鳴り止まないのも迷惑です。5分後に停止するよう設定しておけば、この問題に対応できます。

警報器オートメーション(改良版)

次に、センサーが複数ある警報器を考えてみます。一般にセンサーの誤動作は避けられません。人がいないのに誤って検知してしまうと(誤陽性)、誤った警報ブザーが鳴り迷惑です。そこで、特性の違う人感センサーを組み合わせて、誤陽性による誤動作の軽減を目指します。

前のシナリオで想定した人感センサーIKEA MYGGSPRAYは、体温程度の物体の動きを検出する焦電センサーでした。これに、例えば、ミリ波を使って物体の微小な動きを検出するミリ波センサーを組み合わせ、どちらも感知した時だけ、警報ブザーを鳴らす方式に改良します。

焦電センサーミリ波センサー
焦電センサー(左)とミリ波センサー(右)

改良版のオートメーションは、以下の構成になります。

  1. イベント:焦電センサーがOn、またはミリ波センサーがOn、になったときに、
  2. 条件:警戒中ランプがOn、かつ焦電センサーがOn、かつミリ波センサーがOn、ならば、
  3. アクションセット:警報ブザーをOnにする。

これで、特性の違う2個のセンサーがどちらも検知した時だけ、警報ブザーを鳴らすことになります。

ホーム.appで作る

ホーム.appでは、複数のアクセサリをイベントに記述することができません。なので、一つのオートメーションでは書けません。「焦電センサーがOnになった時」と「ミリ波センサーがOnになった時」を別々のオートメーションにする必要があります。

さらに、前述のように、条件にアクセサリの値を組み込めません。なので、今までと同様、ショートカットで記述する必要があります。

Eveで作る

Eveならば、イベントにも、条件と同様に複数のアクセサリを記述できます。なので、先のオートメーションに、ミリ波センサーを加えるだけです。手順は、イベント、条件の項目を選んで、「追加する」ボタンを押して、アクセサリとその値を指定するだけです。細かい手順は割愛しますが、結果として以下のようになります。イベント(図ではトリガ)が2個、条件が3個になっています。

完成したオートメーション

ホーム.appで設定したカスタムシーンは、Eveで編集しても変化せず残っています。

動作試験をしたところ、警戒中ランプがOnであり、かつ両方のセンサーが検知している時だけ、スマートプラグがOnになることを確認できました。

ホーム.app と Eve の比較

ここまで見てきたホーム.appとEveの実装をまとめて、比較します。

もともとのHomeKit仕様、ホーム.appで実装された機能、Eveで実装された機能を、表にまとめました。

この表で、時刻や人の到着、在宅などの指定を、短く、状況と書きました。また、アクセサリの値の読み取りや変更を、単に、アクセサリと書いてあります。また、ホーム.appがつくる、シーンに現れないアクションセット(複数のアクセサリの操作)を、Eveの用語に合わせてカスタムシーンと書きました。

項目 HomeKitの仕様 ホーム.appの実装 Eveの実装
イベント 複数の状況と
複数のアクセサリ
一つの状況、
または一つのアクセサリ
複数の状況と
複数のアクセサリ
条件 複数の状況と
複数のアクセサリ
複数の状況 複数の状況と
複数のアクセサリ
アクションセット 複数のアクションセット 複数のシーン
およびカスタムシーン、
またはショートカット
複数のシーン

ホーム.appは、HomeKitのオートメーション(trigger)仕様の一部だけを実装していることがわかります。条件の部分の実装で足りない部分は、ショートカットで補ってます。ショートカットは、IF文や変数が使えて、アプリケーション間通信も使える強力な機能ですが、動作が遅い(1秒程度の体感できる遅延があります)のが欠点です。また、ショートカットを作るGUI作業が面倒です。AppleScriptのようなテキストベースでの編集も実現してくれたら良かったのにと思います。

一方で、EveはHomeKitの仕様に、かなり忠実に対応していると言えます。アクションセットについては、Eveは、名前のついたシーンのみ使用できますが、これはHomeKit APIの制約で仕方ないことのようです。

二つを組み合わせる

ホーム.appとEveは、それぞれ長所短所があるので、組み合わせて使うのが良いです。

単純なオートメーションはホーム.appで書く:ホーム.appは純正なので、これで記述できるシンプルなオートメーションは、ホーム.appで作ると、(根拠はありませんが)安心感があります。

Eveでイベントと条件を書き、ホーム.appでカスタムシーンを書く:イベントと条件の部分をEveで記述し、アクションセットの部分をホーム.appでカスタムシーンに上書きします。カスタムシーンを使うので、無駄な名前付きシーンも増えません。イベントと条件に関して、HomeKit仕様の全てを使いこなせます。

記事で示したように、条件にアクセサリの値を書くことができます。また複数イベントを書けるので、例えば「複数の窓に取り付けた接触センサーのどれかが開くと警報を鳴らしたい」場合も、一つのオートメーションで記述でき、編集作業や管理が楽です。

Eveでイベントと条件を書き、ホーム.appでショートカットを書く:こうすれば、複数のイベントに対して、一つのショートカットを実行できます。これも良いところの組み合わせです。

これらの組み合わせは、実際に作ってみて、動作することを確認しました。

まとめ

HomeKitのオートメーションは、以下の3ステップで動作します。

  1. イベントで以下を開始する:
  2. 条件が成立したときに、
  3. アクションセットを実行する。

HomeKitの仕様では、イベントと条件には、複数の状況(時刻や人の在宅)と、複数のアクセサリの値を使えます。しかし、ホーム.appでオートメーション作成をする際には、制約がありました。

Eveを使うと、ほぼHomeKitの仕様通りのオートメーションを記述できます。ただ、ホーム.appならではの機能もあるので、両方を組み合わせると良いことがわかりました。

今回もClaudeの助けを借りながら、HomeKitオートメーションの調査と実験を行いました。長年疑問に思っていたオートメーションの仕組みがわかって、満足です。

コメント

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