Amazon Web Services ブログ

AWS IoT Application Kitを使ったIoT Webアプリケーションの構築

この記事は Sudhir Jena によって投稿された Build IoT web applications using AWS IoT Application Kit を翻訳したものです。

2022年3月1日に IoT アプリケーション開発者向けのオープンソースの UI コンポーネントライブラリ AWS IoT Application Kit を発表しました。AWS IoT Application Kit により、開発者は AWS IoT SiteWise のデータを活用したリッチな対話型 Web アプリケーションを構築することができます。 IoT アプリケーション開発者は ReactJS 、 Vue.js 、ネイティブ JavaScript などの Web フロントエンドフレームワークと AWS IoT Application Kit の再利用可能なコンポーネントを使用して、産業資産監視アプリケーションなどのカスタマイズしたユーザー体験を提供することができます。

図1:AWS IoT Application Kitで構築したReactJSのサンプルアプリケーション

AWS IoT Application Kitとは?

AWS IoT Application Kit は IoT アプリケーション開発者が複雑な IoT アプリケーションの開発を簡素化できるようにする、オープンソースのクライアントサイド・ライブラリです。パフォーマンスと再利用性に優れたコンポーネントによって、リアルタイムの Web アプリケーションに求められる重要な技術要素を抽象化します。例えば、ストリーミングデータの処理、キャッシング、データのプリロード、動的集約、リクエストの断片化の防止などです。この抽象化により IoT アプリケーションの開発者は、カスタムされたユーザーエクスペリエンスの構築に集中でき、根本的な技術的複雑さを気にする必要がなくなります。

AWS IoT SiteWise からの IoT データを可視化するために、お客様が既存の Web アプリケーションを統合してリッチ化する必要がある場合 AWS IoT Application Kit では、付属コンポーネントをお客様の既存の Web アプリケーションに統合することも可能です。

AWS IoT Application Kitの始め方

AWS IoT Application Kit は現在 npm パッケージ – @iot-app-kit/components として提供されています。このパッケージは、以下のコマンドでインストールできます。

npmの使用方法

npm install @iot-app-kit/components

詳しくは、 AWS IoT Application Kit の技術資料をご参照ください。

AWS IoT Application Kitを使った開発

このブログ記事では、 AWS IoT Application Kit と AWS IoT SiteWise を使って、ジュースの瓶詰めラインを監視する ReactJS Web アプリケーションを構築し、瓶詰めラインの構成機器それぞれからテレメトリ(機器の状態や生産数など)を表示します。

チュートリアル

前提条件

本ソリューションの構築には、以下が必要です。

  • AWS CLI
  • AWS CDK
  • AWS CloudFormation経由でスタックをデプロイするための権限を持つAWS CLIプロファイル
  • AWSアカウントに存在するデフォルトのVPC

ステップ1:ボトリングラインのテレメトリーシミュレーション

今回モデル化したいジュース瓶詰めラインは、以下のような相互に接続された機器で構成されています(動作順)

表1: 模擬ジュース製造ラインにおける相互接続機器の順序表
順序 機器名 機器 ID 説明
1st 洗浄マシン ( Washing Machnie ) UN01 空ボトルを1本ずつ洗浄・除菌・乾燥する
2nd 充填マシン ( Filling Machine ) UN02 消毒済みボトルに設定された量まで充填する
3rd 封入マシン ( Capping Machine ) UN03 充填されたボトルにキャップをし、封をする
4th ラベリングマシン (Labelling Machine) UN04 キャップ付きのボトル1本1本に製品ラベルを貼り付けて印刷する
5th ケースパッキングマシン ( Case Packing Machine ) UN05 ラベルが貼られたボトル群を1つのケースに収納する
6th パレット積み上げマシン ( Palletizing Machine ) UN06 加工されたボトルを複数ケース、パレットに載せて出荷する

図2:本デモで模擬したボトリングラインの各機械

これらの各機は、テレメトリとして以下のデータ測定値を出力しています。

表 2: モデル化された OPC-UA タグ一覧
測定名 測定単位 データ型 モデリングタグ 説明
機器の状態
(Machine State)
None Integer {Machine_ID}/Status/StateCurrent マシンの現在の動作状態。使用可能な値は、表3「機器の状態 説明」に記載しています
機器のモード
(Machine Mode)
None Integer {Machine_ID}/Status/ModeCurrent 機械が動作しているモード。設定可能な値は、表4「機器の動作モード」に記載しています
現在の速度
(Current Speed)
ボトル数/分 Double {Machine_ID}/Status/CurMachSpeed 1分間に処理されるボトル数で測定する、機器の現在の動作速度
ブロック状態
(Blocked)
None Boolean {Machine_ID}/Status/Blocked 下流機器の状態により、機器の動作がブロックされているかどうかを示す
不足状態
(Starved)
None Boolean {Machine_ID}/Status/Starved 上流機器の取り込み条件により、機器が不足状態になっているかどうかを示します
停止理由
(Stop Reason)
None Integer {Machine_ID}/Admin/StopReasonCode 機器停止理由コード
処理件数
(Processed Count)
None Integer {Machine_ID}/Admin/ProcessedCount 本機で処理されたボトルの増分カウンタ(成功または失敗)
不具合数
(Defective Count)
None Integer {Machine_ID}/Admin/DefectiveCount 処理に失敗したボトルの増分カウンタ
表3:機器の状態 説明
StateCurrent の値 機器の状態
1 PRODUCING
2 IDLE
3 STARVED
4 BLOCKED
5 CHANGEOVER
6 STOPPED
7 FAULTED
表4:機器の動作モード
ModeCurrent の値 機器の状態
1 AUTOMATIC
2 MAINTENANCE
3 MANUAL

Amazon EC2 インスタンスにホストされた Node-RED を使用して、表2のモデル化されたタグを読み取ることができる OPC-UA サーバーをシミュレートするフローを作成します。 Node-RED の環境を素早く構築するための AWS CDK のコードを github からクローンします。

  • アプリケーションをローカルマシンにクローンします。
git clone https://github.com/aws-samples/aws-iot-app-kit-bottling-line-demo.git iot-app-kit-demo
  • プロジェクトディレクトリに移動します。
cd iot-app-kit-demo
  • AWS CDKの依存関係をインストールします。注意:ここではインフラ構築に必要な依存関係のみの設定されます
npm ci
  • CDK 導入のためのアカウントとリージョンを設定します。
    注意: AWS IoT SiteWise が利用可能な AWS リージョンをご利用ください。
cdk bootstrap aws://<ACCOUNT-NUMBER>/<REGION>
  • OpcuaSimulatorStackという名前のcdkスタックをデプロイします。”Do you wish to deploy these changes (y/n)? “のプロンプトが表示されたら、Yを入力します。
cdk deploy OpcuaSimulatorStack

図3: AWS IoT Application Kit Bottling Line Demo のアーキテクチャ図

OpcuaSimulatorStack の導入に成功すると、 OPC-UA サーバー、 AWS IoT Greengrass V2 コア、対応する AWS IoT SiteWise ゲートウェイ、およびアセットモデルや派生のアセット(ジュース瓶詰めラインの機器)が作成されるはずです。 OPC-UA サーバー、 AWS IoT Greengrass V2 コア、 AWS IoT SiteWise ゲートウェイといったアプリケーションコンポーネントはすべて OpcuaSimulatorStack を通じて作成した Ubuntu EC2 インスタンスにデプロイされます。

OpcuaSimulatorStack のデプロイには数分かかり、 cdk deploy コマンドの出力で表示されます。ステップ2では、ジュースの瓶詰めラインで作成されたアセットを監視するための ReactJS ウェブアプリケーションを構築します。

ステップ2:ボトリングラインのオペレーションを可視化するカスタムアプリケーションの構築

クローンしたコードリポジトリ aws-iot-app-kit-bottling-line-demo.git には assets/react-app というディレクトリにスターター ReactJS アプリケーションが含まれています。このステップでは、スターター ReactJS アプリケーションに AWS IoT Application Kit のコンポーネントを段階的に追加していきます。

  • ReactJS のアプリケーションディレクトリに移動します。
cd assets/react-app
  • 必要なNPMの依存関係をインストールします。
npm ci
  • react-app のルートディレクトリに .env ファイルを作成します。 例: assets/react-app/.env
touch .env
  • .env ファイルを編集し、下記スニペットを参考に REACT_APP_ を先頭に持つ環境変数として、プログラムアクセス用のAWS IAMクレデンシャルを追加します。 REACT_APP_AWS_SESSION_TOKEN の値は、プログラムアクセスに有効期限の短いのIAMクレデンシャルを使用している場合のみ必要です。
REACT_APP_AWS_ACCESS_KEY_ID=<replace-with-aws-access-key-id>
REACT_APP_AWS_SECRET_ACCESS_KEY=<replace-with-aws-access-key>
REACT_APP_AWS_SESSION_TOKEN=<replace-with-aws-session-token>
  • 編集後、 .env ファイルを保存します。

ここからは、 AWS IoT Application Kit のコンポーネントを1つずつ追加していき、各コンポーネントの使い方を紹介していきます。

  • ReactJS アプリケーションの依存関係に AWS IoT Application Kit NPM パッケージを追加します。
npm install @iot-app-kit/components @iot-app-kit/react-components @iot-app-kit/source-iotsitewise
  • src/App.tsx を開き、コメント行 /* --- BEGIN: AWS @iot-app-kit and related imports/ と / --- END: AWS @iot-app-kit and related imports*/ の間にインストールした AWS IoT Application Kit コンポーネントを以下のように記述してインポートします。 awsRegion の値は、実際の AWS リージョン(ステップ1で OpcuaSimulatorStack をデプロイしたリージョン)に置き換えてください。
...
/* --- BEGIN: AWS @iot-app-kit and related imports*/
import { initialize } from "@iot-app-kit/source-iotsitewise";
import { fromEnvReactApp } from "./fromEnv";
import {
    BarChart,
    LineChart,
    StatusTimeline,
    ResourceExplorer,
    WebglContext,
    StatusGrid,
    Kpi,
} from "@iot-app-kit/react-components";
import { COMPARISON_OPERATOR } from "@synchro-charts/core";

import "./App.css";

const { defineCustomElements } = require("@iot-app-kit/components/loader");

const { query } = initialize({
    awsCredentials: fromEnvReactApp(),
    awsRegion: "<replace-with-aws-region>",
});

defineCustomElements();
/* --- END: AWS @iot-app-kit and related imports*/
...
  • AWS IoT SiteWiseコンソールを参照して、AWS IoT Application Kitで表示する必要があるアセットプロパティIDをコメント行 /* --- BEGIN: Asset Id and Asset Property Ids from AWS IoT SiteWise*//* --- END: Asset Property Ids from AWS IoT SiteWise*/ の間に入力します。
...
/* --- BEGIN: Asset Id and Asset Property Ids from AWS IoT SiteWise*/
    
// Asset Id of the AWS IoT SiteWise asset that you want to display by // default
const DEFAULT_MACHINE_ASSET_ID = '<replace-with-sitwise-asset-id>';
const [ assetId, setAssetId ] = useState(DEFAULT_MACHINE_ASSET_ID);
const [ assetName, setAssetName ] = useState('<replace-with-corresponding-sitwise-asset-name>');
    
// Asset Property Ids of the AWS IoT SiteWise assets that you want to // query data for

// Refer AWS IoT SiteWise measurements
const OEE_BAD_COUNT_PROPERTY = '<replace-with-corresponding-sitwise-asset-property-id>';
const OEE_TOTAL_COUNT_PROPERTY = '<replace-with-corresponding-sitwise-asset-property-id>';
const CURRENT_SPEED_PROPERTY = '<replace-with-corresponding-sitwise-asset-property-id>';
const MACHINE_STOP_REASON_CODE_PROPERTY = '<replace-with-corresponding-sitwise-asset-property-id>';

// Refer IoT SiteWise transforms
const MACHINE_STATE_ENUM_PROPERTY = '<replace-with-corresponding-sitwise-asset-property-id>';
const MACHINE_MODE_ENUM_PROPERTY = '<replace-with-corresponding-sitwise-asset-property-id>';
const STARVED_INDICATOR_PROPERTY = '<replace-with-corresponding-sitwise-asset-property-id>';
const BLOCKED_INDICATOR_PROPERTY = '<replace-with-corresponding-sitwise-asset-property-id>';
    

/* --- END: Asset Property Ids from AWS IoT SiteWise*/
...
  • ジュースの瓶詰めのラインにはいくつかのアセットがあるので、まず ResourceExplorer コンポーネントを実装して、アセットのフィルタリング、ソート、ページ分割ができるようにします。src/App.tsx のコメント行 {/* --- BEGIN: `ResourceExplorer` implementation*/}{/* --- END: `ResourceExplorer` implementation*/} の間に、次のコードを追加してください。
...
{/* --- BEGIN: `ResourceExplorer` implementation*/}
<ResourceExplorer
    query={query.assetTree.fromRoot()}
    onSelectionChange={(event) => {
        console.log("changes asset", event);
        props.setAssetId((event?.detail?.selectedItems?.[0] as any)?.id);
        props.setAssetName((event?.detail?.selectedItems?.[0] as any)?.name);
                }}
    columnDefinitions={columnDefinitions}
/>
{/* --- END: `ResourceExplorer` implementation*/}
...
  • 次に、様々なアセットの Machine State アセットプロパティを可視化するために、 StatusTimeline コンポーネントを実装します。コメント行 {/* --- BEGIN: `StatusTimeline` implementation*/}{/* --- END: `StatusTimeline` implementation*/} の間に、以下のコードを追加します。
...
{/* --- BEGIN: `StatusTimeline` implementation*/}
 <div style={{ height: "170px" }}>
    <StatusTimeline
        viewport={{ duration: '15m' }}
        annotations={{
            y: [
                { color: '#1D8102', comparisonOperator: COMPARISON_OPERATOR.EQUAL, value: 'PRODUCING' },
                { color: '#0073BB', comparisonOperator: COMPARISON_OPERATOR.EQUAL, value: 'IDLE' },
                { color: '#D45200', comparisonOperator: COMPARISON_OPERATOR.EQUAL, value: 'STARVED' },
                { color: '#DA4976', comparisonOperator: COMPARISON_OPERATOR.EQUAL, value: 'BLOCKED' },
                { color: '#5951D6', comparisonOperator: COMPARISON_OPERATOR.EQUAL, value: 'CHANGEOVER' },
                { color: '#455A64', comparisonOperator: COMPARISON_OPERATOR.EQUAL, value: 'STOPPED' },
                { color: '#AB1D00', comparisonOperator: COMPARISON_OPERATOR.EQUAL, value: 'FAULTED' }
            ]
        }}
        queries={[
            query.timeSeriesData({
                assets: [{
                    assetId: props.assetId,
                    properties: [{
                        propertyId: props.machineStatePropertyId
                    }]
                }]
            })
        ]}
    />
</div>
{/* --- END: `StatusTimeline` implementation*/}
...
  • 次に、 AWS IoT SiteWise で定義した以下のメトリクスを、ジュース瓶詰めラインの機器ごとに可視化するための LineChart コンポーネントを実装します。
    • 15分ごとに処理されるボトルの総数 (Total Count)
    • 15分ごとに処理されるボトルの不良数 (Bad Count)

コメント行 {/* --- BEGIN: `LineChart` implementation*/}{/* --- END: `LineChart` implementation*/} の間に以下のコードを追加してください。

...
{/* --- BEGIN: `LineChart` implementation*/}
<div style={{ height: "170px" }}>
    <LineChart
        viewport={{ duration: "15m" }}
        queries={[
            query.timeSeriesData({
                assets: [
                    {
                        assetId: props.assetId,
                        properties: [
                            {
                                propertyId: props.badPartsCountPropertyId,
                                refId: "bad-parts-count",
                            },
                            {
                                propertyId: props.totalPartsCountPropertyId,
                                refId: "total-parts-count",
                            },
                        ],
                    },
                ],
            }),
        ]}
        styleSettings={{
            "bad-parts-count": { color: "#D13212", name: "Bad Count" },
            "total-parts-count": { color: "#1D8102", name: "Total Count" },
        }}
    />
</div>
{/* --- END: `LineChart` implementation*/}
...
  • コメント行 {/* --- BEGIN: `WebglContext` implementation*/}{/* --- END: `WebglContext` implementation*/} の間に WebglContext コンポーネントを追加します。
    WebglContextは ReactJS のコンポーネントツリー全体で一度だけ宣言する必要があります。
...
{/* --- BEGIN: `WebglContext` implementation*/}
<WebglContext/>
{/* --- END: `WebglContext` implementation*/}
...
  • ローカル開発サーバーを起動し http://localhost:3000 に移動して修正した ReactJS アプリケーションを表示します。起動したら、ジュース瓶詰めラインのアセット階層を参照し ResourceExplorer コンポーネントを使用して監視するアセットを選択します。特定のセットを選択すると、表示される StatusTimeline コンポーネントで Machine State の測定値を表示し LineChart コンポーネントで Total CountBad Count の測定値を表示することができます。
npm start

AWS IoT Application Kit には、以下の可視化ウィジェット用のコンポーネントも含まれています。

  • BarChart
  • Kpi
  • ScatterChart
  • StatusGrid

スターター ReactJS アプリケーションには、 src/App.tsx ファイルに BarChartKpiStatusGrid コンポーネントのサンプル実装も含まれています。 ReactJS アプリケーションでこれらのコンポーネントを使用する方法の詳細については AWS IoT Application Kit のドキュメントを参照することができます。

図4:デモアプリケーションの画面イメージ

また、AWS IoT Application Kitの実装が完了したサンプルファイル src/App.completed.tsx を参照することができます。

このチュートリアルで作成した ReactJS アプリケーションは AWS Amplify でホストすることもできます。 AWS Amplify getting started hands-on guide を参考に始めることができます。

クリーンアップ

プロジェクトディレクトリにディレクトリを変更し、以下のスタック削除コマンドを実行して、このチュートリアルで設定した作成済みの AWS リソースを削除してください。"Are you sure you want to delete: (y/n)?" とプロンプトが表示されたら Y を入力します。

cd iot-app-kit-demo 
cdk destroy OpcuaSimulatorStack

最後に

AWS IoT Application Kit は、カスタム UI/UX 要件を満たす Web アプリケーションの構築において、抽象化、簡素化、独立性を提供します。 AWS IoT Application Kit にアクセスすると、 AWS IoT SiteWise から IoT データを監視および可視化するリアルタイム IoT Web アプリケーションの構築を開始するための詳細をご覧いただけます。

 

翻訳はソリューションアーキテクトの渡邉が担当しました。