技術を磨くだいぱんまん

散歩とインターネットが大好きなシステムエンジニア。暮らし、おでかけ、テクノロジーについて書いています。

Amazon Dash Buttonをハックして阪神タイガースの試合速報通知ボタンをつくりました

f:id:donchan922:20170802212958j:plain

こんにちは、だいぱんまん(@donchan922)です。

物理的なボタンを押すだけでシャンプーや洗剤、飲料水といったAmazonの商品が注文できる「Amazon Dash Buttonアマゾンダッシュボタン)」。このボタン面白いのが、ハック(改造)することで宅配ピザを注文したり、タクシーを呼んだり、家の照明をON/OFFしたりすることができるんです。

阪神タイガースファンの僕は、Amazon Dash Buttonを押したら、阪神タイガース試合速報をLINEで通知する仕組みをつくりました。

完成形がこちら

阪神広島に負けてるー。

仕組みについて

f:id:donchan922:20170802214749p:plain
以下の流れで処理を行います。

  1. Amazon Dash Buttonを押す
  2. Dasherが検知してPython Web ServerにHTTPリクエストを送信する
  3. Python Web ServerがLINEに阪神の試合速報を通知する

Dasherとは、Amazon Dash Buttonが押されたことを検知してHTTPリクエストを送信するすごいやつです。

そのリクエストを受けるWebサーバとしてBottleを使います。Python上で簡単にWebサーバを立てられるすごいやつです。

阪神タイガースの試合速報の取得については、使えそうなAPIがなかったのでWebスクレイピングで情報を引っこ抜いてきました。スクレイピングは法律うんぬんややこしいところがありますが、以下記事を参照すると今回の場合は特に問題なさそうでした。

Webスクレイピングの注意事項一覧 - Qiita

最後に阪神の試合速報をLINE Notifyを使ってLINEに通知します。LINE NotifyはHTTP POSTを使って簡単にLINEメッセージを送れるすごいやつです。

必要なもの

まずは以下のものを用意しましょう。

Raspberry Pi

前提として、Raspberry Piのセットアップが完了しているものとします。セットアップの手順は以下記事でまとめています。

Raspberry Pi 3をディスプレイ、キーボード、マウスなしでセットアップする方法 - 技術を磨くだいぱんまん

Amazon Dash Button

2021/2/9追記
現在は売ってないようです。

実装手順

Amazon Dash Buttonの設定

以下記事でまとめています。ただ、記事のとおり最後まで設定してしまうと、ボタン押下時に商品を注文してしまうことになります。なので、「商品を選択」画面まで設定を行い、右上のバツボタンを押して設定を途中で終わらせてください。

ボタンをポチッと押すだけで注文できる「Amazon Dash Button」の使い方をまとめてみた - 技術を磨くだいぱんまん

Dasherの設定

まずはRaspberry Piのソフトウェアを最新化しておきます。これをせずに以降のインストールを行うとエラーが発生したので、最新化しておくことをおすすめします。

$ sudo apt-get update
$ sudo apt-get upgrade


Dasherのインストールは以下GitHubの手順をほぼそのまま参考にしました。

dasher/README.md at master · maddox/dasher · GitHub

$ 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 ButtonMacアドレスを確認します。コマンド実行後にAmazon Dash Buttonを押すとボタンの情報が表示されます。XX:XX:XX:XX:XX:XXAmazon Dash ButtonMacアドレスです。あとで使うのでメモしておきましょう。ここで注意すべきは、Protocol:の値。ボタンによってarpudpの2種類があるようです。udpの場合、次の手順で一手間増えます。

$ 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: XX:XX:XX:XX:XX:XX Manufacturer: unknown Protocol: udp


以下コマンドで設定ファイルに{"buttons":[以下を記述します。

$ nano config/config.json

{"buttons":[
  {
    "name": "Tigers Dash Button",
    "address": "XX:XX:XX:XX:XX:XX",
    "protocol": "udp",
    "url": "http://localhost:8080/notify",
    "method": "GET"
  }
]}

以下に補足します。

  • "name":ボタン名。なんでもいいです。
  • "address":Amazon Dash ButtonMACアドレス。さきほどメモした値。
  • "protocol":Amazon Dash Buttonが使用するプロトコル。デフォルトはarpudpの場合のみ記述します。
  • "url":今回はPython Web Server(bottle)のURL。
  • "method":HTTPメソッド。今回はGET。

特に"protocol"の箇所は要注意です。Amazon Dash Buttonが使用するプロトコルudpの場合、本行を記述しないとDasherにリクエストを投げることができません。僕はここで1〜2時間ほどつまづきました。


以下コマンドでDasherを起動しておきます。

$ sudo npm run start &

Python Web Serverの設定

以下コマンドで必要なライブラリをインストールします。

$ pip install requests
$ pip install beautifulsoup4
$ pip install lxml
$ pip install bottle

Python3で書きました。ファイル名はtigers_dash_button.pyとします。

import requests
from bs4 import BeautifulSoup
import re
from bottle import route, run
    
# 試合速報メッセージ作成
def createReportMessage():
    teamNameList = []
    teamPointList = []

    # 阪神の試合速報結果URL
    target_url = 'https://m.hanshintigers.jp/game/score/'
    # 上記URLに対するGET
    r = requests.get(target_url)
    # HTMLパーサ
    soup = BeautifulSoup(r.text, 'lxml')
    # 現在のイニング
    inning = soup.find(class_='inning').text

    # 両チームの名前取得
    for i in soup.find_all('img', src=re.compile("/images/logo/logo_")):
        teamNameList.append(i['src'])

    # 両チームの点数取得
    for i in soup.find_all(class_='number'):
        teamPointList.append(i.text)

    # 両チームの名前と点数をセット
    for i, team in enumerate(teamNameList):
        # 阪神の場合
        if team == '/images/logo/logo_t.png':
            tigers_name = "阪神"
            tigers_number = teamPointList[i]
        # 広島の場合
        elif team == '/images/logo/logo_c.png':
            opponent_name = "広島"
            opponent_number = teamPointList[i]
        # 巨人の場合
        elif team == '/images/logo/logo_g.png':
            opponent_name = "巨人"
            opponent_number = teamPointList[i]
        # 中日の場合
        elif team == '/images/logo/logo_d.png':
            opponent_name = "中日"
            opponent_number = teamPointList[i]
        # ヤクルトの場合
        elif team == '/images/logo/logo_s.png':
            opponent_name = "ヤクルト"
            opponent_number = teamPointList[i]
        # 横浜の場合
        elif team == '/images/logo/logo_db.png':
            opponent_name = "横浜"
            opponent_number = teamPointList[i]

    # メッセージ生成
    message = inning + '\n' + tigers_name + tigers_number + ' - ' + opponent_number + opponent_name
    return message
        
# 試合速報をLine Notifyで通知する
def postLine(message):
    url = 'https://notify-api.line.me/api/notify'
    headers = {
        # ACCESS_TOKENは自身のトークンと置き換えてください
        'Authorization': 'Bearer ACCESS_TOKEN'
    }
    data = [
        ('message', message)
    ]
    requests.post(url=url, headers=headers, data=data)

# http://localhost:8080/notifyにリクエストすると発火するイベント
@route('/notify')
def notify():
    message = createReportMessage()
    postLine(message)

# Python Web Server(bottle)の起動
run(host='localhost', port=8080, debug=True)

以下に補足します。

  • プログラム起動時にPython Web Server(bottle)を起動する
  • httpリクエストを受けると以下処理を行う

LINE Notifyを使うためには設定が必要です。以下記事の「実装手順」⇒「LINE Notifyの設定を行う」を参照ください。

その日の運勢がわかる「Raspberry Pi星占い」はじめました - 技術を磨くだいぱんまん


以下コマンドでプログラムを実行します。

$ python tigers_dash_button.py


f:id:donchan922:20170802192851p:plain
最後にAmazon Dash Buttonを押してLINE通知がくればOK!阪神頑張れ、広島に負けるな。

自動起動の設定

Raspberry Piの起動時にDasherとPython Web Serverプログラムを自動起動する方法です。

Dasherについては、以下GitHubのページを参照ください。

Running Dasher on a Raspberry Pi at startup · maddox/dasher Wiki · GitHub

Python Web Serverプログラムについては、いくつか方法はありますが、今回はcronを使いました。以下コマンドを実行します。

$ crontab -e

ファイル末尾に以下コマンドを追記します。これでRaspberry Pi起動時にPython Web Serverプログラムが実行されます。

@reboot python /home/pi/tigers_dash_button.py