不慣れながら投稿します。アドベントカレンダー 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 update
とapt-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
とし
テキストエディタのなんでもいいので編集を始めます。
以下が設定例を書いています。
{"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
があるので、
これを編集するが、deviceName
とserverPort
を変えないのであれば、このままでOK
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アドレスに、事前に調べて固定化する必要があります。
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へ投げて組み合わせても面白いよ~。