2 min read

Amazon Dash ButtonをIoTボタン化

今やIoTボタン以外の用途で使われているのかわからないAmazon Dash Button(以下ADB)

いまさらだがそんなADBをIoTボタンとして使う記事を書く。

セットアップ

  1. スマホのBluetoothをオン
  2. Amazonアプリを開く
  3. アカウントサービスをタップ
  4. Dash端末 -> 新しい端末をセットアップ
  5. ADBをWi-Fiに接続
  6. ADBで注文する商品の選択になったら右上のバツ印をタップして閉じる

このとき、dash-button-jp.amazon.comの名前解決をLAN内で奪っていると失敗するので注意。

ADBをLAN外へ出られないようにする

誤注文防止のためにADBをLAN内に閉じ込める
うちではRTX1200を基幹ルーター兼DNSサーバーとして利用しているのでそれで設定した

ip host dash-button-jp.amazon.com 10.0.0.1(基幹ルーターIP)

ADBリクエスト監視

先にDHCPでADBのMACアドレスにIPを固定で割り振っておく。

巷ではdasherなるものでADBのリクエストを監視しているらしいが、面倒なことはしたくないのでpingでがんばる。

うちでは3つのADBを使っているのでそれのスクリプト。
curlに関しては後述

dash.sh

#!/bin/bash

dash(){
    while true
    do
        ping -c 1 -w 100 -t 1 $1 > /dev/null 2>&1
        if [ $? -eq 0 ]; then
            $2
            sleep 5
        fi
    done
}

dash    '10.0.1.210' 'curl http://myroomraspi/yukari_bme280 > /dev/null 2>&1' &
dash    '10.0.1.211' 'curl http://myroomraspi/warning > /dev/null 2>&1' &
dash    '10.0.1.212' 'curl http://myroomraspi/main_wol > /dev/null 2>&1' &

これで監視はできた。

curlの理由

うちでは1階と2階でネットワークセグメントが異なる。
ADBは1階のWi-Fiに接続するようになっており、ADB押下時には2階のネットワークに接続されたラズパイから音を鳴らしたい。

そんなわけで2階のラズパイでADBを監視させたところ、TTLが小さすぎてpingのパケットが1階まで到達する前に消えてしまった。
TTLを2以上にするとパケットは1階まで到達できるが、ADBの監視間隔が少し空いてしまうため、取りこぼしてしまうことが多発した。

そのため、1階のラズパイ(ADBと同セグメント)に監視をさせ、押下時には2階のラズパイに向けてcurlしてやることにしたのだ。

2階ラズパイのHttpServer

nginxやApacheでHttpサーバーを立てようかと思ったのだが、簡単なものでいいのでGo言語で作ることにした

dashServer.go

package main

import (
    "fmt"
    "net/http"
    "os/exec"
    "strings"
)

func main() {
    http.HandleFunc("/", rootHandle)
    http.HandleFunc("/yukari_bme280", dashHandle)
    http.HandleFunc("/warning", dashHandle)
    http.HandleFunc("/main_wol", dashHandle)
    http.ListenAndServe(":80", nil)
}

func rootHandle(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "This server for AmazonDashButton")
}

func dashHandle(w http.ResponseWriter, r *http.Request) {
    dashName := r.URL.Path
    dashName = strings.Replace(dashName, "/", "", 1)
    exec.Command("/home/tao/dash/server/" + dashName + ".sh").Run()
    fmt.Fprintf(w, dashName)
}

sudo go run dashServer.goしてやるだけで簡単にWebサーバーが立ち上がる

http://(2階ラズパイ)/yukari_bme280にアクセスがきたら/home/tao/dash/server/yukari_bme280.shを実行するようにというものだ。

これで取りこぼしのないADBのIoT化ができた!

終わり

以前はサーバー含め家中のものがすべて同一のネットワークセグメントだったので2階のラズパイから監視させていたが、今回セグメントを分けたことでこのような弊害が生まれた。

しかし、こうも簡単に対処することができてよかった。
Go言語では簡単にHttpサーバーを立てることができるので、今回のような超簡単なことがしたいときにはとても便利だと思う。