Pro Yearly is on sale from $80 to $50! »

JAWS DAYS 2020 | AWS IoT CoreとM5StickCで作る自動出退勤記録システム

9ec05c5a1b9b0ce9cd53ec3a63838b9a?s=47 Y_uuu
March 14, 2020

JAWS DAYS 2020 | AWS IoT CoreとM5StickCで作る自動出退勤記録システム

AWS IoT Core, LambdaをはじめとするAWSの各種サービスとM5StickCを利用して、
出退勤記録を自動化するIoTシステムを開発した事例を紹介します。

M5StickCはESP32-picoを搭載したプログラマブルな小型デバイスで、
IoTシステムのプロトタイピングと相性の良いデバイスです。

IoTシステムの開発は「デバイス」と「クラウド」それぞれの開発スキルが必要となります。
本発表ではその両者を一通りご紹介いたします。

- 想定する聴講者
- IoTで日常生活を記録・改善したいという想いを持った方
- AWSを使ったIoTシステムの開発に興味がある方
- デバイスに興味がある方

- お話する内容
- M5StickCを開発するための環境を構築する
- M5StickCをWiFi接続する
- M5StickCからIoT Coreへデータを送信する
- 受信したデータを処理するサーバレスシステムを構築する

9ec05c5a1b9b0ce9cd53ec3a63838b9a?s=128

Y_uuu

March 14, 2020
Tweet

Transcript

  1. AWS IoT CoreとM5StickCで作る ⾃動出退勤記録システム 2020/03/14 JAWS DAYS 2020 株式会社Fusic 岡嵜雄平

    
  2. ⾃⼰紹介 岡嵜 雄平(@Y_uuu) IoTエンジニア ⾃社サービスmockmockの開発・運⽤を担当  ⾃⼰紹介

  3. mockmock 最近のお仕事 • IoTサーバへデバイスの代わりにデータ送信 • さまざまな⽅法でテストデータを⾃動⽣成 • 各種クラウドサービス(AWS, GCP, Azure)やSORACOMと連携

     IoTのテストを⽀援する https://bit.ly/37tA9bf で検索
  4. 私のミッション 「IoT開発を啓蒙する」 

  5. IoT開発における課題  • システムの全体像を描きづらい • 技術要素が多彩(デバイス, 通信, クラウド, Web, etc)

    • ⼀品モノが多く、開発⼿法を画⼀化しにくい • プロジェクトにおけるステークホルダーが多い
  6. 解決策︓⼩さく始めて⼤きく育てる  • まずは電⼦⼯作+クラウドで通知からはじめる • PoC(実証実験)で効果を測り、PDCAを回す • ⼩さくてもたたき台がある⽅が認識を合わせやすい

  7. IoTシステムを ⼩さく(社内で使う想定で) 作った事例を紹介 

  8. システム概要 ⾃動出退勤記録システムとは 

  9. 課題: Slackでの出退勤宣⾔がめんどう  • フルフレックス制→みんな出退勤の時間がバラバラ • とあるチームはSlackに⼿動で出退勤を宣⾔する運⽤ 「しゅっしゃー」と ⼊⼒する⼿間を効率化したい

  10. 解決策: iBeaconで出退勤を検知  • iBeacon: スマホをBeacon化する技術 • Bluetooth Low Energyでの通信なのでバッテリー

    消費が⾮常に⼩さい • iBeaconを検知したときに出勤を通知 • iBeaconを検知しなくなったときに退勤を通知 ※iBeaconの検知には⼿元にあったM5StickCを使⽤
  11. 簡易ダッシュボード(Beacons)  • 検出中のBeaconの⼀覧を表⽰ • Beaconに⾃分を紐付けられる→Slack通知時の名前表⽰に使⽤ Beaconに⾃分を紐付け Beaconの ログ⼀覧を表⽰

  12. 簡易ダッシュボード(Logs)  • 特定のBeaconのログを表⽰ 出勤時刻 退勤時刻

  13. 紐付けたBeaconを検出するとSlackへ通知 

  14. つまりこんな感じ – 出勤時  1. iBeaconを発信する スマホを持った⼈が出勤 2. iBeaconを検出 3.

    iBeaconの情報を クラウドへ送信 4. iBeaconの情報から 出社した⼈物を特定 5. Slackへ通知
  15. つまりこんな感じ – 退勤時  1. iBeaconを発信する スマホを持った⼈が退勤 2. 検出されなくなった iBeaconから⼈物を特定

    3. Slackへ通知
  16. システム構成  • AWS Cloud内はAmplify + IoT Core + Lambdaで構築

  17. システム構成  STEP1 STEP2 STEP3 • 構築⼿順はSTEP1〜3に分割して解説します

  18. アジェンダ 事前準備︓システム間のI/Fを定義 STEP1: フロントエンド・バックエンドの実装 STEP2: IoTにおける送受信部の実装 STEP3: デバイス側の開発 まとめ 

  19. 事前準備︓システム間のI/Fを定義 M5StickC, AWS, Slack 

  20. 重要︓IoT開発ではシステム間のI/Fを先に決める  • I/Fが決まらないと各システムの開発を並⾛できない • I/Fがぶれていると後々⼤きな⼿戻りになる I/Fを先に決める

  21. デバイス-クラウド間のI/F  • IoT開発ではI/Fを最初に決めておく(ぶれていると後々⼤きな⼿戻りに) • 今回はAWS IoTを使う都合上、MQTTSで以下のJSONをPublishする { “uuid”: ”XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX“,

    “address”: ”XX:XX:XX:XX:XX:XX” }
  22. クラウド-Slack間のI/F  • Slackへの通知はIncoming Webhookを使⽤ • 出勤時、退勤時に以下のフォーマットでメッセージを通知する

  23. STEP1: フロントエンド・バックエンドの実装 AWS Amplify, DynamoDB, AppSync, S3, Cognito 

  24. AWS Amplifyとは︖  • サーバーレスなWebアプリケーションを簡単に構築 • 今回使ったサービス • Congnito: ユーザ登録・認証

    • AppSync・DynamoDB: GraphQLサーバ・クライアント • S3: フロントエンドアプリのホスティング
  25. React + Material-UI  • SPAの簡易ダッシュボードを構築 • React: フロントエンドフレームワーク •

    Material-UI: マテリアルデザインを採⽤したComponentセット Material-UIでデザインした簡易ダッシュボード
  26. 参考: Amplify + Reactのチュートリアル  • このチュートリアルがとても参考になりました https://github.com/dabit3/react-notes

  27. DynamoDBのテーブル構成  • ダッシュボード表⽰、出退勤通知の処理内容を想定し 以下3テーブルで構成

  28. GraphQLのスキーマ定義(Beacon)  • Beaconテーブルは「検出中のBeaconの⼀覧」を格納する • 検出されなくなったらTTLを使ってテーブルから⾃動削除する type Beacon @model {

    id: ID! address: String! detected_at: String! deleted_at: Int! } • idにはiBeaconのUUIDを使⽤ • detected_atにiBeaconを検知 した時間を格納 • deleted_atはdeletec_atの1分 後を設定(DynamoDBのTTL⽤)
  29. GraphQLのスキーマ定義(AttendanceLog)  • AttendanceLogテーブルは「出退勤時刻」を格納する • パーティションキーはUUID, ソートキーを出勤時刻とする type AttendanceLog @model

    @key(fields: ["id", "started_at"]) { id: ID! started_at: String! ended_at: String } • idにはiBeaconのUUIDを使⽤ • started_atに出勤時刻を格納 • started_atをソートキーとする • ended_atに退勤時刻を格納
  30. GraphQLのスキーマ定義(IdUser)  • IdUserテーブルは「UUIDとユーザ名の組み合わせ」を格納する • Web画⾯の表⽰やSlackへの通知時にUUIDをユーザ名に変換する ために使⽤する type IdUser @model

    { id: ID! user: String } • idにはiBeaconのUUIDを使⽤ • userにはユーザ名を格納
  31. STEP2: IoTにおける送受信部の実装 AWS IoT Core, Lambda, DynamoDB 

  32. 受信(IoT Core->DynamoDB)  • デバイスからPublishされたJSONをDynamoDBの Beaconテーブルに書き込む • 同じUUIDのレコードはdeleted_atを更新して上書き

  33. 送信(DynamoDB->Lambda)  • BeaconテーブルのDynamoDB Streamsをトリガーに Lambdaを発⽕ • イベント名に応じて処理 • INSERT:

    出勤処理 • REMOVE: 退勤処理
  34. 送信(DynamoDB->Lambda) 出勤処理 

  35. 送信(DynamoDB->Lambda) 退勤処理 

  36. 補⾜: DynamoDBのTTL発動タイミング  • 仕様: 期限切れから48時間以内に削除 • https://docs.aws.amazon.com/ja_jp/amazondynamodb/lat est/developerguide/howitworks-ttl.html •

    48時間だと今回のシステムには遅すぎる • 実際に動作検証→結果: 15分以内には削除される • 今回のシステムには15分が丁度良い • 今後、TTL発動タイミングを調整したくなった場合 • Dynamo DBのTTLをOFF • Cloud Watch EventをトリガとしLambdaを定周期実⾏ • LambdaにてTTLを過ぎたItemを削除する
  37. STEP3: デバイス側の開発 M5StickC, IoT Core 

  38. 今回使ったデバイス: M5StickC • ESP32-picoを搭載したスティック状の マイコンモジュール • 48 x 24 x

    14mm • 0.96インチのカラー液晶パネル • 電源スイッチ、A・Bボタン • マイク • IRトランスミッタ • 外部8ピン端⼦ • USB-Cポート • GROVEポート • 6軸IMU • 無線LAN • Bluetooth • ⼩型ながらいろいろなことができるの でプロトタイピングに最適 
  39. Arduino IDEでプログラミング • Arduino⾔語(≒C++) • IDEでコンパイル→ 書き込み • setup()で諸々初期化 •

    loop()が定周期処理 
  40. iBeacon検出処理  • ESP32のBLEライブラリを使って、スキャン • 検出時のコールバック関数で検証 ここに検出時の処理を書く

  41. iBeaconのアドバタイズパケットを判別  • 受信したデータを以下の通りチェック • 先頭2byte(Apple Company ID)が「0x4C00」であること • 次の2byte(iBeacon識別⼦)が「0x1502」であること

    • 受信データはBLEAdvertisedDeviceの getManufacturerData()関数により取得可能 • 値が異なるものはiBeacon以外のBLE通信なので無視
  42. iBeacon情報を読み出す  • それぞれ以下の⽅法で読み出す • デバイスアドレス • BLEAdvertisedDeviceのgetAddress()関数で取得 • RSSI

    • BLEAdvertisedDeviceのgetRSSI()関数で取得 • UUID • 受信データの4〜19byteを抜き出し、16進数表記に変換
  43. MQTTS通信⽤のライブラリを準備  • ArduinoライブラリのPubSubClientをインストール

  44. MQTTSでクラウドに接続する  • WiFi→MQTTSの順で接続 • X.509によるTLS認証も可

  45. MQTTSでJSONをpublishする  • JSON⽂字列を⽣成し、指定したTOPICへpublish

  46. 問題: MQTTSとBLEを併⽤するとreboot • BLEとMQTTSを同時実⾏するとデバイスが再起動 • Heap領域が不⾜している模様 • やむを得ず、Mosquitto経由でIoT Coreへ Publishするよう構成を変更

    
  47. iBeaconのパケットを送信 • ⼿持ちのAndroid端末を使⽤ • Beacon SimulatorというAndroidアプリを使⽤ https://play.google.com/store/apps/details?id =net.alea.beaconsimulator&hl=ja  UUIDを⾃由に設定できる

  48. (⻑い道のりでしたが) 無事完成 

  49. まとめ  • IoTシステムは⼩さく始めて⼤きく育てる • システム間のI/Fを最初に決める

  50. まとめ  • 既存のサービス、プロダクトを組み合わせることで より簡単にIoTシステムを開発できる • Amplifyを使うことでサーバレスなWebアプリケーションを 簡単に構築できる • IoT

    Core, Lambdaと連携させることでIoTと連携できる • M5Stack, M5StickCはプロトタイピングにうってつけ
  51. Thank you! Fusicは技術が好きなエンジニアを 募集しています