16
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AmazonのDashボタンとGoogle Homeを連携させた話

Last updated at Posted at 2017-12-14

不慣れながら投稿します。アドベントカレンダー 14日目です。

何をするの?

老人介護用のヘルプボタンや、
2階部屋・離れなどにいる人の呼び出しボタンに出来ます。

手順的にはこの順序で命令が運ばれます。

  • Dashボタンを押す。
  • Raspberry Piで動いている DasherがARPを拾う。
  • DasherがMACアドレスを確認後、アクションを行う。
  • DasherはGoogle-Home-Notifier[G.H.N.]へポストする。
  • G.H.N.はGoogle-Homeへ喋って欲しいことを投げる。

実行環境は以下の通り

  • Google Home
  • Raspberry Pi[3B]
  • Amazon Dashボタン[なんでもいいです。今回はエビアンを使用]

Raspberry Pi の準備

まずはラズパイの準備からです。

最初にapt-get updateapt-get upgradeにて、最新バージョンへ更新しておきます。

sudo apt-get update
sudo apt-get upgrade

次に、以下コマンドをすべて実行して最新のNode.jsとnpm をインストールします。

sudo apt-get install -y nodejs npm
sudo npm cache clean
sudo npm install npm n -g
sudo n stable

Dashボタンの準備とDasherの準備

次にDashボタンを家の中のWi-Fiに接続する。

スマホにてAmazonショップアプリを開き、商品登録前まで進めてバッテンで終了。

Dasherはパケットキャプチャを使用するので以下をインスト

sudo apt-get install libpcap-dev

次にDasherです。

git clone https://github.com/maddox/dasher.git
cd dasher
sudo npm install

お次はDashボタンのMACアドレスを調べます。
このMACアドレスを指定して各ボタンのアクションを決めます。
以下のコマンドを実行

sudo ./script/find_button

すると現在LANの中を飛んでいるパケットが見えます。

パケットを監視している段階で、Dashボタンを押すと数秒後にMACアドレスが表示されます。
押した分だけ表示されるので、他のパケットと見分けがつかない場合、
複数回押すことで特定できます。

ここで私が躓いた点として、ASUSのルーターが頻繁にARPパケットを投げていました。
その為、Dashボタンパケットが埋もれてしまい、Dasherが検知できなことがありました。
対策は各々必要になってきますが、私はルーターの要らない機能をOFFにすることで回復しました。

このMACアドレスをコピーし記録しておいてください。

次にDasherの設定をして行きます。

Dasherのインストール以下 ./config/config.example.jsonをコピーしてconfig.jsonとし
テキストエディタのなんでもいいので編集を始めます。

以下が設定例を書いています。

config.json
{"buttons":[
    {
    "name": "DASH",
    "address": "00:11:22:33:44:55",
    "interface": "eth0",
    "timeout": "60000",
    "url": "http://localhost/Lanch.py",
    "method": "GET"
    }
]}

構文説明
name は任意の名前 このボタンの名前
address は先程調べたMACアドレスを記入
interface ここはトラブりました。オリジナルはen0となっているのですが、ここはeth0に書き換えます。ifconfigで手に入る使用するアダプタ名にします。
url-methodはGoogle-Home-Notifierに合わせています(後述)

このままセーブを行い、Dasherの直下にてsudo npm run start

[2017-12-xxxxx:00:0000.000] DASH pressed. Count: 1

押すたびにカウントが増えていればDasher機能は成功。

Google Home Notifierのセットアップ

Google Homeに喋って貰います。
これだけ応用しても面白い機能です。

まずGit関連。

sudo apt-get install git-core libnss-mdns libavahi-compat-libdnssd-dev

次にGitからクローンしてインストール。

git clone https://github.com/noelportugal/google-home-notifier
cd google-home-notifier
npm install

次は設定、Google-home-notiferの中にexample.jsがあるので、
これを編集するが、deviceNameserverPortを変えないのであれば、このままでOK

example.js
var express = require('express');
var googlehome = require('./google-home-notifier');
var ngrok = require('ngrok');
var bodyParser = require('body-parser');
var app = express();
const serverPort = 8080;

var deviceName = 'Google Home';
googlehome.device(deviceName);
// googlehome.accent('uk'); // uncomment for british voice

var urlencodedParser = bodyParser.urlencoded({ extended: false });

app.post('/google-home-notifier', urlencodedParser, function (req, res) {
  if (!req.body) return res.sendStatus(400)
  console.log(req.body);
  var text = req.body.text;
  if (text){
    try {
      googlehome.notify(text, function(notifyRes) {
        console.log(notifyRes);
        res.send(deviceName + ' will say: ' + text + '\n');
      });
    } catch(err) {
      console.log(err);
      res.sendStatus(500);
      res.send(err);
    }
  }else{
    res.send('Please POST "text=Hello Google Home"');
  }
})

app.listen(serverPort, function () {
  ngrok.connect(serverPort, function (err, url) {
    console.log('POST "text=Hello Google Home" to:');
    console.log('    http://localhost:' + serverPort + '/google-home-notifier');
    console.log('    ' + url + '/google-home-notifier');
    console.log('example:');
    console.log('curl -X POST -d "text=Hello Google Home" ' + url + '/google-ho$
  });
})

次の設定は同じ場所にある、google-home-notifier.jsを編集する。

変えるところは。

var device = function(name, lang = 'ja')
lang=usこれをusからjaに。

var googlettsaccent = 'ja';
同じくこれをjaに。

deviceAddress = '192.168.1.52';
この行は追加します。
Google-Homeが割り当てられているIPアドレスに、事前に調べて固定化する必要があります。

google-home-notifier.js
var Client = require('castv2-client').Client;
var DefaultMediaReceiver = require('castv2-client').DefaultMediaReceiver;
var mdns = require('mdns');
var browser = mdns.createBrowser(mdns.tcp('googlecast'));
var deviceAddress;
var language;

var device = function(name, lang = 'ja') {
  device = name;
  language = lang;
  return this;
};

var ip = function(ip) {
  deviceAddress = ip;
  return this;
}

var googletts = require('google-tts-api');
var googlettsaccent = 'ja';
var accent = function(accent) {
  googlettsaccent = accent;
  return this;
}

deviceAddress = '192.168.1.52';

var notify = function(message, callback = function() {}) {
  if (!deviceAddress){
    browser.start();
    browser.on('serviceUp', function(service) {
      console.log('Device "%s" at %s:%d', service.name, service.addresses[0], s$
      if (service.name.includes(device.replace(' ', '-'))){
        deviceAddress = service.addresses[0];
        getSpeechUrl(message, deviceAddress, function(res) {
          callback(res);
        });
      }
      browser.stop();
    });
  }else {
    getSpeechUrl(message, deviceAddress, function(res) {
      callback(res);
    });
  }
};
====>続く

自分がポカしていたのは、jaに変更するところをjpにしていた点。
ともにjapanなのだが・・・

ここまできたら、example.jsを起動します。

node example.js

起動したら、別のコンソールからcurlを実行

curl -X POST -d "text=てすとー" http://localhost:8080/google-home-notifier

これで「てすとー」と喋ったら、成功。
いつもの声とちょっと違います。

慣れてる人なら判りますが、text=以降は任意文字でここが喋る文章。
URLが今は自分自身になっていますが、もちろん変えることも可能。
外部から、帰りの電車からスマホなどでもコールできます。

私の場合、後から変えることもあり、pythonにて別ファイルに記述、
これをコールしています。

最後に

DasherもGoogle-home-notifierもサービス登録して自動起動を行うならサービスファイルを作って完了。

おまけ

DasherからのレスポンスをIFTTTへ投げて組み合わせても面白いよ~。

16
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?