BLOG

【AWS IoT + ラズパイ】磁気スイッチの値をSlackで通知してみた!

2021.12.16
TECH

こちらは、ゆるWeb勉強会@札幌 Advent Calendar 2021 の16日目の記事です。

3歳児は鍵の開け方も覚えて、ヤンチャしたくなる年頃です。
いつ玄関のドアを突破するのかドキドキ…

こんにちは、タロウです。

今回は磁気スイッチの状態をラズパイで監視、
AWS IoTと連携してSlackへ通知してみました!
(3歳児対策・・ではない)

全体像


(スマートウォッチを使えば、スマホがそばになくてもより気がつくかも・・)

いきなり完成


ひとまずjsonでセンサーの状態を確認できるようになりました!
※messageは検知値を読み替えて設定しています。

以降、手順になります!

AWS IoTの準備

AWS IoTへモノの追加、通信に必要なエンドポイントや証明書を取得します。

モノ追加


画面に従って追加します。

エンドポイント


左メニューの設定を開いて確認します。

証明書取得


各種証明書をダウンロードします。

ラズパイの準備

まずはセンサーをつなげます。


わかりやすいように磁気スイッチがONの時にLEDが光ります。

今回はGPIO、AWS IoTのSDKを使うのにPythonを使いました。
AWS IoTで取得したエンドポイント、証明書をcertsディレクトリを切って入れています。

ソースはこんな感じにしました。
GPIOの21ピンでONOFF状態を検知します。


# coding:utf-8
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
import RPi.GPIO as GPIO
import json
import time
import sys

# MQTT Client
myMQTTClient = AWSIoTMQTTClient("raspi")

# MQTT Settings
myMQTTClient.configureEndpoint("[エンドポイント].iot.us-east-2.amazonaws.com", 443)
myMQTTClient.configureCredentials("./certs/AmazonRootCA1.pem", "./certs/[ダウンロードした鍵]-private.pem.key", "./certs/[ダウンロードした証明書]-certificate.pem.crt")
myMQTTClient.configureOfflinePublishQueueing(-1)
myMQTTClient.configureDrainingFrequency(2)
myMQTTClient.configureConnectDisconnectTimeout(10)
myMQTTClient.configureMQTTOperationTimeout(5)

# Connect to AWS IoT
myMQTTClient.connect()
print ("Connected to AWS IoT")

# pin is 21
pin = 21

print("Setting: ",pin)

# GPIO mode is GPIO.BCM
GPIO.setmode(GPIO.BCM)
# GPIO21 pulldown on
GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

print ("SetUp to GPIO")

now_value = GPIO.input(pin)
while True:
    try:
        value = GPIO.input(pin)

        if now_value != value:
            message = {}
            message['value'] = now_value
            message['message'] = "Open" if value == 0 else "Close"
            messageJson = json.dumps(message)
            myMQTTClient.publish("data/sensor", messageJson, 1)
            print ("data/sensor send:%s" % (messageJson))
            now_value = value
        
        time.sleep(1)
    except KeyboardInterrupt:
        GPIO.cleanup()
        myMQTTClient.disconnect()
        sys.exit()

通知の準備

AWS IoTからルールアクションを設定し、ラズパイからpublishされたらSNSに流すよう設定します。

SNSからLambdaを実行するよう設定します。

Lambdaで作成した関数はSlackへ通知するロジックのみです。


import json
import urllib.request
import logging
from collections import OrderedDict
import pprint

def lambda_handler(event, context):
    message = event['Records'][0]['Sns']['Message']
    send_data = {
        "text": message,
    }
    send_text = json.dumps(send_data)
    request = urllib.request.Request(
        "https://hooks.slack.com/services/[Slackで作成したWebhook URL]", 
        data=send_text.encode('utf-8'), 
        method="POST"
    )
    with urllib.request.urlopen(request) as response:
        response_body = response.read().decode('utf-8')

ソースはこちら

ハマったところ

いくつかありました・・

GPIO操作可能なnodeのパッケージで検知できなかった

なぜかセンサーを離しているのにONOFFが勝手に切り替わってしまう・・

(コマンドで確認しても不安定だったのでパッケージは関係ないのか・・)

ChatbotでSlackに通知が出せない

IoT → SNS → Chatbot でSlack連携したかったのですが、全く通知が来ず、
Chatbotのログを見るとnot supportedが・・

まだサポートされていない(?)みたいでした。公式

さいごに

眠りかけていたラズパイを掘り起こしてきっとラズパイも喜んでいることでしょう。
ずっとやってみたかったAWS IoTにも触れられ、とても楽しかったです!

配線などなど綺麗にして実際に玄関ドアにつけて運用してみたいと思います!

The following two tabs change content below.
Taro

Taro

ディレクターも、サーバ構築も、ゴリゴリ開発もやります。 オールマイティ担当。 スパイスも甘いものも大好き。