python

SORACOM Button by Pythonでゴルフのスコアカウンタを作った

IoTのプロジェクトに配属され、キャッチアップのために何か作成したい

そんな思いから、SORACOM LTE-M Buttonを買いました!

SORACOMの公式がnode.jsで作成しているのであまり、Pythonでまとまっているものありません

なので、この記事が今時点でもっとも詳しく書かれているかなと思います

  • SORACOM Buttonを押してSlackに通知するところまでを解説します

SORACOM LTE-M Buttonとは

AWSと超簡単に連携可能なSORACOMが出したIoT Buttonです
イメージは、Amazon Dash Buttonだと思ってください

詳しい説明は公式を確認してください。

SORACOM Button by Pythonの開発の流れ

開発の流れは以下の5Stepに分かれます。
1〜4の登録は、他の記事に説明を譲ります。(参考リンクを貼ります。)
本記事では、5〜8について詳しく説明します。

  1. AWS IoT 1-Click に登録する
  2. AWS IoT 1-Click のプロジェクトを作成する
  3. SORACOM ガジェット管理に登録する
  4. SORACOM ガジェット管理からデバイスの情報を確認する
  5. Lambda関数を作成する
  6. Lambda関数をアップロードする
  7. Lambda関数をテストする
  8. 実際にSlack通知してみる

SORACOM Button by Pythonのアーキテクチャイメージ

iot-architecheriot-architecher

SORACOM LTE-M Buttonの処理をAWS Lambdaで受けて、Slackに通知します。
Lambdaに関数をデプロイする手段としてzappaを利用します。

Lambda関数を作成する

zappaのインストール

手前味噌ですが下記を参考にインストールしてください

slackwebのインストール

PythonからSlackに連携するツールをインストールします

pip install slackweb

zappaでは、virtualenv上にインストールされたパッケージを自動でアップロードしてくれます

chaliceの場合、requirements.txtを自分で作成してあげる必要があるので楽ですね

slackでincoming-webhookを用意

こちらのリンクから作成してください

Pythonで処理を書く

lambda.py(任意の名前で問題ありません)というファイルを作成します

import os
import json
from datetime import datetime, timedelta, timezone
import slackweb

# タイムゾーンの生成
JST = timezone(timedelta(hours=+9), 'JST')
tmp_dir = '/tmp'
file_nm = 'score.txt'
score_file_path = os.path.join(tmp_dir, file_nm)
score = '0'

def app(event, context):
    button_type = event['deviceEvent']['buttonClicked']['clickType']
    if button_type == 'SINGLE':
        count_up()
        return button_type
    elif button_type == 'DOUBLE':
        count_down()
        return button_type

    elif button_type == 'LONG':
        push()
        return button_type
    else:
        return button_type

def read_score():
    if not os.path.exists(score_file_path):
        reset()

    with open(score_file_path, 'r') as f:
        tmp_score = f.read()
        return tmp_score

def write_score(tmp_score):
    with open(score_file_path, 'w') as f:
        f.write(tmp_score)

def count_up():
    score = read_score()
    tmp_cnt = int(score)
    tmp_cnt+=1
    write_score(str(tmp_cnt))

def count_down():
    score = read_score()
    tmp_cnt = int(score)
    if tmp_cnt == 0:
        return
    tmp_cnt-=1
    write_score(str(tmp_cnt))

def reset():
    write_score('0')
    
def push():
    push_score = read_score()
    now = datetime.now(JST).strftime('%Y/%m/%d %H:%M')
    payload = '```{} score: {}```'.format(now, push_score)
    slack = slackweb.Slack(url="https://hooks.slack.com/services/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")
    slack.notify(text=payload, mrkdwn=True)
    reset()

続いて、zappa init時に自動で作成されるzappa_settings.jsonを編集します

vi zappa_settings.json
{
    "dev": {
        "app_function": "lambda.app",
        "aws_region": "us-east-2",
        "profile_name": "default",
        "project_name": "score-counter",
        "runtime": "python3.6",
        "s3_bucket": "zappa-2txhj5ihk",
        "apigateway_enabled": false
    }
}

app.functionの部分は、ファイル名+関数名にしてください。

私の場合、lambda.pyのapp(event, context)を呼び出すためlambda.appとしています。

Lambda関数をアップロードする

zappa deploy
# 2回目以降
zappa update

AWS Lambdaにアクセスして関数が作成されているか確認しましょう

Lambda関数をテストする

毎回、SORACOM LTE-M Buttonを押して挙動を確認していると上限の1,500回にすぐ到達してしまうので

テストで挙動を確認しましょう!

テストイベントを設定する

AWS Lambdaのアップロードした関数のページトップに『テスト』というボタンがあるので、テストイベントを設定しましょう

SORACOM LTE-M Buttonを押した時に渡されるパラメータはこのようになっています

このパラメータを登録します

{
    "deviceEvent": {
      "buttonClicked": {
        "clickType": "SINGLE",
        "reportedTime": "2018-05-04T23:26:33.747Z"
      }
    },
    "deviceInfo": {
      "attributes": {
        "key3": "value3",
        "key1": "value1",
        "key4": "value4"
      },
      "type": "button",
      "deviceId": " G030PMXXXXXXXXXX ",
      "remainingLife": 5.00
    },
    "placementInfo": {
      "projectName": "test",
      "placementName": "myPlacement",
      "attributes": {
        "location": "Seattle",
        "equipment": "printer"
      },
      "devices": {
        "myButton": " G030PMXXXXXXXXXX "
      }
    }
  }

 

テストする

テストイベントが設定できたら、テストボタンを押下します

実際にSlack通知してみる

最後に実際にボタンを押してみましょう

slack-scoreslack-score

 

上記のように通知がきたら完成です

 

まとめ

PythonとLambdaで簡単にIoTを試すことができました

SORACOM Buttonが1個(セールで¥4,000、定価で¥8,000)ゴルフのカウンタとしては少々値段が張りますねw

ただ導入としては大変よいチュートリアルになると思います

特にLambdaはサーバレスアーキテクチャの基本です

今後、サーバレスを語る上で必須知識になります

さらに詳しくなりたい方は実践AWS Lambda ~「サーバレス」を実現する新しいアプリケーションのプラットフォーム~を読みましょう

ABOUT ME
アバター
ロッピー
コンサルタントから2018年にエンジニアに転向。年収400万円のサラリーマンエンジニアから、半年で月収100万円を稼ぐエンジニアになった。 Python、Golangなど単価の高い言語を得意とする。