【IoT】Google Home+Raspberry Pi+学習リモコンで家電操作してみた

【IoT】Google Home+Raspberry Pi+学習リモコンで家電操作してみた

with コメントはまだありません

はじめに

はじめに
こんにちは。ケイトです。唐突ですが、みなさんはスマートスピーカーお持ちですか?
この記事にたどり着いた方でご存じない方は恐らくいないと思いますが、「なにそれおいしいの?」という人のために簡単に説明させて頂くと、音声対話型のAIアシスタントが内蔵されており、話しかけることで音楽の再生、調べ物やニュースの読み上げ、家電の操作ができてしまうとっても便利なスピーカーのことです。

今や様々なメーカーから発売されており、代表的なものだと

  • Amazon Echo
  • Google Home
  • Line Clova
  • Apple HomePod(2018年7月時点日本未発売)

などがあります。

私はというと、最初はあまり興味なかったのですが、たまたまGoogle Homeが半額セールをやっているのを見かけて衝動買いしてしまいました。(妻に少しだけ怒られました)
普段の使い方としては、やはり音楽を流すのがメインです。音質はそこそこですが、私はSpotify(音楽ストリーミングサービス)を愛用しているので、Google Homeは対応スピーカーとしてとても使い勝手が良いです。あと、Googleアシスタントは「なぞなぞ」や「冗談(オヤジギャク)」を言ってくれるので、よく子どもたちが話しかけて遊んでいます。

Google Homeで家電操作

Google Homeでできることのメインとして、「家電操作」があります。対応製品を家のネットワークに繋いでおくことで、声で操作ができるようになります。対応製品にはテレビ(Chromecast)やLED照明、スマートリモコン(エアコン等の赤外線リモコンの代わりになる)などがあります。最近だとロボット掃除機のルンバや、オーブンレンジのヘルシオも操作できるみたいです。もう映画の世界みたいですね。
私もGoogle Home買ったからには家電操作でしょと思っていたので、スマートリモコンを買おうとしたのですが、既成品買って設定するだけじゃつまらないので、タイトルの通りラズパイ(Raspberry Pi)と学習リモコン基盤、その他Webサービスをフル活用して実現してみることにしました。

用意したもの(Google Home以外で)

使ったサービス

概念図

処理の流れ
  1. GoogleHomeが指示を受けてIFTTTにフレーズを送信
  2. レシピに基づいてフレーズをFirebaseのデータベースに書き込み
  3. Raspberry Pi上のプログラムでデータベースの内容を監視
  4. 書き込まれたフレーズをもとに送信する赤外線を決定
  5. 学習リモコン基板から登録されている赤外線を送信

上記の処理を実現させるために必要な設定について順を追って説明していきます。

必要な設定について

その1 リモコンの赤外線を登録しよう

今回使用する学習リモコン基板は、操作したい機器のリモコンから出る赤外線を予め読み取って登録しておくことで、同じ赤外線を送信できるようになります。(最大10個登録可能)Raspberry Piでプログラムを組んで送信したり、基板上にあるボタンを押して送信したりできます。
登録の仕方は

  1. スライドスイッチをLEARNモードにする。
  2. 登録したい番号のボタンを押す。
  3. 記録したいリモコンのボタンを基板に向けて押す。

たったこれだけです。
公式ページにわかりやすい動画がありますのでそちらも参照してください。
今回私はシーリングライトのON・OFFボタンと、テレビのON・OFFボタン、音量UP・DOWNを登録してみました。

その2 Raspberry Piでリモコン基盤を操作しよう

基板に送信したいリモコンの赤外線を登録できたので、プログラム上からその赤外線が送信できるようにします。リモコン基板には物理ボタンがついていて、そのボタンを押すことで記憶した赤外線を送信できるのですが、それぞれのボタンがRaspberry PiのGPIOピンに繋がっています。(GPIOピンは全部で26本あります)
GPIO↑公式HPの説明。SW番号が基板のボタン番号。それぞれのボタンに対応するGPIO番号がある。

このGPIOピンをRaspberry Piから操作することで赤外線を送信することが可能となります。GPIOピンはメモリの特定の場所にデータを書き込んだり読み込んだりすることで接続されているもののON/OFFを制御できます。ただ、メモリ操作を直接行うことは難しいのでRaspberry Piのシステム標準で用意されているコマンドを使います。
今回はNode.jsでプログラミングしたかったので、Node.jsでRaspberry Pi GPIOピンの制御ができるパッケージ(rpi-gpio)を活用してプログラムを作っていきます。
https://github.com/JamesBarwell/rpi-gpio.js
なお、Raspberry Piは初めに初期設定(OSのインストールなど)が必要です。この記事での説明は端折りますが、「Raspberry pi 初期設定」などのワードで検索すると詳しい説明をされているブログがたくさんでてきますので、そちらを参考に設定を済ませておいてくださいね。もちろんNode.jsの導入も必要ですので合わせ実施してください。
さっそく基板のボタン1に登録されている赤外線を送信するコードを書いていきます。
sample.js

var gpio = require('rpi-gpio');
var number = 7;
 
// setupでピンの使用を宣言
gpio.setup(number, gpio.DIR_OUT, () => {
  // 値のtrue(= 1)を書き込んで送信させる
  gpio.write(number, true, () => {
    // 使用したピンを開放
    gpio.destroy();
  });
});

上記のコードの変数「number」は操作したいボタン番号を指していますが、先程の対応表では「4」となっていたはずが、ここでは「7」となっています。これはパッケージのデフォルトの指定方法が「ピン番号」になっているためです。ピン番号はGPIO番号とは別もので、単純にRaspberry Piの拡張ピンの端から連番で振られている番号です。番号の指定方法を切り替えることも可能ですが、今回はこのピン番号で指定していきます。
※GPIOピンの説明はこちらのページがとても参考になりますのでご覧ください。
https://tool-lab.com/make/raspberrypi-startup-22/
このsample.jsを実行すると、リモコン基板のボタン1に登録されている赤外線が1回送信されるはずです。

その3 Firebaseのデータベースを準備しよう

プログラムで赤外線が送信できるようになったので、ここからはGoogle Homeでプログラムが実行されるようにしていきます。初めにGoogle Homeからの司令を書き込んでおく場所を作ります。今回はFirebaseのリアルタイムデータベースの機能を利用します。
下記ページにアクセスしてGoogleアカウントでログイン後、プロジェクトを作成します。
https://firebase.google.com/
firebase1
プロジェクトが作成されたら画面左側のDatabaseを選択し、画面中央に表示されているRealtime Databaseの「データベースを作成」をクリックします。
firebase2
セキュリティルールの設定画面が表示されるかもしれませんが、「テストモードで開始」を選択してください。(データ保護のルールはあとから適宜作成してください)これでデータベースを利用する準備はできました。データベースはツリー構造となっており、子を追加して値を格納する枠を作るイメージです。今回はシーリングライトとテレビの操作コマンド(フレーズ)を格納するための場所を以下のように作成しました。
firebase3
「light」や「tv」に入っている値(画像上の”つけて”、”消して”の部分)をプログラムで読み取って、処理を分岐させることになります。ちなみに画像真ん中にあるURLはIFTTTの設定時に使いますので、コピーしておきましょう。

その4 IFTTTでレシピを作成しよう

IFTTTでレシピを作成しておけば、GoogleHome(Googleアシスタント)にお願いした内容に合わせて、指定の処理を行ってくれるようになります。今回は、「Googleアシスタントが特定のフレーズを聞いたら、Firebaseにそのフレーズを書き込む」というレシピを作ります。
GoogleHomeで使用しているGoogleアカウントと同じアカウントでIFTTTに登録し、New Appletで新しいレシピを作成します。ifは「Google Assistant」→「Say a phrase with a text ingredient」の順に選択します。
IFTTT1
そして、処理対象のフレーズに「電気 $」、聞き取ったあとのGoogleアシスタントの返事に「電気を操作します」を設定します。一応予備のフレーズとして「ライト $」もつけました。(「$」をつけるのは「電気」から始まる言葉を全て対象にするという意味です)

次にThenを設定していきます。Thenには「webhooks」→「Make a web request」を選択して、以下の通りに設定します。

URLには先程Firebaseで作成したデータベースのURLを設定します。データベースのlightの部分に書き込みたいので、最後の部分を「light.json」にします。設定できたら最後にCreate actionを押して、次のページでFinishを押せばレシピの作成は完了です。上記の例は電気(シーリングライト)の操作レシピでしたが、私はテレビの分のレシピも同様に作成しています。操作したいものの分だけレシピを作成しておいてください。

その5 データベースを監視してリモコン基盤を操作しよう

これまでの設定で、GoogleHomeに「電気をつけて」「テレビをつけて」と話しかけたら、IFTTTを通してFirebaseのデータベースにそのフレーズが書き込まれるようになりました。あとはデータベースの書き込み内容をRaspberry Piで監視して、変更があったら指示の内容に合わせて赤外線を送信するようにしていきます。
先程作成したsample.jsを参考に、電気のON・OFF、テレビのON・OFFと音量UP・DOWNができるようなコードを書いていきます。
googlehome.js

var firebase = require('firebase');
var gpio = require('rpi-gpio');
 
// Firebaseの設定(Firebaseのサイトからスニペットをコピー)
var config = {
  apiKey: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  authDomain: 'homeproject-xxxxx.firebaseapp.com',
  databaseURL: 'https://homeproject-xxxxx.firebaseio.com',
  projectId: 'homeproject-xxxxx',
  storageBucket: 'homeproject-xxxxx.appspot.com',
  messagingSenderId: 'xxxxxxxxxxxx'
};
 
// 電気ON(ボタン6)
var light_on = 31;
// 電気OFF(ボタン7)
var light_off = 33;
// テレビのリモコンのON&OFF(ボタン1)
var tv_onoff = 7;
// テレビの音量UP(ボタン2)
var tv_up = 11;
// テレビの音量DOWN(ボタン3)
var tv_down = 13;
 
// Firebaseのインスタンス
firebase.initializeApp(config);
var ref = firebase.database().ref();
// データベースに書き込みがあったらその内容を読み取る
ref.on('value', function(snapshot) {
  var key = snapshot.key;
  var command = snapshot.val();
  // 電気に対する操作
  if (command.light !== '') {
    switch (true) {
      case /起動|つけ.*て/.test(command.light):
        console.log('電気つけるよ');
        gpio.setup(light_on, gpio.DIR_OUT, () => {
          gpio.write(light_on, true, () => {
            gpio.destroy();
          });
        });
        break;
      case /けし.*て|消し.*て|止め.*て/.test(command.light):
        console.log('電気けすよ')
        gpio.setup(light_off, gpio.DIR_OUT, () => {
          gpio.write(light_off, true, () => {
            gpio.destroy();
          });
        });
        break;
    }
  }
  // テレビに対する操作
  if (command.tv !== '') {
    switch (true) {
      case /起動|つけ.*て|けし.*て|消し.*て/.test(command.tv):
        console.log('テレビつけるまたは消すよ');
        gpio.setup(tv_onoff, gpio.DIR_OUT, () => {
          gpio.write(tv_onoff, true, () => {
            gpio.destroy();
          });
        });
        break;
      case /大きく.*て|上げ.*て/.test(command.tv):
        console.log('テレビの音量あげるよ');
        gpio.setup(tv_up, gpio.DIR_OUT, () => {
          gpio.write(tv_up, true, () => {
            gpio.destroy();
          });
        });
        break;
      case /小さく.*て|下げ.*て/.test(command.tv):
        console.log('テレビの音量さげるよ');
        gpio.setup(tv_down, gpio.DIR_OUT, () => {
          gpio.write(tv_down, true, () => {
            gpio.destroy();
          });
        });
        break;
    }
  }
  
  // DBリセット
  var updates = {};
    updates['light'] = '';
    updates['tv'] = '';
  ref.update(updates);
 
});

もっときれいな書き方があると思いますが、とりあえずこんな感じで・・・。データベースに書き込まれたらそのフレーズを読み込んで、含まれている言葉を正規表現で判別し、操作するピンを分けています。次に操作するときに誤作動しちゃうので、赤外線送信後に書き込まれたフレーズを消しておくこと(空白で上書き)を忘れずに。
コードを保存したらconsoleから実行して、GoogleHomeに話しかけてみましょう。これで声だけで電気やテレビが操作できるようになりました!(自分でリモコンのボタン押したほうが早いやんと思ったら負け)

最後に

いかがでしたでしょうか。お家には赤外線で操作する家電が結構ありますので、全部GoogleHomeで操作できるようにしたらかなりスマートですね。今回は学習リモコンだけを使いましたが、Raspberry Piにはいろいろなセンサーモジュールを取り付けられます。例えば光センサーを追加して、暗くなったら勝手に電気つけるなんてこともできそうです。
あと、GoogleHomeを使わなくてもiPhoneがあればRaspberry Piを操作できます。iPhoneにも『Home Kit』という家電操作の仕組みがあり、homebridgeというライブラリをRaspberry Piにインストールしてちょいと設定してあげれば同じような仕組みが構築できますよ。

「Hey Siri! 電気つけて!」
なんか「OK Google」よりこちらのほうがカッコイイ気がする。

さて今回はここまで。今後もIoTでやってみたことをご紹介していければと思います。
あなたのお家もスマートハウスにしてみてくださいね!
それでは!

Follow ケイト:

2014年入社。修羅の国出身。体が丈夫なことが唯一の取り柄である三十路のエンジニア。 娘二人の思春期が来るのを恐れている。