Amazon DashでおとうさんDashボタンをつくる
Twitterの方ではちょいちょい呟いているのですが、四ヶ月ほど前に長男が生まれました。それはもう大変にかわいいのですが、生活は一変。これまでは休日になれば半田ごてを握るほどに自由奔放に生きてきたのですが、今ではテレビの音量を上げることすらままならなくなってしまいました。
当然、趣味の電子工作に割ける時間は激減してしまいました(←ここ三ヶ月ほどほぼ毎週更新できたのは、年末年始の間に記事をある程度ストックしていたからです)。少しは時間を捻出できるのですが、奥様が長男の世話をしてくれている横で自分一人趣味に耽るのもなんだか申し訳ない気がしましたので、せめて奥様の役に立つものを作ることにしました。
何を作ろうか考えていたところに、たまたまAmazon Dashの活用(ハック)例の記事が色々目に入ってきましたので、これを使って、奥様が自室にいる私を簡単に呼び出すことができるボタンを作ることにしました。長男を抱っこしていると両手が塞がってしまうので、ナースコールのように、ボタン一つでお父さん(=私)を呼び出すボタンがあれば便利かな、と考えたのです。
ということで、早速Amazon Dashを入手しまして、いざチャレンジ。
Amazon Dashボタンのハックについては、先人の方々がたくさんおられます。
- Amazon Dash Buttonの仕組みとハック
- Amazon Dash ButtonをただのIoTボタンとして使う
- Amazon Dash Buttonを(正しくない方向で)使ってみた
- Amazon Dash Buttonをハックしてワンプッシュで宅配ピザを注文したりコーヒーを淹れたりタクシーを呼んだりする改造例まとめ
実現方法は色々あるみたいですが、自分的には
「Amazon Dashのボタン押下を検知してHTTPリクエストを発行」
という、自分のやりたいことをドンピシャで実現してくれているdasherを使いたいと思います。なお、Amazon Dashのボタン押下を監視するサーバマシンにはRaspberry Pi 3 Type Bを使います。
dasherでは、基本的にはHTTPリクエストの送り先としていろんなWeb APIを想定していると思いますが、ここでは簡単かつ実用的に、ローカルホストでサーバを動かして、それに対してHTTPリクエストを投げることにします。イメージとしては、こんな感じですね。
事前にRaspberry PiにはUSBオーディオデバイスとLEDを接続してるものとします。USBオーディオデバイスを認識させる方法は、こちらを参照ください。
ということで、個人的にお気に入りのPython Web Frameworkのbottleをインストールします。
$ sudo pip install bottle
ついでに、HTTPリクエストを受けたら音声が再生されるように、VoiceText Web APIを利用するためのパッケージもインストールしておきます。
$ sudo apt-get install python-pyaudio $ sudo pip install python-voicetext
もちろん、dasherから直接VoiceText Web APIを叩きにいってもよいのかもしれませんが、VoiteText Web APIのベーシック認証とかをどう対応したら良いのかよくわかっていないので、ここでは一旦bottleをかましてから、パッケージを利用してVoiceText Web APIを利用するようにしています。
インストールが済んだら、適当なフォルダを作ってそこで待受用プログラムを作成します。
$ cd $ mkdir python-server $ cd python-server $ vi controller.py
例えばこんな感じ。
# -*- coding: utf-8 -*- from bottle import route,run,request,response,hook from voicetext import VoiceText import requests import threading import pigpio import json import time vt = VoiceText('YOUR API KEY') R_PIN = 18 G_PIN = 24 B_PIN = 23 pi = pigpio.pi() pi.set_mode(R_PIN, pigpio.OUTPUT) pi.set_mode(G_PIN, pigpio.OUTPUT) pi.set_mode(B_PIN, pigpio.OUTPUT) def led_off(): pi.set_PWM_dutycycle(R_PIN, 0) pi.set_PWM_dutycycle(G_PIN, 0) pi.set_PWM_dutycycle(B_PIN, 0) ########################################## class PapaDashThread(threading.Thread): def __init__(self): threading.Thread.__init__(self) def run(self): pi.set_PWM_dutycycle(R_PIN, 255) vt.speaker('haruka').emotion('happiness',3).speak('お父さん、お母さんがお呼びですよー') requests.get('http://maker.ifttt.com/trigger/papa_dash/with/key/xxxxxxxxxxxxxxxxxxxxxxx') time.sleep(60) led_off() @hook('after_request') def header_json(): response.content_type = 'application/json' ########################################## def control_response_json(value): obj = {'control':value} return json.dumps(obj) @route('/call') def control_call(): th = PapaDashThread() th.start() return control_response_json("call") ########################################## run(host='192.168.xxx.xxx', port=10080, debug=True)
上記のソースコードについて、いくつか補足です。
- フルカラーLEDはGPIO経由で制御していて、ライブラリとしてpigpioを使っています。もちろん、フルカラーでなくて単色のLEDでもOKです。
- HTTPリクエストを受け取った後は、別にスレッド(PapaDashThread)を起動するようにして、すぐにHTTPレスポンスを返すようにしています。時間のかかるLED ON/OFFや音声再生の処理はスレッドの方で処理するようにしています。
- スレッドの中で、ついでにIFTTTのMaker Channelを使って、スマホの方にも通知が来るようにしています。
試しに、これを以下のように実行します。一つめのコマンドはpigpioを有効にするためのデーモン起動コマンドなので、一度デーモンが起動した後は不要です。
$ sudo pigpiod $ python controller.py
ブラウザで”http://192.168.xxx.xxx:10080/call”を入力すると、「お父さん、お母さんがお呼びですよー」という音声が再生されるハズです。確認できたら、Ctrl+Cで一旦サーバプログラムを終了させます。
これで、HTTPリクエストの受け側の準備はできました。いよいよAmazon Dash側の方の設定に入ります。
Amazon Dash本体の設定については、こちらの方の記事が詳しいので、こちらの内容に従ってセットアップしてください。最後の「3. 注文する商品を選択する」で、商品を選択せずに右上の×で終了させることだけ注意が必要です。この作業については、こちらの方の記事が詳しいです。
サーバプログラムのdasherのRaspberry Piへのインストールについては、githubのページに詳細が記載されているので、それをそっくりそのまま実行します。
$ cd $ sudo apt-get install libpcap-dev $ sudo apt-get install npm $ sudo apt-get install node $ wget http://node-arm.herokuapp.com/node_latest_armhf.deb $ sudo dpkg -i node_latest_armhf.deb $ git clone https://github.com/maddox/dasher.git $ cd dasher $ sudo npm install
これで最初のセットアップは完了。次に、Amazon DashのMacアドレスを確認します。
$ sudo ./script/find_button Watching for arp & udp requests on your local network, please try to press your dash now Dash buttons should appear as manufactured by 'Amazon Technologies Inc.' Possible dash hardware address detected: 34:d2:70:xx:xx:xx Manufacturer: unknown Protocol: udp Possible dash hardware address detected: 34:d2:70:xx:xx:xx Manufacturer: unknown Protocol: arp
Macアドレスが確認できたら、設定用ファイルを作成します。URLには、先ほど作成したPythonサーバのURLを指定します。
$ cp config/config.example.json config/config.json $ vi config/config.json {"buttons":[ { "name": "Papa Dash Button", "address": "34:d2:70:xx:xx:xx", "url": "http://192.168.xxx.xxx:10080/call", "method": "GET" } ]}
以上で準備完了です。早速実行してみましょう。
まずは、HTTPリクエストの受け側のPythonサーバを起動。
$ cd ~/python-server $ sudo pigpiod $ python controller.py &
“$ sudo pigipod”コマンドは、すでにpigpioのデーモンを起動中であれば不要です。それから、dasherを起動。
$ cd ~/dasher $ sudo npm run start
この状態でAmazon Dashのボタンを押せば、LEDが光って先ほど設定した音声が鳴る!。。。ハズ。ちなみに自分の環境ではボタンを押してから5〜6秒後に音声が再生されました。
上の動画では、前に作ったコミュニケーション向けロボを使用していますので、ついでにLEDマトリクスでロボットが目覚めるような表情付けを行っています。表情付けのコードは、上のコードに対してこちらのコードを組み合わせてもらえば実現できます。
(以下、2017/8/14 追記)
この段階でAmazon Dashのボタンを押しても何が反応がない、という人は、改めて”$ sudo ./script/find_button”のコマンドを使って、Amazon DashのMACアドレスとプロトコルを確認してみてください。MACアドレスが見えているときのプロトコルが”udp”のみの場合(=”arp”プロトコルのリクエストが見えない場合)、config.jsonに以下のようにptorocolのパラメータを追加してください。
{"buttons":[ { "name": "Papa Dash Button", "address": "34:d2:70:xx:xx:xx", "url": "http://192.168.xxx.xxx:10080/call", "method": "GET", "protocol": "udp" } ]}
これを指定しないと、デフォルトでは”arp”プロトコルをチェックするようになっているため、udpリクエストに反応することができません。こちらを見る限り、最近のAmazon Dashは”udp”プロトコルを指定しておいた方が確実そうです。
(以上、2017/8/14 追記)
最後に、Raspberry Piの電源を入れたときに、これらのプログラムが自動的に起動するようにしておきます。
dasherの方の設定の仕方はこちらに手順が書かれていますので、その設定の仕方に従っていきます。ファイル”/etc/init.d/dasher”を新規に作成し、こちらのページのinit scriptの全文をコピーして貼り付けます。
$ sudo vi /etc/init.d/dasher #!/bin/sh ### BEGIN INIT INFO # Provides: # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start daemon at boot time # Description: Enable service provided by daemon. ### END INIT INFO dir="" cmd="" user="" name=`basename $0` pid_file="/var/run/$name.pid" stdout_log="/var/log/$name.log" stderr_log="/var/log/$name.err" get_pid() { cat "$pid_file" } is_running() { [ -f "$pid_file" ] && ps `get_pid` > /dev/null 2>&1 } case "$1" in start) if is_running; then echo "Already started" else echo "Starting $name" cd "$dir" if [ -z "$user" ]; then sudo $cmd >> "$stdout_log" 2>> "$stderr_log" & else sudo -u "$user" $cmd >> "$stdout_log" 2>> "$stderr_log" & fi echo $! > "$pid_file" if ! is_running; then echo "Unable to start, see $stdout_log and $stderr_log" exit 1 fi fi ;; stop) if is_running; then echo -n "Stopping $name.." kill `get_pid` for i in {1..10} do if ! is_running; then break fi echo -n "." sleep 1 done echo if is_running; then echo "Not stopped; may still be shutting down or shutdown may have failed" exit 1 else echo "Stopped" if [ -f "$pid_file" ]; then rm "$pid_file" fi fi else echo "Not running" fi ;; restart) $0 stop if is_running; then echo "Unable to stop, will not attempt to start" exit 1 fi $0 start ;; status) if is_running; then echo "Running" else echo "Stopped" exit 1 fi ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit 0
そして、冒頭の以下の部分を記述します。
... # Provides: Dasher ... dir="/home/pi/dasher" cmd="DEBUG=* node app.js" user="root" ...
作成したら、
$ sudo chmod 755 /etc/init.d/dasher $ sudo update-rc.d dasher defaults
これで再起動後に自動でdasherプログラムが立ち上がるようになりますが、手動で立ち上げて動作確認したい場合は、以下を実行します。
$ sudo /etc/init.d/dasher start
次に、Pythonサーバの方の自動起動の設定です。こちらは、サーバプログラムの実行前に、”$ sudo pigpiod”コマンドが確実に実行されていないといけないので、dasherとは別の方法で起動設定をします。
$ sudo vi /etc/rc.local
ファイル末尾のexitの手前で、以下を追記します。
... fi sudo pigpiod sudo -u pi /usr/bin/python /home/pi/python-server/controller.py & exit 0
ここまで出来たら一度再起動して、先ほどと同様にAmaon Dashのボタンに対して反応があればOKです。おつかれさまでした。ちなみに、今回は二種類の方法でRaspberry Pi起動時のプログラム実行を行っていますが、このあたりのことを詳しく知りたい方は、こちらの方の記事が参考になると思います。
というわけで、おとうさんDashボタン無事完成です。
せっかくなので、ラベルも変えてみました。こちらの方が用意してくださったラベルのテンプレートを使ってデザインをして、ラベル用用紙にインクジェットプリンタで印刷してみました。ちょっと雑ですみません。
ちなみに、デザインには以下の素材を使わせてもらいました。本業の方のお仕事でも大変お世話になっています。
一部はこちらで無料で利用できます。便利。
おとうさんDashボタンは、写真のような感じで、ベビーベッドの横のラックに結びつけています。そんなに頻繁に出番があるわけではないのですが、奥様的には「結構便利」だそうなので、まあとりあえずは良かったかなと思います。
にしても、Amazon Dashはなかなか楽しいですね。他にも色々遊べそうです。Amazonから怒られるまで遊ぼう。
ディスカッション
コメント一覧
はじめましてAmazon DashでおとうさんDashボタンを
拝見しました。内容に関してお聞きしたいのですがお時間が
御座いましたらお願いします。
Raspberry Piでナースコール的な緊急連絡を作りたいのですが
説明が上手くないのですがトイレ、浴室、寝室などで高齢者が
緊急を要する場合、ボタン操作で知らせる内容です。
出来れば屋内での警報音と指定された連絡先にメールが
配信されれば一番です。
上記、記載のAmazon Dashにて可能でしょうか?
スズキ 様
可能だと思いますが、何を優先されるかで、手段は変わってくるかなと思っています。
Raspberry Piを使うことが最優先なのであれば、今回のおとうさんDashボタンと同じやり方を試すのが良いと思います。ただ、これはあくまでAmazon Dashの非公式な使い方になりますので、商品登録を行わずにボタンを押しまくっていると、Amazonから「ちゃんと商品登録してね」という催促メールが届くようになり、あまりおすすめしません。
Raspberry Piはあくまで手段であり、ナースコール的な緊急連絡を作るのが最優先なのであれば、今なら普通のAmazon Dashボタンは使わず、AWS IoTエンタープライズボタンを使うのが適切かと思います。私がおとうさんDashボタンを作ったときにはまだ国内販売されていなかったのですが、こちらが公式の「プログラム可能なAmazon Dash」ボタンになります。
価格は通常のAmazon Dashボタンの5倍、2,500円ほどしますが、こちらを使う場合はRaspberry Piを使用する必要がなくなるので、トータル費用としてはそんなに高くならないと思います。
こちらのAWS IoTボタンを使う場合、Raspberry Piのセットアップの代わりに、その名の通りAWS(Amazonのクラウドサービス)のセットアップが必要になりますが、ボタンに反応してメールを送るぐらいならおそらく設定も簡単で、料金もそんなにかかわらないと思います。メール以外に何かしら機器を連携させたいのであれば、メール送信の代わりにAWS Lambda関数の呼び出しを設定して、そのLambdaプログラムの中で、メール送信の他、IFTTTと連携するという手もあると思います。
なお、このAWS IoTボタンは、WiFi接続限定で、さらに電池交換ができないので、約2000回ほどボタンを押したら使えなくなります。この仕様が嫌であれば、SORACOM LTE-M Buttonを使うという手もあります。こちらは機能としてはAWS IoTボタンと同じですが、LTE網を使用するのでほぼどこでも使用可能、かつ、電池交換も可能になっています。その分、本体価格はお高い(7,980円)ですし、SORACOMの利用費用もかかっています。
こんな感じで、色々選択肢がありますので、ここで挙げたキーワードを参考に、ご自身の優先順位に従って手段を選んでもらえればと思います。
ピンバック & トラックバック一覧
[…] Amazon DashでおとうさんDashボタンをつくる | MUDAなことをしよう。 […]