コマンドラインから macOS をコントロールする

Siri + Homebridge を使ったオートメーションをいろいろ設定していると iMac も Siri を使ってコントロールしたくなってくる。
Siri で Mac のディスプレイを消灯させたり、ボリュームを調整したり、音楽を再生・停止したりしたくなるのは自然な欲求だと思う。そして、現在それは思うように出来ない。出来ないなら、なんとか実現してやろう。
たとえ実装が変態的になっても…たとえ秋にリリースされる macOS Monterey で同等の機能が実現されるのだとしても…私は今使いたいのだ。
Homebridge と Cmdswitch2 を使えば Siri への指示をトリガーに任意のコマンドラインを実行することはできそうなので、まずはコマンドラインから macOS をコントロールする方法をまとめておく。
Mac のモニタを消灯する
先ずは iMac のモニタだけを消灯させたい。仕事を終えてベッドに突っ伏して「ああ今日はもうこのまま寝てしまおう」と「Hey Siri, 全ての照明を消して」と言えば部屋の電気は消える。でも、デスクの iMac が眩しい…。「Hey, Siri iMac のモニタを消して」で iMac が消灯してくれたらいいのに!
そのための下準備として、先ずはコマンドラインから Mac のモニタを消灯させる方法を調べておく。
Mac でモニタを消灯させる(スリープではない)させるには pmset コマンドを使う。macOS で電源管理を行うためのコマンドだ(おそらく pm = "power management" の略)。
$ pmset displaysleepnow
pmset コマンドでは「システム環境設定」の「省エネルギー」で設定できることはなんでもできるし、スリープの種類を細かく指定して実行させるなんてことも可能だ。
電源管理に関するありとあらゆる設定を行うことができるので、興味のある人は検索するか $ man pmset して man を読んでほしい。
macOS のボリュームをコントールする
HomePod mini や iPhone のボリュームは Siri からコントールができるし、macOS の Siri もボリュームコントロールはしてくれる。ところが、HomePod mini があり、iPhone があり、なんなら iPad もあるという状況を想像してみてほしい。Mac の近くに iPhone が置いてるあるなんてよくあることだ。
そうなると Siri はオーナーにもっとも近いデバイス、または HomePod 系のデバイスがあればそちらで反応して処理をしてしまう。素晴らしい連携機能だが、Mac のボリュームを変えたいのに iPhone や HomePod mini のボリュームが変わってしまうのは困る。
ボリュームを調整するための方法はいくつかあるが、今回は osascript コマンドから Apple Script を使ってコントロールする。
osascript コマンドは Apple Script などのスクリプトをコマンドラインから実行することができるコマンドだ。
そして、Big Sur でも古の Apple Script が使えるのだ。System 7(1997年リリース)に搭載されて以来24年、現在もバリバリ現役で使えるオブジェクト指向スクリプト言語だ。Apple Script が使えれば macOS だけじゃなく、GUIアプリだってなんでも操作できる。
現在の音量は以下のコマンドで Apple Script を実行するとわかる。
$ osascript -e 'output volume of (get volume settings)'
18
現在の音量は "18" だ。この値は 0 でミュート(無音)で、100が最大音量となる。
音量を"18"に設定したい時は以下のようなコマンドになる。
$ osascript -e 'set Volume output volume 18'
ところで、純正のキーボードには音量調整のファンクションキーがある。1回押すごとにいくつ加算されるのか調べてみたら面白いことがわかった。
ボリュームの上がり方が一定ではないのだ。ボリュームを0にしてから、1回キーを押すごとに値を調べていくと以下のようになった。
0 > 7 > 12 > 18 > 26 > 33 > 36 > 43 > 51 > 55 > 64 > 69 > 73 > 84 > 89 > 94 > 100
一定の値(ボリューム増加量)が加算されるのではなく、キーを押すたびに異なる値が加算されている。
そして、特に法則性は無さそうだ。加算される値を並べてみると以下のような上がり方をしていた。
+7 > +5 > +6 > +8 > +7 > +3 > +7 > +8 > +4 > +9 > +5 > +4 > +9 > +5 > +4 > +5 > +4 > +11 > +5 > +6 > +5 > +6
おそらくなんらかの根拠にしたがって加算される値が決まっている…と思われる。仮に人の聞こえ方特性に合わせて調整されているのであれば、なんとも Apple らしい気遣いだ。
Music.app をコントロールする
iTunes.app あらため、Music.app も Apple Script を通じてコントロールすることができる。
Utilities フォルダにある "Script Editor.app" へ "Music.app" をドラッグ&ドロップすると、AppleScrit 用語辞書が表示される。
Music.app で再生ボタンを押すのこと同じことをするなら、以下のようなコマンドになる。
$ osascript -e 'tell application "Music" to play'
「マイレート」プレイリストを再生したければ以下のようになる。
$ osascript -e 'tell application "Music" to play the playlist named "マイレート"'
毎回書くには冗長なので、引数でコントロールできる以下のような "Music.scpt" という AppleScript を書いておこう。
on run argv
tell application "Music"
set cmd to first item of argv
if cmd = "play" then
play -- 再生
else if cmd = "stop" then
stop -- 停止
else if cmd = "toggle" then
playpause -- 再生中なら一時停止、一時停止中なら再生を実行
else if cmd = "pause" then
pause -- 一時停止
else if cmd = "next" then
next track -- 次の曲
else if cmd = "previous" then
previous track -- 前の曲
else if cmd = "forward" then
fast forward -- 早送り
else if cmd = "back" then
back track -- 頭出し
else if cmd = "rewind" then
rewind -- 巻き戻し
else if cmd = "pauseback" then
pause -- 一時停止
back track -- 頭出し
else if cmd = "playfavorites" then
play playlist "マイレート" -- プレイリスト"マイレート"を再生
else if cmd = "track" then
return name of current track -- 再生中の曲の曲名を表示する
else if cmd = "artist" then
return artist of current track -- 再生中の曲のアーティスト名を表示する
else if cmd = "info" then
return artist of current track & name of current track -- 再生中の曲のアーティスト名と曲名を表示する
else if cmd = "album" then
return album of current track -- 再生中の曲のアルバムタイトルを表示する
else if cmd = "count" then
return played count of current track -- 再生中の曲の今までの再生回数を表示する
else if cmd = "playlist" then
return name of current playlist -- 再生中の曲がプレイスとのものなら、プレイリスト名を表示する
(*
else if cmd = "volup" then
set «class pVol» to «class pVol» + 5
else if cmd = "voldown" then
set «class pVol» to «class pVol» - 5
*)
else if cmd = "like" then
set loved of current track to true
set rating of current track to 60
else if cmd = "love" then
set loved of current track to true
set rating of current track to 75
else if cmd = "excellent" then
set loved of current track to true
set rating of current track to 100
end if
end tell
end run
以下のように引数をつけて Music.app をコントロールすることができるようになる。
# 再生
$ osascript Music.scpt play
# 停止
$ osascript Music.scpt stop
# 次の曲
$ osascript Music.scpt next
# 前の曲
$ osascript Music.scpt previous
# 再生中の曲にラブをして、レートを星を3つ半にする
$ osascript Music.scpt love
これで、コマンドラインから Music.app や Mac のディスプレイをオフにすることができるようになった。
準備は整った。
Homebridge と Cmdswitch2 を組み合わせて Siri にこれらのコマンド実行をさせる方法については、また別にまとめたい。