前編では、M5StickC・AWS IoT Core の設定をしました。
後編では、AWS Lambda・Amazon API Gateway・Slack API の部分を作っていきます。
やりたいことのイメージ(再掲)
イメージ図
処理の流れ
- Slack 上で Bot にメッセージを送る
- Slack Bot が Amazon API Gateway が発行した API を叩く
- Amazon API Gateway をトリガーにして、Lambda function が実行される
- Lambda function が AWS IoT Core にメッセージを格納する(Publish する)
- M5StickC が AWS IoT Core に定期的にメッセージをとりに行く(Subscribe する)
- M5StickC が 受信したメッセージに応じて、エアコンのリモコン操作を実行する(赤外線を照射する)
※前編には6,5を実装する手順を記載し、後編には4,3,2を実装する手順を記載します。
エアコンのリモコン操作の種類
- Cool:電源オン(冷房)
- Heat:電源オン(暖房)
- Stop:電源オフ
目次
- Lambda function の作成
- Amazon API Gateway の作成
- Slack API の作成
1. Lambda function の作成
関数を作成する
AWSコンソールにサインインし、画面上部の検索欄に「Lambda」と入力し、[サービス]-[Lambda]をクリックします。
[関数の作成]をクリックします。
「一から作成」を選択し、任意の関数名を入力します。ここでは「M5StickC_Publish」と入力します。ランタイムは「Python」を選択して、[関数の作成]をクリックします。
関数が作成されると、画面上にデフォルトのプログラムコードが表示され、そのまま画面上で編集できる状態となります。デフォルトのプログラムコードは削除します。
コードを書く
環境ごとの設定
以下の部分は自分の環境に合わせて書く必要があります。
iot = boto3.client("iot-data", endpoint_url='https://xxxxxxxxxxx-ats.iot.<region>.amazonaws.com')
endpoint_url の部分は、AWS IoTの設定画面から「設定」ボタンを押して確認できます。
コード全文
Amazon API Gateway から渡されるイベントデータに、キーワード(「Cool」「Heat」「Stop」)が含まれていた場合は、対応するメッセージを IoT core に発行(Publish)するようにしています。
# coding: utf-8
import json
import boto3
import logging
iot = boto3.client("iot-data", endpoint_url='https://xxxxxxxxxxxxxxx.iot.xxxxxxxxx.amazonaws.com')
topic = "$aws/things/myM5StickC/shadow/update/delta"
# ログ設定
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
msg = event.get("event").get("text")
# 受信データをCloud Watchログに出力
logging.info(json.dumps(event))
# SlackのChallenge認証
if "challenge" in event:
return event["challenge"]
# メッセージ毎に処理を行う
if "Cool" in msg:
payload = {
"message": "Cool"
}
elif "Heat" in msg:
payload = {
"message": "Heat"
}
elif "Stop" in msg:
payload = {
"message": "Stop"
}
else:
print("キーワードが一致しません。")
return "OK"
# publishする
try:
iot.publish(
topic=topic,
qos=0,
payload=json.dumps(payload, ensure_ascii=False)
)
print(payload, "をpublishしました。")
return "Succeeeded."
# 例外のメッセージをログに出力
except Exception as e:
print(e)
return "Failed."
関数のアクセス権限を設定する
続いて、[設定]-[アクセス権限]を開き、ロール名のリンクをクリックします。
検索欄に「IoTDataAccess」と入力します。
「IoTDataAccess」にチェックを入れて、[許可を追加]をクリックします。
テストしてみる
関数の画面に戻り、[テスト]タブを開きます。
「イベントJSON」欄に、以下の様に入力して、[テスト]をクリックします。
{
"event": {
"text": "Cool"
}
}
ログを確認すると、メッセージ"Cool"を受け取り、対応するメッセージ"Cool"を IoT core に発行したことが確認できました。
次に、実際に、IoT core にメッセージが格納されるかを確認します。
AWS IoT > 管理 > すべてのデバイス > モノ > myM5StickC を開きます。
[アクティビティ]タブを開き、「MQTTテストクライアント」をクリックします。
[トピックにサブスクライブする]タブを開き、トピックのフィルター欄に「$aws/things/myM5StickC/shadow/update/delta」を入力し、[サブスクライブ]をクリックします。
メッセージ"Cool"が格納されることを確認します。
2. Amazon API Gateway の作成
APIを作成する
AWSコンソール画面上部の検索欄に「API Gateway」と入力し、[サービス]-[API Gateway]をクリックします。
[APIを作成]をクリックします。
API タイプは「REST API」を選択します。[構築]をクリックします。
API名欄に任意の名前を入力します。ここでは「M5StickC_Publish-API」と入力します。[APIを作成]をクリックします。
リソース名欄に任意の名前を入力します。ここでは「M5StickC_Publish」と入力します。「リソースを作成」をクリックします。
メソッドタイプは、「POST」を選択します。Lambda関数は、先ほど作成した関数を選択します。「メソッドを作成」をクリックします。
任意のステージを選択します。ここでは、新たにステージを作成し、ステージ名を「production」としました。[デプロイ]をクリックします。
この時点で、関数の画面から[設定]-[トリガー]を開いてみると、作成した API Gateway がトリガーとして追加されていることが確認できます。ここに表示されている API endpoint は、 Slack API 作成時に必要となるので控えておきます。
3. Slack API の作成
Slack API を作成する
Slack API にアクセスします。
[Create New App]をクリックします。
App Name 欄に任意の名称を入力します。ここでは「Air Conditioning by M5StickC」と入力します。Workspace を選択し、[Create App]をクリックします。
[Event Subscriptions]を開き、[Enable Events]を On にします。
[Request URL]欄に、先ほど控えた API endpoint を入力します。
Lambda関数によるSlackのChallenge認証がうまく通れば、Verified と表示されるはずです。
少し下にスクロールし、[Subscribe to bot events]を展開して、[Add Bot User Event]をクリックし、「app_mention」を追加します。
[Install App]を開き、[Install to Workspace]をクリックします。
テストしてみる
スマホ上でSlackを開き、適当なチャンネルを作成して、チャンネルにAppを追加します。
Botにメンションして、キーワード(「Cool」「Heat」「Stop」)を送ってみます。
ここで、Lambda のログを確認すると、Slackから送ったメッセージが届いていることが確認できました。
IoT core にも、メッセージが格納されていることが確認できました。
そして、ほどなくしてエアコン操作が実行できれば成功です。
おわりに
最後まで読んで頂いてありがとうございました。
今回の取り組みは、やりたいことが先にあって、どうやってそれを実現するかを考えながら手を進めました。世の中には、色んな製品やサービスがあって、それらを組み合わせることで色んなことが実現できて便利ですね。
私にとっては、M5StickC も、Arduino IDE も、AWS の各サービスも、Slack API も、初めて触るものばかりで苦労しましたが、その分、学びの楽しさと、実現の喜びを感じることが出来ました。
この記事が、同じ目的を持つ人のお役に立てば幸いです。