リアルタイムにセンサーデータを表示しデバイス操作可能な IoT アプリを作る

2021-03-02
日常で楽しむクラウドテクノロジー

Author : 飯塚 将太

こんにちは、IoT ソリューションアーキテクトの飯塚です。
最近ではスマートホームデバイスと呼ばれるアプリやスマートスピーカーから操作できる製品が数多く発売され、一般化してきました。そういった製品を買うのも良いのですが、カスタマイズができず自分のやりたかったことができない、ケースもあるかと思います。そんな時に、インターネットにつながるデバイスと少しの技術力があれば、デバイスの現在の状態を取得したり、デバイスを操作できるアプリを簡単に開発できます。

そこで本記事では、スマートプロダクトとそれを制御する簡単な IoT アプリをプロトタイピングしてみようと思います。このプロトタイピングに AWS IoT を始めとする AWS サービスを用いることで、IoT アプリのコア機能を短時間で開発できることをお伝えできればと思います。

ご注意

本記事で紹介する AWS サービスを起動する際には、料金がかかります。builders.flash メールメンバー特典の、クラウドレシピ向けクレジットコードプレゼントの入手をお勧めします。

*ハンズオン記事およびソースコードにおける免責事項 »

このクラウドレシピ (ハンズオン記事) を無料でお試しいただけます »

毎月提供されるクラウドレシピのアップデート情報とともに、クレジットコードを受け取ることができます。 


1. 構成と使用するコンポーネント

今回作成する全体構成を見てみましょう。

上記の構成で使用するコンポーネントとその役割を以下にまとめました。また本記事では東京リージョンを使用する前提で記載しています。他のリージョンでも構築できますが、その場合には ap-northeast-1 と書かれた箇所を適宜置き換えてください。

M5StickC 操作対象のデバイス
AWS IoT Core デバイスを認証し、アプリと通信するために用います
AWS Cloud9 開発環境として用います
Amazon Cognito アプリを認証するために用います
AWS Amplify Framework 簡単に AWS IoT Core と通信するためにアプリに用います
Console アプリをホスティングするために利用します
CLI アプリのプロジェクトや Amazon Cognito、ホスティング環境を作成するために用います
Vue.js アプリ画面を作成するフレームワークとして

本記事では画像にあるような M5StickC をデバイスとして用います。M5StickC は、プロトタイピング用の小型マイコンボードです。Wi-Fi や Bluetooth モジュールを内蔵しているため、追加の部品を必要とせずインターネット接続や無線通信が可能です。さまた温度センサーや加速度・ジャイロセンサーも内蔵しており、センサーを接続しなくてもこれらの値を読み取ることができ、前面のディスプレイに表示することもできます。また Grove コネクタと呼ばれる共通の端子が設けられているので、Grove コネクタに対応した数多くの種類のセンサーを接続して読み取ることもできます。


2. 必要な作業

必要な作業は以下となります。大きく分けて、デバイス側の実装とアプリ側の実装があります。

デバイス側の実装 Arduino 開発環境のセットアップ
クライアント証明書の発行とポリシーの作成
デバイスの動作確認
アプリ側の実装 アプリ開発環境の構築
アプリへの権限の付与
アプリの実装
アプリのホスティング

3. デバイス側の実装

それではまずデバイス側の実装から始めていきましょう。まずは こちらのデバイス用コードをダウンロード してください。

またここでの手順は こちらの記事 の 4 章を参考に進めていきましょう。
4-1. Arduino IDE のセットアップ から 4-3. 実装 までを実施してください。変更点は以下です。

  • 今回の実装では ArduinoJson は使用しません。そのため ArduinoJson のインストールは不要です。4-2-2. ArduinoJson のセットアップ はスキップしてください。
  • ポリシーの作成では、アクションを iot:*、リソース ARN は * に設定してください。
  • ソースコードを修正する では、同様に同じような項目を変更する必要があります。本記事では、config.h に変更の必要がある変数をまとめていますので、貼り付けてください。m5stickc-remote-control.ino は変更しません。

 

クリックすると拡大します

config.h の変更まで終了したら、M5StickC に書き込みましょう。これでデバイス側の準備は完了です。次にデバイス側の動作確認をします。

3-1. デバイスの動作確認

ここでは、センサーの値が読み取れ表示されるか、そして変化するかをまず確認します。その後、そのセンサー値がクラウドへ送信できているか、またクラウドからコマンドを送信してデバイスが受信し動作するかを確認していきます。

まず書き込みが正常に完了すると、M5StickC の液晶に数字が表示されます。こちらは X 軸のジャイロセンサーの値になります。そのため、M5StickC を傾けると数値が変化すると思います。逆に机の上に静止しておいておくと数値は一定になるはずです。

そこまで確認できたら、次にクラウドとのメッセージのやりとりを確認していきます。まずは M5StickC からのデータ受信を確認していきます。

クリックすると拡大します

  1. AWS IoT Coreを利用しているので、テスト画面 を開きます。
  2. トピックのサブスクリプションで、data/sensor と入力します。
  3. そして右隣のトピックへのサブスクライブボタンを押してください。
  4. すると、1 秒に 2 回メッセージが到着していることがわかります。このデータがまさに M5StickC から送信されてきたセンサーデータになります。
  5. 試しに M5StickC を傾けてセンサーデータを変化させてみてください。するとテスト画面で見られる数値も変化するはずです。

クリックすると拡大します

次にクラウドからコマンドを送信して M5StickC を操作してみましょう。

  1. 先ほどの画面そのままで、発行 と書かれているところのトピックを、cmd/device にしましょう。
  2. そしてその下の {"message": "Hello from AWS IoT console"} と書かれているメッセージ内容を削除し、かわりに test と入力します。
  3. そして右隣にある トピックに発行ボタン を押してみてください。
  4. すると、M5StickCのディスプレイ表示が test になりました。このように M5StickC では、メッセージを受信するとその受信したメッセージ内容を数秒間表示する実装になっています。
  5. 今度は送信するメッセージを変更してみましょう。先ほどの test を短い好きな文字列にしてみてください。
  6. また トピックに発行 ボタンを押すと、ディスプレイにその文字列が表示されるはずです。

クリックすると拡大します

このようにデバイスとクラウド間でメッセージの送受信ができるようになりました !
ここまで確認できれば、デバイス側の実装は完了です。次にアプリ側の実装を進めていきましょう。


4. アプリ側の実装

ではここからはアプリ側の実装をしていきます。操作は全てマネジメントコンソールで実施していきます。

4-1. アプリ開発環境の構築

まずは下の構成図のようにアプリの開発環境を構築します。

この章は、こちらの記事 を参考に作業を進めます。こちらの記事の 2. AWS Cloud9 環境構築 から、9. Vue.js プロジェクトを Amplify プロジェクトとして初期化 までを実施してください。変更点は以下です。

アプリのビルド時にメモリや CPU パワーが足らなくなるので、インスタンスタイプはデフォルトの t2.micro (1 GiB RAM + 1 vCPU) ではなく、t3.small (2 GiB RAM + 2 vCPU) に変更しておきましょう。

AWS Cloud9 でターミナルを開く場合には、画面上部の緑色の丸で囲われた + ボタンを押し、New Terminal を押してください。

このリポジトリのクローン の手順はスキップしてください。

AWS Cloud9 が利用できない場合、こちらのブログ をご参考に AWS IDE Toolkits または AWS CloudShell をご利用ください。

AWS Cloud9 から AWS IDE Toolkits または AWS CloudShell に移行する方法 »

Vue.js プロジェクトを作成 では、以下のように表示されたら下記と同様に Default ([Vue 2] babel, eslint) を選択して Enter を押してください。また下記の画像のような Warning が表示された場合は、Don’t Show Again を押してください。

Vue CLI v4.5.11
? Please pick a preset: (Use arrow keys)
❯ Default ([Vue 2] babel, eslint) 
  Default (Vue 3 Preview) ([Vue 3] babel, eslint) 
  Manually select feature

クリックすると拡大します

6. Vue.js プロジェクトに Cloud9 向けの設定を追加 では、代わりに以下のように操作してください。

  • touch ~/environment/notes/vue.config.js コマンド入力
  • 左のファイルツリーの environment/notes の中に vue.config.js ファイルが作成されているので開く
  • 下記の内容を貼り付け、保存
module.exports = {
  devServer: {
    disableHostCheck: true
  }
}

4-2. アプリへの権限の付与

では次に、AWS IoT Core と通信するための権限をアプリに付与するために Amazon Cognito の IDプール を作成します。

ただし今回は認証を実装しません。そのため今回は Amazon Cognitoで認証されていないロールを使用してアプリに権限を付与します。本番アプリでは当然、認証機能を実装し、認証されたロールを用いてアプリに権限を付与してください。またこのロールにアタッチするポリシーも、手順簡略化のため管理ポリシーをアタッチしています。ですが本番ではこのポリシーも最小権限になるように設定してください。

ここの手順ではこの構成図にあるように、先ほどインストールした Amplify CLI を用いて Amazon Cognito の ID プールを作成します。

  1. ここでもまず先ほどの記事の 10. 認証機能の追加 を実施します。
  2. 上記の手順が正常に完了したら、この設定を実際に自身のクラウド環境へ反映させましょう。そのために amplify push とコマンドを実行します。? Are you sure you want to continue?y を入力して反映させます。
  3. この実行には数分かかるため、完了するまで待ちます。

次に作成した ID プールの設定をしていきます。

先ほどのコマンドが正常に完了したら、Amazon Cognito の画面 を開きます。

このトップ画面で ID プールの管理ボタンを押します。

すると先ほどの操作で、notesXXXXXXX_identitypool_XXXXXXX__dev のような ID プールが作成されているので、それを選択します。

この ID プールの画面で、右上にある ID プールの編集を押します。すると ID プールの編集画面が表示されます。

クリックすると拡大します

この画面で認証されていない ID を開き、認証されていない ID に対してアクセスを有効にするにチェックを入れます。

次のその上の認証されていないロールの右にある、amplify-notes-dev-XXXXX-unauthRole となっているロール名を覚えていてください。

そして画面右下の変更の保存ボタンを押して、変更を保存します。

クリックすると拡大します

次に先ほど覚えた認証されていないロールに AWS IoT Core と通信するための権限を付与していきます。

そこでまず、IAM ロールの画面 を開きます。
ロールの一覧から、先ほどの amplify-notes-dev-XXXXX-unauthRole を探し、選択します。

アクセス権限のタブでは、また何もポリシーがアタッチされておらず、このロールにはまだ権限な与えられていないことがわかります。今回のアプリでは、AWS IoT Core とデータのやり取りができれば良いので、その権限を付与していきます。そこでこのロールにポリシーをアタッチしましょう。ボリシーをアタッチしますというボタンを押してください。

次のポリシーをアタッチする画面でポリシーの一覧が出てきます。検索窓に iotdata と入力して、AWSIoTDataAccess を探します。

AWSIoTDataAccess の左にチェックを入れたら、画面右下のポリシーのアタッチボタンを押してください。するとロールにポリシーがアタッチされ、権限を付与できました。

後この IAM の画面は利用しないため、閉じても構いません。

クリックすると拡大します

ここまでの手順で、Amazon Cognito の ID プールを作成し IAM ロールも設定することで、アプリに権限を付与できました。では次にアプリの実装をしていきましょう。

4-3. アプリの実装

ここまでで開発環境を整え、アプリへ権限を付与できるようになったので、アプリの核となる AWS IoT Core とメッセージを送受信する部分の実装をしていきます。このメッセージングを実装するために、Amplify Framework にある PubSub モジュールを使用していきます。またこの際の権限は、先ほど作成した Amazon Cognito によって渡されます。

アプリの実装をしていくので、プロジェクトを作成した AWS Cloud9 の画面に戻りましょう。そして Amplify Framework にある PubSub モジュールをインストールするために、AWS Cloud9 のターミナルで下記のコマンドを実行します。

npm i aws-amplify @aws-amplify/pubsub

次に実際に PubSub モジュールを利用した実装をしていきましょう。AWS Cloud9 の左のファイルツリーから、notes/src/App.vue を開きます。今回はこのファイルだけ変更し、アプリを作成していきます。開いたら、既にあるコードを全て削除し、以下のコードに置き換えてください。

<template>
  <div id="app">
      <div>
        Gyro: {{gyro}}
      </div>
      <div>
        <button @click="publish">Send command</button>
      </div>
  </div>
</template>

<script>
import awsconfig from './aws-exports'
Amplify.configure(awsconfig)

import Amplify, { PubSub } from 'aws-amplify';
import { AWSIoTProvider } from '@aws-amplify/pubsub/lib/Providers';

Amplify.addPluggable(new AWSIoTProvider({
  aws_pubsub_region: 'ap-northeast-1',
  aws_pubsub_endpoint: 'wss:///mqtt',
}));

export default {
  name: 'App',
  data: () => {
    return {
      gyro: "value"
    }
  },
  mounted: async function () {
    PubSub.subscribe('data/sensor').subscribe({
      next: data => {
        this.gyro = data.value.data
        console.log('Message received', data)
      },
      error: error => console.error(error),
      close: () => console.log('Done'),
    });
  },
  methods: {
    publish() {
      PubSub.publish('cmd/device', "cmd");
    }
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

このコードでアプリはほぼ完成です。非常にシンプルで簡単ですね。ただ、1 箇所だけ書き換えていただく必要があります。それは、AWS IoT Core のエンドポイントを自身のアカウントのエンドポイントに書き換えていただく必要があります。そのためまずはエンドポイントを確認しましょう。AWS Cloud9 のターミナルで、下記のコマンドを実行してください。

aws iot describe-endpoint --endpoint-type iot:Data-ATS

すると、このような JSON が表示されると思います。

{
    "endpointAddress": "XXXXXXXXXXXX-ats.iot.ap-northeast-1.amazonaws.com"
}

この値をコピーして、先ほどのApp.vue中の

aws_pubsub_endpoint: 'wss:///mqtt',

の箇所に追記する形で、

aws_pubsub_endpoint: 'wss://XXXXXXXXXXXX-ats.iot.ap-northeast-1.amazonaws.com/mqtt',

のようにしてください。末尾の /mqtt も必要です。そして保存します。これでアプリの実装は完了です。簡単ですね。

では実装したアプリの動作を確認していきましょう。AWS Cloud9 のプレビュー画面を開く、もしくは開いたままの方は更新ボタンを押して画面を更新してみてください。すると下記の画像のように、画面上部に Gyro の数値とボタンが 1 つ表示されるはずです。

クリックすると拡大します

このアプリでは、M5StickC からくるデータの最新値を AWS IoT Core を介してリアルタイムに表示しています。そのため、M5StickC を傾けるとセンサデータが変わり、画面に表示される数値も変化するはずです。このようにデバイスのデータをクラウドを介してアプリにリアルタイムに表示できました。

また、コマンド送信ボタンも用意しています。このボタンを押すことで、AWS IoT Core を介してコマンドを M5StickC に送信できます。押してみましょう。すると M5StickC がコマンドをすぐに受信し、ディスプレイに cmd と表示しました。これでアプリからクラウドを介してデバイスにコマンドを送信できました。

4-4. アプリのホスティング

さてこれでアプリの実装も完了し、動作も確認できました。ここで終わってもいいのですが、せっかくなのでどの端末からも、世界中どこからでもこのアプリを開き、センサデータを確認したりコマンド送信できるよう、次にアプリをホスティングしましょう。

アプリのホスティングには Amplify Console を利用します。Amplify Console でのアプリの作成やデプロイは、既にインストール済みの Amplify CLI を利用することで非常に簡単にできます。

AWS Cloud9 のターミナルで、

amplify hosting add

を実行します。すると、下記のような表示が出てくるので、

? Select the plugin module to execute (Use arrow keys)
❯ Hosting with Amplify Console (Managed hosting with custom domains, Continuous deployment) 
  Amazon CloudFront and S3 

このまま Enter で上の Hosting with Amplify Console (Managed hosting with custom domains, Continuous deployment) を選択します。次に下記のような表示が出てくるので、

? Choose a type (Use arrow keys)
  Continuous deployment (Git-based deployments) 
❯ Manual deployment 
  Learn more 

ここもこのまま Enter Manual deployment を選択します。そして下記のように表示されたら、設定完了です。

Admin:~/environment/notes (master) $ amplify hosting add
? Select the plugin module to execute Hosting with Amplify Console (Managed hosting with custom domains, Cont
inuous deployment)
? Choose a type Manual deployment

You can now publish your app using the following command:

Command: amplify publish
Admin:~/environment/notes (master) $ 

ここまでではホスティング環境を作成しただけですので、実際にホスティング環境をアプリをデプロイしましょう。上記に記載されているように、下記のコマンドを実行します。

amplify publish

また実行後すぐに、? Are you sure you want to continue? と聞かれるので、y と入力しましょう。しばらくするとアプリのビルドとデプロイが完了し、下記のような公開された URL が表示されます。

https://dev.XXXXXXXXX.amplifyapp.com

こちらをクリックすると、ブラウザで今回作成したアプリが表示されます。先ほどの動作確認と同様に、データ受信やコマンド送信ができます。これでクラウドを介してデバイスを遠隔操作できるようになりました !

一方で注意点としては、今回はアプリにも認証をかけずに公開 URL が発行されています。この URL が知られてしまうと、デバイスに対してメッセージの送受信ができてしまいます。ですのでお試し後はホスティングを停止するか、アプリの認証を実装しておきましょう。


まとめ

本記事ではスマートプロダクトとそれを制御する簡単な IoT アプリをプロトタイピングしてみました。AWS IoT を始めとする AWS サービスを用いることで、IoT アプリのコア機能を短時間で開発できることが本プロトタイピングでお分かり頂けたと思います。

今回作成したアプリは非常にシンプルでしたが、認証や時系列データの表示などの機能追加やカスタマイズをし、お好きなアプリへ改変できます。もちろんデバイス側も拡張や応用が可能です。今回使用した M5StickC には Grove と呼ばれる共通コネクタがあり、このコネクタを持った様々な種類のセンサやアクチュエータを簡単に接続して、データ計測やアクションをさせることができます。例えば、水分量センサーを接続して鉢植えの水分量をアプリに表示させ、アプリから水やりコマンドを送信して鉢植えに水をやる、なんてこともアイディア次第で可能です。

ぜひ楽しく役に立つ IoT アプリとデバイスを開発してみてください !

なお、本記事の内容は過去の登壇を元にしており、こちら から説明とプロトタイピングデモを収録した動画をご視聴いただけますので、合わせてご覧ください。


builders.flash メールメンバーへ登録することで
AWS のベストプラクティスを毎月無料でお試しいただけます

筆者プロフィール

飯塚 将太
アマゾン ウェブ サービス ジャパン合同会社
IoT ソリューションアーキテクト

IoT のワークロードを持つお客様の技術支援しています。
自宅のスマートホーム化が趣味です。

AWS を無料でお試しいただけます

AWS 無料利用枠の詳細はこちら ≫
5 ステップでアカウント作成できます
無料サインアップ ≫
ご不明な点がおありですか?
日本担当チームへ相談する