Edited at

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

More than 1 year has passed since last update.

不慣れながら投稿します。アドベントカレンダー 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へ投げて組み合わせても面白いよ~。