Amazon Web Services ブログ

AWS IoT Greengrass のための効率的な開発環境の構築

この記事は Tim Mattison によって投稿された Build an efficient development environment for AWS IoT Greengrass を翻訳したものです。

はじめに

この記事では、AWS IoT Greengrass のためのクリーンで効率的な開発環境をセットアップする方法を紹介します。この環境を使えば、アイデアをすばやくテストし、エッジコンピューティングシステムをゼロから構築するプロセスを自動化することができます。エッジシステムのための再現性のある開発環境を構築するには、長い時間がかかることがあります。これらのツールを使用することで、スタートにかかる時間を短縮し、本番アプリケーションを構築するためのベースを作成することができます。

概要

構築する Ubuntu 20.04 ベースの仮想マシンは、以下を行うことができます。

  • 数分でゼロからスタート
  • 実際の USB デバイスへの接続
  • AWS の認証情報を使用して各種 AWS サービスを利用
  • USB カメラから画像をキャプチャーし、ホストシステムに保存する
  • AWS IoT Greengrass を1つのコンポーネントで実行する

GreenEyes を使用してデジタルビデオレコーダー (DVR) のプラットフォームを実装します。このプラットフォームは AWS IoT Greengrass や FreeRTOS などエッジコンピューティングのための複数の AWS サービスを使用します。

前提条件

全ての OS

AWS Command Line Interface v2 をインストールし、デフォルトの場所 $HOME/.aws に認証情報をセットアップしておく必要があります。プロジェクトでは、これらの認証情報を VM に取り込み、すぐに AWS と対話できるようにします。

MacOS もしくは Linux 環境の場合

git と bash がインストールされている必要があります。最近のバージョンの Linux や MacOS には、これらは既にインストールされています。

Windowsの場合

bash スクリプトを実行できるシェルが必要です。Git for Windows に付属している Git Bash をおすすめします。Windows ターミナルをインストールしている場合は、Git for Windows のインストールプロセスで Git Bash profile for Windows Terminal を有効にしてください。そうすれば、デフォルトのターミナルを使う代わりに Windows ターミナルのドロップダウンから Git Bash を選択できるようになります。

ツールの概要

Virtual Box での仮想化

仮想化プラットフォームが必要です。近年はコンテナで多くのことが可能となっており、頻繁に使用されています。今回の場合、いくつかのカーネルモジュールをロードしたり、USB デバイスにアクセスしたりする必要があり、コンテナベースのシステムではサポートできない場合があります。さらに、Windows、MacOS、Linux のいずれの環境でも可能な限り同じような体験ができるようにする必要があります。

そのため、今回は VirtualBox を仮想化プラットフォームとして使用します。VirtualBox は、クロスプラットフォームで、無料で、USB パススルーに対応しています。テストでは、シングルストリームのビデオキャプチャと処理に十分な性能があることが確認されています。

Vagrant を用いたビルドの自動化

仮想マシンをできるだけ簡単にセットアップするためのツールが必要です。コマンドラインでマシンの起動、停止、再構築ができれば、時間を節約し、手動で設定するステップを省くことができます。

Vagrant は仮想マシンの構築と設定を自動化します。Vagrant はクロスプラットフォームで、USB パススルーに対応した VirtualBox をバックエンドとして使うことができます。

Vagrant はホストとゲスト OS の間でファイルを共有することも可能です。結果はすぐに表示され、ホストから直接システムを監視することができます。

カメラの選択

USB カメラはすべて同じではありませんが、すべての UVC ウェブカメラは等価であると考えることができます。UVC は USB Video Class の略です。UVC はビデオをキャプチャするための標準的なインターフェイスを提供する規格です。一部のウェブカメラはこの規格に対応しておらず、追加のソフトウェアが必要となります。

この記事では簡単のため、対象を UVC ウェブカムに限定しています。ここで紹介するシステムは、他のカメラを使用するように拡張させることもできますが、ここでは対象外とします。

信頼性の高い UVC カメラとして、Logitech C922 があります。これは、新品でも中古でも様々なお店でオンラインで入手することができます。また、C920sC920e のような C922 のいくつかのバリエーションがありますが、これらも同様に動作するはずです。これらの機器の動作確認を行った際にはドキュメントに情報を追加していく予定です。

使用するカメラが UVC デバイスリストに載っているか、UVC をサポートしていると明記されているものであれば、問題なく動作するはずです。ただし、デフォルトのコードでは Logitech C922を使用しています。他のカメラを使用する場合は、設定にいくつかの変更が必要です。VirtualBox と Vagrant をセットアップしたら、カメラをテストしてセットアップを検証することができます。

ツールのインストール

VirtualBox

VirtualBox は簡単にセットアップを行うことができます。VirtualBox wiki の downloads ページで、実行するプラットフォームに対応する VirtualBox プラットフォームをクリックします。VirtualBox をインストールするには、管理者権限が必要ですので、管理者権限のあるコンピュータを使用してください。

この記事は、MacOS 上の VirtualBox 6.1.32 をベースにしています。他のプラットフォームや新しいバージョンを使用している場合、画面が若干異なる場合があります。もし問題が発生した場合は、GreenEyes のリポジトリにスクリーンショットともに issue を登録してください。

VirtualBox extension pack

USB カメラが正しく動作するように、USB3.x のサポートを追加する必要があります。USB 3.x のサポートを得るために、VirtualBox をダウンロードしたのと同じダウンロードページにある Oracle VM VirtualBox Extension Pack をインストールする必要があります。

注意:拡張パックをインストールする際に、すでに VirtualBox GUI を開いている場合は、一旦閉じて再度開く必要があります。

Vargrant

Vagrant のダウンロードページに移動し、お使いの OS に適したビルドをインストールします。OS によってはパッケージマネージャ (Homebrew, apt など) で Vagrant をインストールできるものもありますし、バイナリビルドをダウンロードする必要があるものもあります。

コード

GreenEyes のリポジトリの概要

GreenEyes のリポジトリには、このシリーズの各投稿のスクリプトとドキュメントが含まれています。ホスト上で実行されるスクリプトは greeneyes/blog-posts/001/host ディレクトリにあります。ゲスト上で実行されるスクリプトは、greeneyes/blog-posts/001/guest ディレクトリにあります。

GreenEyes リポジトリのクローン

シェル上でリポジトリを格納したいディレクトリに移動し、以下のようにクローンします。

git clone https://github.com/awslabs/greeneyes/

環境

環境の初期化

お使いのシステムが MacOS または Linux の場合は、そのまま実行することができます。
お使いのシステムが Windows の場合、Hyper-V を有効にする必要があります。管理者用のターミナルセッションで、次のコマンドを使用して Hyper-V を有効にします。

powershell Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All

VM の開始

注意:vagrant コマンドを使うときは、必ず greeneyes/blog-posts/001/host ディレクトリにいる必要があります。

greeneyes/blog-posts/001/host ディレクトリで vagrant up を実行します。これが完了すると、VM は必要なカーネルモジュールでブートストラップされ、USB 3.0 が有効になります。このコマンドは、インターネットの帯域幅、CPU、RAM などの多くの要因に依存して、しばらく時間がかかることがあります。低速の場合、 3 分半程度かかることがあります。

VMがプロビジョンに失敗する場合

一時的なネットワーク接続の問題により VM がプロビジョニングステップの実行に失敗する場合があります。この場合には以下のようなエラーが表示されます。

The SSH command responded with a non-zero exit status. Vagrant
assumes that this means the command failed. The output for this command
should be in the log above. Please read the output to determine what
went wrong.

このメッセージが表示された場合には、vagrant destroy を実行して VM を一度消去し、再度 vagrant up を実行してください。そうしないと、VM が正しい依存関係やコンフィグレーションを得ることができなくなります。

USB3.0 サポートの検証

vagrant ssh を実行すると VM 上にシェルが立ち上がります。USB サポートが動作していることを検証するために以下のコマンドを実行してください。

dmesg | grep -i xhci

以下に似た出力が表示されるはずです。

[    1.287174] usb usb3: Product: xHCI Host Controller
[    1.287928] usb usb3: Manufacturer: Linux 5.4.0-107-generic xhci-hcd

もしこれらの行が表示されていれば (更に多くの行が表示される場合もあります) 、USB 3.0 サポートは正しく動作しています。exit コマンドを実行してシェルを抜けてください。
次に、Web カメラ用に USB パススルーを設定できるようにするため、 vagrant halt を実行して VM を停止してください。

USB パススルーの設定

注意: Vagrant のデフォルト設定では、USB 3.0 パススルーが設定され、Logitech C922 用のデバイスフィルタが追加されています。Logitech C922 を使用している場合は、このセクションをスキップすることができます。それ以外の場合は、このセクションに従って、Web カメラのデバイスフィルタを追加してください。

USB カメラをコンピュータに接続します。次の画面でリストから選択する必要があるので、インターフェイスを再読み込みする必要がないように、すぐに使える状態にしておくとよいでしょう。

VirtualBox の GUI を起動します。インターフェイスは以下のようになっているはずです。

「Setting」 から 「Port」 へ、その次に 「USB」 を選択します。

「Enable USB Controller」をチェックし、「USB 3.0 (xHCI) Controller」を選択します。空欄の「USB Device Filters」と、右側に2つの USB のアイコンが確認できます。

図に示すように、USB ケーブルとプラスの印があるアイコンをクリックします。

リストから接続したカメラを選択します。以下のように表示されます。

OKを選択し、インスタンスを再起動し、テストを行います。

USB パススルーのテスト

それでは、VM に入り、カメラから写真をキャプチャーしてみましょう。
VM をスタートするために vagrant up を実行します。vagrant ssh を実行することで、VM 上にターミナルを開きます。以下のコマンドをシェルで実行することで、キャプチャーのテストを実行します。

~/guest/bash-capture-loop/capture-one

テストが成功した場合、キャプチャーのテストからは、単に1つの < の文字が出力されます。~/shared ディレクトリに .jpg が作成されます。ファイル名はイメージがキャプチャーされたときの UNIX エポック時間を示す数字となります。このイメージはカメラからのシングルフレームの画像となっています。このファイルはホスト上の shared ディレクトリからも見て確認することができます。Vagrant は VM 上の ~/shared をホスト上の shared にマップする機能を提供します。

AWS 認証情報のテスト

まだ開いていない場合には、vagrant ssh を実行することで VM 上にターミナルを開き、以下のコマンドを実行します。

aws sts get-caller-identity

認証情報が正しく設定されていれば、以下のような出力が得られます。

{
  "UserId": "AXXXXXXXXXXXXXXXXXXXXX",
  "Account": "123456789012",
  "Arn": "arn:aws:iam::123456789012:user/me"
}

認証情報がなければ、出力は以下のようになります。

Unable to locate credentials. You can configure credentials by running "aws configure".

ホスト上でも同じコマンドを実行することで AWS 認証情報が正しく設定されているか検証してください。もし正しく設定されていない場合には、設定の基本のドキュメントを参照して認証情報を設定してください。

AWS IoT Greengrass のインストール

まだ開いていない場合には、vagrant ssh を実行することで VM 上にターミナルを開き、以下のコマンドを実行します。

gg-install

このコマンドは最新バージョンの AWS IoT Greengrass Nucleus をダウンロードし、VM 上に AWS IoT Greengrass をプロビジョニングします。完了すると以下のようなメッセージが表示されます。

Successfully set up Nucleus as a system service
Greengrass S3 access policy created [...] for bucket [...]

以下を実行することで AWS IoT Greengrass の全てのログをモニターすることができます。

gg-logs

gg-logs は新たなログが生成されるとそれらをピックアップするので、コンポーネントが何を行っているかを確認するために gg-logs をリスタートする必要はありません。

注意: gg-logs スクリプトを終了するには、CTRL とバックスラッシュを押します (CTRL + \)。

Bash キャプチャーループコンポーネントのデプロイ

前に実行した capture-one は実は Bash のスクリプトです。capture-loop と呼ばれる capture-one をループするようにラップする別のプログラムがあり、このプログラムは1秒に1回イメージをキャプチャーし、最後の 10 イメージを shared ディレクトリに保存します。

capture-loop も Bash のスクリプトです。これは、Bash スクリプトとしてどのような言語で書かれたコンポーネントにも対応できるように書かれています。

Bash キャプチャーループコンポーネントをデプロイするには、まずターミナルが開かれていて、以前に実行した gg-logs によってログがモニタリングされていることを確認します。それから、新しいターミナルを開き、以下のコマンドを実行します。

gg-cloud-deploy

数秒後、以下のようなメッセージが表示されます。

2022-04-29T15:31:37.495Z [WARN] (Copier)
greeneyes.BashCaptureLoop: stderr. <.
{scriptName=services.greeneyes.BashCaptureLoop.lifecycle.Run,
serviceName=greeneyes.BashCaptureLoop, currentState=RUNNING}

これは、Bash キャプチャーループが動作していることを示しています。ホストコンピュータ上でも shared ディレクトリに画像が保存されているのが確認できるはずです。

クラウドデプロイコマンドを理解する

gg-cloud-deploy コマンドは AWS IoT Greengrass Development Kit Command-Line Interface、もしくは GDK とも呼ばれる、を使用して guest ディレクトリにある AWS IoT Greengrass のコンポーネントを AWS IoT Greengrass クラウドサービスを使ってビルド、パブリッシュ、デプロイします。
gg-cloud-deploy コマンドは以下のことを行います:

  • dev tools パッケージの AWS IoT Greengrass CLI がインストールされていることを確認します。これは、最初のデプロイで gg-install スクリプトにより --deploy-dev-tools true オプションを指定することで実施されます。
  • ゲストディレクトリにある、GDK と互換性のあるコンポーネントを探します。これは、gdk-config.json または gdk-config.json.template ファイルを探すことによって行われます。
  • gdk-config.json があり、gdk-config.json.template がない場合は、何も変更せずに gdk-config.json が使用されます。これにより、この投稿に含まれないコンポーネントをサポートすることができます。
  • gdk-config.json.template ファイルがある場合は、プレースホルダの値を更新し、更新された情報で gdk-config.json を上書きします。これにより、Amazon Simple Storage Service(S3)バケットを毎回更新することなく、複数の AWS IoT Greengrass VM でコンポーネントの設定を再利用することが容易になります。
  • gdk component build コマンドで各コンポーネントをビルドします。これにより、S3に公開可能なコンポーネントの ZIP アーカイブを作成します。
  • gdk component publish コマンドで各コンポーネントをパブリッシュします.これにより、ZIP アーカイブがS3 にアップロードされます。
  • gg-cli deployment create で各コンポーネントの最新版をデプロイします。最新版を取得するために、プライベートでデプロイした Bash キャプチャーループコンポーネントに AWS CLI で問い合わせを行います。

追加の便利なスクリプト

gg-cloud-deploygg-install に加えて、greengrass ディレクトリにいくつかの便利なスクリプトがあります。デフォルトでは greengrass ディレクトリは vagrant ユーザの PATH に含まれているので、VM 内のどこからでもこれらのツールを使うことができます。他に利用できるスクリプトは以下の通りです。

  • gg-cli – AWS IoT Greengrass CLI を実行します。
  • gg-names – AWS IoT Greengrass の現在の VM のインスタンスを設定、管理するために使用される名前を表示します。
  • gg-password – AWS IoT Greengrass のローカル開発者コンソールのユーザー名とパスワードの情報を出力します。
  • gg-start – systemd を使用してAWS IoT Greengrass を起動します
  • gg-status – systemd を使って AWS IoT Greengrass のステータスを表示する
  • gg-stop – systemd を使って AWS IoT Greengrass を停止します

クリーンアップ

クリーンアッププロセスは、スクリプトが作成した AWS リソースを削除し、その後、Vagrant VM を破棄します。
AWS IoT Greengrass をインストールし、クラウドデプロイスクリプトを実行することで作成されたリソースは以下の通りです。

  • 1つのAWS IoT Greengrass のデプロイアーティファクト用のS3バケット
  • デプロイにつき、1つのS3オブジェクト
  • 1つのモノグループ
  • 1つのAWS IoT 証明書
  • 2つのAWS IoT ポリシー
    • AWS IoT Greengrass Core の証明書を使用して、AWS Identity and Access Management (IAM) ロールからAWS Security Token Service (STS) クレデンシャルを取得するためのトークン交換サービス用のポリシー
    • AWS IoT Greengrass コアが AWS IoT と AWS IoT Greengrass のサービスにアクセスするためのポリシー
  • AWS IoT Greengrass コアの証明書で Assume することのできる IAM ロール1つ
  • 2つの IAM ポリシー
    • AWS IoT Greengrass が CloudWatch Logs にログを送信するために作成したデフォルトのポリシー
    • gg-install で作成した、AWS IoT Greengrass が gg-cloud-deploy で作成したデプロイメントアーチファクト用の S3 バケットにアクセスできるようにするためのポリシー
  • AWS IoT Credentials Provider サービスを IAM ロールに指定するための AWS IoT ロールエイリアス
  • 1つの AWS IoT Greengrass のコアデバイス
  • 1つの AWS IoT のモノ

これらのリソースを手動で削除したい場合は、gg-names スクリプトを実行して、リソースの名前を見つけることができます。

自動クリーンアップを行うために、Superfluid ツールを使用することができます。ツールをダウンロードし、以下のコマンドを実行してください。

superfluid greeneyes cleanup THING_NAME

THING_NAMEgg-names で報告されたモノの名前に置き換えます。これは、AWS にモノを問い合わせ、この投稿シリーズのモノに関連するリソースを見つけ、それらを自動的にクリーンアップしてくれます。まず、クリーンアップしたいリソースを表示し、確認のプロンプトを表示した後、リソースをクリーンアップします。また、操作に失敗した場合はログに記録されるので、後でリソースのクリーンアップを行うことができます。

まとめ

この投稿では、AWS IoT Greengrass コンポーネントの開発環境をセットアップしました。Ubuntu VM と Vagrant を使用して、カメラから画像をキャプチャすることができる AWS IoT Greengrass コンポーネントをデプロイしました。VM には USBパススルーがあり、USB Webカメラに接続できます。VM 内のコンポーネントのコードを変更し、それを再デプロイすると、変更内容をすぐに確認することができます。

執筆者について

Tim Mattison は、Amazon Web Services の IoT エコシステムサービスグループにおける Principal Technologist です。元々はファームウェアエンジニアでしたが、Linux カーネルドライバから GUI まで、様々なスタックを渡り歩いてきました。開発者の障害を取り除くことに挑戦することが好きで、常に改善策を探し求めています。主に AWS IoT のコンテンツを担当し、ラピッドプロトタイピングから製品化までの製品ライフサイクルにおいて、複数のサービスを組み合わせる方法を紹介しています。

Nenad Ilic は、10年以上の経験を持つ Internet of Things のスペシャリストです。現在、Amazon Web Services の Senior Developer Advocate として、業界全体の開発者がエッジソフトウエア開発を加速できるよう支援し、他の開発者がコードで自己表現できるようインフラを構築しています。自由時間には、電動スケートボードの実験を行い、その経験をより広いコミュニティと共有しています。

この記事はプロフェッショナルサービス本部 IoT コンサルタントの小林が翻訳しました。