GoogleHome と Chromecast でキーワード＆画像＆Wikipedia検索～TV表示

#<b>■はじめに</b>
最近日本でも Amazon Echo Show とか GoogleHome Hub など画面付きのスマートスピーカーの発表が続いていますが、これらを使わなくても、GoogleHome と Chromecast を組み合わせると音声と TV 画面を使った UI を自分で作って遊んでみることが出来ます。

![echoshow-ghun.png](https://qiita-image-store.s3.amazonaws.com/0/241735/6651c0d2-5332-28fe-aa39-464d5139f88e.png)

既存のスマートホームに TV 画面での UI 表示を組み合わせることでより広がりのある楽しいシステムに拡張することが可能です。

今回は GoogleHome と Chromecast の組合せで実際にどんなことが出来るか事例と実装方法のご紹介です。

#<b>■全体図</b>
![ghome-cast.png](https://qiita-image-store.s3.amazonaws.com/0/241735/eef57128-440b-83be-57cc-239bda20a0be.png)


処理の中心となるのはラズパイです。cast API を制御できる node ライブラリを適用することで、Google Home をしゃべらせたり（google-home-notifierも同じAPIを使っています）、Chromecast 経由で TV に任意の画面を表示させたりすることが可能です。

#<b>■画像&キーワード検索</b>
インターネットで画像やキーワードを検索して TV に表示するサンプルです。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">IMG検索DEMO <a href="https://t.co/O3P8W7fog4">pic.twitter.com/O3P8W7fog4</a></p>&mdash; ktsz (@ededken) <a href="https://twitter.com/ededken/status/1052804765992738816?ref_src=twsrc%5Etfw">2018年10月18日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

以下が cast API を使って chromecast ～ TV に任意の WEB 画面を表示させるための node ライブラリです。まずこちらを新規ディレクトリにインストールしてください。
参考：[castv2-web](https://www.npmjs.com/package/castv2-web)

```
$ npm install castv2-web
```

次に以下を同じディレクトリから実行することで cast API が使用可能です（オリジナルサンプルを少しだけ改造しています）

```webcast.js
var Client                = require('castv2-client').Client;
var Web                   = require('castv2-web').Web;
var mdns                  = require('mdns');

const sleep = msec => new Promise(resolve => setTimeout(resolve, msec));

var argExe = process.argv[0];
var argScr = process.argv[1];
if (process.argv.length < 3) {
    console.log('use: ' + argExe + ' ' + argScr + ' web-url');
    return;
}

var targetUrl = process.argv[2];

var browser = mdns.createBrowser(mdns.tcp('googlecast'));

browser.on('serviceUp', function(service) {
  console.log('Found device ',service.name, ' at ', service.addresses[0], ':', service.port);
  if( 'Chromecast-xxxxx' == service.name ) // 自分の Chromecast の名前
  {
      ondeviceup(service.addresses[0]);
  }
});

browser.start();

function ondeviceup(host) {
  var client = new Client();
  client.connect(host, function() {
    console.log('Connected');
    client.launch(Web, function(err, manager) {
      console.log('Dashboard Launched');
      manager.load( targetUrl );
      return;
    });
  });
}

// browser の機器検索で対象が見つからなくても一定時間で強制終了
(async () => {
  await sleep(7000);
  browser.stop();
  process.exit(0);
})();
```

例えば以下の様に node コードから呼び出せば任意の WEB ページを TV に表示できます。（ただしあまり重くて複雑なページは表示できません。比較的軽めなページのみ表示可能です）

※Google Home から使う場合には IFTTT の Google Assistant 自由キーワード・レシピで取得したキーワードを以下の(keyword)引数に渡す事で、そのキーワードの検索結果が表示されます。
※IFTTT からラズパイへキーワードを通知する方法はこちらなどを参考にしてください [[LINK]](https://qiita.com/kt-sz/items/e8ccec02605584e62b53#webhook-%E3%82%B5%E3%83%BC%E3%83%90%E3%81%AE%E6%A7%8B%E7%AF%89)

```
commandLine( 'node webcast.js "https://websearch.excite.co.jp/?q=' + encodeURIComponent(keyword) + '&page=1"' );
```

もしくは以下の様にすれば画像検索の結果が表示されます。
例えば・・・自宅で友達との会話中に◯◯◯◯っていうタレントさんどんな顔だったけ？などの話になったら・・・その場で Google Home に「画像検索◯◯◯◯」の様に話しかければ TV に検索画像一覧が表示され「あ～◯◯◯◯ってこの人ね！！」的に話もはずみます。

```
commandLine( 'node webcast.js "https://imagesearch.excite.co.jp/?q=' + encodeURIComponent(keyword) + '&page=1"' );
```

#<b>■Wikipedia 検索～画面表示＆内容読み上げ</b>
上記の応用で、Wikipedia から任意のキーワードを検索しその画面を TV に表示しつつ、Google Home で Wikipedia の内容を読み上げるというサンプルも作ってみました。
僕はこちらよりも上記の画像検索機能のほうが良く使いますが、、GoogleHomeが Wikipedia の内容をとつとつと話しているのを聞くのはなかなかシュールですｗ
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">WIKI検索DEMO <a href="https://t.co/EVVEzcCjdC">pic.twitter.com/EVVEzcCjdC</a></p>&mdash; ktsz (@ededken) <a href="https://twitter.com/ededken/status/1052805322169974784?ref_src=twsrc%5Etfw">2018年10月18日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


```wiki-search.js
let http = require('http');

googlehomeTalk = "xxxxx" // google-home-notifier を呼び出すコマンドなど指定してください
googlehomeWebCast = 'node webcast.js ' // 上記ソースを参照

// 引数チェック
var argExe = process.argv[0];
var argScr = process.argv[1];
if (process.argv.length < 3) {
    console.log('use: ' + argExe + ' ' + argScr + ' search-keyword');
    return;
}

const execSync = require('child_process').execSync;
commandLine = function( cmdLine ) {
   const result = execSync( cmdLine ).toString();
   console.log(result);
   return this;
}

// 検索キーワード取得
var keywd = process.argv[2];
// キーワード文字列からスペース削除
keywd = keywd.replace(/\s+/g, '');
// キーワード文字列を URL に追加
keywd = encodeURIComponent(keywd);
// URL 設定
var targetUrl = 'http://wikipedia.simpleapi.net/api?keyword=' + keywd + '&output=html';

// GET 取得
http.get(targetUrl, (res) => {
  let body = '';
  res.setEncoding('utf8');
      body += chunk;
  });

  res.on('end', (res) => {
      var split_str = body.split('strong');
      if( split_str[2] )
      {
          // HTML タグを削除
          var ret_str = split_str[2].replace(/<("[^"]*"|'[^']*'|[^'">])*>/g, ' ');
          ret_str = ret_str.replace(/</g, ' ');
          ret_str = ret_str.replace(/>/g, ' ');
          ret_str = ret_str.replace(/\s+/g, '');
          ret_str = ret_str.replace(/\n/g, '');
          ret_str = ret_str.substring(0,190);
          var wikiUrl = 'https://ja.wikipedia.org/wiki/' + keywd;
          // GoogleHome で該当 Wikipadia の記事読み上げ
          commandLine( 'sudo node ' + googlehomeTalk + ' \"' + ret_str + '\"' );
          // Chromecast に該当 Wikipedia 画面を表示
          commandLine( 'sudo node ' + googlehomeWebCast + wikiUrl );
      } else {
          commandLine( 'sudo node ' + googlehomeTalk + '\'お探しのキーワードは見つかりませんでした\'');
      }
  });
}).on('error', (e) => {
  console.log(e.message); // HTTP エラー時
});
```
※wikipedia.simpleapi.net の API を使うと、 Wikipadia 内のテキストを加工してプログラムから利用しやすい形で取得できます。


#<b>■最後に</b>
今回は ネットでのキーワード＆画像検索と Wikipedia 検索＆読み上げを例としてご紹介しましたが、他にも例えばラズパイ上で Apache を立ち上げて・・・独自画面を作ってスマートホームのダッシュボード的に使ったり、あまり使いやすいとは言えない GoogleHome & Chromecast を使った Google Photo 表示を独自画面でもっと使いやすくしたり、天気図を表示したり、Amazon Echo Show とか GoogleHome Hub で出来ることを自分でも自作出来るようになり Google Home の使い方も広がります。

（そんなのラズパイに直接モニタ繋げばいいでしょ！という身も蓋もない話もありますが・・既存のTV画面に表示するところにロマンを感じて頂ければ・・・笑）

ところで・・・ GoogleHome Hub 上の画面の API 的仕様はまだ公開されていませんが、もし画面制御用のAPI が chromecast 互換なら、上記の方法で GoogleHome Hub の画面でも色々遊べそうで楽しいのにな~と妄想しています ：D

#<b>■更新履歴</b>
・webcast.js を改変＞全てのネットワーク機器からの通知が来るまで待つように変更＆一定時間で終了

##<b>※投稿記事一覧</b>
他にも 自分で「おうちハック」した内容を以下に投稿しているので、よろしければ合わせてご覧ください☆

・GoogleHome/AmazonEcho とラズパイでやった事・やりたい事一覧[[LINK]](https://qiita.com/kt-sz/items/86536aff99d80c1cd464)
・Google Home でちょっと未来風のスマート TV を作ってみたよ☆[[LINK]](https://qiita.com/kt-sz/items/0362d5fe3e9a3e478245)
・黒豆 (Broadlink RM Mini 3) の IR 信号解析してみたよ♪ [[LINK]](https://qiita.com/kt-sz/items/1c36a7b22a58359a8e6f)
・スマートロック SESAME の WEB API が便利だった！[[LINK]](https://qiita.com/kt-sz/items/e8ccec02605584e62b53)
・Amazon Echo の沢山ある面白スキルを気軽に遊ぶ方法[[LINK]](https://qiita.com/kt-sz/items/0d01e763d540ddea5816)
・LINEを「ラズパイのターミナル化＆スマートホームのフロントエンド化(ChatOps風)」してみた♪[[LINK]](https://qiita.com/kt-sz/items/9adcb02a3b3a6cf3dd7b)
・LINE と Firebase とラズパイを繋いでみたよ☆[[LINK]](https://qiita.com/kt-sz/items/c008084300a978516153)
・GoogleHome と Chromecast でキーワード＆画像＆Wikipedia検索～TV表示[[LINK]](https://qiita.com/kt-sz/items/9edea18c4f0f5e8cf631)
・スマホ ハック＆スマートホーム連携 [[LINK]](https://qiita.com/kt-sz/items/9e23bd5969f0024b17f8)
・ラズパイとサーモセンサーで自宅のガスコンロ監視（火の用心） [[LINK]](https://qiita.com/kt-sz/items/471f469cc89d2bac0c76)
・トニー・スタークの家にありそうなスマート・テーブル（笑） [[LINK]](https://qiita.com/kt-sz/items/13cb71214604081dbf7c)