インフィニットループ 技術ブログ

2016年12月07日 (水)

著者 : mizuno_as

クリスタルシグナルPiで作るゴミ出しリマインダーシステム

Bah Humbug! こんにちは、mizuno_asです。
言うまでもありませんが、12月25日といえば古典力学の創始者、ニュートンの誕生日ですね ((ただしユリウス暦。)) 。毎年この季節になると、街中のツリーに飾りつけられたリンゴの実のイミテーションを、みなさんもよく目にしますよね。もちろん我らがサッポロファクトリーでも、アトリウムに大きなツリーが用意され、生涯独身であったニュートンの生誕を盛大に祝っています。

赤りんごだけじゃなくて青りんごもあった。


閑話休題(それはさておき)
人類が毎朝こなさなければならないタスクの中に、ゴミ出しというものがあります。
朝起きた時はちゃんと覚えていたのに、ついうっかりゴミを持って家を出るのを忘れ、通勤電車の中ではっと気づく。そんな経験はありませんか? 筆者はよくあります。その結果、来週の水曜日まで大量の酒瓶との同棲生活を余儀なくされてしまうわけです。あるいは、月に1度しかないスプレー缶の日を忘れてしまった時の悲劇たるや。
これから年末年始にかけて、ゴミ収集のスケジュールも変則的になりがちです。残念ながら、このままではゴミといっしょにお正月を過ごすことになるリスクは非常に高いと言わざるを得ません。
しかし幸いなことに我々はITエンジニア。二度とこのような悲しみを繰り返さないためにも、テクノロジーによってスマートに問題を解決すべきでしょう。

ゴミ出しのスケジュールを知る

なにはともあれ、まずはゴミの収集日を知るところからはじめましょう。冷蔵庫のドアに貼ってある、自治体配布のゴミカレンダーを手で電子化してもよいのですが、せっかくなのでありもののサービスを使うことにしました。それがゴミ収集日お知らせサービス 53calです。
53calはメールアドレスを登録しておくと、指定したエリアのゴミ収集日情報を前日の夕方、または当日の朝にメールで通知してくれるサービスです。毎朝この受信メールをパースすれば、今日が何ゴミの日なのか知ることができそうです。
筆者は53cal専用のメールアドレスをGMailに用意して、Raspberry Piからメールを受信できるよう、IMAPを有効にしました。

リマインダーメールを受信する

Raspberry Piからは、getmailコマンドでメールを受信します。getmail4パッケージをインストールしてください。

$ sudo apt install getmail4

getmailの設定は~/.getmail/getmailrcに記述します。受信したメールは外部スクリプト(~/bin/mail_received.sh)にそのまま渡すことにしました。この中でクリスタルシグナルを光らせる処理を実装します。また無関係なメールを除外するため、スクリプトには引数として送信元アドレスを渡しています。

[retriever]
type = SimpleIMAPSSLRetriever
server = imap.gmail.com
port = 993
username = GMailアドレス
password = パスワード
[destination]
type = MDA_external
path = ~/bin/mail_received.sh
arguments = ("%(sender)", )
[options]
read_all = false
delete = false

~/bin/mail_received.shは以下のようになりました。
getmailは標準入力を経由して外部スクリプトにメールを流し込みますので、nkfは/dev/stdinを読んで、メールをUTF-8に変換しています。メール本文内では、今日のゴミの種別が鍵括弧でくくられて記載されていますので、この部分をgrep -oで拾います。あとはcase文で、ゴミの種別にあわせてクリスタルシグナルの発光色を調整し、発光させています。

#!/bin/sh
if [ "$1" != "53cal-sender@53cal.jp" ]; then
  exit 0
fi
gomi=$(nkf -w < /dev/stdin | grep -o '「.*」')
if [ -z "$gomi" ]; then
  exit 0
fi
case "$gomi" in
  "「燃やせるごみ(有料)」")
    R=255; G=0; B=0 ;;
  "「燃やせないごみ(有料)、スプレー缶・カセットボンベ、筒型乾電池」")
    R=0; G=0; B=255 ;;
  "「容器包装プラスチック」")
    R=128; G=255; B=0 ;;
  "「びん・缶・ペットボトル」")
    R=255; G=128; B=0 ;;
  "「枝・葉・草」")
    R=; G=255; B=0 ;;
  "「雑がみ」")
    R=255; G=0; B=255 ;;
  *)
    R=128; G=255; B=64 ;;
esac
curl -s "http://localhost/ctrl/?color=${R},${G},${B}&info=${gomi}&mode=0"

53calからのメールは毎朝6時に届きますので ((前日の夕方6時を選択することも可能です。出勤時間が朝6時よりも早いようなハードコアな人生を送られている方は、適宜調整してください。)) 、それにあわせてgetmailコマンドをCronで叩いてあげればよいでしょう。このクリスタルシグナルを玄関の下駄箱の上あたりに置いておけば、ゴミの出し忘れはもうありませんよね!

これで出し忘れたら専門医に相談するレベル。

Slackと連携する

光らせるだけならこれでよいのですが、せっかくですからSlackのチャンネルにも通知を投げることにしてみました ((今回はSlackを使いましたが、家族のLINEグループに投げる方がおそらく便利だと思います。)) 。これなら家の外に出ていてもゴミの日に気づけるわけです ((53calのメールそのまま見りゃいいじゃん、という無粋なツッコミは間に合っております。)) 。APIドキュメントを参考に、incoming webhookをチャンネルに用意してください。あとは前述のスクリプトに、送信処理を追記するだけです。

SLACK=https://hooks.slack.com/services/なんやかんや
curl -s -X POST --data-urlencode "payload={\"text\": \"今日は${gomi}の日ですよぉぉ\"}" $SLACK >/dev/null

毎朝しゃべります。

クリスタルシグナルPiから情報を発信するには

これでゴミの日を忘れることはなくなりました。でもゴミを出した後もクリスタルシグナルが点灯しっぱなしでは紛らわしいですよね。ゴミを持って家を出る際に消灯するのがスマートでしょう。そんな用途のために、クリスタルシグナルにはAckボタンが実装されています。このボタンを押すと、たちどころにアラートが解消するというナイス物理ボタンです。

これが勝利の鍵だ。

しかしこれだけでは、まだ家にいる家族にしかゴミ出し完了が伝わりません。Slack(ないしLINE)に通知してしまっている以上、そちらのケアも必要でしょう。さもなくば先に家を出たヨメから「あんたちゃんとゴミ出したの?」と疑惑追求のメールが飛んできかねません。そこでボタンにSlack発言機能を追加してしまいましょう。
現在開発中の新バージョンでは、ボタンを押した時とボタンを長押しした時に、任意のスクリプトを実行させる機能が実装される予定です。先ほどのメール受信時のスクリプトと同様、Slackに発言するだけのスクリプトを作成し、アラート発生時のボタン押下にアサインしました。また「ゴミが溜まってないから今日は出さなくていいや」という日は、ボタンを長押しして通知することにしました。

これが開発中のボタンカスタマイズ機能。

ポチっと押せばゴミ出し完了が通知されます。

ゴミがない日は長押しで。

このようにサーバーを別途用意しなくても、警告灯本体に新たな監視機能、通知機能を実装できるのが、従来の警告灯製品にはないクリスタルシグナルの特徴のひとつです。ご家庭でひとつ、ぜひ役立ててみてはいかがでしょうか?
それではみなさま、よいお年を。

ブログ記事検索

このブログについて

このブログは、札幌市・仙台市の「株式会社インフィニットループ」が運営する技術ブログです。 お仕事で使えるITネタを社員たちが発信します!