7
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

郵便受けに投函されたらSlack/LINEに通知してみた

Last updated at Posted at 2021-07-03

概要

解決したい課題

マンションに住んでいるのですが、帰宅時の導線上に郵便受けがなく、部屋のドアを開けるまでにちょっと遠回りしないといけない構造になっており、郵便受けを開けに行くのをサボりがちな毎日。  
またリモートワークになっていることもあり、中身があるかどうかわからない郵便受けを開けに行くのがなかなかストレスでした。
最近は自治体のワクチン接種のお知らせが来てないかを毎日チェックしてます。まだ来てない。

そんなわけで毎日郵便受けを開けに行くことなく、郵便受けに何かが入ったかどうかを検知したい。

解決方針

郵便受けの口(投函側)が空いたかどうかを検知し、LINEまたはSlackに対して通知をしたいと思います。
郵便受けの回りは当然Wi-Fiも飛んでいないので、LTE回線を利用できるIoTデバイスを利用しました。

基本的にはこちらの記事を参考に、SORACOM LTE-M Button Plusを用いて実装しました(※実際に購入したのはIoT 体験キット 〜磁気センサー〜の方)。
こちらの記事ではjavascriptで実装されていたので、自分は慣れてるPythonで実装。ついでにLINEへの通知も実装しました。

実装

postal_notify.png

GitHubにupしました。

from flask import abort, Response
import os
from datetime import datetime, timezone, timedelta
import requests
import json

def notify_from_mailbox(request):

    JST = timezone(timedelta(hours=+9), 'JST')
    dt_now = datetime.now(JST)

    if request.method != 'POST':
        print(f'This is not post request: {request.method}')
        return Response(response=f'This is not post request: {request.method}', status=400)

    request_dict = request.get_json()

    # バッテリー情報を取得する
    if request_dict['batteryLevel'] >= 0.5:
        battery_notification = 'バッテリー残量は充分です'
    else:
        battery_notification = 'そろそろバッテリーが切れます'

    notify_message = "ポストに投函がありました。\n" \
    + f"投函時刻:{dt_now.strftime('%Y年%m月%d日 %H:%M:%S')}\n" \
    + f"{battery_notification}\n" \
    + f"<debug> clickType: {request_dict['clickType']}"

    # Slackへ送信
    slack_payload = {"token": os.environ['SLACK_TOKEN'],
                    "channel": os.environ['SLACK_CHANNEL'],
                    "username": "ポスト投函通知",
                    "text": f"<!channel> {notify_message}"}

    slack_res = requests.post('https://slack.com/api/chat.postMessage', data=slack_payload)

    # LINEへ通知
    headers = {
        "Authorization": f"Bearer {os.environ['LINE_ACCESS_TOKEN']}",
    }

    files = {
        "message": (None, notify_message),
    }

    line_res = requests.post("https://notify-api.line.me/api/notify", headers=headers, files=files)

    return {"slack": slack_res.json(), "line": line_res.json()}

上記をGCP Cloud Functionsにデプロイし、そのエンドポイントをSORACOMのコンソールから指定すればOK。
- SORACOMの設定: https://soracom.jp/recipes_index/2966/
- Slackの設定: https://www.whizz-tech.co.jp/5857/
- LINEの設定: https://rooter.jp/web-crawling/line-notify_with_python/

独自の部分

LINEへの通知以外に、参考にした記事から実装を少し変えたのは2点あります。

バッテリー残量を通知

SORACOM LTE-M Button Plusは単4電池で動かしていますが、電池の残量も合わせて通知してくれています。

SORACOM LTE-M Button Plusの通知内容
{
    "clickType": 1,
    "clickTypeName": "SINGLE",
    "batteryLevel": 1,
    "binaryParserEnabled": true
}

このbatteryLevelが0.5を切ったら通知内容にバッテリー残量が少ないことを通知するようにしています。

clickTypeによる判定を削除

clickTypeとは、SORACOM LTE-M Button Plusのボタンをどのように押したかの情報が入っています。

clickType 意味
1 シングルクリック
2 ダブルクリック
3 長押し

郵便受けの口がどのように開くかは郵便屋さんの操作次第であるため、clickTypeが1,2,3いずれになるかは予想が付きませんでした。そのためclickTypeによる処理の分岐はやめておきました。
一応、通知内容にどのclickTypeだったかを入れるようにしているので、運用していく中で必要に応じて処理を入れることもあるかもしれません。

ちょっとハマったところ

SORACOM公式の実装例と実物とで、配線の色の組み合わせがどうも違うみたいでした。実装例では「赤」「灰」のコードの組み合わせになっているのですが、それだとどうしても動かず、試しに「赤」「白」の組み合わせにしたら思い通りに動いたため、初期不良かあるいは実装例に誤りがあるのではないかと思われます。

[追記]
実装例をよく見たら

A: お手元のセンサー部のケーブル色が「赤・白・灰」における動作

B: お手元のセンサー部のケーブル色が「茶・白・灰」における動作

の2種類が書いてあった。「赤・白・灰」の方を見ながらやってたけど、手元にあるのは「茶・白・灰」だった。
なので実装例通りの配線でした。初期不良とか疑って申し訳ありませんでした。

完成

SORACOMLTE-MButtonPlus設置.png

ezgif.com-gif-maker.gif

image.png

image.png

まとめ

参考記事のおかげもあり、とてもかんたんに実装できました。

実装の運用はこれからですが、生活が潤いそう。

Cloud FunctionsからAlexaへ通知して、郵便受けに物が入ったらAlexaに教えてもらう、みたいなのもできそうだなと思いました。

参考

7
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?