はじめに
数ヶ月前に Google Home Mini を購入しました。また、時を同じくして念願の PS4 を購入し、モンハン と Nier: Automata にドハマリしております(Nier本当に面白い...)。
さて、僕は毎日PS4 を使ってテレビを見ているのですが、
- PS4 電源つける
- ユーザー選ぶ
- トルネ(PS4のTVアプリ)起動
の3つの動作を取るのが非常にめんどくさい...と感じていました。その解決策として、PS4 の Remote Play 機能の応用とGoogle Home を使って、音声1発でトルネを起動する方法を構築したので紹介します。
準備したもの
- Raspberry Pi3 Model B
- Google Home Mini
- Play Station 4
- 設定用のスマホ(僕は iPhone 6 を使いましたが、AndroidでもOK)
4つのデバイスは同一ネットワークに接続してください(Google Home は同じじゃなくてもOK)。
Raspberry Pi のセットアップについては本記事では省略します。以下の記事などを参考にしてみてください。自分の記事ですみません...笑
Raspberry Pi をディスプレイ/キーボードなしで初期設定する - Qiita
また、スマホには事前に "PS4 Second Screen" というアプリを入れておいてください。
Raspberry Pi から PS4 を操作する
まずは、Raspberry Pi から PS4 を操作できるようにしていきます。
順番としては、まずコンソールから操作できるようにし、その後、Google Home から連携しやすいようにnode.js から制御できるようにしていきます。
コンソールから PS4 を操作する
今回は GitHub - dhleong/ps4-waker を利用させてもらいます。
まずは、ps4-waker
をインストールします。READMEに書いてあるとおりに、以下のコマンドをラズパイで実行します。
sudo npm install ps4-waker -g
インストール終了後、以下のコマンドを実行してみます。
sudo ps4-waker
すると、以下のような表示になりますので、スマホ側のPS4 Second Screen
の操作に移ります。
No credentials; Use the PS4 Second Screen App and try to connect to PS4-Waker
スマホ側でPS4 Second Screen
を起動すると、以下の画面のようになります。リスト上のPS4-Waker
をタップします。
すると、コンソールには以下の内容が表示されますので、次に PS4 の操作に移ります。
Got credentials! { 'client-type': 'i',
'auth-type': 'C',
'user-credential': 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' }
Go to 'Settings -> PlayStation(R) App Connection Settings -> Add Device' on your PS4 to obtain the PIN code.
Pin code>
PS4 を起動し、設定 > モバイルアプリ接続設定 > 機器を登録する
と進むと、以下のような画面になります。画面に表示されているPINコードをラズパイのコンソールに打ち込みます。
PINコードをコンソールに打ち込むと、以下のようになります。
Pin code> 95783208
Logged into device! Future uses should succeed
これで、ps4-waker
の設定は終了です。例えば、以下のコマンドをPS4がスタンバイ状態のときに実行するとPS4が起動するはずです。
sudo ps4-waker
なお、ラズパイからPS4への接続情報は /root/.ps4-wake.credentials.json
に保存されています。
Node.js から PS4 を操作する
次に、ラズパイの Node.js から PS4 を操作してみます。Node.js を使用するのは、後ほどGoogle Home との連携をする際に都合が良いからです。ここでも、ps4-waker
を使用します。
まずは、適当なフォルダを作成し、ps4-waker
をインストールします。また、先ほど作成したPS4への設定ファイルもユーザーのHomeディレクトリに移動します。
mkdir MySmartHome
cd MySmartHome
nmp install ps4-waker
sudo mv /root/.ps4-wake.credentials.json $HOME
なお、ps4-waker
を再度インストールしたのは、Node.js から Global にインストールした ps4-waker
モジュールを使用する方法が分からなかったためです…。また、ps4-waker
はデフォルトでユーザーのHomeディレクトリに接続情報を探しに行くので、$HOME
に移動しています。
では、Node.js で簡単なプログラムを書いていきます。ここでは、PS4 電源オン -> トルネ起動
のシナリオを README を参考に書いていきます。
const {Device} = require("ps4-waker");
var ps4 = new Device();
ps4.turnOn().then(() => ps4.startTitle("CUSA00442").then(() => ps4.close()))
PS4 の電源を切った状態で、以下のコマンドを実行すると PS4 が起動しトルネが立ち上がります。
node index.js
Google Home への発話内容を Raspberry Pi で受け取る
次に、Google Home へ発話した内容をラズパイで受け取る仕組みを作っていきます。
ここでは、
の2つのサービスを利用していきます。
なお、Google Home と ラズパイの連携では Firebase や Action on Google などを使う方法もよく取り上げられます。
今回もそれらのサービスを検討したのですが、Firebase に関しては非推奨の方法でしかセキュリティが担保できそうになく、Action on Google に関してはテストバージョンとしての利用しかできず、一定期間でアプリが無効になってしまうようなので、今回は不採用ということにしました。以下参考。
- GoogleHomeとiftttとDialogflowとfirebaseとLINEBOTとラズパイを使って子供と音声によるLINE交換をしてみる(後編) - Qiita
- Actions On Googleなんちゃって中級編 - Qiita
もし、情報が古かったり、間違ったことを言っていたらご指摘いただければ幸いです。
Beebotte の設定
以下のページを参考にさせていただきました。
IFTTTとBeebotteを使ってGoogleHomeからRaspberryPiを操作する - Qiita
僕はこんな感じで設定しました(綴ミスはご愛嬌)。
IFTTT の設定
同様に
IFTTTとBeebotteを使ってGoogleHomeからRaspberryPiを操作する - Qiita
や
Token Based Authentication - Beebotte
Publishing Data - Beebotte
を参考に設定。
ほとんど一緒なのですが、唯一URL
の項目を、チャンネル名に private-
という接頭辞をつけて
https://api.beebotte.com/v1/data/publish/private-MySmartHause/PS4?token=XXXX
としています。これについては、Bebotteのドキュメント に
When publishing data to a channel, the message access level is public by default.
To publish a private message, the channel name must start with private- prefix.
と記載があるため追加しています。おそらく、チャンネルがPrivate の場合に必要なのかと考えています…が、参考先の記事はそのような記載なくうまく動いているようので、よく分かっていません…(詳しい方教えてください‥)。とりあえず、本記事ではドキュメントに従って記載しようと思います。
Google Home から Beebotte のフローの動作確認
先程の記事をまた参考にして、動作確認を行いました。
「OK, Google. PS4 つけて」と発話することで、ちゃんとデータが送られていることがわかりました。
なお、ここでも Channel名には private-
の接頭辞をつけています。
Raspberry Pi で Beebotte の更新情報を受け取る
続いて、Raspberry Pi 側で Beebotte の更新情報を受ける処理を書いていきます。ここでは MQTT というプロトコルとNode.js
を使用してプログラムを作成します。参考にしたのは下記ページになります。
Beebotte MQTT Support - Beebotte
GitHub - mqttjs/MQTT.js
上記を参考にしつつ作ったプログラムがこちら。
var mqtt = require("mqtt");
client = mqtt.connect("mqtts://mqtt.beebotte.com",
// Authenticate with your channel token,
// セキュアな接続を使用するため、port 8883 を明示
// Document に従って、"username" に token を、"password" は空
{port: "8883", username: "token:YOUR_CHANNEL_TOKEN", password: ""}
);
client.on("message", function (topic, message) {
console.log(topic + " " + message);
})
動作確認をしてみます。PS4 をスタンバイにした状態で、上のプログラムを実行します。
node index.js
その状態で、「PS4つけて」と発話すると以下のような出力がなされます。
MySmartHause/PS4 {"data":"つけ て","ispublic":false,"ts":1536077036975}
あとは、data
の内容に従って、ps4-waker
の任意のコマンドを実行できるようにすれば完成です。
完成
これまでやってきたことをまとめて、最終的にラズパイ上で動かすプログラムを作成します。
現在作成中ですが、僕のプログラムを例として掲載しておきます。日本語の文法を解析する良い方法が思いついておらず、若干汚いコードになっていますがご了承ください…。良い方法がある方は教えていただければ幸いです。
var mqtt = require("mqtt");
const {Device} = require("ps4-waker");
client = mqtt.connect("mqtts://mqtt.beebotte.com",
//Authenticate with your channel token,
{port: "8883", username: "token:XXXXXXX", password: ""}
);
client.on("message", function (topic, message) {
// message は文字列で入ってくるので、JSONに変換する
words = JSON.parse(message).data.split(" ");
switch (topic) {
case "MySmartHause/PS4":
var ps4 = new Device();
switch (words[0]) {
case "つけ":
ps4.turnOn().then(() => ps4.close());
case "消し":
ps4.turnOff().then(() => ps4.close());
case "で":
switch (words[1]) {
case "トルネ":
case "テレビ":
if (words[3] == "つけ") ps4.turnOn().then(() => ps4.startTitle("CUSA00442").then(() => ps4.close()));
default:
// nop
}
default:
// nop
}
default:
// nop
}
})
client.subscribe("MySmartHause/PS4");
ひとまず、
- PS4 の電源をつける
- 電源を消す(スタンバイ)
- トルネを起動
あたりをやってみました。今後他のコマンドも順次増やしていく予定です。
終わりに
今回、初めてスマートスピーカを使って家電を操作する経験をしました。声で操作すること は、様々な場面で有効だということがわかりました。荷物を持っているときとか着替えているとき、リモコンがなかなか見つからない時など、何かをしながら操作できることに価値を感じると思いました。
今後は、PS4以外にも色んな家電をハックしていきたいと思います。とりあえず次は赤外線リモコンにでも挑戦してみたいと思います。