macOSターミナルからHomeKitを使う

HomeKitを使う

macOSのショートカットアプリを使うと、HomeKitアクセサリをmacOSのターミナルからも操作可能です。これにより、照明を点灯・消灯する、エアコンを稼働するなどのHomeKit操作が、シェルスクリプトやさまざまなプログラム言語から実行できます。

Mac版ショートカットを使う

ショートカットは、元々はiPhoneのアプリでした。ショートカットは、iPhoneの一連の操作をまとめて一つのアイコンにしてくれます。このアイコンをiPhoneの画面に置けば、アイコンをタップするだけで自動実行できます。複数ステップで行う操作を、タップ1回で近道できるという意味で、ショートカットと名付けられてます。

iPhoneアプリだったショートカットが、macOS 12.0 MontereyからmacOSでも動くようになりました。macOSでは、完成したショートカットアイコンがファインダーに並ぶことはありませんが、常時表示されるサービスメニュー(アプリケーション共通のメニュー)やメニューバーにショートカットを登録できます。ユーザはいつでもこのメニューを選択できて、ショートカットを実行できます。

ショートカットからHomeKitを使う

ショートカットは、macOSと対応アプリケーションの機能を呼び出すことができます。Macのショートカットから、LedvanceのLED電球を点灯して、5秒後に消灯する簡単なショートカットを作ってみます。新規ショートカットを選んで、名前をLedvance 5sにして、右側のカテゴリやAppから色々選びます。

  1. 最初に、Appのホームから、XXXをコントロールの項目を選び、LedvanceのLED電球を点灯するステップを作りました。
  2. 次にスクリプティングから、待機を選び5秒に設定し、
  3. 再び電球を選び、今度は消灯するステップを作りました。

これで、5秒だけ点灯させるショートカットを作成できました。

このショートカットは、Macのメニューバーから起動できるだけでなく、iPhoneやApple Watchにもすぐに現れて、そちらからも起動できます。MacとiPhoneがApple IDで連携しているからです。コンピュータとスマホのスムーズな連携は、どちらも手掛けているApple製品ならではです。

コマンドラインからショートカットを使う

Mac版ショートカットのさらに素晴らしいところは、コマンドラインインタフェース(CLI)が用意されているところです。ターミナルアプリからショートカットをCLIで操作できます。これに使用するのがshortcutsというコマンドです。shortcuts -hでヘルプが出ます。

% shortcuts -h
OVERVIEW: Command-line utility for running shortcuts.
USAGE: shortcuts 
OPTIONS:
-h, --help              Show help information.
SUBCOMMANDS:
run                     Run a shortcut.
list                    List your shortcuts.
view                    View a shortcut in Shortcuts.
sign                    Sign a shortcut file.
See 'shortcuts help ' for detailed help.

shortcuts listコマンドで一覧が表示されます。shortcuts runコマンドで、ショートカットを起動できます。上で作成したLedvance 5sを起動したかったら、

shortcuts run "Ledvance 5s"

とタイプします。ショートカット名にスペースを入れてしまったので、””が必要になってしまいました。これで、シェルスクリプトや各種プログラミング言語からショートカットを起動できます。

ショートカットで標準入力を読む

これで色々なアクセサリをon/offできるのですが、その全ての組み合わせに対して、一つずつショートカットを作っていくと、数が膨大になりそうです。なので、標準入力を読み、その内容に従って複数の動作をするショートカットを考えました。名前は、HomeKitShortcutとしました。内容は以下です。

  1. 最初に標準入力の内容をcommandという変数に設定しています。
  2. 次に、それを文字列比較して、
  3. LEDVANCE_ONという文字列だったらLEDをonして、
  4. LEDVANCE_OFFという文字列だったらLEDをoffにします。

文字列の一致ではなくて、「・・・で始まる」かどうかで判定しているのは、改行コードなどの影響を無視するためです。

コマンドラインからは、送信したい文字列をパイプで送れば良いです。例えば、

echo LEDVANCE_ON | shortcuts run HomeKitShortcut

とすればLED電球を点灯して、

echo LEDVANCE_OFF | shortcuts run HomeKitShortcut

とすればLED電球を消灯できます。crontabに仕込んでおけば、時刻指定の繰り返し実行ができますね。

コマンドラインから呼び出せるので、そのままシェルスクリプトにもできます。例えば以下のシェルスクリプトで、LEDを3秒間onにした後、offにすることができます。

#!/bin/sh
echo LEDVANCE_ON | shortcuts run HomeKitShortcut
sleep 3
echo LEDVANCE_OFF | shortcuts run HomeKitShortcut

同じことはC言語でも:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
  printf("Going to switch the LED\n");
  system("echo LEDVANCE_ON | shortcuts run HomeKitShortcut");
  sleep(3);
  system("echo LEDVANCE_OFF | shortcuts run HomeKitShortcut");
  return 0;
}

Pythonでも:

#!/usr/local/bin/python3
import subprocess
import time
subprocess.run("echo LEDVANCE_ON | shortcuts run HomeKitShortcut", shell=True)
time.sleep(3)
subprocess.run("echo LEDVANCE_OFF | shortcuts run HomeKitShortcut", shell=True)

できます。これでどんなに高度で複雑な処理をするプログラムからでも、HomeKitを呼び出せますね。

ショートカットから標準出力に書く

上の例では、ホームアプリの、「xxxをコントロール」というコマンドを使って、xxxの家の中にあるアクセサリ(上の例ではLedvance RGBという名前のLED電球)を制御しました。ここで、「xxxの状態を取得」というコマンドを選べば、そのアクセサリの状態を取得できます。

例えば、「Ledvance RGBの電源状態を取得する」をショートカットに追加すると、次にウィンドウが開いて、電源状態に合わせて1 (on)か0 (off)が表示されます。

もう少し面白い例をやってみます。手元のHomebridgeに接続されているNature Remoには内蔵の温度計があり、エアコンリモコンからその値を読めます。なので、アクセサリとしてエアコンを指定すると、現在室温を表示させることができます。

シェルコマンドのshortcutsコマンドでは、この出力は標準出力に送られるようです。Pythonプログラムで、シェルコマンドを実行して、標準出力を表示するプログラムを書き、この室温を表示してみます。(このショートカットにgetHomekitという名前を付けてます。)

#!/usr/local/bin/python3
import subprocess
from subprocess import PIPE
proc=subprocess.run("shortcuts run getHomekit", stdout=PIPE, shell=True)
print(proc.stdout)

実行させると以下のようになりました。

% ./getHomekit.py
b'23.2\xc2\xb0C'

16進数のc2b0に相当する部分は、多分23.2°Cの°を表すunicodeだと思います。これで室温をプログラムで得ることができました。On, offの状態などももちろん得られます。これにより、HomeKitのアクセサリの状態に合わせて、色々な動作をするPythonプログラムを書くことが可能になります。

ショートカットとクリップボード

上記の例ではPythonを使いました。シェルコマンドからはどうでしょうか。ということで、ショートカットをシェルコマンドから呼び出します。

% shortcuts run getHomekit

でもなぜか標準出力が表示されません。良いやり方があるのかもしれませんが、お手上げでした。

そこで、クリップボードを使ってみました。クリップボードは、ペーストバッファとも呼ばれるメモリで、コピーペーストで使われる部分です。「クリップボードにコピー」というコマンドを書いてあげると、

結果がクリップボードに入ります。

% shortcuts run getHomekit

と実行させても、変化はありませんが、この後、コマンドpを押すと、結果が表示されます。

% shortcuts run getHomekit
% 23.3°C

macOSのシェルコマンドには、pbcopyとpbpasteというコマンドがあります。ペーストバッファへコピーする・ペーストするコマンドです。なので、pbpasteコマンドを実行すれば、クリップボードの内容を標準出力に表示できます。

% shortcuts run getHomekit
% pbpaste
23.3°C

1行で書くなら、;で接続して、

% shortcuts run getHomekit; pbpaste
23.3°C

と書けます。

まとめ

macOSのショートカットアプリはコマンドラインから呼び出せます。またショートカットアプリはHomeKitをコントロールできます。なので、HomeKitはコマンドラインからコントロール可能です。各種プログラミング言語との連携が簡単に作れます。ショートカットアプリは、HomeKitに限らず、様々な機能の自動化を提供します。これがコマンドラインから起動できることで、可能性が広がると思います。

コメント

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