📮

xbiff で物理世界のポストの様子を可視化する

2021/12/13に公開

はじめに

前回の記事(IoT ポスト with ひげボタン) の最後で、通知用のデバイスを作ろうと言っておりましたが、我々には古くからメールボックスを可視化するためのツールがあったことを思い出しました。その名は xbiff です!

xbiff

こういうやつです。平成初期のUNIX端末室では誰しもがデスクトップに置いてましたよね。

メールが着信すると、旗が立って白黒反転します。

これを現実世界のメールボックスとリンクしようという試みです。

構成

前回作った部分と比べるとかなり複雑な構成になっています。

センシングデバイス側

  • 磁気センサーからの信号を受け、LTE-M Button Plus がクリックのイベントを Unified Endpoint に送信
  • SORACOM Funk から AWS Lambda を起動
  • Lambda では送られてきたイベントの内容を元に DynamoDB にクリックタイプを保存

郵便物を取りに行った時は、フタを素早く2回開閉することでダブルクリック信号を送り、郵便物を取り除いた状態として扱います。

表示側

  • Rapberry Pi は定期的にスクリプトを実行し、DynamoDB 上のクリックタイプの種類に応じてメールスプールファイルを空にしたり、ダミーのデータを書き込む
  • xbiff プログラムがメールスプールファイルを監視し、メールが来ていたら通知する

そして、xbiff プログラムを mac で表示したいので、SSH 経由で X11 Forwarding して手元に表示しています。

動作画面

郵便物が届いたようです!xbiff の表示が白から黒に変わりました!

ますます便利になりました。

おまけ

Lambda と Raspberry Pi で動いているコードを貼っておきます。

Lambda で動作しているコード

lambda_function.py
import json
import boto3
from boto3.dynamodb.conditions import Key, Attr

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('post')

def update_state(imsi, click_type):
    res = table.update_item(
        Key={
            "imsi": imsi
        },
        AttributeUpdates={
            "clickType": {
                "Value": click_type,
                "Action": "PUT"
            }
        }
    )
    if res.get('ResponseMetadata', {}).get('HTTPStatusCode', 500) == 200:
        return True
    else:
        return False

def funk_handler(event, context):
    click_type = event.get('clickType', 0)

    try:
        imsi = context.client_context.custom.get('imsi')
    except BaseException:
        imsi = "999999999999999"
    print(f'imsi={imsi}')

    return update_state(imsi, click_type)

def lambda_handler(event, context):
    print(json.dumps(event))
    if event.get('clickType'):
        return funk_handler(event, context)

    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }


if __name__ == '__main__':
    print(lambda_handler({"clickType": 2,"clickTypeName": "DOUBLE","batteryLevel": 1,"binaryParserEnabled": True}, {}))

Raspberry Pi で動作しているスクリプト

check_post.sh
#!/bin/bash
#
# set crontab like this to execute periodically.
# * * * * * ~/check_post.sh
#

# imsi value should be replaced with actual IMSI
status=$(aws dynamodb get-item --table-name post --key '{"imsi":{"S":"44052xxxxxxxxxx"}}' --query Item.clickType.N)
if [ "$status" = "2" ]
then
#	echo no mail.
	echo -n > /var/spool/mail/pi
else
#	echo you gotta mail!
	echo you have mail in mailbox! > /var/spool/mail/pi
fi

Discussion