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

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

Siri + Homebridge を使ったオートメーションをいろいろ設定していると iMac も Siri を使ってコントロールしたくなってくる。

Siri で Mac のディスプレイを消灯させたり、ボリュームを調整したり、音楽を再生・停止したりしたくなるのは自然な欲求だと思う。そして、現在それは思うように出来ない。出来ないなら、なんとか実現してやろう。

たとえ実装が変態的になっても…たとえ秋にリリースされる macOS Monterey で同等の機能が実現されるのだとしても…私は今使いたいのだ。

HomebridgeCmdswitch2 を使えば 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 のボリュームが変わってしまうのは困る。

macOS 11 の音量調整チャーム

ボリュームを調整するための方法はいくつかあるが、今回は 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 の AppleScript用語辞書

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 のディスプレイをオフにすることができるようになった。

準備は整った。

HomebridgeCmdswitch2 を組み合わせて Siri にこれらのコマンド実行をさせる方法については、また別にまとめたい。

Previous

Node.js を ReadyNAS 202 で動かす

Next

Windows 11 のプレビュービルドが Insider Preview へ提供開始

Related