GoogleHomeからテレビ(LG製WebOS)をコントロールしてみる

# はじめに
GoogleHomeとChromecastの組み合わせはテレビON/OFFができて便利ですよね。
しかし、番組を変えたい、ボリュームを下げたいが出来ないのが非常に残念です。
仕組みが分かれば出来ないのはしょうがないですが、一般ユーザーからしてみたら仕組みなんかどうでもいいことで・・・
しょうがないなーと赤外線リコモンのirMagicianの購入を考えていたところ、GitHubに面白そうなソースがありました。
**lgtv2**。LG製のテレビに積んであるWebOS用のAPIがあるみたいなんです。
ほーほーこれはこれはと使ってみたところ、なかなかいいじゃないですか。
WebSocketで通信するので、テレビの電源が切れている場合は使えないですが、テレビON以外はほとんど使えそうです。
そのテレビONもWOLを使えば出来そうですね。
今回は、そのlgtv2とWOLをつかってGoogleHomeからLG製テレビを音声コントロールして見たいと思います。

# 実現イメージ
<img src="https://qiita-image-store.s3.amazonaws.com/0/211866/35c6140d-1ad9-7f71-d645-0655f0fbfb9d.png" width=80%>

* ok google テレビを点けて → テレビの電源ON
* ok google テレビを消して → テレビの電源OFF
* ok google テレビのチャンネル３ →　チャンネルを３に変更
* ok google テレビのボリューム１０ →　音量を１０に変更
* ok google テレビの番組表 →　番組表を表示
* ok google テレビに変えて →　入力をテレビに変更

嫁がキッチンでテレビの基本操作を出来ることを目標とします。

# 用意するもの
GoogleHome
IFTTT
Firebaseアカウント
ラズパイ(自宅サーバーがあれば、それでもOK)

# 設定
## Firebase
まず、自宅サーバーとIFTTTをつなげるFirebaseの設定をします。
Firebeseの導入は、過去の記事を参照してみてください。
Firebaseのスキーマ定義は以下のとおりです。
パスをURL、値はjsonで表現しています。

* パス
    * https://****.firebaseio.com/lgtv/action/
* 値
    * 初期値（firebaseコンソールで追加してください）
        * { "type" : "none" }
    * 電源ON
        * { "type" : "wol" }
    * 電源OFF
        * { "type" : "off" }
    * チャンネル変更
        * { "type" : "channel", param : 1 }
    * ボリューム変更
        * { "type" : "volume", param : 1 }
    * テレビ切り替え
        * { "type" : "launch_tv" }
    * 番組表
        * { "type" : "launch_tvguide" }

設定例
![firebase_lgtv.png](https://qiita-image-store.s3.amazonaws.com/0/211866/879be376-7a28-1728-1ae7-28f8d57f08dc.png)

チャンネルや音量などをラズパイ上の自作サービスに通知する必要がありますので、アクション種別とパラメータとなるチャンネルと音量の数字をFirebaseに設定します。

## IFTTT
次はIFTTTの設定です。
### this
GoogleHomeへの呼びかけ方法を設定します。
テレビのチャンネルやボリュームなど、用途にあった呼びかけを設定してください。

Google Assistant
![ifttt_googlehome_lgtv_this.png](https://qiita-image-store.s3.amazonaws.com/0/211866/aca80bf4-f0ac-619f-1adc-4688cecbd544.png)

### that
Firebaseを更新して自作サービスが変更通知を受け取ります。
webhookのURLに「https://****.firebaseio.com/lgtv/action.json」を設定し、bodyに
Firebaseで説明したjsonの値を設定します。
認証の設定などは、前回の記事を参考にしてください。

Webhook
![ifttt_googlehome_lgtv_that.png](https://qiita-image-store.s3.amazonaws.com/0/211866/059ff0de-68ed-b7c9-5db8-81dcdcee0c45.png)

これで準備完了です。
電源ONやボリューム変更など用途ごとにレシピを作成してください。

では、次は自作サービスの説明です。

# 自作サービス
今回もnodeを使ってサクッと作ってみたいと思います。
lgtv2という非常に有能なソースがありますので、これを使います。

前回と違い、永続化する必要もありませんの非常にシンプルになります。
・・・と思っていましたが、そもそものテレビの挙動に翻弄されて、結構Promiseだらけになってしまいました。
WebSocketはテレビの状態としてOFFがあるので、繋げっ放しにできません。
要求の度にconnect、disconnectするように対策します。
また、入力がテレビ以外だとチャンネルを変更してもテレビに自動的に切り替わらなかったりなど、日本製のテレビでは考えられないグローバル仕様が盛りだくさんです。
なので、

　1. 現在動いているアプリを取得（WebOSではテレビも録画リストなど全てアプリ扱いです）
　2. アプリがテレビでなければテレビに切り替え
　3. チャンネルを変更

という流れが必要になります。
ある程度汎用的な実装にしたかったので、アンチパターンと分かりつつ、Promiseのネストにも手を出してしまいました・・・。自分のスキル不足ですね。

### ソース 
ソースをGitHubに上げましたのでそちらを参照してください。
https://github.com/nk-tamago/googlehome-lgtv

### Firebaseの導入
firebase-adminを事前にインストールする必要があります。
導入方法は以下を参照してください。
https://firebase.google.com/docs/admin/setup?hl=ja

### インストールと起動
firebase-adminの導入が終わったらGitHubからソースをcloneして、`npm install`してください。
nodeの永続化はforeverを使うといいと思います。

# まとめ

WebOS限定となりますが、非常に便利になりました。
特にリモコンが見つからない時や手仕事をしている時は重宝します。
普段、何気なく行っているライフスタイルが変化するってのは非常に素晴らしいことですね。
この調子で、次のネタを模索してみたいと思います。
やっぱり電気かなあ・・・Hueは高いので今度こそirMagicianを買って試してみたいと思います。
他にも、何かリクエストがあればコメントしてください。
出来る範囲で実現してみます。

長々と最後までありがとうございました！