タグ「python」が付けられているもの


車バイクセキュリティ発報を LINE 通知へ変更 - SORACOM LTE-M Button Plus と AWS Lambda/SNS

昨年設定したバイクとカーセキュリティのメール発報を、LINE 通知に変更してみました。

仕組は、セキュリティ装置にリレー接続した SORACOM LTE-M Button Plus と SORACOM Funk で Amazon Lambda へ飛ばし、さらに LINE Notify 宛にリクエスト発行する形です。

以前ボタンを購入した際、ちょうどソラコム側で簡単メール通知機能が用意されたので、そのまま使ってました。
ただ、通知到着までが、かなり遅いんですよね(早いときもある)。

  • SORACOM Funk
  • Amazon Lambda
  • Amazon SNS (SMS 通知、Eメール通知)
  • LINE Notify (LINE 通知)

使用したサービスは、これだけ。
ついでに Amazon SNS 使って SMS 通知も機能いれてみました。

LINE 以外にもインタフェースが用意されてれば通知はできます。Slack への通知は簡単かな。Facebook Messenger は面倒そうだったのでやめました。

色々試しましたが Amazon SNS 経由の SMS 通知より、LINE Notify が早いですね。

 

LINE、Amazon AWS、SORACOM 環境準備

それでは、サービス側 LINE, Amazon AWS, SORACOM の環境を準備していきます。

  1. LINE Notify
  2. Amazon IAM
  3. Amazon SNS
  4. Amazon Lambda
  5. SORACOM 認証ストア
  6. SORACOM Funk

LINE Notify準備

以下 URL からマイページへログインし、自分への通知用にトークンIDを発行、メモしておきます。
LINE をメールアドレスでログインできる様に変更しておく必要があります。

  • https://notify-bot.line.me/ja/
  • 「トークン名」:(任意)
    ※LINE 通知した際にメモ程度に表示されます。私は button にしました。
  • 「通知するトークルーム」:「1:1 でLINE Notify から通知を受け取る」を選択
    ※複数人で受ける場合はグループ宛もできます

トークンIDは漏れると誰でも通知できる様になっちゃうので注意。漏れたら別のトークンIDの再発行も可能です。

Amazon AWS

リージョン選択

どこの国の AWS で動かすかですが、私は ap-northeast-1 (東京) で動かしています。

IAM

SORACOM Funk 用に「Amazon IAM」の「アクセス管理ーユーザー」で、アクセスキーとシークレットを作成します。

アクセスキーIDとシークレットは、後の SORACOM サイトへ登録するので、メモしておきます。

SNS

Amazon SNS では、メール通知、SMS 通知の設定を行います。

  1. 「トピックの作成」で、トピック作成します。
    https://ap-northeast-1.console.aws.amazon.com/sns/v3/home?region=ap-northeast-1#/topics
    「タイプ」は「スタンダード」。
    「名前」は、適当に。
    「表示名」は「名前」と同じ値に。私は「名前を」 "soracom-funk-app1" としました。
  2. 「サブスクリプション」で、メールアドレスと、SMS通知用に電話番号を登録します。
  3. 「プロトコル名」の所は、「Eメール」、「SMS」をそれぞれ選択して登録完了。
    ※ SMS、あまり多く発信すると拒否されるらしいので注意が必要です。
  4. 最後に、「トピック ARN」を、メモしておきます。
    ※ こんな感じの ARN 名です。
    「arn:aws:sns:??????????:???????:soracom-funk-app1」

Lambda

関数を作成して、プログラムを用意します。

  1. 「関数の作成」から関数を作成します。
    https://ap-northeast-1.console.aws.amazon.com/lambda/home?region=ap-northeast-1#/functions
    「関数名」は適当に。私は soracom-funk-to-line としました。
    「ランタイム」は、Python 3.8 を選択します。
    「アクセス権」は、「基本的な Lambda アクセス権限で新しいロールを作成」で進みます。
    「関数の作成」ボタンで登録を完了させます。
  2. 関数の ARN をメモします 「arn:aws:lambda:???????:???????:???????」
  3. 先に作成した LINE のトークンIDを環境変数へ登録します。
    「設定」の「環境変数」から「編集」ボタンを推して「キー」にアクセスキーID、「値」にシークレットキーを登録します。
  4. ソースコードを "lumbda_function.py" ファイル記述していきます。
    変更すると自動保存されますが、"Changes not deployed" と出ているので、「Deploy」ボタンで反映させます。
    いろんなサイトを参考に簡単な Python のプログラムコードを作成しました。
    TopicArn 部分は、Amazon SNS の ARN 名に変えてください。
    パクってつぎはぎだらけのコードで未使用のコメントアウト部分などあります。それと SMS の SenderID の付け方を調べてないので NOTICE と通知されます。
# -*- coding: utf-8 -*-
import os
import urllib.request
import urllib.parse
import urllib3
import boto3
sns = boto3.client('sns')
http = urllib3.PoolManager()
def get_message(data):
    clicktype = data['clickTypeName']
    if   clicktype == 'SINGLE':
        message = u'ALERT SINGLE'
    elif clicktype == 'DOUBLE':
        message = u'ALERT DOUBLE'
    elif clicktype == 'LONG':
        message = u'ALERT LONG'
    else:
        message = u'unkown'
    return message
def line_notify(msgx):
    url = "https://notify-api.line.me/api/notify"
    headers = {"Authorization" : "Bearer "+ os.environ['LINE_TOKEN']}
    data = urllib.parse.urlencode({"message" :  msgx}).encode('utf-8')
    request = urllib.request.Request(url, data=data, headers=headers)
    r = urllib.request.urlopen(request)
    print(r)
def slack_notify(msgx):
    url = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    msg = {
        "Content": msgx
    }
    encoded_msg = json.dumps(msg).encode('utf-8')
    resp = http.request('POST',url, body=encoded_msg)
    print(resp)
def sns_publish(message, subject):
#    message_attributes = {
#        'AWS.SNS.SMS.SenderID': {
#            'DataType': 'String',
#            'StringValue': 'AWS-SORACOM'
#        }
#    }
#       'MessageAttributes': message_attributes
    request = {
        'TopicArn': "arn:aws:sns:??????:??????:soracom-funk-app1",
        'Message': str(message),
        'Subject': str(subject)
    }
    sns.publish(**request)
def lambda_handler(event, context):
    batl = event['batteryLevel'] * 100
    posi = context.client_context.custom['location']['lat']
    posk = context.client_context.custom['location']['lon']
    message = get_message(event)
    subj = message
    message = message + '\nBat ' + str(batl) + "%"
    message = message + '\nhttps://maps.google.com/maps?q=' + str(posi) + ',' + str(posk)
#    if event['clickTypeName'] == 'LONG':
#        line_notify(message)
#    if event['clickTypeName'] == 'DOUBLE':
#        line_notify(message)
#    slack_notify(message)
    line_notify(message)
    sns_publish(message, subj)
    return

SORACOM 認証ストア

AWS へ接続する為の認証情報を登録します。

  1. 管理画面内の右上から「セキュリティ」を選択し「認証情報ストア」を開き、「認証情報を登録」します
  2. 「認証情報ID」、「概要」は任意文字
  3. 「種別」は「AWS 認証情報」を選びます
  4. 「AWS Access Key ID」、「AWS Secret Access Key」をそれぞれ登録します

SORACOM Funk

Amazon 側で準備した情報を登録していきます。
SORACOM管理画面のメニューから「SIM グループ」を選び無ければ新規作成し、SIMグループの設定に入ります。
https://console.soracom.io/#/groups?coverage_type=jp

  1. 「SORACOM Air for Cellular 設定」
    1. 「簡易位置即位機能」をON。
    2. 「バイナリパーサー」をON。
      フォーマットへ @button と文字を登録
  2. 「SORACOM Funk 設定」
    1. 「サービス」は、「AWS Lambda」を選択
    2. 「送信データ形式」は、「JSON」を選択
    3. 「認証情報」は、先に「SORACOM 認証ストア」で作成した認証情報を選択します。
    4. 関数の ARN をコピペ入力します。

これで準備は完了。

後はボタンを押して、SINGLE、DOUBLE、LONG と基地局位置のマップが LINE 通知されるかを確認。

  • 警戒ON:SINGLE
  • 警戒OFF:DOUBLE
  • 威嚇アラーム:DOUBLE
  • 本警報:LONG

私のセキュリテイ装置の場合は、こんな形で LINE Notify されますが、威嚇アラーム(DOUBLE)後、1分以内にすぐ本警報(LONG)の場合は LONG が無視されるので威嚇のときも注意が必要。