AWS Loft TokyoのIoT@Loftハンズオンに参加しました


はじめに

昨日、AWS Loft Tokyo の IoT@Loft ハンズオン #2に参加させて頂きました。STマイクロエレクトロニクス株式会社殿、AWS殿ありがとうございました。アンケートに答えて、STM32L4の開発ボード STM32L4 Discovery kit IoT node までお土産に頂いて帰りました。

この開発ボードは、4種の無線モジュールと8種のセンサが搭載されているし、ST-LINKも組み込まれていてデバッグモニター(リモートデバッガ)を使用して、単体でワンステップ実行もできるようになっています。普段使っているM5Stackで残念なのがこの機能が使えないところです。

Greengrassとの連携

ハンズオンでモノ自体は登録されているので、近接センサーを使用して、人が近づいたらGreengrassを載せたスマートスピーカー(COETくん)から音を出してみましょう。パトランプなどに比べると、スマートスピーカーは言葉で様々な情報を伝えることができます。

1.センサー情報のトピック発行

センサー情報を拾ってトピックを発行するのは、ネット上に様々な情報がありますので、そちらを参照してください。

2.IoT ルール

センサーから常時発行されるトピックから、スマートスピーカーで音を出すために条件を絞ってトリガーを実行するために、今回はルールを使用します。

  • ルールの作成

  AWS IoT の管理画面で、ACTからルールを登録します。

  • ルールクエリステートメントに条件を指定します。

センサーのトピックは、トピック名が 'freertos/demos/sensor' で、次のような形式になっているので、

{
  "temperature": 29,
  "humidity": 35,
  "pressure": 1001,
  "proximity": 2312
}

ルールクエリステートメントは、

select proximity from 'freertos/demos/sensor' where proximity < 1000

アクションに、「AWS IoT のトピックにメッセージを再パブリッシュする」を指定し、スマートスピーカー(COETくん)に連携するためのトピック('hello/world/wav/trigger')のように指定します。ロールにはトピックをパブリッシュするため"iot:Publish"のポリシーが必要です。

3.Greengrass環境

音を出すためにOSのリソースにアクセスするのですが、前回までに作成したGreengrass環境はコンテナーなしで作成したので、AWS IoT グループからリソース登録ができません。そこでGreengrassをルートとして実行するようにします。

/boot/config/config.json の "runtime" に、"allowFunctionsToRunAsRoot" : "yes" を追加します

/boot/config/config.json
...

  "runtime" : {
    "cgroup" : {
      "useSystemd" : "yes"
    },
    "allowFunctionsToRunAsRoot" : "yes"
  },

...

追加したら、greengrassを再起動します

cd /greengrass/ggc/core
sudo ./greengrassd restart

未確認ですが、コンテナーを使っている場合は、リソースに /dev/snd/controlC0 と /dev/snd/pcmC0D0p を追加してあげればいいようです。

4.Lambda関数

スマートスピーカ(COETくん)から音を出す関数を作成します。

音を出すために必要な箇所は、次のようになります。サウンドデバイス、WAVファイルはご自分の環境に合わせてご確認ください。

import os
os.system('aplay -D plughw:0,0 /opt/wav/startup.wav')

サンプルコードはこうなります。テスト用にデモのカウンターのコードも残しています。

#
# Copyright 2020 fukuebiz.
#

# greengrassHelloWorldWav.py
#
# This Lambda function requires the AWS Greengrass SDK to run on Greengrass devices. This can be found on the AWS IoT Console.

import greengrasssdk
import platform
import time
import json
import os

# Creating a greengrass core sdk client
client = greengrasssdk.client('iot-data')

# Retrieving platform information to send from Greengrass Core
my_platform = platform.platform()

# Counter to keep track of invocations of the function_handler
my_counter = 0


def function_handler(event, context):
    global my_counter
    my_counter = my_counter + 1
    if not my_platform:
        client.publish(
            topic='hello/world/counter',
            payload=json.dumps({'message': 'Hello world! Sent from Greengrass Core.  Invocation Count: {}'.format(my_counter)})
        )

        os.system('aplay -D plughw:0,0 /opt/wav/startup.wav')
    else:
        client.publish(
            topic='hello/world/counter',
            payload=json.dumps({'message': 'Hello world! Sent from Greengrass Core running on platform: {}.  Invocation Count: {}'
                                .format(my_platform, my_counter)})
        )

        os.system('aplay -D plughw:0,0 /opt/wav/startup.wav')
    time.sleep(20)
    return

Greengrass グループのサブスクリプションに、ソース:IoT Cloud、ターゲット:Greengrass_HelloWorld_Wav Lambda関数、トピックに'hello/world/wav/trigger' を指定します。

完成

センサーに近づくと、スマートスピーカー(COETくん)から音が出ました。
昨日は、STマイクロエレクトロニクス株式会社殿、AWS殿ありがとうございました。

メモ

第1回 Amazon FreeRTOSインストール
第2回 Lチカ
第3回 TFT
第4回 SDカード
第5回 AWS Shadows
第6回 OTA
第7回 Greengrass