SORACOM LTE-M Buttonでお母さんに親孝行しようと思った話(元気やでボタン)

SORACOM LTE-M Buttonでお母さんに親孝行しようと思った話(元気やでボタン):


とある休日に、何を思ったか

  • SORACOMのボタン(俗に言う「あのボタン」)が発売されるねんなぁ
  • 何作ろうかなぁ
  • そりゃ作るのはできるけどさ、せっかく作るなら使うもんがいいなぁ


そんな時、どこからともなくお母さんからLINEが

68747470733a2f2f71696974612d696d6167652d

  • それに対し、息子はこう返す。 
    68747470733a2f2f71696974612d696d6167652d
  • そういえば、そろそろお母さんの誕生日やねんなぁ…


息子の悩み

実家の大阪、自分の住む関東。
元気やけど、それを言うのはなんか気恥ずかしい。
でもお母さんから来る「元気か?」「元気やろ?」はちょっと嬉しい。

お母さんに心配はかけたくない。


そうだ、これだ

いつでもどこでもお母さんに「元気やで」って言えればメッチャ良くね?

…お母さんの誕生日に贈ることにしました。あのボタン。



68747470733a2f2f71696974612d696d6167652d



どんなものを作ろうと思ったか

  • ボタンを押すと、LINEに通知が届く
  • ボタンの役割によって届くメッセージが異なる
  • どうせだったら汎用的に使えるものが欲しい
  • 名付けて


fudechar_jibyt.png



仕組み

こんな感じです。

1. AWS IoT 1-Clickで、ボタンにLambdaの関数を割り当て

2. ボタンの属性に、それぞれのクリックに対応するメッセージを仕込む

3. ボタンの押された種別に応じて、LambdaからLINE Notifyにメッセージを発行


68747470733a2f2f71696974612d696d6167652d



AWS IoT 1-Clickの設定について

SORACOMのMaxさんが分かりやすく書いてくれてます。
SORACOM LTE-M Button powered by AWS を用いた開発 TIPS - SORACOM Blog

これを基にして、今回のプロジェクトで設定した内容を図解したので参考になれば。


68747470733a2f2f71696974612d696d6167652d



Lambda側の設定


の前に、気をつけたいこと


コードで工夫した点

  • 例外処理ちゃんと書いて、CloudWatchで出力されるログに、エラーが出るようにした
  • LINE Notifyのトークンが設定されていれば、そのログをLINE側に通知するようにした
  • LINE Notifyのトークンをコード内に設定できるようにした(環境変数にしたら良かった…)


実際のコード

messageのところは、適宜書き換えて好きなフォーマットで出力してください。

lambda_function.py
# -*- coding:utf-8 -*- 
 
import json 
import requests 
import datetime as dt 
 
# LINE NotifyのURLとデフォルトの通知先トークン(これよりもボタン側に設定したトークンが優先される) 
LINE_NOTIFY_URL = "https://notify-api.line.me/api/notify" 
LINE_NOTIFY_TOKEN = "" 
 
# UTCとの時差(時間) 
UTC = 9 
 
 
def lambda_handler(event, context): 
    global LINE_NOTIFY_TOKEN 
    print("Received event: " + json.dumps(event)) 
 
    # デバイス情報(デバッグ用) 
    deviceInfo = event['deviceInfo'] 
    deviceId = deviceInfo['deviceId'] 
    deviceAttributes = deviceInfo['attributes'] 
 
    # プロジェクト名、プレイスメント名(デバッグ用) 
    projectName = deviceAttributes['projectName'] 
    placementName = deviceAttributes['placementName'] 
 
    # クリック種別とクリック時間の取得 
    buttonClicked = event['deviceEvent']['buttonClicked'] 
    clickType = buttonClicked['clickType'] 
    reportedTime = buttonClicked['reportedTime'] 
 
    # AWSデフォルト表記:2018-11-09T12:37:10.614Z 
    input_datetime_format = '%Y-%m-%dT%H:%M:%S.%fZ' 
    # 出力表記:2018/11/09 12:37:10 
    output_datetime_format = '%Y/%m/%d %H:%M:%S' 
 
    # datetimeオブジェクト作成 
    datetime_obj = dt.datetime.strptime(reportedTime, input_datetime_format) 
    # 時差補正 
    td = dt.timedelta(hours=UTC) 
    # 日時フォーマット整形 
    reportedTime = (datetime_obj + td).strftime(output_datetime_format) 
 
    # 属性情報の取得 
    attributes = event['placementInfo']['attributes'] 
 
    try: 
        # トークンが設定されていれば 
        if 'LINE_NOTIFY_TOKEN' in attributes: 
            LINE_NOTIFY_TOKEN = attributes['LINE_NOTIFY_TOKEN'] 
        else: 
            raise AttributeError("LINE Notifyのトークンが見つかりません。") 
 
        # ボタン名が設定されていれば 
        if 'BUTTON_NAME' in attributes: 
            BUTTON_NAME = attributes['BUTTON_NAME'] 
        else: 
            raise AttributeError("ボタン名が見つかりません。") 
 
        # クリック種別に応じた処理 
        if clickType == "SINGLE": 
            if 'SINGLE_MESSAGE' in attributes: 
                message = attributes['SINGLE_MESSAGE'] 
            else: 
                raise AttributeError("シングルクリック時のメッセージが定義されていません。") 
 
        elif clickType == "DOUBLE": 
            if 'DOUBLE_MESSAGE' in attributes: 
                message = attributes['DOUBLE_MESSAGE'] 
            else: 
                raise AttributeError("ダブルクリック時のメッセージが定義されていません。") 
 
        elif clickType == "LONG": 
            if 'LONG_MESSAGE' in attributes: 
                message = attributes['LONG_MESSAGE'] 
            else: 
                raise AttributeError("ロングクリック時のメッセージが定義されていません。") 
 
        # メッセージ生成 
        message = "\n"+BUTTON_NAME+"が「"+message+"」と言っています。\n" \ 
            + "時刻:"+reportedTime 
            # + "時刻:"+reportedTime+"\n" \ 
            # + "ボタン名:"+placementName+"\n" \ 
            # + "シリアル:"+deviceId 
 
        # LINE送信処理 
        send_to_line(message) 
 
    except AttributeError as e: 
        error_message = "\nプロジェクト名["+projectName+"]の端末["+placementName+"("+deviceId+")]でエラーが発生しました:"+e.args[0]+"\n" \ 
            + "時刻:"+reportedTime 
 
        print(error_message) 
 
        # LINE Notifyのトークンが設定されていれば、エラーメッセージを通知 
        if 'LINE_NOTIFY_TOKEN' in attributes: 
            send_to_line(error_message) 
 
 
def send_to_line(message): 
    headers = {"Authorization": "Bearer " + LINE_NOTIFY_TOKEN} 
    payload = {"message":  message} 
 
    requests.post(LINE_NOTIFY_URL, headers=headers, params=payload) 


テストイベント用のJSON

これをLambdaのテストイベントの箇所に貼り付けてテストしたら、LINEに通知されます。

(トークンだけ書き換えてね)

test_event.json
{ 
    "deviceInfo": { 
        "deviceId": "1AB2CDEFGHI3456", 
        "type": "button", 
        "remainingLife": 98.4, 
        "attributes": { 
            "projectRegion": "ap-northeast-1", 
            "projectName": "howareyou_mom", 
            "placementName": "button_01", 
            "deviceTemplateName": "notifyToLINE" 
        } 
    }, 
    "deviceEvent": { 
        "buttonClicked": { 
            "clickType": "SINGLE", 
            "reportedTime": "2018-11-09T16:29:40.474Z" 
        } 
    }, 
    "placementInfo": { 
        "projectName": "howareyou_mom", 
        "placementName": "button_01", 
        "attributes": { 
            "SINGLE_MESSAGE": "元気です。", 
            "DOUBLE_MESSAGE": "元気してる?", 
            "LINE_NOTIFY_TOKEN": "(LINE Notifyトークン)", 
            "LONG_MESSAGE2": "連絡ちょうだい!", 
            "BUTTON_NAME": "息子" 
        }, 
        "devices": { 
            "notifyToLINE": "1AB2CDEFGHI3456" 
        } 
    } 
} 


実際の画面

できたー!オカンがもうすぐ誕生日やから、このボタン渡して親孝行するんだ!日本初の「オカンにソラコムボタン渡した息子」になりたい…!

AWS IoT 1-Click側の設定だけでLambdaには手を加えなくていい親切設計です。メッチャ汎用的。(近日Qiitaに書きます)#SORACOM #あのボタン #AWS #IoT pic.twitter.com/lqdj3xm0Uj

— itox(dev) (@itoxdev) 2018年11月9日
やりとりのイメージ


68747470733a2f2f71696974612d696d6167652d


エラー出力


68747470733a2f2f71696974612d696d6167652d



作ってみた感想


  • 実は今回AWSというかLambda初めて触ったけどメッチャ面白い

    • アカウント作って1週間くらい(いや、ずっとやりたいとは思ってたのよ)

  • お母さんに早く渡したい

    • お母さんと電話して頭出しは済んでる
    • お母さん「それよりあんた、誕生日プレゼントにひこにゃんのLINEスタンプ欲しいわ
    • まさかのスタンプおねだりかよ
  • え、VSCodeメッチャ便利…(これまでメモ帳で頑張ってた)
  • PythonいいよPython、モジュール使いやすいぜ
  • よく考えたら「元気やでボタン」やのに本文中は「元気です」とか言ってるごめん
  • IoTって技術ありきじゃなくて、アイデア勝負やんな、やっぱ
  • IoTはきっと人を幸せにできる


今後考えてること

  • DynamoDBに入れたいなぁ
  • もうちょい可視化したいなぁ
  • LINEじゃなくてAlexaに出力しても面白いなぁ
  • Wio + モータードライバ or リレーとか使って、元気ならぬいぐるみ動かしても面白いなぁ
以上

コメント

このブログの人気の投稿

投稿時間:2021-06-17 22:08:45 RSSフィード2021-06-17 22:00 分まとめ(2089件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)