AWS IoT Coreと連携してRaspberry PiでLチカしてみる

AWS IoT CoreはIoTデバイスのためのクラウドインフラをマネージしてくれるサービスです。


先日購入したラズパイをAWS IoT Coreに接続して、AWSからのアクションをトリガーにLチカを試してみようというのが今回の趣旨です。

IoT CoreにRaspberry Piを登録

まずはIoT Core側の設定から


チュートリアルを参考にRaspberry PiをIoT Coreに登録します。

ポリシーの作成

まずは、ラズパイに許可するアクションポリシーを作成します。

モノの登録

IoT Coreで管理するモノ(Thing)として、ラズパイを登録します。
単一のモノとして作成します。
名前を付けて次へ
IoT Coreがモノを認証するための証明書を作成します。
作成した証明書をダウンロードして有効化します。
ルートCA証明書はダウンロードリンク先から共通の証明書がダウンロードできます。
先ほど作成したポリシーをアタッチ。
ラズパイの登録が完了しました!

Raspberry PiからIoT Coreに接続

IoT Coreにモノ(ラズパイ)が登録できたので、次はラズパイからIoT Coreへ接続してみます。


Node.jsでつなぐチュートリアルを参考にやってみます。
# Node.jsのインストール
$ curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
$ sudo apt-get install -y nodejs

# サンプルソースのダウンロード・SDKのインストール
$ cd ~
$ git clone https://github.com/aws/aws-iot-device-sdk-js.git
$ cd aws-iot-device-sdk-js/
$ npm install
モノの登録時にダウンロードした秘密鍵と証明書、ルートCA証明書を配置します。
分かりやすい名前にリネームしています。
# 証明書の配置
$ mkdir certs
$ ls -l certs/
合計 12
-rw-r--r-- 1 pi pi 1188  4月 12 08:06 Amazon-root-CA-1
-rw-r--r-- 1 pi pi 1220  4月 12 08:07 device.pem.crt
-rw-r--r-- 1 pi pi 1679  4月 12 08:08 private.pem.key
これで準備完了です。
ターミナルを2つ立ち上げて、サンプルアプリを起動します。

引数には先ほど配置した証明書と秘密鍵のパス、エンドポイントを設定します。
エンドポイントはモノの操作メニューから確認できます。
# 端末1
$ cd ~/aws-iot-device-sdk-js/examples/
$ node device-example -k "../certs/private.pem.key" \
                      -c "../certs/device.pem.crt" \
                      -i "raspberry-pi-1" \
                      -a "../certs/Amazon-root-CA-1" \
                      -H "XXXXXXXXXXXXXXX.iot.ap-northeast-1.amazonaws.com" \
                      -p 8883 \
                      -T "RaspberryPi" --test-mode 1
connect
message topic_1 {"mode2Process":1}
message topic_1 {"mode2Process":2}
message topic_1 {"mode2Process":3}
# 端末2
$ cd ~/aws-iot-device-sdk-js/examples/
$ node device-example -k "../certs/private.pem.key" \
                      -c "../certs/device.pem.crt" \
                      -i "raspberry-pi-2" \
                      -a "../certs/Amazon-root-CA-1" \
                      -H "XXXXXXXXXXXXXXX.iot.ap-northeast-1.amazonaws.com" \
                      -p 8883 \
                      -T "RaspberryPi" --test-mode 2
connect
message topic_2 {"mode1Process":1}
message topic_2 {"mode1Process":2}
message topic_2 {"mode1Process":3}
2つの端末間でメッセージが送受信されているようにみえます。

端末1では「topic_2」というMQTTトピックを作成し、そこにメッセージをpublishし、「topic_1」をSubscribe、
端末2では「topic_1」というMQTTトピックを作成し、そこにメッセージをpublishし、「topic_2」をSubscribeしているようです。
マネジメントコンソールのテストからMQTTクライアントを起動して、pub/subすることもできます。

メッセージをPub/Subして、LEDを点滅させる

GPIO2番にLEDを配線しました。
SDKをインストールして秘密鍵と証明書をコピーします。
$ cd ~
$ mkdir lchika
$ cd lchika
$ npm install aws-iot-device-sdk
$ cp -r ../aws-iot-device-sdk-js/certs .
$ vi index.js
var awsIot = require('aws-iot-device-sdk');

var device = awsIot.device({
   keyPath: 'certs/private.pem.key',
  certPath: 'certs/device.pem.crt',
    caPath: 'certs/Amazon-root-CA-1',
  clientId: 'RaspberryPi',
      host: 'XXXXXXXXXXXXXXX.iot.ap-northeast-1.amazonaws.com'
});

var fs = require('fs');

var gpio_dir = '/sys/class/gpio';
var gpio2 = gpio_dir + '/gpio2';

// デバイスの接続
device
  .on('connect', function() {
    // GPIO2番の出力設定
    fs.writeFileSync(gpio_dir + '/export', 2);
    fs.writeFileSync(gpio2 + '/direction', 'out');

    console.log('connect');
    device.subscribe('topic_led');
  });

// メッセージの受信
device
  .on('message', function(topic, payload) {
    console.log('message', topic, payload.toString());
    message = JSON.parse(payload);

    if(message.led == 'on'){
      fs.writeFileSync(gpio2 + '/value', 1); // 点灯
    }else{
      fs.writeFileSync(gpio2 + '/value', 0); // 消灯
    }
  });

// プロセスの終了
process
  .on('SIGINT', function() {
    // GPIO2番の解放
    console.log('close');
    fs.writeFileSync(gpio_dir + '/unexport', 2);
    process.exit();
  });
「topic_led」というトピックをsubし続け、メッセージに応じてLEDを点灯・消灯します。
$ sudo node index.js
connect
message topic_led {
  "led": "on"
}
message topic_led {
  "led": "off"
}
^Cclose
MQTTクライアントから送信したメッセージで手元のラズパイのLEDを点灯消灯することができました。


簡単にIoTデバイスをAWSクラウドに接続できて、IoTデバイス間の通信もできるのはすごいですね。
他にも色々と機能があるようなので試してみたいと思います。