RaspberryPi
Line
LineNotify
AmazonDashButton

ダッシュボタンとラズパイとLINEでタイマーを作った話

はじめに

半年前のプライムデーで調子に乗って買ったダッシュボタンが5つほどPC周りに転がってたんですよ
で、そいつを有効活用する方法ないかなーとずっと思ってて、つい先日echo dotが届いたタイミングで思いついたのがこれ

そうだ、タイマー作ろう

フロー的なもの

  1. ダッシュボタンを押す
  2. ラズパイがそれを検知
  3. xx分待ってからLINEに通知を送る
  4. ハッピー

誰か簡単に図が描けるツール教えてください

やったこと

ダッシュボタンのセットアップ(途中まで)

そこらじゅうに記事が溢れるので適当に探してください
個人的にこれが丁寧でわかりやすかった

Amazon Dash Button でおうちハックしようその1 セットアップ編 - Qiita
https://qiita.com/tokio-takeda/items/02bae474f8f20f35a02c

ついでに「ダッシュボタンを押すと毎回スマホに通知がきてうざい」問題を解決するために、
 amazonアプリ>左上のハンバーガーメニュー(三みたいなやつ)>設定>プッシュ通知
から「Dash Buttonの通知」をオフにすればおk
#iosの場合。androidは知らぬ

ラズパイにdasherを入れてボタンの検知まで

Q. dasherって何?
A. ダッシュボタンが押されたことを検知してくれるやつ。これ↓

maddox/dasher: A simple way to bridge your Amazon Dash buttons to HTTP services
https://github.com/maddox/dasher

readmeに従ってlibpcap-devとnpmとnodeを入れて、nodeを手動更新

$ 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

node -vが効けばおk
効かなかったらとりあえずsudo reboot nowしよう

gitを入れてgithubからdasherをcloneしてnpm install

$ sudo apt-get install git
$ git clone https://github.com/maddox/dasher.git
$ cd dasher
$ npm install

これでdasherの初期設定完了

ダッシュボタンを探すスクリプトを起動し、ダッシュボタンを押すと情報が出て来る
それっぽいのが出てきたらctrl + cでキャンセル

$ 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
Possible dash hardware address detected: xx:xx:xx:xx:xx:xx Manufacturer: unknown Protocol: arp
^C
$

12桁のアドレスをメモっておく

dasherの設定ファイルを編集

config/config.example.jsonにサンプルがあるのでコピー

$ cp -p config{.example,}.json
  • -pでpermissionなどもコピる
  • config{.example,}.jsonconfig.example.json config.jsonに展開される
    • 同期に教えてもらったのをそのまま使ってるだけだからちゃんと理解してないのだけども

で、config.jsonを編集

config.json
{"buttons":[
  {
    "name": "timer dash button",
    "address": "xx:xx:xx:xx:xx:xx",
    "cmd": "/path/to/shell/settimer.sh"
  }
]}

今回はボタンが押されたらシェルを実行したいのでcmdオプションを指定
サンプルの最後のブロックの"Command Exec Button"という名前の設定がコマンドを実行するものなので、それを参考に
他の設定もサンプルとgithubのreadmeとでにらめっこすればだいたい察せるはず

タイマー代わりのcrontabを設定するシェルを作る

タイマー部分どうしようかなーと考えた結果、crontabに任せることに
というわけでダッシュボタンが押されたときに実行されてcrontabを設定するシェルがこれ

settimer.sh
#!/bin/bash

TARGET_DIR='/path/to/shell'

# backup
crontab -u pi -l > $TARGET_DIR/crontab.bak

# create new crontab
crontab -u pi -l > $TARGET_DIR/crontab.new
min=`date --date "40 minutes" +%M`
echo "$min * * * * sh $TARGET_DIR/exectimer.sh" >> $TARGET_DIR/crontab.new

# set new crontab
crontab -u pi $TARGET_DIR/crontab.new

# clean new crontab
rm $TARGET_DIR/crontab.new

特に難しいことは書いてないと思うけどいくつか説明

  • crontab -lで現在のcrontabの設定を表示、書き出し
  • 変数minに現在時刻の40分後の時刻の「分」の値を設定
    • 例えば今が12時半なら「10」になる
    • "40 minutes"のところを変えればタイマーの時間を変更可能
  • それをcrontabの起動時刻の「分」に指定して一度crontab.newに追記書き込みし、そのファイルをcrontabに食べさせて設定
  • もちろん後処理も忘れずに(.bakの方は後で使うので残す)

ついでに試行錯誤したこともいくつか

  • 当初はTMP_DIR=`pwd`としてたけど、これだとシェルのあるディレクトリではなくdasherのあるディレクトリが取れてしまうのでイマイチうまくいかなかった
  • .bak.newファイルはディレクトリまで指定しないとやっぱりdasherのあるディレクトリに作られてこれまたうまくいかなかった
  • crontab -u piと明に実行ユーザを指定しないと、dasherの実行ユーザ(おそらくsudoするのでroot)のcrontabが対象になって混乱する(した)

そして賢明な読者諸氏は気づいたと思うが、このタイマーは60分以上には対応していない
つらい

さらに言えばタイマー完了前にもう一度シェルが実行されるとバグる
とてもつらい

line notifyを設定する

通知部分にはline notifyを使う
line notifyを知らない?
ぐぐってください

LINE Notify
https://notify-bot.line.me/ja/

ログインしてマイページに移動

スクリーンショット (3).png

トークンを発行する

スクリーンショット (4).png

トークン名を適当に考えて、通知先は今回は自分宛てなので一番上(たぶん)の「1:1で~」を選択

スクリーンショット (5).png

これ、マジでここを逃すと二度と取得できないのでコピーしてどこかにメモっておきましょう

とりあえず一度curlで叩いてみる

$ curl -X POST https://notify-api.line.me/api/notify -H 'Authorization: Bearer [accesstoken]' -H 'Content-Type: application/x-www-form-urlencoded' -d 'message=aaa asdf gggfs'

結果

スクリーンショット (6).png

いい感じ

タイマー時刻になったら起動するシェルを作る

というわけでさきほどのcurlを叩くシェルを作成

exectimer.sh
#!/bin/bash

TARGET_DIR='/path/to/shell'

# call line notify
curl -X POST https://notify-api.line.me/api/notify -H 'Authorization: Bearer [accesstoken]' -H 'Content-Type: application/x-www-form-urlencoded' -d 'message=時間だよ!!!'

# set backup crontab
crontab -u pi $TARGET_DIR/crontab.bak

# clean backup crontab
rm $TARGET_DIR/crontab.bak

まあ説明はいらないですね

dasherを起動

$ cd /path/to/dasher
$ sudo npm run start

> dasher@1.4.1 start /path/to/dasher
> node app.js

[2018-01-03T10:10:48.909Z] timer dash button added.

これでdasherがスタンバイ状態になっていつでもボタンを押しておk

[2018-01-03T10:11:14.751Z] timer dash button pressed. Count: 1

ボタンを押すとこんな感じに出てくる
そしてタイマーの方も起動してるはず

スクリーンショット (7).png

はい

ラズパイ起動時にdasherを自動起動

いちいちdasherを起動してらんないので勝手に起動してもらう
/etc/rc.localに以下を追記

rc.local
# dasher
sh /path/to/dasher/autorun.sh

まあシェルの場所はどこでもいいのだけども

autorun.sh
#!/bin/bash

cd /path/to/dasher
sudo npm run start &

で、起動時に肝心のrc.local自体が実行されないのは困るので、設定を変更

Raspbian Jessie /etc/rc.local で起動させる方法 | アラコキからの Raspberry Pi 電子工作
https://arakoki70.com/?p=852

これにてすべて世は事も無し

まとめ

はじめにを見返してみる

つい先日echo dotが届いたタイミングで思いついたのがこれ

見返してみる

echo dotが届いた

echo dot使ってねえ!!!