LoginSignup
17
16

More than 5 years have passed since last update.

ESP-WROOM-02をAWS IoTにつないでみた

Last updated at Posted at 2017-02-12

はじめに

EC2インスタンスの電源ボタンを、ESP-WROOM-02開発ボードで作ってみた。

EC2インスタンスの電源状態のモニタリングをAPI Gateway+Lambdaでやろうとしたが、ポーリングでリクエストが多くなるとお財布事情が、、、と思い、AWS IoTからプッシュ通知ができないか調べてみたところ、ドンピシャなライブラリaws-mqtt-websocketsがあったのでこれを使ってみる。

事前準備

IAMユーザの作成

サンプルスケッチを見ればわかるが、AWSの認証情報(アクセスキー,シークレットキー)を書かないといけないので、専用IAMユーザを作って、認証情報を保存しておく。

アタッチするポリシーは、インラインポリシーで以下のものを(ここまでいらないかもしれない。コメント求む。)。

policy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect",
                "iot:Publish",
                "iot:Subscribe",
                "iot:Receive",
                "iot:GetThingShadow",
                "iot:UpdateThingShadow"
            ],
            "Resource": "*"
        }
    ]
}

Thingの作成

AWS IoTでThingをaws iot create-thing --thing-name ${thing_name}で作成する。以下はec2power-switchという名前のthingを作る例。


$ aws iot create-thing --thing-name ec2power-switch
{
    "thingArn": "arn:aws:iot:${region}:${account}:thing/ec2power-switch",
    "thingName": "ec2power-switch"
}

# \${region}や${account}は、それぞれ実行環境で変わる。

※登録済みのthingのリストは、aws iot list-thingsで確認できる。

$ aws iot list-things
{
    "things": [
        {
            "attributes": {},
            "version": 1,
            "thingName": "ec2power-switch"
        }
    ]
}

エンドポイントアドレスの確認

AWS IoTのエンドポイントアドレスを確認する。

$ aws iot describe-endpoint
{
    "endpointAddress": "xxxxxxxxxxxxxx.iot.${region}.amazonaws.com"
}

ここまでで、

  • AWSの認証情報
    • アクセスキー
    • シークレットキー
  • Thingの名前
  • エンドポイントアドレス

がそろっているはず。

また

  • AWSのリージョン名(ex. ap-northeast-1)
  • 実行環境の下記無線LAN情報
    • ssid
    • password

も確認しておく。

Arduino用ライブラリの取得

既にArudino IDEの構築や、ESP-WROOM-02用の設定は済ませているものとして、AWS IoTにESP-WROOM-02をつなぐのに必要な部分だけ書く。

以下の4つの追加ライブラリを入れる。

  1. aws-mqtt-websockets
  2. aws-sdk-arduino
  3. WebSockets for Arduino
  4. Paho MQTT for Arduino

aws-mqtt-websockets

aws-mqtt-websockets
githubから取得して、librariesディレクトリ12に展開して保存する。

aws-sdk-arduino

aws-sdk-arduino
githubから取得して、librariesディレクトリ12に展開して保存した後、src/common以下をこのライブラリのルートにコピー、さらにsrc/esp8266以下を同じ場所に上書きコピーする。

WebSockets for Arduino

Arduino IDEのメニューから、[スケッチ]→[ライブラリのインクルード]→[ライブラリの管理...]と辿って検索フィルタにWebSockets for Arduino (Server + Client)と入れて出てくるライブラリの最新バージョンをインストールする。

Paho MQTT for Arduino

Paho MQTT for Arduino
公式サイトからArduino Client Library 1.0.0(2017/02/12現在)を取得して、librariesディレクトリ12に展開して保存する。

サンプルスケッチの実行

Arduino IDEのメニューから[ファイル]→[スケッチ例]→[aws-mqtt-websocket]→[aws-mqtt-websocket-example]を選択してサンプルスケッチを開き、30行目付近にある下記設定値を変更する。

aws-mqtt-websocket-example
 :
//AWS IOT config, change these:
char wifi_ssid[]       = "your-ssid";
char wifi_password[]   = "your-password";
char aws_endpoint[]    = "your-endpoint.iot.eu-west-1.amazonaws.com";
char aws_key[]         = "your-iam-key";
char aws_secret[]      = "your-iam-secret-key";
char aws_region[]      = "eu-west-1";
const char* aws_topic  = "$aws/things/your-device/shadow/update";
 :

Thingの名前は、aws_topicyour-deviceの部分に書く。

このスケッチをコンパイルして書き込めば、AWS IoTに接続して待ち受けして、シリアルコンソールに以下のようなログが出る。

connected with {SSID}, channel 11
dhcp client start...
..........ip:192.168.0.16,mask:255.255.255.0,gw:192.168.0.1
7682 - conn: 1 - (34528)
please start sntp first !
websocket layer connected
MQTT connecting
MQTT connected
MQTT subscribed

ここまでくると接続成功。

またこのサンプルスケッチでは、接続成功時に自分のThingにメッセージを送っていて、その結果も併せて出力されている(下記2行)。

Message 1 arrived: qos 0, retained 0, dup 0, packetid 0
Payload {"state":{"reported":{"on": false}, "desired":{"on": false}}}

余談

自分の環境では、setup()内の

  WiFiMulti.addAP(wifi_ssid, wifi_password);
  Serial.println ("connecting to wifi");
  while(WiFiMulti.run() != WL_CONNECTED) {
    delay(100);
    Serial.print (".");
  }

の部分(175行目付近)を、

  WiFi.begin(wifi_ssid, wifi_password);
  Serial.println ("connecting to wifi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print(".");
  }

のように書き換えないとWiFiにつながらなかった。
これはAWS IoTとかmqttとかwebsocketは関係なく、自分の無線環境の問題か。

おまけ

冒頭の「EC2インスタンスの電源ボタンを~」というのをやるには、CloudWatchのルールでEC2インスタンスの状態を監視して、変化時に起動されるLambda関数でAWS IoTに通知するようにした。

CloudWatchのルールは、以下のような設定。
ec2monitoring_cloudwatch.png

状態に変化があった時に実行されるLambda関数の、AWS IoTへの通知部分は以下のようなコード。

index.js
var IoTData = new AWS.IotData({
  endpoint: 'xxxxxxxxxxxxxx.iot.${region}.amazonaws.com',
  region: '${region}'
});

var params = {
  topic: '$aws/things/${thingName}/shadow/update',
  payload: 
};

IoTData.publish(params).promise()
.then((data) => {
  :
});

あと電源のOn/Offは結局API Gateway+Lambdaでやった。



  1. Windowsの場合: %USERPROFILE%\Documents\Arduino\libraries 

  2. macOSの場合:~/Documents/Arduino/libraries 

17
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
16