秘密の本棚

気になることをなんでも書きます

OK Google, パソコンつけて。

Google Assistantにパソコンをつけさせたい

前の記事ではRaspberry Piをセットアップしましたが、今回からはこれを使ってホームオートメーションを進めていきます。今回取り組むのはパソコンの電源操作の自動化です。目指す形としては、Google AssistantにOK Google, パソコンつけて」と言うとパソコンが立ち上がるというものです。
nexusuica.hatenablog.jp

必要なステップに分解する

Google Assistantからパソコンの電源をつけるまでに必要なステップは、以下の4つです。

  • Google Assistantがフレーズを解釈してIFTTTをトリガーする
  • IFTTTがBeebotteにWebhookを投げる
  • Raspberry PiがBeebotteを監視してデータを取得する
  • Raspberry PiがLAN経由でPCの電源を起動する

それぞれのステップを作ればうまく動くはずです。

Google Assistantがフレーズを解釈してIFTTTをトリガーする

IFTTTは様々なサービスを連携させることができる超便利なツールで、「もしAならBする」ということを指示しておくと勝手にやってくれるツールです。
ifttt.com
今回であれば、「Google Assistantが『パソコン入れて』という文字列を受け取ったら」という条件付けを行います。この設定は以下のサイトを参考にします。
qiita.com
特に難しいことはありません。

IFTTTがBeebotteにWebhookを投げる

次に、IFTTTの動作を定義します。今回は、Beebotteというサービスを利用します。これは、Webhookを受け付けて出力してくれるサービスで、IFTTTから動作させることができます。ここの設定もさきほどのリンクを参考にします。

Raspberry PiがBeebotteを監視してデータを取得する

あとはRaspberry Pi側での処理です。Beebotteの監視のためにPAHO-MQTTをインストールし、Pythonでプログラムを書きます。ここの部分もさきほどの記事を参考に。

Raspberry PiがLAN経由でPCの電源を起動する

ここまでできれば、あとはRaspberry PiWake On Lanの処理を行わせます。Wake On Lanとはパソコンにある特定のパケットを投げると電源を投入してくれる機能のことで、今回はRaspberry Piから同一のLAN内に接続されているパソコンに対して特定のパケットを送信させます。Wake On Lanを使用するためには使用するパソコンのMACアドレスが必要ですので、調べておきます。また、パソコン側での設定も必要で、以下の記事を参考にします。
www.taneyats.com
worktoolsmith.com
ただしMacの場合は完全な電源OFFではなく、スリープからの復帰しかできません。また、Macは放っておくと2時間毎に勝手にスリープから復帰してしまうので、「PleaseSleep」というアプリを用いて強制的にスリープ状態を維持させます。
download.cnet.com
Raspberry Pi側では、「wakeonlan」というパッケージを利用します。先ほどのプログラムを以下のように書き換えます。IFTTTが投げるWebhookで、Macを起動する場合"action"に"mac_on"を、Windows PCを起動する場合"action"に"pc_on"をそれぞれ指定しているとします。

import paho.mqtt.client as mqtt
import json
import subprocess

TOKEN = "<Beebotteのトークン>"
HOSTNAME = "mqtt.beebotte.com"
PORT = 8883
TOPIC = "<Beebotteのチャンネル名>/<Beebotteのリソース名>"
CACERT = "mqtt.beebotte.com.pem"

def on_connect(client, userdata, flags, response_code):
    print('status {0}'.format(response_code))
    client.subscribe(TOPIC)

def on_message(client, userdata, msg):
    data = json.loads(msg.payload.decode("utf-8"))["data"][0]
    print(data)
    for key, value in data.items():
        if key == "action" and value == "mac_on":
            print("mac mini turning on...")
            for x in range(0,10):
                subprocess.call("sudo wakeonlan -i 192.168.3.255 <MacのMACアドレス>",shell=True)
        if key == "action" and value == "pc_on":
            print("desktop pc turning on...")
            for x in range(0,10):
                subprocess.call("sudo wakeonlan -i 192.168.3.255 <PCのMACアドレス>",shell=True)

client = mqtt.Client()
client.username_pw_set("token:%s"%TOKEN)
client.on_connect = on_connect
client.on_message = on_message
client.tls_set(CACERT)
client.connect(HOSTNAME, port=PORT, keepalive=60)
client.loop_forever()

これでちゃんと動いてくれます。マジックパケットを10回連続で送っているので、失敗することはまずありません。これで外出先からでも「パソコンつけて」と言えばパソコンが起動するようになります。リモートデスクトップを多用している僕にとっては非常に便利です。