Google HomeとRaspberry pi(HDMI-CEC soap)でテレビを完全にコントロールする
Google HomeとRaspberry piを使って、テレビの視聴時間の制限機能を構築しています。
まとまった時間ができた時に、いろいろなことを試してベストな構築を目指します。子供のYouTube閲覧を制限する為に、面倒ではありますが最後まで続けたいですね。
前回までで一通り必要なハードの環境は揃ったので、今回からソフト面を開発していきます。
機能のおさらい
- Google Homeにテレビリモコンの指示
- iftttで家のRaspberry piをキック
- Raspberry piで制限時間を確認し、各ボタンの指示を実行
※一日の視聴可能時間を超えている場合は、Google Homeからその旨をメッセージで喋らせる
まあ、やりたいことはシンプルに!をテーマで進めていきます。
今回開発する機能は
iftttから受けた指示をRaspberry piで処理し、テレビを操作するまでを構築します。
当初は、Raspberry piからテレビを操作するのは、HDMIを使って全て行う予定でしたが、いろいろと調べた限りではHDMI-CECではチャンネルなどのボタン操作が行えない?と分かりました。
HDMI-CECの機能を使うために、cec-utilsをインストールしました。
cec-utilsの使い方例
■電源・ON
echo 'on 0' | cec-client -s
■電源・OFF
echo 'standby 0' | cec-client -s
■ボリューム・UP
echo 'volup' | cec-client -s
■ボリューム・DOWN
echo 'voldown' | cec-client -s
上記のようにcec-utilsには、大まかなコマンドが用意されています。
当初はこの流れで、txコマンドと 目的のコードを組み合わせることで、チャンネルの操作ができると考えていました。
のコード一覧を確認するサイトをいくら見ても、チャンネルボタンの操作に関する内容を見つけることができませんでした。
自分の調べ方が悪いのかもしれませんが・・・
確かにビデオカメラ、デジカメ、ブルーレイレコーダーをHDMIケーブルで接続した時も、電源のON・OFF、ボリューム、入力画面の操作以外は必要なさそうですからね・・・
あれ?企画終了?う~ん。
そう言えば、以前にnode.jsからブラビアテレビ(SONY Bravia)を操作した時に、利用したライブラリを思い出しました。
https://github.com/alanreid/bravia です。
HTTPからリクエストを送って、テレビ操作ができ初めて使って遊んだ時は、なにげに感動したものです。
ただ、テレビの電源をON・OFFする機能が、WOL(Wake On LAN)であり家の環境では動作しない為、本格的に使って遊ぶのをやめてしまった経験があります。
(WOLは、無線LANでは動作しない仕様らしいです)
電源のON・OFFは使えなかったけど、その他操作は十分にできたので、電源のON・OFFはcec-utils(cec-client)を使い、その他のボタン操作はHTTPリクエストをcurlで実行して対応することにしました。
(また、cec-utilsでHDMIのアクティブステータスを確認し、視聴時間を集計するためcec-utilsは必ず使います)
Curl(HTTP)からブラビアを操作
curl -X POST -d ' <?xml version="1.0" encoding="utf-8"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:X_SendIRCC xmlns:u="urn:schemas-sony-com:service:IRCC:1"> <IRCCCode>$IRCCCode</IRCCCode> </u:X_SendIRCC></s:Body></s:Envelope>' http://$BRAVIA_IP/IRCC
$IRCCCode のコード一覧
PowerOff = AAAAAQAAAAEAAAAvAw== PowerOn = AAAAAQAAAAEAAAAuAw== ※↑WOLを使わなくても、上のコードから電源のON・OFFは可能? VolumeUp = AAAAAQAAAAEAAAASAw== VolumeDown = AAAAAQAAAAEAAAATAw== Mute = AAAAAQAAAAEAAAAUAw== Input = AAAAAQAAAAEAAAAlAw== GGuide = AAAAAQAAAAEAAAAOAw== EPG = AAAAAgAAAKQAAABbAw== Favorites = AAAAAgAAAHcAAAB2Aw== Display = AAAAAQAAAAEAAAA6Aw== Home = AAAAAQAAAAEAAABgAw== Options = AAAAAgAAAJcAAAA2Aw== Return = AAAAAgAAAJcAAAAjAw== Up = AAAAAQAAAAEAAAB0Aw== Down = AAAAAQAAAAEAAAB1Aw== Right = AAAAAQAAAAEAAAAzAw== Left = AAAAAQAAAAEAAAA0Aw== Confirm = AAAAAQAAAAEAAABlAw== Red = AAAAAgAAAJcAAAAlAw== Green = AAAAAgAAAJcAAAAmAw== Yellow = AAAAAgAAAJcAAAAnAw== Blue = AAAAAgAAAJcAAAAkAw== Num1 = AAAAAQAAAAEAAAAAAw== Num2 = AAAAAQAAAAEAAAABAw== Num3 = AAAAAQAAAAEAAAACAw== Num4 = AAAAAQAAAAEAAAADAw== Num5 = AAAAAQAAAAEAAAAEAw== Num6 = AAAAAQAAAAEAAAAFAw== Num7 = AAAAAQAAAAEAAAAGAw== Num8 = AAAAAQAAAAEAAAAHAw== Num9 = AAAAAQAAAAEAAAAIAw== Num0 = AAAAAQAAAAEAAAAJAw== Num11 = AAAAAQAAAAEAAAAKAw== Num12 = AAAAAQAAAAEAAAALAw== Tv = AAAAAQAAAAEAAAAkAw== Hdmi1 = AAAAAgAAABoAAABaAw== Hdmi2 = AAAAAgAAABoAAABbAw== Hdmi3 = AAAAAgAAABoAAABcAw== Hdmi4 = AAAAAgAAABoAAABdAw== Google = AAAAAgAAAMQAAAA7Aw== ActionMenu = AAAAAgAAAMQAAABLAw== ChannelUp = AAAAAQAAAAEAAAAQAw== ChannelDown = AAAAAQAAAAEAAAARAw== SubTitle = AAAAAgAAAJcAAAAoAw== ClosedCaption = AAAAAgAAAKQAAAAQAw== Enter = AAAAAQAAAAEAAAALAw== DOT = AAAAAgAAAJcAAAAdAw== Analog = AAAAAgAAAHcAAAANAw== Teletext = AAAAAQAAAAEAAAA/Aw== Exit = AAAAAQAAAAEAAABjAw== Analog2 = AAAAAQAAAAEAAAA4Aw== AD = AAAAAgAAABoAAAA7Aw== Digital = AAAAAgAAAJcAAAAyAw== Analog = AAAAAgAAAJcAAAAuAw== BS = AAAAAgAAAJcAAAAsAw== CS = AAAAAgAAAJcAAAArAw== BSCS = AAAAAgAAAJcAAAAQAw== Ddata = AAAAAgAAAJcAAAAVAw== PicOff = AAAAAQAAAAEAAAA+Aw== Tv_Radio = AAAAAgAAABoAAABXAw== Theater = AAAAAgAAAHcAAABgAw== SEN = AAAAAgAAABoAAAB9Aw== InternetWidgets = AAAAAgAAABoAAAB6Aw== InternetVideo = AAAAAgAAABoAAAB5Aw== Netflix = AAAAAgAAABoAAAB8Aw== SceneSelect = AAAAAgAAABoAAAB4Aw== Mode3D = AAAAAgAAAHcAAABNAw== iManual = AAAAAgAAABoAAAB7Aw== Audio = AAAAAQAAAAEAAAAXAw== Wide = AAAAAgAAAKQAAAA9Aw== Jump = AAAAAQAAAAEAAAA7Aw== PAP = AAAAAgAAAKQAAAB3Aw== MyEPG = AAAAAgAAAHcAAABrAw== ProgramDescription = AAAAAgAAAJcAAAAWAw== WriteChapter = AAAAAgAAAHcAAABsAw== TrackID = AAAAAgAAABoAAAB+Aw== TenKey = AAAAAgAAAJcAAAAMAw== AppliCast = AAAAAgAAABoAAABvAw== acTVila = AAAAAgAAABoAAAByAw== DeleteVideo = AAAAAgAAAHcAAAAfAw== PhotoFrame = AAAAAgAAABoAAABVAw== TvPause = AAAAAgAAABoAAABnAw== KeyPad = AAAAAgAAABoAAAB1Aw== Media = AAAAAgAAAJcAAAA4Aw== SyncMenu = AAAAAgAAABoAAABYAw== Forward = AAAAAgAAAJcAAAAcAw== Play = AAAAAgAAAJcAAAAaAw== Rewind = AAAAAgAAAJcAAAAbAw== Prev = AAAAAgAAAJcAAAA8Aw== Stop = AAAAAgAAAJcAAAAYAw== Next = AAAAAgAAAJcAAAA9Aw== Rec = AAAAAgAAAJcAAAAgAw== Pause = AAAAAgAAAJcAAAAZAw== Eject = AAAAAgAAAJcAAABIAw== FlashPlus = AAAAAgAAAJcAAAB4Aw== FlashMinus = AAAAAgAAAJcAAAB5Aw== TopMenu = AAAAAgAAABoAAABgAw== PopUpMenu = AAAAAgAAABoAAABhAw== RakurakuStart = AAAAAgAAAHcAAABqAw== OneTouchTimeRec = AAAAAgAAABoAAABkAw== OneTouchView = AAAAAgAAABoAAABlAw== OneTouchRec = AAAAAgAAABoAAABiAw== OneTouchStop = AAAAAgAAABoAAABjAw== DUX = AAAAAgAAABoAAABzAw== FootballMode = AAAAAgAAABoAAAB2Aw== Social = AAAAAgAAABoAAAB0Aw==
テレビ操作に関する機能は、この2つで実現できそうです。
これらを使ってベースとなる機能を開発していきます。
一応ほぼ出来上がったのですが、現在はiftttから送られてくるテキストの処理・分木を柔軟に対応するための方法を模索中です。
Google Homeを操作するのは子供なので、キーワードが毎回バラバラになるのを想定しての対応です。
(テレビリモコン)で、1チャンネルにして、 (テレビリモコン)で、1チャンにして、 (テレビリモコン)で、1チャンネル、 (テレビリモコン)で、1チャン、 (テレビリモコン)で、1チャンネルに変えて、 (テレビリモコン)で、1チャンに変えて
などなど
正規表現で対応するのが1番?なのかもしれませんが、頑張って多くのキーワードを登録しても、結局は取りこぼしが多そうなので・・・
何らかかのベストな方法を考えてみます。
Google HomeとRaspberry piでテレビを操作する(環境編)
子供のテレビの閲覧時間を制限したい!その野望のためにまずは環境を構築しようと考えています。
現状の問題点
Android TVを利用しているため、テレビで簡単にYouTubeが見れてしまい、気がつけば何時間も子供がYouTubeを見ている日があります。
(ほぼ毎日です。朝・晩と・・・。夏場になると朝早くに起きて見ています。。。)
ワイワイ、ガヤガヤ騒いで知るYouTuberの映像のどこがそんなに面白いのか?(それでもまあ、20本に1本程度は、面白いと思うのはあるのですが・・・)
甲高い声のYouTuberの声を聞くと、たまにイラッとするときがあります。。。
そんな訳で、1日のテレビ視聴時間を制限できればと考えています。
テレビ側で制限の設定できると良いのですが、さすがに無い!Androidアプリを探してもやはり無い!
いっそ、設定からYouTubeアプリを停止しよう!そう思うこともあったのですが、都度、停止と起動の操作が面倒・・・
そこで、外部の機器を使って、テレビの起動時間を計測し、制限時間を超えていれば電源を付けない(オフ)などの処理を考えています。
描いている道のり
①テレビのリモコンをGoogle Homeに変更
テレビを付けてっと言えば、制限時間無いであれば電源をONにし、制限時間を超えていれば制限時間を超えていますとメッセージを流し何もしない。
制限時間が近づくと、後何分ですのメッセージを自動で流す。
②Raspberry piで1日のテレビ視聴時間を管理する
時間の管理の他に、Raspberry piのHDMI-CEC機能を使ってテレビの状態&操作を行う。
※Android TVのため、Google Homeから直接テレビを操作できません。
当初は上の仕様に、API操作ができる赤外線リモコンのNature remoを挟む予定でしたが、Raspberry piのHDMI-CECで十分なのでやめました。
また、Nature remoとGoogle Homeで直接テレビを操作した時の、認識率の悪さとレスポンスの悪さに使う気が無くなったのも理由の1つです。
環境の構築
・Google Homeの用意
既に使っているGoogle Homeをそのまま利用します。
・Raspberry piの用意
raspbianをOSとして、一般的なWEBサーバー仕様でセットアップ
・OSのインストール ・日本語設定 ・ネットワーク設定(&ssh接続) ・WEBサーバーの構築(Nginx、node.js、Python、PHP-fpmなど)
ごくごく一般的な仕様で構築しました。
Google HomeとRaspberry piの接続は、iftttのWEBサービスを利用することにしました。
dialogflowを使った方が、iftttよりレスポンスが早いようですが、テストアプリを起動などの発言が邪魔なのでiftttを使うことにしました。
(iftttでもレスポンスは2秒程度なので許容範囲です。ただ、レスポンスメッセージをRaspberry piが設定できると良かったのですが、お決まりの定型文?しか返せないのが残念です)
iftttからRaspberry piへの接続は、iftttのwebhooksを使って直接通信することにしました。
他の参考にさせていただいたサイトでは、良く外部サービスを利用しているのですが、もっとシンプルに構築したいと思い直接アクセスするようにしました。
もちろん、通信環境は固定IPではありません。動的IPアドレスの対策として、年間1,000円程度のオリジナルドメインを契約し
ダイナミックDNSのように、IPアドレスに変更があれば自動で更新する仕様で対応しました。
また、iftttのwebhooksを処理するために、Nginx上のPHPを使うことにしました。
Node.jsでも良かったのですが、ポートの開放またはNginxのプロキシ設定などが面倒・・・
Pythonも同様、他にPythonスクリプトをCGIで動作させるのもありかもしれませんが・・・
基本的に世間一般的な環境でシンプルを目指したので、プログラム言語はPHPを採用することにしました。
これで、シンプルな環境が構築できました。
続きます・・・