Top View


Author matsuyama

IoT でオンライン会議スペースを監視し Slack に表示する

2022/04/27

設置した IoT デバイス

さっそくですが、個室に設置した IoT デバイスを紹介します。

IoT デバイス の中身

"いる"/"いない" の判断には超音波センサーを使いました。

デバイスの材料は以下です。

材料値段備考
Grove IoT スターターキット17,578 円Wio LTE超音波センサー を使用

こちらは、なんと ! Grove IoT スターターキット にあるものだけで作成できます!
「試しに買ったけど余っているんだよなー」という方は是非、作ってみてください〜。

設置したら以下のようになります。

設置した IoT デバイス

  • ケース: 3D プリンタで 花園 が作ってくれました
    • 洗練されたシックなデザイン
  • 設置: 壁がフェルトだったので、マジックテープで付けています
    • 壁を傷つけずに​設置可能
  • 給電: 個室にある USB を利用しています

設置に必要な部材は以下です。

部材値段備考
アクリルケース2,580 円市販のものだとこのくらいのお値段
USB ケーブル612 円2 本分のお値段
マジックテープ655 円10 cm くらいしか使っていない

なぜ超音波センサーにしたのか ?

人を感知するものとしては、人感センサー (赤外線) が有名かと思います。
が、動きがないと "いない" と判断されるという落とし穴があります
(トイレで、照明が消えて手を振ったことがある人もいるかと思います)。
人がいる間は反応し続ける、超音波センサーを選びました。

なぜ LTE にしたのか ?

そこに Grove IoT スターターキット があったから、、、

Wi-Fi で社内ネットワークに接続するというのは、一見簡単で、お手軽に思います。
が、そこは社内ネットワーク、重要な情報にアクセスできてしまうパスワードを、IoT デバイスが持つことに。。
実は、LTE の方が社内ネットワークに影響を与えず、セキュアで手軽に試せるのです!

ユーザーインターフェース

他の IT の会社でもそうでしょうが Fusic では Slack が日常的なコミュニケーションツールとして使われています。
Slack には スラッシュコマンド という、特定のアクションを簡単に呼べる仕組みがあります。
Slack を日常的に使っているのであれば、 Web ページを開くよりも身近なインターフェースであるため、今回はスラッシュコマンドを選びました。

今回作成したスラッシュコマンドを実行すると、以下のようなメッセージが返ってきます。

Slack のメッセージ

数字が部屋番号で、🟥 が空いていない、🟩 が空いている、ということを示します。
文字で書かれるより直観的に分かる!

システム構成

システム構成を以下に示します。

システム構成図

利用したサービスは以下です。

サービス名初期費用サービス使用量備考
SORACOM Air1,287 円330 円/月plan-D (データ通信のみ/D-300MB)
SORACOM Funnel0 円0 円/月月間 50,000 リクエストまで毎月無料
AWS IoT CoreAWS IoT Core の料金メッセージング、ルールエンジンを利用
Amazon DynamoDBAmazon DynamoDB 料金プロビジョニング済みキャパシティーモードを利用
Amazon API GatewayAmazon API Gateway の料金REST API を作成
AWS LambdaAWS Lambda 料金今回は Ruby で実装

収集フローの実装

以下の作業を実施することで、個室の利用状況を IoT デバイスで取得し DynamoDB に保存できます。

Wio LTE の実装

超音波センサーを用いて、"いる"/"いない" を判定し、状態を SORACOM Funnel に送信する、プログラムを Wio LTE に実装します。

Wio LTE、超音波センサーのセットアップについては、 SORACOM IoT レシピ:IoTでジェスチャーシステム が詳しいので、こちらをご参照ください。

今回のソースは こちら

ソースだけだと分からないと思いますので、フローチャートを書きました。

Wio LTE のフローチャート

↓動かすとこんな感じ

Wio LTE 動画

LTE の色の意味は以下のようになってます。

  • 緑 = 'leave' (近くに何もない)
  • 赤 = 'enter' (近くに何かある)
  • 青 = 'leave' (動きがない)

SORACOM Funnel で AWS IoT Core に送る設定

Wio LTE からのデータを AWS IoT Core まで送るためには、SORACOM FunnelAWS IAMAWS IoT Core の設定が必要です。

AWS IoT アダプターを使用する に詳しく書かれています。
AWS IoT アダプターを使用するステップ 4 までを実施すれば、ここで実現したい、 AWS IoT Core への送信が実現できます。

DynamoDB テーブルの作成

Wio LTE からのデータを貯めるのに、Amazon DynamoDB を利用します。

今回は、

  • パーティションキー: imsi (文字列)
  • ソートキー: timestamp (数値)

でテーブルを作成します。

DynamoDB テーブルの作成

DynamoDB へデータを送る AWS IoT ルールの作成

AWS IoT Core から、作成した Amazon DynamoDB のテーブルへ送るための設定を実施します。

AWS IoT アダプターを使用する は、Amazon SNS でメール通知する手順ですので、これを Amazon DynamoDB へデータを送るルールにしたいです。

AWS IoT アダプターを使用するステップ 6 において、
アクションの追加で、DynamoDB テーブル (DynamoDBv2) の複数列にメッセージを分割する を選択し、
アクションの設定において、作成したテーブル名を指定、ロールの作成 を実施して、アクションを追加します。

DynamoDBv2 テーブル名の選択

これで、データが保存されているはずです。
IoT デバイスを起動し、DynamoDB にデータが保存されているか、確認してみてください。

表示フローの実装

以下の作業を実施することで、Slack のスラッシュコマンドから DynamoDB の保存された個室の利用状況を表示できます。

Lambda の実装

AWS Lambda にて Amazon DynamoDB から個室の状態を取得し、Slack へのメッセージを返すプログラムを作成します。

Lambda で実行する Ruby のソースコードを以下に示します。
処理の大まかな流れは、

  • Slack slash コマンドのパラメータから token を取得し、検証する。
  • DynamoDB から IMSI ごとの最新データを取得する。
  • 部屋が空いてたら 🟩 空いてなかったら 🟥 のメッサージを返す。

です。

require 'uri'
require 'aws-sdk'

TABLE_NAME = 'usage_of_compartment'.freeze
IMSI_LIST = [ 'xxxxxxxxxxxxxxx', 'yyyyyyyyyyyyyyy', 'zzzzzzzzzzzzzzz' ].freeze
STATUS_EMOJI = { 'leave' => '🟩', 'enter' => '🟥' }.freeze

def lambda_handler(event:, context:)
    params = Hash[URI::decode_www_form(event['body-json'])]
    return { text: 'Unauthorized' } unless params['token'] == ENV['SLACK_APP_TOKEN']
    
    message = ''
    IMSI_LIST.each_with_index do |imsi, index|
        response = latest_room_status(imsi)
        message += "#{index + 1} #{STATUS_EMOJI[response]} "
    end
    
    { text: message }
end

def latest_room_status(imsi)
    query = {
        table_name: TABLE_NAME,
        limit: 1,
        scan_index_forward: false,
        key_condition_expression: 'imsi = :imsi',
        expression_attribute_values: { ':imsi' => imsi }
    }
    
    client = Aws::DynamoDB::Client.new
    response = client.query(query)
    return 'leave' if response[:count] == 0
    
    response.dig(:items, 0, 'payloads', 'status')
end

Lambda から DynamoDB への接続設定

このままでは、AWS Lambda から Amazon DynamoDB へのアクセス権限がないため、権限を付与します。

  1. アクセス権限実行ロールロール名 のところにあるリンクをクリックし、Lambda のアクセス権限ロールを開きます。

ラムダアクセス権限

  1. AmazonDynamoDBReadOnlyAccess を選択し、ポリシーをアタッチ をクリックします。

DynamoDBReadOnly

Slack スラッシュコマンド向け API Gateway の作成

Slack スラッシュコマンドからは、HTTP の POST リクエストがくるため、リクエストを受ける REST API を Amazon API Gateway で作成します。

HTTP POST リクエストが来たら、作成した Lamdba を呼び出すよう、設定します。

  1. REST API を作成し、POST のメソッドに作成した Lambda を指定します。

API Gateway の POST メソッド

  1. POST統合リクエスト から Slack スラッシュコマンドを受けるための マッピングテンプレートを設定します。
    • テンプレートが定義されてない場合 (推奨) を選択し
    • マッピングテンプレートの追加 から application/x-www-form-urlencoded を選択
    • テンプレートの生成 から メソッドリクエストのパススルー を選択し、保存

API Gateway の Content-Type

  1. アクション ボタンから API のデプロイ を実行し、URL の呼び出し にある URL を確認します。

API Gateway の URL

Slack アプリおよびスラッシュコマンドの作成

個室の利用状況を表示する、独自の Slack アプリおよび、スラッシュコマンドを作成します。

slack apiCreate New App よりアプリを作成します。
作成したアプリの Basic Information で、 Add features and functionality の中から、 Slash Commands をクリックし、スラッシュコマンドを作成します。

Request URL には API Gateway の URL を入力してください。 Create New Command

Slack からこのアプリ使うために Install your app より、アプリをインストールしてください。
これで、ようやく、スラッシュコマンドは実行できます。
が、今の時点で実行しても、Unauthorized が返ってくるだけです。。。

Slack アプリの Verification Token を Lambda に設定

Lambda の実装SLACK_APP_TOKEN の環境変数設定が必要なことを覚えていますでしょうか ?
そうです、外部から実行されないために Lambda において Token の検証を行なっているのです。

Token は、Basic InformationApp Credential にある Verification Token です。

App Credentials

これを Lambda の環境変数 SLACK_APP_TOKEN に設定します。

Environment variable

これで、Slack から作成したスラッシュコマンドを実行すると、 ユーザーインターフェース で示すような表示がえられるはずです !

まとめ

matsuyama

matsuyama

最近 Unity 触ってます