SORACOM LTE-M Button PlusとAWS Lambdaを組み合わせて「助けて！」ボタンを作る

# 経緯

最近リモートワークで自宅にいながら仕事していることが多いのですが，日々ストレスを貯めながら黙々と仕事をしていると，隣の部屋にいる家族が仮に死の危険に瀕していたとしても気が付かないなと思いたち，何か作ることにしました．


SORACOM LTE-M Buttonを利用して，ボタンを押した際に「助けて！」メールが届くシステムを作ります．
このメールに気が付かなかったら家族は死にます．

ナースコールみたいなイメージ．

# システム構成
LTE-MボタンからAWS Lambdaを直接叩けるようになっていたのでこれを利用します．
Lambdaではメッセージの生成とメール送信を行います．


## 使うもの
- SORACOM LTE-M Button Plus + SORACOM Funk
- AWSのアカウント
- SMTPサーバ（というよりメールアカウント）

SORACOM LTE-M Button Plusが手元にあったので利用したんですが，おそらくどのボタンでもいいと思います


# 作り方

## AWS Lambda側の関数構築

事前にSORACOM Funkが利用できるよう
AWSのコンソールからLambdaのダッシュボードを開きます．関数の作成から新たに関数を作成します．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310137/10dc12e1-7b7e-faca-48ca-d5ae21fde150.png)

こんな感じで設定しました．


関数を作成後に関数のARNを確認しておきます．（あとで使う）


↓赤枠の部分

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310137/5fd7bc48-b5f5-1fe1-e723-8d2de7132129.png)

Lambda関数のコード自体は記事末尾に載せてあります．

## SORACOM Funkの設定
AWS IAMでユーザを作成してアクセスキーとシークレットキーを発行し，SORACOM Funkを利用するための設定をSORACOMのユーザーコンソールから行う必要があります．

下記に設定についての記載があります．

[SORACOM Funk を利用して AWS Lambda を呼び出し Slack へ通知する](https://dev.soracom.io/jp/start/funk_aws_lambda/)

## SORACOM LTE-M Buttonのセットアップ

[SORACOMのUserConsole](https://console.soracom.io/) にログインします．
ボタンを買ったら「SIM管理」画面にボタンが登録されているのでグループを作ります．

「SORACOM Funk設定」の項目を設定します．
サービスはAWS Lambdaを選択，送信データ形式はjsonとして，認証情報にはAWS IAMで作成したユーザの情報を選択します．
関数のARNは先程作ったLambda関数のARNを指定します．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310137/a50b9a37-49e2-17b0-8c25-0b5090bdb317.png)


### 簡易位置測位機能の有効化

「SORACOM Air for Cellular 設定」の終盤に簡易位置測位機能の設定があります．
基地局のIDから位置情報引いてきてくれる機能かと察するところですが，今回はこれも有効にしておきます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310137/90fdf991-b6d0-5001-ac13-aedcb82d4f74.png)

### ボタンを利用するグループで忘れがちな設定項目

いつも忘れるので書き留めておきます．
「SORACOM Air for Cellular 設定」の最後の項目に「バイナリパーサー」の項目があるのでONしておきます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310137/b6cbaf0f-2055-59b7-d20c-4d1daac76992.png)

## Lambda関数

こんなコードを書きました．

SORACOM FunkからLambda関数が呼ばれた際，データはcontext.client_context.customの中に入って渡されるようです．
この中の簡易位置計測機能に関する要素が時々抜け落ちる事があるようなので，例外処理を入れておきました．

```python
import json
import smtplib
from email.mime.text import MIMEText
from email.header import Header

FROM_ADDR = "" #SMTPサーバのログインアカウント
PASSWD = "" #SMTPサーバのログインパスワード
TO_ADDR = "" #送信先メールアドレス

#SMTPサーバ設定
SMTP_SERVER = ''
SMTP_PORT=587

def send_email(title, message):
    # メールタイトル
    title_text = title
    # メール本文
    body_text = message
    msg = MIMEText(body_text)
    msg['Subject'] = Header(title_text, 'utf-8')
    msg['From'] = FROM_ADDR
    msg['To'] = TO_ADDR
    s  = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
    s.ehlo()
    s.starttls()
    s.login(FROM_ADDR, PASSWD)
    s.sendmail(FROM_ADDR, TO_ADDR, msg.as_string())
    s.close()
    
def lambda_handler(event, context):    
    # 位置情報取得
    location_lat = -1
    location_lon = -1
    try:
        if(context.client_context.custom["locationQueryResult"] == "success"):
            location_lat = context.client_context.custom["location"]["lat"]
            location_lon = context.client_context.custom["location"]["lon"]
    except:
        pass

    # メッセージ生成
    title = '助けて！'
    message = "おおよその位置：緯度:" + str(location_lat) + " 緯度:" + str(location_lon) + "\n https://www.google.com/maps/search/?api=1&query=" + str(location_lat) + "," + str(location_lon)

    send_email(title, message)
    
    return {
        'statusCode': 200,
        'body': json.dumps('hoge'),
        'event': json.dumps(event)
    }

```


# まとめ
- ボタンを押したらメールが届きました．
- 複数のボタンを使って運用はじめると，どのボタンが押されたかわからなかったので，このあたりもう少し考えて作ればよかったと思うところです．
- LambdaからSlackにWebhook使って通知するなどの方法もスマートかもしれません．
- 防犯ブザーみたいな用途でお子さんに持たせても安心かも

作り終わったあとで備忘録的なものにしようと思い立って書いたんですが，スクショもなければ手順も忘れちゃうので書きながら作らないとダメですね．反省．