ITやAIに関するちょっとしたメモ

AIやIoTをはじめITに関して記録しておきたいことをメモ的に書いていきます。

温度センサーを接続したRaspberry Pi 3 B+ をクラウドのAmazon AWS IoTとつなぎ、メールを自動で送るようにしてみた

 Raspberry Pi 3 B+に温度湿度センサーをつなぎ、AWS IoTからAmazon SNSを介してメールを出すということをやってみたので、メモ代わりにその概要とポイントについて書いておきます。

 

1.はじめに

 Raspberry Pi 3 B+を購入し、ここまでOSの設定、パソコンからの接続と操作、Python で書かれたプログラムによるLEDの点灯、さらにはクラウドであるAmazon Web Services(AWS)の接続とMQTT用のサンプルプログラムを使った簡単な疎通確認までを行いました。

2.今回の目的と全体環境について

 ここでは、今までに行った設定に基づき、Raspberry Piに温度センサーをつないで検知した情報をインターネットを通じてAWSへ送信し、その内容に応じてメールを送信する、ということをやってみます。

 今回設定した環境全体は、1枚の図にまとめると以下のようになります。小規模ながらも、ここまでくるとIoT(Internet Of Things)といえると思います。

f:id:ColdSnap:20190406193558p:plain

 

3.手順のポイントについて 

 AWS IoTとAWS IoT SDKを使った設定手順については、以下にあるAWSチュートリアルを全面的に参考にしました。

 これはかなり長いうえに、同じことを書いても仕方ないので、少し難しかったところ、ポイントになるところ、少し変えたところだけを書いておきます。

 

(1). 最初に何をやっているのか理解してから進める

 実はポイントはそんなにないのですが、手順が長いので、まったくの初めてだと苦戦する可能性があります。ですので、何をやっているか最初に中身をきちんと理解してから手を動かした方がよいでしょう。

(2). チュートリアルの画面ハードコピーは英語

 チュートリアルは日本語訳でかかれていてわかりやすくて丁寧なのですが、画面のハードコピーが英語のままです。AWSの設定画面を日本語で使っていても画面が同じであれば特に困ることはありませんが、AWSはよく画面の仕様が変更されるので、そうなると少し困るかもしれません。

(3). 証明書関連

 ラズパイとAWS IoTをつなぐときには、証明書とエンドポイントの情報がカギになります。AWS IoT画面では、以下のように証明書を作成してモノに追加する必要があります。チュートリアルの説明では英語のハードコピー画面ですが、日本語画面で設定していると次のように出ます。

f:id:ColdSnap:20190406202734p:plain

 ここから証明書の作成に移るのですが、AWSクラウドにあるので、セキュアなアクセスを実現するに[パブリックキー]、[プライベートキー]、[AWS IoT のルート CA] の3つの情報を使います。[ルートCA]も重要です。ラズパイとAWS IoTはこれらのキー情報とエンドポイントの情報で接続することになります。

 尚、プライベートキーとパブリックキーは一度ダウンロードして閉じてしまうと同じものはダウンロードできないので注意が必要です。

f:id:ColdSnap:20190406203413p:plain


(4). AWS SNSの設定

 AWS SNSですが、チュートリアルが作成されたときから仕様変更が入り、画面が変わっていました。単にIoTのアクションからSNSを呼び出してメールを出せればいいので、AWSのコンソールからAmazon SNSを選び、トピックの作成を行います。

f:id:ColdSnap:20190407162049p:plain

AWS IoT側では以下のような感じになります。

f:id:ColdSnap:20190407161004p:plain

(5). 湿度温度計

 AWSチュートリアルでは、観葉植物用の土壌湿度を測定することになっています。しかし、私のIoTデバイスキットでは温度湿度センサーはありますが、それを土にさすデバイスは無いので、温度湿度センサーだけでやりました。結局、線の抜き差しでON/OFFを検知するという形でSNSにアクションを出す形になりました。

 Pythonのサンプルは今回のチュートリアル用のものをコピーし、キー情報などを今回用に直して使います。

f:id:ColdSnap:20190407165900j:plain

 Pythonのプログラムは以下のサイトに説明してあるものを、証明書やエンドポイントの情報を修正して使います。

 

https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/iot-plant-step12.html

from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTShadowClient

import RPi.GPIO as GPIO

import time

 

# A random programmatic shadow client ID.

SHADOW_CLIENT = "myShadowClient"

 

# The unique hostname that AWS IoT generated for

# this device.

HOST_NAME = "yourhostname-ats.iot.us-east-1.amazonaws.com"

 

# The relative path to the correct root CA file for AWS IoT,

# that you have already saved onto this device.

ROOT_CA = "AmazonRootCA1.pem"

 

# The relative path to your private key file that

# AWS IoT generated for this device, that you

# have already saved onto this device.

PRIVATE_KEY = "yourkeyid-private.pem.key"

 

# The relative path to your certificate file that

# AWS IoT generated for this device, that you

# have already saved onto this device.

CERT_FILE = "yourkeyid-certificate.pem.crt.txt"

 

# A programmatic shadow handler name prefix.

SHADOW_HANDLER = "MyRPi"

 

# Automatically called whenever the shadow is updated.

def myShadowUpdateCallback(payload, responseStatus, token):

  print()

  print('UPDATE: $aws/things/' + SHADOW_HANDLER +

    '/shadow/update/#')

  print("payload = " + payload)

  print("responseStatus = " + responseStatus)

  print("token = " + token)

 

# Create, configure, and connect a shadow client.

myShadowClient = AWSIoTMQTTShadowClient(SHADOW_CLIENT)

myShadowClient.configureEndpoint(HOST_NAME, 8883)

myShadowClient.configureCredentials(ROOT_CA, PRIVATE_KEY,

  CERT_FILE)

myShadowClient.configureConnectDisconnectTimeout(10)

myShadowClient.configureMQTTOperationTimeout(5)

myShadowClient.connect()

 

# Create a programmatic representation of the shadow.

myDeviceShadow = myShadowClient.createShadowHandlerWithName(

  SHADOW_HANDLER, True)

 

# Represents the GPIO21 pin on the Raspberry Pi.

channel = 21

 

# Use the GPIO BCM pin numbering scheme.

GPIO.setmode(GPIO.BCM)

 

# Receive input signals through the pin.

GPIO.setup(channel, GPIO.IN)

 

while True:

 

  if GPIO.input(channel):

     myDeviceShadow.shadowUpdate(

       '{"state":{"reported":{"moisture":"low"}}}',

      myShadowUpdateCallback, 5)

  else:

     myDeviceShadow.shadowUpdate(

       '{"state":{"reported":{"moisture":"okay"}}}',

      myShadowUpdateCallback, 5)

 

  # Wait for this test value to be added.

  time.sleep(60)

 

4.実際にやってみて

 設定のためのステップが多いので、結構面倒でした。なので、「AWS Notification Message」のメールが送られてきたときには、ほっとしましました。

  次は、Raspberry Pi側にAWS Greengrassを入れて中継するようにしたいと思います。