Python
RaspberryPi
Wake-on-LAN
beebotte

RaspberryPi使って遠隔地から自宅PCをスリープ復帰させる

目的

我が家はマンション契約の無料インターネットでグローバルIPがもらえません。そのため遠隔地からの自宅PCからのリモートデスクトップ接続は諦めていたのですが、最近chromeリモートデスクトップの存在を知りました。これで接続できる!!となったら、次はPCを常時起動しっぱなしなのが気になりはじめたので、Wake-on-LANとbeebotteを利用して、外出先からpcのスリープを解除してみました。

概要

同じローカル環境内にWindowsPCに対して、Raspberry piがwake_on_lanを送信。発動タイミングとしては、Rasberry piがbeebotteを監視して、beebotteにリクエストがあればwolが仕込まれたスクリプトをキックする。

名称未設定-1.jpg

WOLの設定(windows側)

以下のページを参考にwindowsPCで実施できるようにしました

Wake on Lan で Windows 10 の PC を遠隔で起動する

この時点でAndroidアプリWake On Lanとか使ってLAN環境下であれば、スマホからスリープ復帰できるようになるので便利ですね。ただ外出先ではまだ出来ず。

wolを設定する

wol用のpythonライブラリとかも調べてたんですけど、あんまり良さそうなのがなかったため、バイナリを使おうと思います。
ほぼこの方の記事の通りですが、一応手順を書いておきます。

1.wgetで下記のファイルを取得する

wget http://www.gcd.org/sengoku/docs/wol.c

2.gccでコンパいる

gcc wol.c -o wol

これでwolというバイナリファイルが生成されたと思います。
起動オプションとして、スリープから復帰したいpcのipアドレスとmacアドレスを渡します。

wol 192.168.x.x xx:xx:xx:xx:xx:xx

これでスリープから復帰させたいpcが、同じネットワーク上にいる場合はラズパイから起動できるようになりました。やったね。まだまだこれでは役に立たん。次はラズパイの監視先を作ります。

beebotteの設定

beebotteに行き、アカウント作成。その後chanel -> Create Newで新規チャンネルを作成
channel Name: raspberrypi
channel Discription: ラズパイ
resource name: action
resource discription:アクション
image.png

上記の設定で作りましたが、全部好きな値にして大丈夫です。
ただあとで、channel Nameとresource nameは使うので自分の設定値を覚えておいてください

出来たらこんな感じ。
image.png

で、チャンネル名クリックして、channel Tokenをメモっとく

image.png

raspberrypiからbeebotteを監視する

今回はpython3を使います。

beebotteを監視するためのライブラリインストール

sudo pip3 install paho-mqtt

beebotteを監視するためのスクリプト

wol.py
import paho.mqtt.client as mqtt
import json

TOKEN = "[beebotteのトークン]"
HOSTNAME = "mqtt.beebotte.com"
PORT = 8883
ADDRESS = "raspberrypi/action"

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

def on_message(client, userdata, msg):
    print(msg.topic + " " + str(msg.payload))

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

これで繋がったタイミングと、何かしらのメッセージがbeebotteに来たタイミングで文字が出力されるようになりました。あとはon_messageの関数内でwolを起動できるようになればOKです。

pythonからwolを起動する

pythonから外部プログラムを起動するのはsubprocessってのが良さそう。
ということでsubprocessを使って同じディレクトリにあるwolのバイナリを呼び出します。

wol.py
import paho.mqtt.client as mqtt
import json
import subprocess #追加

TOKEN = "[beebotteのトークン]"
HOSTNAME = "mqtt.beebotte.com"
PORT = 8883
ADDRESS = "raspberrypi/action"
MACADDR = "[対象pcのMACアドレス]" #追加
IPADDR = "[対象pcのIPアドレス]" #追加

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

def on_message(client, userdata, msg):
    print(msg.topic + " " + str(msg.payload))
    #subprocessは配列でオプション渡す
    subprocess.call(["./wol",IPADDR,MACADDR]) # 追加

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

あとはこのwol.pyを実行しつつ、何かしらのメッセージをcurlでbeeboteを送ってみましょう。

curl -i -H "Content-Type: application/json" -X POST -d '{"data":"Hello World"}' http://api.beebotte.com/v1/data/publish/raspberrypi/action?token=[大分上のほうでメモったchannel Token]

スリープ状態のpcが復帰すれば完成です。
raspberrypiでこのpython実行しっぱなしにしておけばいつでもインターネット上から家のpcがスリープ復帰できますね。やったね。

ここからIFTTTと連携したりして、beebotteへのwebリクエストをslackからとかgoogle homeからとかにすると更にドヤれますが、もう私は疲れたので各自やっておくように。以上です。

参考サイト

Raspberry PiからWOL(Wake On Lan)
IFTTTとBeebotteを使ってGoogleHomeからRaspberryPiを操作する