

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# AWS IoT Greengrass バージョン 1 からの移行
<a name="migrate-from-v1"></a>

AWS IoT Greengrass Version 2 は AWS IoT Greengrass Core ソフトウェア、APIs、コンソールのメジャーバージョンリリースです。 AWS IoT Greengrass V2 では、モジュラーアプリケーション AWS IoT Greengrass V1、大規模なデバイスフリートへのデプロイ、追加のプラットフォームのサポートなど、いくつかの改善点が に導入されています。

**注記**  
サポート終了通知: 2026 年 10 月 7 日、 AWS はサポートを終了します AWS IoT Greengrass Version 1。2026 年 10 月 7 日以降、 AWS IoT Greengrass V1 コンソールまたは AWS IoT Greengrass V1 リソースにアクセスできなくなります。

このガイドの指示に従って、 から に移行 AWS IoT Greengrass V1 します AWS IoT Greengrass V2。

## 移行の概要
<a name="migration-overview"></a>

大まかに言うと、次の手順を使用してコアデバイスを から AWS IoT Greengrass V1 にアップグレードできます AWS IoT Greengrass V2。

移行する前に、次の 2 つのランタイムオプションから選択します。
+ **Greengrass nucleus** (移行作業の短縮、フル機能のサポート)
+ **Greengrass nucleus lite** (リソースに制約のあるデバイス向けに設計された、移行作業の向上）。

実行する正確な手順は、デバイスリソース、必要な機能、および特定の環境要件によって異なります。

![\[から に移行する方法の概要 AWS IoT Greengrass V1 AWS IoT Greengrass V2。\]](http://docs.aws.amazon.com/ja_jp/greengrass/v2/developerguide/images/migration-workflow-updated.png)


1. 

**[V1 と V2 の違いを理解](greengrass-v1-concept-differences.md)**

   AWS IoT Greengrass V2 は、デバイスフリートとデプロイ可能なソフトウェアの新しい基本概念を導入し、V2 は V1 からのいくつかの概念を簡素化します。

    AWS IoT Greengrass V2 クラウドサービスおよび AWS IoT Greengrass Core ソフトウェア v2.x は、 AWS IoT Greengrass V1 クラウドサービスおよび AWS IoT Greengrass Core ソフトウェア v1.x と下位互換性がありません。そのため、 AWS IoT Greengrass V1 over-the-air (OTA) の更新では、コアデバイスを V1 から V2 にアップグレードできません。

1. 

**[ランタイム (Greengrass nucleus または Greengrass nucleus lite) を選択します。](choose-runtime.md)**

   デバイスリソースと機能要件に基づいて、Greengrass nucleus と Greengrass nucleus lite のどちらかを決定します。
   + **Greengrass nucleus パス**: 移行の労力を軽減します。Lambda 関数は、最小限のコード変更で Lambda コンポーネントとしてインポートできます。V1 機能 (ローカルシャドウサービス、クライアントデバイス、コネクタ) をサポートします。
   + **Greengrass nucleus ライトパス**: 移行の労力が高くなります。Lambda 関数は汎用コンポーネントに変換する必要があり、 AWS IoT Greengrass Core SDK の代わりに AWS IoT Device SDK V2/AWS IoT Greengrass Component SDK を使用するようにコードを変更する必要があります。ローカルシャドウサービス、クライアントデバイス、またはコネクタはサポートされていません。

1. 

**[V2 で V1 アプリケーションをテストする新しいデバイスをセットアップ](set-up-test-device.md)**

   本番環境のデバイスのリスクを最小限に抑えるには、V2 で V1 アプリケーションをテストする新しいデバイスを作成します。ランタイムの選択に基づいてセットアップガイドを選択します。
   + **オプション A - Greengrass nucleus ランタイム**: [ V2 で V1 アプリケーションをテストするための新しいデバイスをセットアップします](set-up-v2-test-device.md)。最小限のコード変更で Lambda 関数を Lambda コンポーネントとしてインポートします。
   + **オプション B - Greengrass nucleus lite ランタイム**: [ V2 (Greengrass nucleus lite) で V1 アプリケーションをテストするための新しいデバイスをセットアップ](set-up-v2-test-device-lite.md)します。を使用して Lambda 関数を汎用コンポーネントに変換します AWS IoT Device SDK。

1. 

**[V1 コアデバイスをアップグレードして V2 を実行](upgrade-v1-core-devices.md)**

   新しいデバイスでテストしたら、既存の V1 AWS IoT Greengrass コアデバイスをアップグレードして Core ソフトウェア v2.x と AWS IoT Greengrass V2 コンポーネントを実行します。V1 から V2 にデバイスのフリートを移行するには、フリートの各デバイスに対してこの手順を繰り返します。

# AWS IoT Greengrass V1 と AWS IoT Greengrass V2 の違い
<a name="greengrass-v1-concept-differences"></a>

AWS IoT Greengrass V2 ではデバイス、フリート、およびデプロイ可能なソフトウェアに関する新しい基本概念が導入されています。このセクションでは、V2 では異なる V1 の概念について説明します。


**Greengrass の概念と用語**  

| 概念 | AWS IoT Greengrass V1 | AWS IoT Greengrass V2 | 
| --- | --- | --- | 
|  アプリケーションコード  |  AWS IoT Greengrass V1 では、Lambda 関数はコアデバイスで実行されるソフトウェアを定義します。各 Greengrass グループで、関数が使用するサブスクリプションとローカルリソースを定義します。コンテナ化された Lambda ランタイム環境で AWS IoT Greengrass Core ソフトウェアが実行する Lambda 関数については、メモリ制限などのコンテナパラメータを定義します。  |  AWS IoT Greengrass V2 では、コンポーネントは、コアデバイス上で動作するソフトウェアモジュールです。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/greengrass/v2/developerguide/greengrass-v1-concept-differences.html) AWS IoT Greengrass V2 で Lambda ランタイム環境で実行されるコンポーネントとして V1 Lambda 関数をインポートできます。Lambda 関数をインポートするときは、関数のサブスクリプション、ローカルリソース、およびコンテナパラメータを指定します。詳細については、「[ステップ 2: AWS IoT Greengrass V1 アプリケーションを移行する AWS IoT Greengrass V2 コンポーネントを作成してデプロイする](set-up-v2-test-device.md#run-v1-applications)」を参照してください。 カスタムコンポーネントを作成する方法の詳細については、「[AWS IoT Greengrass コンポーネントの開発](develop-greengrass-components.md)」を参照してください。  | 
|  AWS IoT Greengrass グループとデプロイ  |  AWS IoT Greengrass V1 では、グループはコアデバイスや、そのコアデバイスの設定とソフトウェア、およびそのコアデバイスに接続できる AWS IoT のモノのリストを定義します。グループの設定をコアデバイスに送信するデプロイを作成します。  |  AWS IoT Greengrass V2 では、デプロイを使用して、コアデバイスで実行されるソフトウェアコンポーネントと設定を定義します。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/greengrass/v2/developerguide/greengrass-v1-concept-differences.html) 詳細については、「[AWS IoT Greengrass コンポーネントをデバイスにデプロイする](manage-deployments.md)」を参照してください。 AWS IoT Greengrass V2 では、[Greengrass CLI](gg-cli.md) を使用してローカルデプロイを作成して、コンポーネントを開発するデバイスでカスタムソフトウェアコンポーネントをテストすることもできます。詳細については、「[AWS IoT Greengrass コンポーネントを作成する](create-components.md)」を参照してください。  | 
|  AWS IoT Greengrass Core ソフトウェア  |  AWS IoT Greengrass V1 では、AWS IoT Greengrass Core ソフトウェアは、ソフトウェアとそのすべての機能を含む単一のパッケージです。AWS IoT Greengrass Core ソフトウェアをインストールしたエッジデバイスは Greengrass コアと呼ばれます。  |  AWS IoT Greengrass V2 では、AWS IoT Greengrass Core ソフトウェアはモジュール式であるため、メモリフットプリントを制御するために何をインストールするかを選択できます。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/greengrass/v2/developerguide/greengrass-v1-concept-differences.html)  | 
|  Connector  |  AWS IoT Greengrass V1 でのコネクタとは、AWS IoT Greengrass V1 のコアデバイスでローカルインフラストラクチャや、デバイスプロトコル、AWS、その他のクラウドサービスとやり取りが可能なモジュールを指します。  |  AWS IoT Greengrass V2 では、V1 のコネクタによって提供される機能を実装する Greengrass コンポーネントは AWS によって提供されます。以下の AWS IoT Greengrass V2 コンポーネントで Greengrass V1 コネクタ機能が提供されます。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/greengrass/v2/developerguide/greengrass-v1-concept-differences.html) 詳細については、「[AWSが提供したコンポーネント](public-components.md)」を参照してください。  | 
|  接続デバイス (Greengrass デバイス)  |  AWS IoT Greengrass V1 での接続されたデバイスとは、Greengrass グループに追加することで、そのグループ内のコアデバイスに接続し、MQTT 経由で通信する AWS IoT モノを指します。接続デバイスを追加または削除するたびに、そのグループをデプロイする必要があります。サブスクリプションを使用して、接続されたデバイスや AWS IoT Core、コアデバイス上のアプリケーション間でメッセージを中継します。  |  AWS IoT Greengrass V2 では、接続されたデバイスは Greengrass クライアントデバイスと呼ばれます。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/greengrass/v2/developerguide/greengrass-v1-concept-differences.html) AWS IoT Greengrass V1 と AWS IoT Greengrass V2 で接続できるコアデバイスに関する情報を取得するには、デバイスで [FreeRTOS](https://docs.aws.amazon.com/freertos/latest/userguide/freertos-lib-gg-connectivity.html) を実行するか、[AWS IoT Device SDK](https://docs.aws.amazon.com/iot/latest/developerguide/iot-sdks.html) または [Greengrass Discovery API](greengrass-discover-api.md) を使用します。Greengrass Discovery API は下位互換性があるため、V1 コアデバイスに接続するクライアントデバイスがある場合は、コードを変更せずに V2 コアデバイスに接続できます。 デバイスクラスの詳細については、「[ローカル IoT デバイスとやり取りする](interact-with-local-iot-devices.md)」を参照してください。  | 
|  ローカルリソース  |  AWS IoT Greengrass V1 では、コンテナで実行される Lambda 関数を、コアデバイスのファイルシステム上のボリュームとデバイスにアクセスするように設定できます。これらのファイルシステムリソースは、ローカルリソースと呼ばれます。  |  AWS IoT Greengrass V2 では、[Lambda 関数](run-lambda-functions.md)、[Docker コンテナ](run-docker-container.md)、または[ネイティブオペレーティングシステムプロセスまたはカスタムランタイム](develop-greengrass-components.md) のコンポーネントを実行できます。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/greengrass/v2/developerguide/greengrass-v1-concept-differences.html)  | 
|  ローカルシャドウサービス  |  AWS IoT Greengrass V1 では、ローカルシャドウサービスはデフォルトで有効になっており、名前のないクラシックシャドウのみがサポートされています。デバイス上のシャドウとやり取りするには、Lambda 関数の AWS IoT Greengrass Core SDK を使用します。  |  AWS IoT Greengrass V2 では、シャドウマネージャーコンポーネントをデプロイして、ローカルシャドウサービスを有効にします。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/greengrass/v2/developerguide/greengrass-v1-concept-differences.html) 詳細については、「[デバイスシャドウとやり取り](interact-with-shadows.md)」を参照してください。  | 
|  サブスクリプション  |  AWS IoT Greengrass V1 では、Greengrass グループのサブスクリプションを定義して、Lambda関数、コネクタ、接続デバイス、AWS IoT Core MQTT ブローカー、ローカルシャドウサービス間の通信チャネルを指定します。サブスクリプションは、関数ペイロードとして消費するイベントメッセージを Lambda 関数が受け取る場所を指定します。  |  AWS IoT Greengrass V2 では、サブスクリプションを使用せずに通信チャネルを指定します。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/greengrass/v2/developerguide/greengrass-v1-concept-differences.html)  | 
|  他の AWS のサービス へのアクセス  |  AWS IoT Greengrass V1 では、グループロールと呼ばれる AWS Identity and Access Management (IAM) ロールを、Greengrass グループにアタッチします。グループロールは、そのグループのコアデバイス上の Lambda 関数と AWS IoT Greengrass 機能が AWS のサービス にアクセスするために使用する権限を定義します。  |  AWS IoT Greengrass V2 では、AWS IoT のロールエイリアスを Greengrass コアデバイスにアタッチします。ロールエイリアスは、トークン交換ロールと呼ばれる IAM ロールを参照します。トークン交換ロールは、コアデバイス上の Greengrass コンポーネントが AWS のサービス にアクセスするために使用する許可を定義します。詳細については、「[コアデバイスが AWS サービスとやり取りできるように認可する](device-service-role.md)」を参照してください。  | 

# ランタイム (Greengrass nucleus または Greengrass nucleus lite) を選択します。
<a name="choose-runtime"></a>

Greengrass nucleus と Greengrass nucleus lite のどちらを選択するかは、デバイスリソースと Lambda 関数が使用する機能によって異なります。次の表のイベントソースの互換性マトリックスを確認し、決定フロー図を使用して移行に適したランタイムを決定します。Greengrass nucleus と Greengrass nucleus lite の機能の詳細な比較については、[「ランタイムの選択](choosing-your-runtime.md)」を参照してください。

## イベントソースの互換性マトリックス
<a name="event-source-compatibility"></a>

では AWS IoT Greengrass V1、Lambda 関数は、他の Lambda 関数、ローカルシャドウサービス AWS IoT Core、クライアントデバイス、コネクタの 5 種類のイベントソースと通信できます。次の表は、各 V2 ランタイムでサポートされているイベントソースを示しています。

注: イベントソース名は AWS IoT Greengrass V1 用語を使用します。V2 に移行すると、Lambda 関数は Lambda コンポーネント (Greengrass nucleus でのみサポート) または汎用コンポーネント (Greengrass nucleus と Greengrass nucleus lite の両方でサポート) に変換されます。


| イベントソース | Greengrass nucleus | Greengrass nucleus lite | 
| --- | --- | --- | 
|  グループ内の他の Lambda 関数  |  ✓ (Lambda コンポーネントと汎用コンポーネント)  |  ✓ (汎用コンポーネントのみ)  | 
|  AWS IoT Core サービス  |  ✓  |  ✓  | 
|  ローカルシャドウサービス  |  ✓  |  ✗  | 
|  クライアントデバイス  |  ✓  |  ✗  | 
|  コネクタ  |  ✓  |  ✗  | 

## ランタイム選択決定フロー
<a name="runtime-selection-decision-flow"></a>

![\[Greengrass nucleus と Greengrass nucleus lite のどちらかを選択するための決定フロー図。\]](http://docs.aws.amazon.com/ja_jp/greengrass/v2/developerguide/images/runtime-selection-decision-flow.png)


### 注意事項
<a name="runtime-selection-notes"></a>

1. Greengrass nucleus lite の要件と互換性の詳細については、[「Greengrass nucleus lite](greengrass-nucleus-lite-component.md)」を参照してください。Greengrass nucleus lite には最低 5 MB の RAM が必要で、リソースに制約のあるデバイス用に設計されています。

1. 決定フローは、一般的なユースケースに基づくガイダンスを提供しますが、厳密な要件ではありません。リソースに制約のあるデバイスとリソースに十分なデバイスの両方を持つお客様は、一部のデバイスがいずれかのランタイムをサポートできる場合でも、運用を簡素化するためにすべてのデバイスで単一のランタイムを使用することを選択できます。

## 次の手順
<a name="next-steps-runtime"></a>

ランタイムを選択したら、テストデバイスをセットアップします。
+ Greengrass nucleus ランタイムの場合: V[V2 で V1 アプリケーションをテストする新しいデバイスをセットアップする](set-up-v2-test-device.md)
+ Greengrass nucleus lite ランタイムの場合: [Greengrass nucleus lite を使用して新しいデバイスをセットアップ](set-up-v2-test-device-lite.md)する

# V2 で V1 アプリケーションをテストする新しいデバイスをセットアップ
<a name="set-up-test-device"></a>

本番環境のデバイスへのリスクを最小限に抑えるには、本番環境のデバイスをアップグレードする前に、新しいデバイスを作成して V2 で VV1 アプリケーションをテストします。

前のステップで選択したランタイムに基づいて、次のいずれかの設定ガイドを選択します。
+ **オプション A - Greengrass nucleus ランタイム**: Greengrass nucleus [V2 で V1 アプリケーションをテストする新しいデバイスをセットアップ](set-up-v2-test-device.md)を選択した場合はフォローします。このオプションを使用すると、コードの変更を最小限に抑えながら Lambda 関数を Lambda コンポーネントとしてインポートし、ローカルシャドウサービス、クライアントデバイス、コネクタなどの V1 機能をサポートできます。
+ **オプション B - Greengrass nucleus lite ランタイム**: Greengrass nucleus lite [V2 (Greengrass nucleus lite) で V1 アプリケーションをテストする新しいデバイスを設定する](set-up-v2-test-device-lite.md)を選択した場合はフォローします。このオプションでは、 AWS IoT Device SDK V2 またはコンポーネント SDK を使用して Lambda 関数を汎用 AWS IoT Greengrass コンポーネントに変換する必要がありますが、リソースに制約のあるデバイス用に最適化されています。

# V2 で V1 アプリケーションをテストする新しいデバイスをセットアップ
<a name="set-up-v2-test-device"></a>

新しい AWS IoT Greengrass V2 コアデバイスをセットアップして、 AWS IoT Greengrass V1 アプリケーション用に AWS提供されたコンポーネントと AWS Lambda 機能をデプロイしてテストします。この V2 コアデバイスを使用して、コアデバイスでネイティブプロセスを実行する追加のカスタム Greengrass コンポーネントを開発およびテストすることもできます。V2 コアデバイスでアプリケーションをテストした後、既存の V1 コアデバイスを V2 にアップグレードし、V1 機能を提供する V2 コンポーネントをデプロイできます。



## ステップ 1: を新しいデバイスにインストール AWS IoT Greengrass V2 する
<a name="install-v2-test-device"></a>

Core AWS IoT Greengrass ソフトウェア v2.x を新しいデバイスにインストールします。[[getting started tutorial]](getting-started.md) (入門チュートリアル) に従ってデバイスをセットアップし、コンポーネントを開発およびデプロイする方法を学ぶことができます。このチュートリアルでは、[[automatic provisioning]](quick-installation.md) (自動プロビジョニング) を使用して、デバイスをすばやくセットアップできます。 AWS IoT Greengrass Core ソフトウェア v2.x をインストールするときは、[Greengrass CLI ](greengrass-cli-component.md)をデプロイする引`--deploy-dev-tools`数を指定して、デバイス上でコンポーネントを直接開発、テスト、デバッグできるようにします。プロキシの背後で AWS IoT Greengrass Core ソフトウェアをインストールする方法やハードウェアセキュリティモジュール (HSM) を使用する方法など、その他のインストールオプションの詳細については、「」を参照してください[AWS IoT Greengrass Core ソフトウェアをインストールします。](install-greengrass-core-v2.md)。

### (オプション) Amazon CloudWatch Logs へのログ記録を有効にする
<a name="enable-cloudwatch-logging-v2"></a>

V2 コアデバイスが Amazon CloudWatch Logs にログをアップロードできるようにするには、 AWSが提供する[ログマネージャーコンポーネント](log-manager-component.md)をデプロイします。CloudWatch Logs を使用してコンポーネントログを表示できるため、コアデバイスのファイルシステムにアクセスせずにデバッグとトラブルシューティングを行うことができます。詳細については、「[AWS IoT Greengrass ログのモニタリング](monitor-logs.md)」を参照してください。

## ステップ 2: AWS IoT Greengrass V1 アプリケーションを移行する AWS IoT Greengrass V2 コンポーネントを作成してデプロイする
<a name="run-v1-applications"></a>

ほとんどの AWS IoT Greengrass V1 アプリケーションは で実行できます AWS IoT Greengrass V2。Lambda 関数は、 で実行されるコンポーネントとしてインポートでき AWS IoT Greengrass V2、 AWS IoT Greengrass コネクタと同じ機能を提供する [AWSが提供するコンポーネント](public-components.md)を使用できます。

カスタムコンポーネントを開発して、Greengrass コアデバイスで実行する任意の機能またはランタイムをビルドすることもできます。コンポーネントをローカルで開発およびテストする方法の詳細については、「[AWS IoT Greengrass コンポーネントを作成する](create-components.md)」を参照してください。

**Topics**
+ [V1 Lambda 関数をインポートする](#run-v1-lambda-functions)
+ [V1 コネクタを使用する](#use-v1-connectors)
+ [Docker コンテナを実行する](#run-v1-docker-containers)
+ [V1 Greengrass デバイスを接続する](#connect-v1-greengrass-devices)
+ [ローカルシャドウサービスを有効にする](#enable-shadow-service)
+ [との統合 AWS IoT SiteWise](#integrate-with-iot-sitewise)

### V1 Lambda 関数をインポートする
<a name="run-v1-lambda-functions"></a>

Lambda 関数を AWS IoT Greengrass V2 コンポーネントとしてインポートできます。以下のアプローチのいずれかを選択できます。
+ V1 Lambda 関数を Greengrass コンポーネントとして直接インポートします。
+ Lambda 関数を更新して v2 AWS IoT Device SDK の Greengrass ライブラリを使用し、Lambda 関数を Greengrass コンポーネントとしてインポートします。
+ Lambda 以外のコードと AWS IoT Device SDK v2 を使用して、Lambda 関数と同じ機能を実装するカスタムコンポーネントを作成します。

Lambda 関数がストリームマネージャーやローカルシークレットなどの機能を使用する場合は、これらの機能をパッケージ化する AWSが提供するコンポーネントへの依存関係を定義する必要があります。Lambda 関数コンポーネントをデプロイすると、依存関係として定義する各機能のコンポーネントもデプロイに含まれます。デプロイでは、コアデバイスにデプロイするシークレットなどのパラメータを設定できます。V1 のすべての機能で、V2 の Lambda 関数にコンポーネントの依存関係が必要なわけではありません。次のリストは、V2 Lambda 関数コンポーネントで V1 機能を使用する方法を示しています。 V2 
+ **他の AWS サービスにアクセスする**

  Lambda 関数が AWS 認証情報を使用して他の AWS サービスにリクエストを行う場合、コアデバイスのトークン交換ロールは、Lambda 関数が使用する AWS オペレーションの実行をコアデバイスに許可する必要があります。詳細については、「[コアデバイスが AWS サービスとやり取りできるように認可する](device-service-role.md)」を参照してください。
+ **ストリームマネージャー**

  Lambda 関数がストリームマネージャーを使用している場合は、関数をインポートするときのコンポーネントの依存関係として `aws.greengrass.StreamManager` を指定します。ストリームマネージャーコンポーネントをデプロイするときに、ターゲットコアデバイスに設定するストリームマネージャーパラメータを指定します。コアデバイスのトークン交換ロールは、コアデバイスがストリームマネージャーで使用する AWS クラウド 送信先にアクセスすることを許可する必要があります。詳細については、「[ストリームマネージャー](stream-manager-component.md)」を参照してください。
+ **ローカルシークレット**

  Lambda 関数がローカルシークレットを使用している場合は、関数をインポートするときのコンポーネントの依存関係として `aws.greengrass.SecretManager` を指定します。シークレットマネージャーコンポーネントをデプロイするときは、ターゲットコアデバイスにデプロイするシークレットリソースを指定します。コアデバイスのトークン交換ロールは、コアデバイスがデプロイするシークレットリソースを取得できるようにする必要があります。詳細については、「[シークレットマネージャー](secret-manager-component.md)」を参照してください。

  Lambda 関数コンポーネントをデプロイするときは、 AWS IoT Device SDK V2 で [GetSecretValue ](ipc-secret-manager.md) [IPC オペレーションを使用するアクセス許可を付与する IPC 認可ポリシー](interprocess-communication.md#ipc-authorization-policies)を持つように設定します。
+ **ローカルシャドウ**

  Lambda 関数がローカルシャドウとやり取りする場合は、 AWS IoT Device SDK V2 を使用するように Lambda 関数コードを更新する必要があります。また、関数をインポートするときのコンポーネントの依存関係として `aws.greengrass.ShadowManager` を指定する必要があります。詳細については、「[デバイスシャドウとやり取り](interact-with-shadows.md)」を参照してください。

  Lambda 関数コンポーネントをデプロイするときは、 AWS IoT Device SDK V2 でシャ[ドウ](ipc-local-shadows.md) [IPC オペレーションを使用するアクセス許可を付与する IPC 認可ポリシー](interprocess-communication.md#ipc-authorization-policies)を持つように設定します。
+ **サブスクリプション**
  + Lambda 関数がクラウドソースからのメッセージをサブスクライブする場合は、関数をインポートするときにそれらのサブスクリプションをイベントソースとして指定します。
  + Lambda 関数が別の Lambda 関数からのメッセージをサブスクライブする場合、または Lambda 関数が AWS IoT Core 他の Lambda 関数にメッセージを発行する場合は、Lambda 関数をデプロイするときに[レガシーサブスクリプションルーターコンポーネント](legacy-subscription-router-component.md)を設定してデプロイします。レガシーサブスクリプションルーターコンポーネントをデプロイするときは、Lambda 関数が使用するサブスクリプションを指定します。
**注記**  <a name="legacy-subscription-router-requirement-note"></a>
レガシーサブスクリプションルーターコンポーネントは、Lambda 関数が AWS IoT Greengrass Core SDK で `publish()`関数を使用する場合にのみ必要です。 AWS IoT Device SDK V2 でプロセス間通信 (IPC) インターフェイスを使用するように Lambda 関数コードを更新する場合、レガシーサブスクリプションルーターコンポーネントをデプロイする必要はありません。詳細については、次の[プロセス間通信](interprocess-communication.md)サービスを参照してください。  
[ローカルメッセージをパブリッシュ/サブスクライブする](ipc-publish-subscribe.md)
[AWS IoT Core MQTT メッセージを発行/サブスクライブする](ipc-iot-core-mqtt.md)
  + Lambda 関数がローカルに接続されたデバイスからのメッセージをサブスクライブする場合は、関数をインポートするときにそれらのサブスクリプションをイベントソースとして指定します。また、接続されたデバイスからイベントソースとして指定したローカルのパブリッシュ/サブスクライブトピックにメッセージを中継するために、[MQTT ブリッジコンポーネント](mqtt-bridge-component.md)を設定およびデプロイする必要があります。
  + Lambda 関数がローカル接続デバイスにメッセージを発行する場合は、 AWS IoT Device SDK V2 を使用して[ローカル発行/サブスクライブメッセージを発行](ipc-publish-subscribe.md)するように Lambda 関数コードを更新する必要があります。また、ローカルのパブリッシュ/サブスクライブメッセージブローカーから接続されたデバイスにメッセージを中継するために、[[MQTT bridge component]](mqtt-bridge-component.md) (MQTT ブリッジコンポーネント) を設定およびデプロイする必要があります。
+ **ローカルボリュームとデバイス**

  コンテナ化された Lambda 関数がローカルボリュームまたはデバイスにアクセスする場合は、Lambda 関数をインポートするときにそれらのボリュームとデバイスを指定します。この機能では、コンポーネントの依存関係は必要ありません。

詳細については、「[AWS Lambda 関数を実行する](run-lambda-functions.md)」を参照してください。

### V1 コネクタを使用する
<a name="use-v1-connectors"></a>

一部の AWS IoT Greengrass コネクタと同じ機能を提供する AWSが提供するコンポーネントをデプロイできます。デプロイを作成するときに、コネクタのパラメータを設定できます。

以下の AWS IoT Greengrass V2 コンポーネントは Greengrass V1 コネクタ機能を提供します。
+ [CloudWatch メトリクスのコンポーネント](cloudwatch-metrics-component.md)
+ [AWS IoT Device Defender コンポーネント](device-defender-component.md)
+ [Firehose コンポーネント](kinesis-firehose-component.md)
+ [Modbus-RTU プロトコルアダプタコンポーネント](modbus-rtu-protocol-adapter-component.md)
+ [Amazon SNS コンポーネント](sns-component.md)

### Docker コンテナを実行する
<a name="run-v1-docker-containers"></a>

AWS IoT Greengrass V2 は、V1 Docker アプリケーションデプロイコネクタを直接置き換えるコンポーネントを提供しません。ただし、Docker アプリケーションマネージャーコンポーネントを使用して Docker イメージをダウンロードし、ダウンロードしたイメージから Docker コンテナを実行するカスタムコンポーネントを作成できます。詳細については、「[Docker コンテナの実行](run-docker-container.md)」および「[Docker アプリケーションマネージャー](docker-application-manager-component.md)」を参照してください。

### V1 Greengrass デバイスを接続する
<a name="connect-v1-greengrass-devices"></a>

の接続されたデバイスは AWS IoT Greengrass V1 、 のクライアントデバイスと呼ばれます AWS IoT Greengrass V2。クライアントデバイスの AWS IoT Greengrass V2 サポートは と下位互換性があるため AWS IoT Greengrass V1、アプリケーションコードを変更せずに V1 クライアントデバイスを V2 コアデバイスに接続できます。クライアントデバイスが V2 コアデバイスに接続できるようにするには、クライアントデバイスのサポートを有効にする Greengrass コンポーネントをデプロイし、クライアントデバイスをコアデバイスに関連付けます。クライアントデバイス、 AWS IoT Core クラウドサービス、Greengrass コンポーネント (Lambda 関数を含む) 間でメッセージを中継するには、[[MQTT bridge component]](mqtt-bridge-component.md) (MQTT ブリッジコンポーネント) をデプロイおよび設定します。[[IP detector component]](ip-detector-component.md) (IP 検出コンポーネント) をデプロイして接続情報を自動検出することも、エンドポイントを手動で管理することも可能です。詳細については、「[ローカル IoT デバイスとやり取りする](interact-with-local-iot-devices.md)」を参照してください。

### ローカルシャドウサービスを有効にする
<a name="enable-shadow-service"></a>

では AWS IoT Greengrass V2、ローカルシャドウサービスは、 AWSが提供するシャドウマネージャーコンポーネントによって実装されます。 には、名前付きシャドウのサポート AWS IoT Greengrass V2 も含まれています。コンポーネントがローカルシャドウとやり取りし、シャドウの状態を に同期できるようにするには AWS IoT Core、シャドウマネージャーコンポーネントを設定してデプロイし、コンポーネントコードでシャドウ IPC オペレーションを使用します。詳細については、「[デバイスシャドウとやり取り](interact-with-shadows.md)」を参照してください。

### との統合 AWS IoT SiteWise
<a name="integrate-with-iot-sitewise"></a>

V1 コアデバイスを AWS IoT SiteWise ゲートウェイとして使用する場合は、[手順に従って](https://docs.aws.amazon.com/iot-sitewise/latest/userguide/configure-gateway-ggv2.html)新しい V2 コアデバイスを AWS IoT SiteWise ゲートウェイとしてセットアップします。 AWS IoT SiteWise には、 AWS IoT SiteWise コンポーネントをデプロイするインストールスクリプトが用意されています。

## ステップ 3: AWS IoT Greengrass V2 アプリケーションをテストする
<a name="test-v2-features"></a>

V2 コンポーネントを作成して新しい V2 コアデバイスにデプロイしたら、アプリケーションが期待を満たしていることを確認します。デバイスのログをチェックして、コンポーネントの標準出力 (stdout) および標準エラー (stderr) メッセージを表示できます。詳細については、「[AWS IoT Greengrass ログのモニタリング](monitor-logs.md)」を参照してください。

[Greengrass CLI](greengrass-cli-component.md) をコアデバイスにデプロイした場合は、それを使用してコンポーネントとその設定をデバッグできます。詳細については、「[Greengrass CLI コマンド](gg-cli-reference.md)」を参照してください。

アプリケーションが V2 コアデバイスで動作することを確認したら、アプリケーションの Greengrass コンポーネントを他のコアデバイスにデプロイできます。ネイティブプロセスまたは Docker コンテナを実行するカスタムコンポーネントを開発した場合は、まず[それらのコンポーネントをサービスに公開](publish-components.md)して、他のコアデバイスにデプロイする必要があります。 AWS IoT Greengrass 

# V2 (Greengrass nucleus lite) で V1 アプリケーションをテストする新しいデバイスを設定する
<a name="set-up-v2-test-device-lite"></a>

Greengrass nucleus lite を使用して新しいデバイスをセットアップし、 AWS IoT Greengrass V1 アプリケーションを V2 に移行するために作成する汎用コンポーネントをテストします。Greengrass nucleus lite は、リソースに制約のあるデバイス用に最適化された軽量ランタイムです。このデバイスを使用して、ネイティブプロセスを実行するカスタム Greengrass コンポーネントを開発およびテストできます。Greengrass nucleus lite デバイスでアプリケーションをテストしたら、Greengrass nucleus lite を実行している他のデバイスに V2 コンポーネントをデプロイするか、既存の V1 コアデバイスを V2 にアップグレードできます。



## ステップ 1: 新しいデバイスに Greengrass nucleus lite をインストールする
<a name="lite-step-1-install"></a>

Greengrass nucleus lite を新しいデバイスにインストールします。[Greengrass nucleus lite のインストールガイド](https://docs.aws.amazon.com/greengrass/v2/developerguide/greengrass-nucleus-lite-component.html#greengrass-nucleus-lite-component-install)に従ってデバイスをセットアップします。

**注記**  
Greengrass nucleus lite は現在、ローカルシャドウサービス、クライアントデバイス、またはコネクタをサポートしていません。このガイドに進む前に、V1 アプリケーションがこれらの機能に依存していないことを確認してください。

## ステップ 2: AWS IoT Greengrass V1 Lambda 関数を移行するための汎用コンポーネントを作成してデプロイする
<a name="lite-step-2-convert-lambda"></a>

Greengrass nucleus lite で AWS IoT Greengrass V1 Lambda 関数の機能をレプリケートするには、汎用コンポーネントに変換する必要があります。これには、 AWS IoT Greengrass Core SDK の代わりに AWS IoT Device SDK V2 または AWS IoT Greengrass コンポーネント SDK を使用するように Lambda 関数コードを書き換えることが含まれます。

次の表に、このガイドの V2 コンポーネントの例で使用される SDKs を示します。


| SDK | 最小バージョン | 
| --- | --- | 
| [AWS IoT Device SDK for Python v2](https://github.com/aws/aws-iot-device-sdk-python-v2) | v1.11.3 | 
| [AWS IoT Device SDK for Java v2](https://github.com/aws/aws-iot-device-sdk-java-v2) | v1.9.3 | 
| [AWS IoT Device SDK for JavaScript v2](https://github.com/aws/aws-iot-device-sdk-js-v2) | v1.12.0 | 
| [AWS IoT Greengrass コンポーネント SDK (C/C\$1\$1)](https://github.com/aws-greengrass/aws-greengrass-component-sdk) (現在プレビュー中) | v0.4.0 | 

以下の例は、 AWS IoT Greengrass V1 Core SDK と同等の汎用コンポーネントを使用する Lambda 関数を示しています。2 つの主なシナリオでは、コンポーネントコード、レシピ、ビルド手順が複数のプログラミング言語で記述されています。
+ **ローカル通信** - ローカル pub/sub を使用して同じデバイス上の他のコンポーネントと通信するコンポーネント
+ **クラウド通信** - AWS IoT Core または他の AWS サービスと通信するコンポーネント

### シナリオ 1: ローカル通信 (パブリッシャー → プロセッサ → サブスクライバー)
<a name="lite-example-local-communication"></a>

このシナリオでは、ローカル pub/sub 通信を使用する V1 Lambda 関数を V2 汎用コンポーネントに変換する方法を示します。

#### アプリケーションのアーキテクチャ
<a name="lite-example-1-scenario"></a>

この例では、次の 3 つのコンポーネントを使用します。
+ パブリッシャー Lambda が温度データを公開する
+ プロセッサ Lambda がデータを受信して処理する
+ プロセッサ Lambda が処理結果をサブスクライバー Lambda に発行する

以下のコード例は、ローカル通信のメッセージのサブスクライブと発行の両方を示すプロセッサ Lambda に焦点を当てています。

##### V1 グループのサブスクリプション
<a name="lite-example-1-v1-subscriptions"></a>

では AWS IoT Greengrass V1、次のグループサブスクリプションにより、Lambda 関数間の通信が有効になります。

サブスクリプション 1: パブリッシャー → プロセッサ
+ ソース: Lambda (パブリッシャー)
+ ターゲット: Lambda (プロセッサ)
+ トピック: センサー/温度

サブスクリプション 2: プロセッサ → サブスクライバー
+ ソース: Lambda (プロセッサ)
+ ターゲット: Lambda (サブスクライバー)
+ トピック: Lambda/アラート

#### Processor Lambda 関数 (V1)
<a name="lite-example-1-v1-code"></a>

------
#### [ Python ]

```
import greengrasssdk
import json

iot_client = greengrasssdk.client('iot-data')

def lambda_handler(event, context):
    """
    Receives temperature from publisher Lambda,
    processes it, and forwards to subscriber Lambda
    """
    # Receive from publisher Lambda.
    sensor_id = event['sensor_id']
    temperature = event['temperature']
    
    print(f"Received from sensor {sensor_id}: {temperature}°F")
    
    # Process: Check if temperature is high.
    if temperature > 80:
        alert_data = {
            'sensor_id': sensor_id,
            'temperature': temperature,
            'alert': 'HIGH_TEMPERATURE'
        }
        
        # Publish to another Lambda using greengrasssdk.
        iot_client.publish(
            topic='lambda/alerts',
            payload=json.dumps(alert_data)
        )
        
        print(f"Alert sent to subscriber Lambda")
    
    return {'statusCode': 200}
```

------
#### [ Java ]

```
import com.amazonaws.greengrass.javasdk.IotDataClient;
import com.amazonaws.greengrass.javasdk.model.PublishRequest;
import com.amazonaws.services.lambda.runtime.Context;
import com.google.gson.Gson;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class TemperatureProcessorLambda {
    private static final Gson gson = new Gson();
    private final IotDataClient iotDataClient;

    public TemperatureProcessorLambda() {
        this.iotDataClient = new IotDataClient();
    }

    public String handleRequest(Map<String, Object> event, Context context) {
        /*
         * Receives temperature from publisher Lambda,
         * processes it, and forwards to subscriber Lambda
         */

        // Receive from publisher Lambda.
        String sensorId = (String) event.get("sensor_id");
        Number temp = (Number) event.get("temperature");
        int temperature = temp.intValue();

        System.out.println("Received from sensor " + sensorId + ": " + temperature + "°F");

        // Process: Check if temperature is high.
        if (temperature > 80) {
            Map<String, Object> alertData = new HashMap<>();
            alertData.put("sensor_id", sensorId);
            alertData.put("temperature", temperature);
            alertData.put("alert", "HIGH_TEMPERATURE");

            // Publish to another Lambda using greengrasssdk.
            String payload = gson.toJson(alertData);
            PublishRequest publishRequest = new PublishRequest()
                .withTopic("lambda/alerts")
                .withPayload(ByteBuffer.wrap(payload.getBytes(StandardCharsets.UTF_8)));

            iotDataClient.publish(publishRequest);

            System.out.println("Alert sent to subscriber Lambda");
        }

        return "Success";
    }
}
```

------
#### [ JavaScript ]

```
const greengrasssdk = require('aws-greengrass-core-sdk');

const iotClient = new greengrasssdk.IotData();

/**
 * Greengrass v1 Lambda function
 * Receives temperature from publisher Lambda,
 * processes it, and forwards to subscriber Lambda
 */
exports.handler = function(event, context) {
    // Receive from publisher Lambda.
    const sensorId = event.sensor_id;
    const temperature = event.temperature;
    
    console.log(`Received from sensor ${sensorId}: ${temperature}°F`);
    
    // Process: Check if temperature is high.
    if (temperature > 80) {
        const alertData = {
            sensor_id: sensorId,
            temperature: temperature,
            alert: 'HIGH_TEMPERATURE'
        };
        
        // Publish to another Lambda using greengrasssdk.
        const params = {
            topic: 'lambda/alerts',
            payload: JSON.stringify(alertData)
        };
        
        iotClient.publish(params, (err) => {
            if (err) {
                console.error('Error publishing alert:', err);
                context.fail(err);
            } else {
                console.log('Alert sent to subscriber Lambda');
                context.succeed('Success');
            }
        });
    } else {
        context.succeed('Success');
    }
};
```

------
#### [ C ]

```
#include <aws/greengrass/greengrasssdk.h>
#include <stdio.h>
#include <string.h>
#include <jansson.h>  // For JSON parsing.

static aws_greengrass_iot_data_client *iot_client = NULL;

void on_message_received(const char *topic, const uint8_t *payload, size_t payload_len, void *user_data) {
    // Parse the incoming message.
    char *payload_str = strndup((char *)payload, payload_len);
    json_error_t error;
    json_t *event = json_loads(payload_str, 0, &error);
    free(payload_str);
    
    if (!event) {
        fprintf(stderr, "Error parsing JSON: %s\n", error.text);
        return;
    }
    
    // Receive from publisher Lambda.
    json_t *sensor_id_obj = json_object_get(event, "sensor_id");
    json_t *temperature_obj = json_object_get(event, "temperature");
    
    const char *sensor_id = json_string_value(sensor_id_obj);
    int temperature = json_integer_value(temperature_obj);
    
    printf("Received from sensor %s: %d°F\n", sensor_id, temperature);
    
    // Process: Check if temperature is high.
    if (temperature > 80) {
        // Create alert data.
        json_t *alert_data = json_object();
        json_object_set_new(alert_data, "sensor_id", json_string(sensor_id));
        json_object_set_new(alert_data, "temperature", json_integer(temperature));
        json_object_set_new(alert_data, "alert", json_string("HIGH_TEMPERATURE"));
        
        // Convert to JSON string.
        char *alert_payload = json_dumps(alert_data, JSON_COMPACT);
        
        // Publish to another Lambda using greengrasssdk.
        aws_greengrass_publish_params params = {
            .topic = "lambda/alerts",
            .payload = (uint8_t *)alert_payload,
            .payload_len = strlen(alert_payload)
        };
        
        aws_greengrass_iot_data_publish(iot_client, &params);
        
        printf("Alert sent to subscriber Lambda\n");
        
        free(alert_payload);
        json_decref(alert_data);
    }
    
    json_decref(event);
}

int main(int argc, char *argv[]) {
    // Initialize Greengrass SDK.
    iot_client = aws_greengrass_iot_data_client_new();
    
    // Subscribe to temperature sensor topic.
    aws_greengrass_subscribe_params subscribe_params = {
        .topic = "sensors/temperature",
        .callback = on_message_received,
        .user_data = NULL
    };
    
    aws_greengrass_iot_data_subscribe(iot_client, &subscribe_params);
    
    printf("Temperature Processor Lambda started\n");
    printf("Subscribed to sensors/temperature\n");
    printf("Waiting for sensor data...\n");
    
    // Keep the Lambda running.
    while (1) {
        sleep(1);
    }
    
    return 0;
}
```

------
#### [ C\$1\$1 ]

```
#include <aws/greengrass/greengrasssdk.h>
#include <iostream>
#include <string>
#include <memory>
#include <jansson.h> // For JSON parsing.
#include <unistd.h>

class TemperatureProcessor {
private:
    std::unique_ptr<aws_greengrass_iot_data_client, 
                    decltype(&aws_greengrass_iot_data_client_destroy)> iot_client;
    
    static void message_callback_wrapper(const char *topic, 
                                        const uint8_t *payload, 
                                        size_t payload_len, 
                                        void *user_data) {
        auto* processor = static_cast<TemperatureProcessor*>(user_data);
        processor->on_message_received(topic, payload, payload_len);
    }

public:
    TemperatureProcessor() 
        : iot_client(aws_greengrass_iot_data_client_new(), 
                     aws_greengrass_iot_data_client_destroy) {
        if (!iot_client) {
            throw std::runtime_error("Failed to create Greengrass IoT client");
        }
    }

    void on_message_received(const char *topic, 
                            const uint8_t *payload, 
                            size_t payload_len) {
        // Parse the incoming message.
        std::string payload_str(reinterpret_cast<const char*>(payload), payload_len);
        
        json_error_t error;
        json_t *event = json_loads(payload_str.c_str(), 0, &error);
        
        if (!event) {
            std::cerr << "Error parsing JSON: " << error.text << std::endl;
            return;
        }

        json_t *sensor_id_obj = json_object_get(event, "sensor_id");
        json_t *temperature_obj = json_object_get(event, "temperature");
        
        const char *sensor_id = json_string_value(sensor_id_obj);
        int temperature = json_integer_value(temperature_obj);
        
        std::cout << "Received from sensor " << sensor_id 
                  << ": " << temperature << "°F" << std::endl;

        if (temperature > 80) {
            send_alert(sensor_id, temperature);
        }

        json_decref(event);
    }

    void send_alert(const char *sensor_id, int temperature) {
        // Create alert data.
        json_t *alert_data = json_object();
        json_object_set_new(alert_data, "sensor_id", json_string(sensor_id));
        json_object_set_new(alert_data, "temperature", json_integer(temperature));
        json_object_set_new(alert_data, "alert", json_string("HIGH_TEMPERATURE"));

        // Convert to JSON string.
        char *alert_payload = json_dumps(alert_data, JSON_COMPACT);

        // Publish to another Lambda using greengrasssdk.
        aws_greengrass_publish_params params = {
            .topic = "lambda/alerts",
            .payload = reinterpret_cast<uint8_t*>(alert_payload),
            .payload_len = strlen(alert_payload)
        };
        
        aws_greengrass_iot_data_publish(iot_client.get(), &params);
        
        std::cout << "Alert sent to subscriber Lambda" << std::endl;

        free(alert_payload);
        json_decref(alert_data);
    }

    void subscribe_to_topic(const std::string& topic) {
        aws_greengrass_subscribe_params subscribe_params = {
            .topic = topic.c_str(),
            .callback = message_callback_wrapper,
            .user_data = this
        };
        
        aws_greengrass_iot_data_subscribe(iot_client.get(), &subscribe_params);
        
        std::cout << "Temperature Processor Lambda started" << std::endl;
        std::cout << "Subscribed to " << topic << std::endl;
        std::cout << "Waiting for sensor data..." << std::endl;
    }

    void run() {
        // Keep the Lambda running.
        while (true) {
            sleep(1);
        }
    }
};

int main(int argc, char *argv[]) {
    try {
        TemperatureProcessor processor;
        processor.subscribe_to_topic("sensors/temperature");
        processor.run();
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        return 1;
    }
    
    return 0;
}
```

------

#### 汎用コンポーネント (V2)
<a name="lite-example-1-v2-code"></a>

で同じ機能を実現するには AWS IoT Greengrass V2、以下を使用して汎用コンポーネントを作成します。

##### 1. コンポーネントコード
<a name="lite-example-1-component-code"></a>

------
#### [ Python ]

前提条件: このコンポーネントコードを使用する前に、Greengrass デバイスに AWS IoT Device SDK for Python をインストールして検証します。

```
# Install the SDK
pip3 install awsiotsdk

# Verify installation
python3 -c "import awsiot.greengrasscoreipc.clientv2; print('SDK installed successfully')"
```

インストール中に依存関係の競合が発生した場合は、 の特定のバージョンをインストールしてみてください AWS IoT Device SDK。

検証コマンドで「SDK が正常にインストールされました」と表示される場合は、コンポーネントコードを使用する準備が整います。

```
from awsiot.greengrasscoreipc.clientv2 import GreengrassCoreIPCClientV2
from awsiot.greengrasscoreipc.model import (
    PublishMessage,
    JsonMessage
)
import time

ipc_client = GreengrassCoreIPCClientV2()

def on_sensor_data(event):
    """
    Receives temperature from sensor publisher component,
    processes it, and forwards to alert component
    """
    try:
        # Receive from publisher component.
        data = event.json_message.message
        sensor_id = data['sensor_id']
        temperature = data['temperature']
        
        print(f"Received from sensor {sensor_id}: {temperature}°F")
        
        # Process: Check if temperature is high.
        if temperature > 80:
            alert_data = {
                'sensor_id': sensor_id,
                'temperature': temperature,
                'alert': 'HIGH_TEMPERATURE'
            }
            
            # Publish to another component (AlertHandler).
            ipc_client.publish_to_topic(
                topic='component/alerts',
                publish_message=PublishMessage(
                    json_message=JsonMessage(message=alert_data)
                )
            )
            
            print(f"Alert sent to AlertHandler component")
    
    except Exception as e:
        print(f"Error processing sensor data: {e}")

def main():
    print("Temperature Processor component starting...")
    
    # Subscribe to sensor data from publisher component.
    ipc_client.subscribe_to_topic(
        topic='sensors/temperature',
        on_stream_event=on_sensor_data
    )
    
    print("Subscribed to sensors/temperature")
    print("Waiting for sensor data...")
    
    # Keep running.
    while True:
        time.sleep(1)

if __name__ == '__main__':
    main()
```

------
#### [ Java ]

```
import software.amazon.awssdk.aws.greengrass.GreengrassCoreIPCClientV2;
import software.amazon.awssdk.aws.greengrass.model.PublishMessage;
import software.amazon.awssdk.aws.greengrass.model.PublishToTopicRequest;
import software.amazon.awssdk.aws.greengrass.model.JsonMessage;
import software.amazon.awssdk.aws.greengrass.model.SubscribeToTopicRequest;
import software.amazon.awssdk.aws.greengrass.model.SubscriptionResponseMessage;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

public class TemperatureProcessor {
    private static GreengrassCoreIPCClientV2 ipcClient;

    public static void main(String[] args) {
        System.out.println("Temperature Processor component starting...");

        try (GreengrassCoreIPCClientV2 client = GreengrassCoreIPCClientV2.builder().build()) {
            ipcClient = client;

            SubscribeToTopicRequest subscribeRequest = new SubscribeToTopicRequest()
                .withTopic("sensors/temperature");

            ipcClient.subscribeToTopic(
                subscribeRequest, 
                TemperatureProcessor::onSensorData,
                Optional.empty(),
                Optional.empty()
            );

            System.out.println("Subscribed to sensors/temperature");
            System.out.println("Waiting for sensor data...");

            while (true) {
                Thread.sleep(1000);
            }
        } catch (Exception e) {
            System.err.println("Error: " + e.getMessage());
            e.printStackTrace();
        }
    }

    public static void onSensorData(SubscriptionResponseMessage message) {
        try {
            Map<String, Object> data = message.getJsonMessage().getMessage();
            String sensorId = (String) data.get("sensor_id");
            Number temp = (Number) data.get("temperature");
            int temperature = temp.intValue();

            System.out.println("Received from sensor " + sensorId + ": " + temperature + "F");

            if (temperature > 80) {
                Map<String, Object> alertData = new HashMap<>();
                alertData.put("sensor_id", sensorId);
                alertData.put("temperature", temperature);
                alertData.put("alert", "HIGH_TEMPERATURE");

                JsonMessage jsonMessage = new JsonMessage().withMessage(alertData);
                PublishMessage publishMessage = new PublishMessage().withJsonMessage(jsonMessage);
                PublishToTopicRequest publishRequest = new PublishToTopicRequest()
                    .withTopic("component/alerts")
                    .withPublishMessage(publishMessage);

                ipcClient.publishToTopic(publishRequest);
                System.out.println("Alert sent to AlertHandler component");
            }
        } catch (Exception e) {
            System.err.println("Error processing sensor data: " + e.getMessage());
        }
    }
}
```

------
#### [ JavaScript ]

```
const greengrasscoreipc = require('aws-iot-device-sdk-v2').greengrasscoreipc;

class TemperatureProcessor {
    constructor() {
        this.ipcClient = null;
    }

    async start() {
        console.log('Temperature Processor component starting...');
        
        try {
            this.ipcClient = greengrasscoreipc.createClient();
            await this.ipcClient.connect();
            
            const subscribeRequest = {
                topic: 'sensors/temperature'
            };

            const streamingOperation = this.ipcClient.subscribeToTopic(subscribeRequest);
            
            streamingOperation.on('message', (message) => {
                this.onSensorData(message);
            });
            
            streamingOperation.on('streamError', (error) => {
                console.error('Stream error:', error);
            });
            
            streamingOperation.on('ended', () => {
                console.log('Subscription stream ended');
            });
            
            await streamingOperation.activate();
            
            console.log('Subscribed to sensors/temperature');
            console.log('Waiting for sensor data...');
            
        } catch (error) {
            console.error('Error starting component:', error);
            process.exit(1);
        }
    }

    async onSensorData(message) {
        try {
            const data = message.jsonMessage.message;
            
            const sensorId = data.sensor_id;
            const temperature = data.temperature;
            
            console.log(`Received from sensor ${sensorId}: ${temperature}°F`);
            
            if (temperature > 80) {
                const alertData = {
                    sensor_id: sensorId,
                    temperature: temperature,
                    alert: 'HIGH_TEMPERATURE'
                };
                
                const publishRequest = {
                    topic: 'component/alerts',
                    publishMessage: {
                        jsonMessage: {
                            message: alertData
                        }
                    }
                };
                
                await this.ipcClient.publishToTopic(publishRequest);
                console.log('Alert sent to AlertHandler component');
            }
            
        } catch (error) {
            console.error('Error processing sensor data:', error);
        }
    }
}

// Start the component.
const processor = new TemperatureProcessor();
processor.start();
```

------
#### [ C ]

```
#include <gg/buffer.h>
#include <gg/error.h>
#include <gg/ipc/client.h>
#include <gg/map.h>
#include <gg/object.h>
#include <gg/sdk.h>
#include <unistd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

#define SUBSCRIBE_TOPIC "sensors/temperature"
#define PUBLISH_TOPIC "component/alerts"

typedef struct {
    char sensor_id[64];
    int64_t temperature;
} AlertData;

static pthread_mutex_t alert_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t alert_cond = PTHREAD_COND_INITIALIZER;
static AlertData pending_alert;
static bool has_pending_alert = false;

static void *alert_publisher_thread(void *arg) {
    (void) arg;
    
    while (true) {
        pthread_mutex_lock(&alert_mutex);
        while (!has_pending_alert) {
            pthread_cond_wait(&alert_cond, &alert_mutex);
        }
        
        AlertData alert = pending_alert;
        has_pending_alert = false;
        pthread_mutex_unlock(&alert_mutex);
        
        GgBuffer sensor_id_buf = { .data = (uint8_t *)alert.sensor_id, .len = strlen(alert.sensor_id) };
        GgMap payload = GG_MAP(
            gg_kv(GG_STR("sensor_id"), gg_obj_buf(sensor_id_buf)),
            gg_kv(GG_STR("temperature"), gg_obj_i64(alert.temperature)),
            gg_kv(GG_STR("alert"), gg_obj_buf(GG_STR("HIGH_TEMPERATURE")))
        );
        
        GgError ret = ggipc_publish_to_topic_json(GG_STR(PUBLISH_TOPIC), payload);
        
        if (ret != GG_ERR_OK) {
            fprintf(stderr, "Failed to publish alert\n");
        } else {
            printf("Alert sent to AlertHandler component\n");
        }
    }
    
    return NULL;
}

static void on_sensor_data(
    void *ctx, GgBuffer topic, GgObject payload, GgIpcSubscriptionHandle handle
) {
    (void) ctx;
    (void) topic;
    (void) handle;
    
    if (gg_obj_type(payload) != GG_TYPE_MAP) {
        fprintf(stderr, "Expected JSON message\n");
        return;
    }
    
    GgMap map = gg_obj_into_map(payload);
    
    GgObject *sensor_id_obj;
    if (!gg_map_get(map, GG_STR("sensor_id"), &sensor_id_obj)) {
        fprintf(stderr, "Missing sensor_id field\n");
        return;
    }
    GgBuffer sensor_id = gg_obj_into_buf(*sensor_id_obj);
    
    GgObject *temperature_obj;
    if (!gg_map_get(map, GG_STR("temperature"), &temperature_obj)) {
        fprintf(stderr, "Missing temperature field\n");
        return;
    }
    int64_t temperature = gg_obj_into_i64(*temperature_obj);
    
    printf("Received from sensor %.*s: %lld°F\n", 
           (int)sensor_id.len, sensor_id.data, (long long)temperature);
    
    if (temperature > 80) {
        pthread_mutex_lock(&alert_mutex);
        snprintf(pending_alert.sensor_id, sizeof(pending_alert.sensor_id),
                 "%.*s", (int)sensor_id.len, sensor_id.data);
        pending_alert.temperature = temperature;
        has_pending_alert = true;
        pthread_cond_signal(&alert_cond);
        pthread_mutex_unlock(&alert_mutex);
    }
}

int main(void) {
    setvbuf(stdout, NULL, _IONBF, 0);
    printf("Temperature Processor component starting...\n");
    
    gg_sdk_init();
    
    GgError ret = ggipc_connect();
    if (ret != GG_ERR_OK) {
        fprintf(stderr, "Failed to connect to Greengrass nucleus\n");
        exit(1);
    }
    printf("Connected to Greengrass IPC\n");
    
    // Start alert publisher thread.
    pthread_t alert_thread;
    if (pthread_create(&alert_thread, NULL, alert_publisher_thread, NULL) != 0) {
        fprintf(stderr, "Failed to create alert publisher thread\n");
        exit(1);
    }
    
    GgIpcSubscriptionHandle handle;
    ret = ggipc_subscribe_to_topic(
        GG_STR(SUBSCRIBE_TOPIC),
        &on_sensor_data,
        NULL,
        &handle
    );
    
    if (ret != GG_ERR_OK) {
        fprintf(stderr, "Failed to subscribe to topic\n");
        exit(1);
    }
    
    printf("Subscribed to %s\n", SUBSCRIBE_TOPIC);
    printf("Waiting for sensor data...\n");
    
    // Keep running.
    while (true) {
        sleep(1);
    }
    
    return 0;
}
```

------
#### [ C\$1\$1 ]

```
#include <gg/ipc/client.hpp>
#include <gg/buffer.hpp>
#include <gg/object.hpp>
#include <gg/types.hpp>

#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <string>
#include <string_view>
#include <thread>

struct AlertData {
    std::string sensor_id;
    int64_t temperature;
};

static std::mutex alert_mutex;
static std::condition_variable alert_cv;
static AlertData pending_alert;
static bool has_pending_alert = false;

void alert_publisher_thread() {
    auto& client = gg::ipc::Client::get();
    
    while (true) {
        std::unique_lock<std::mutex> lock(alert_mutex);
        alert_cv.wait(lock, [] { return has_pending_alert; });
        
        AlertData alert = pending_alert;
        has_pending_alert = false;
        lock.unlock();
        
        // Create alert payload as JSON string.
        std::string json_payload = "{\"sensor_id\":\"" + alert.sensor_id + 
                                  "\",\"temperature\":" + std::to_string(alert.temperature) + 
                                  ",\"alert\":\"HIGH_TEMPERATURE\"}";
        
        // Convert to Buffer and publish.
        gg::Buffer buffer(json_payload);
        auto error = client.publish_to_topic("component/alerts", buffer);
        
        if (error) {
            std::cerr << "Failed to publish alert\n";
        } else {
            std::cout << "Alert sent to AlertHandler component\n";
        }
    }
}

class SensorCallback : public gg::ipc::LocalTopicCallback {
    void operator()(
        std::string_view topic,
        gg::Object payload,
        gg::ipc::Subscription& handle
    ) override {
        (void) topic;
        (void) handle;
        
        // Payload is a Buffer containing JSON string.
        if (payload.index() != GG_TYPE_BUF) {
            std::cerr << "Expected Buffer message\n";
            return;
        }
        
        // Extract buffer using gg::get.
        auto buffer = gg::get<std::span<uint8_t>>(payload);
        std::string json_str(reinterpret_cast<const char*>(buffer.data()), buffer.size());
        
        // Simple JSON parsing for demo.
        std::string sensor_id = "sensor1"; 
        int64_t temperature = 0;
        
        // Extract temperature (simple string search).
        size_t temp_pos = json_str.find("\"temperature\":");
        if (temp_pos != std::string::npos) {
            temp_pos += 14; // Skip "temperature".
            size_t end_pos = json_str.find_first_of(",}", temp_pos);
            if (end_pos != std::string::npos) {
                temperature = std::stoll(json_str.substr(temp_pos, end_pos - temp_pos));
            }
        }
        
        std::cout << "Received from sensor " << sensor_id << ": " 
                  << temperature << "°F\n";
        
        if (temperature > 80) {
            std::lock_guard<std::mutex> lock(alert_mutex);
            pending_alert = {sensor_id, temperature};
            has_pending_alert = true;
            alert_cv.notify_one();
        }
    }
};

int main() {
    // Disable stdout buffering for real-time logging.
    std::cout.setf(std::ios::unitbuf);
    
    std::cout << "Temperature Processor component starting..." << std::endl;
    
    auto& client = gg::ipc::Client::get();
    std::cout << "Got client instance" << std::endl;
    
    auto error = client.connect();
    std::cout << "Connect returned, error code: " << error.value() << std::endl;
    
    if (error) {
        std::cerr << "Failed to connect to Greengrass nucleus: " << error.message() << std::endl;
        return 1;
    }
    
    std::cout << "Connected to Greengrass IPC" << std::endl;
    
    // Start alert publisher thread.
    std::thread alert_thread(alert_publisher_thread);
    alert_thread.detach();
    
    // Handler must be static lifetime if subscription handle is not held.
    static SensorCallback handler;
    error = client.subscribe_to_topic("sensors/temperature", handler);
    
    if (error) {
        std::cerr << "Failed to subscribe to topic: " << error.message() << std::endl;
        return 1;
    }
    
    std::cout << "Subscribed to sensors/temperature" << std::endl;
    std::cout << "Waiting for sensor data..." << std::endl;
    
    // Keep running.
    while (true) {
        using namespace std::chrono_literals;
        std::this_thread::sleep_for(1s);
    }
    
    return 0;
}
```

------

##### 2. コンポーネントを構築してパッケージ化する
<a name="lite-example-1-build-component"></a>

一部の言語では、デプロイ前に構築またはパッケージ化が必要です。

------
#### [ Python ]

Python ではコンパイルは必要ありません。コンポーネントは .py ファイルを直接使用できます。

------
#### [ Java ]

すべての依存関係がバンドルされた実行可能 JAR を構築するには:

1. プロジェクトディレクトリに `pom.xml` ファイルを作成します。

   ```
   <?xml version="1.0" encoding="UTF-8"?>
   <project xmlns="http://maven.apache.org/POM/4.0.0"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
       <modelVersion>4.0.0</modelVersion>
   
       <!-- Basic project information: organization, component name, and version -->
       <groupId>com.example</groupId>
       <artifactId>temperature-processor</artifactId>
       <version>1.0.0</version>
   
       <properties>
           <!-- Java 11 LTS (Long Term Support) is recommended for Greengrass v2 components -->
           <maven.compiler.source>11</maven.compiler.source>
           <maven.compiler.target>11</maven.compiler.target>
       </properties>
   
       <dependencies>
           <!-- AWS IoT Device SDK for Java - provides IPC client for Greengrass v2 local communication -->
           <dependency>
               <groupId>software.amazon.awssdk.iotdevicesdk</groupId>
               <artifactId>aws-iot-device-sdk</artifactId>
               <version>1.25.1</version>
           </dependency>
       </dependencies>
   
       <build>
           <plugins>
               <!-- Maven Shade Plugin - creates a standalone JAR with all dependencies included for Greengrass deployment -->
               <plugin>
                   <groupId>org.apache.maven.plugins</groupId>
                   <artifactId>maven-shade-plugin</artifactId>
                   <version>3.2.4</version>
                   <executions>
                       <execution>
                           <phase>package</phase>
                           <goals>
                               <goal>shade</goal>
                           </goals>
                           <configuration>
                               <transformers>
                                   <!-- Set the main class for the executable JAR -->
                                   <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                       <mainClass>TemperatureProcessor</mainClass>
                                   </transformer>
                               </transformers>
                               <filters>
                                   <!-- Exclude signature files to avoid security exceptions -->
                                   <filter>
                                       <artifact>*:*</artifact>
                                       <excludes>
                                           <exclude>META-INF/*.SF</exclude>
                                           <exclude>META-INF/*.DSA</exclude>
                                           <exclude>META-INF/*.RSA</exclude>
                                       </excludes>
                                   </filter>
                               </filters>
                           </configuration>
                       </execution>
                   </executions>
               </plugin>
           </plugins>
       </build>
   </project>
   ```

1. JAR を構築します。

   ```
   mvn clean package
   ```

   これにより、すべての依存関係を含む `target/temperature-processor-1.0.0.jar` が作成されます。

1. JAR を S3 バケットにアップロードしてデプロイします。

------
#### [ JavaScript ]

Node.js コンポーネントをすべての依存関係でパッケージ化するには:

1. `package.json` ファイルを作成します。

   ```
   {
     "name": "temperature-processor",
     "version": "1.0.0",
     "description": "Temperature processor component for Greengrass v2",
     "main": "TemperatureProcessor.js",
     "dependencies": {
       "aws-iot-device-sdk-v2": "^1.21.0"
     },
     "engines": {
       "node": ">=14.0.0"
     }
   }
   ```

1. 開発マシンに依存関係をインストールします。

   ```
   npm install
   ```

   これにより、v2 AWS AWS IoT Device SDK を含む`node_modules`フォルダが作成されます。

1. デプロイ用のパッケージ:

   ```
   zip -r TemperatureProcessor.zip TemperatureProcessor.js node_modules/ package.json
   ```

1. zip ファイルを S3 バケットにアップロードしてデプロイします。

**注記**  
Greengrass デバイスには Node.js ランタイムがインストールされている必要があります (バージョン 14 以降）。コンポーネントアーティファクト`npm install`にはバンドルされた`node_modules`フォルダ内のすべての依存関係が含まれているため、Greengrass コアデバイスで を実行する必要はありません。

------
#### [ C ]

**前提条件**:

SDK と コンポーネントを構築するには、次のビルド依存関係が必要です。
+ GCC または Clang
+ CMake (バージョン 3.22 以上)
+ または Ninja を作成する

**ビルドの依存関係をインストールします。**

Ubuntu/Debian の場合:

```
sudo apt install build-essential cmake
```

Amazon Linux で

```
sudo yum install gcc cmake make
```

**コンポーネントの CMakeLists.txt ファイルを作成します。**

```
cmake_minimum_required(VERSION 3.10)
project(TemperatureProcessor C)

set(CMAKE_C_STANDARD 11)

# Add AWS Greengrass Component SDK
add_subdirectory(aws-greengrass-component-sdk)

# Build your component executable
add_executable(temperature_processor temperature_processor.c)
target_link_libraries(temperature_processor gg-sdk)
```

**ビルドステップ:**

```
# Clone the AWS Greengrass Component SDK into your project
git clone https://github.com/aws-greengrass/aws-greengrass-component-sdk.git

# Build your component
cmake -B build -D CMAKE_BUILD_TYPE=MinSizeRel
make -C build -j$(nproc)

# The binary 'temperature_processor' is in ./build/
# Upload this binary to S3 for deployment
```

------
#### [ C\$1\$1 ]

**前提条件**:

SDK と コンポーネントを構築するには、次のビルド依存関係が必要です。
+ C\$1\$120 をサポートする GCC または Clang
+ CMake (バージョン 3.22 以上)
+ または Ninja を作成する

**ビルドの依存関係をインストールします。**

Ubuntu/Debian の場合:

```
sudo apt install build-essential cmake
```

Amazon Linux で

```
sudo yum install gcc-c++ cmake make
```

**コンポーネントの CMakeLists.txt ファイルを作成します。**

```
cmake_minimum_required(VERSION 3.10)
project(TemperatureProcessor CXX)

set(CMAKE_CXX_STANDARD 20)

# Add SDK as subdirectory
add_subdirectory(aws-greengrass-component-sdk)

# Add C++ SDK subdirectory
add_subdirectory(aws-greengrass-component-sdk/cpp)

add_executable(temperature_processor temperature_processor.cpp)
target_link_libraries(temperature_processor gg-sdk++)
```

**ビルドステップ:**

```
# Clone the AWS Greengrass Component SDK into your project
git clone https://github.com/aws-greengrass/aws-greengrass-component-sdk.git

# Build your component
cmake -B build -D CMAKE_BUILD_TYPE=MinSizeRel
make -C build -j$(nproc)

# The binary 'temperature_processor' will be in ./build/
# Upload this binary to S3 for deployment
```

------

##### 3. コンポーネントレシピ
<a name="lite-example-1-component-recipe"></a>

コンポーネントが使用する実際のトピックで「リソース」配列を更新します。

------
#### [ Python ]

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.TemperatureProcessor",
  "ComponentVersion": "1.0.0",
  "ComponentType": "aws.greengrass.generic",
  "ComponentDescription": "Receives sensor data and forwards alerts to AlertHandler",
  "ComponentPublisher": "[Your Company]",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.pubsub": {
          "com.example.TemperatureProcessor:pubsub:1": {
            "policyDescription": "Allows access to subscribe to sensor topics",
            "operations": [
              "aws.greengrass#SubscribeToTopic"
            ],
            "resources": [
              "sensors/temperature"
            ]
          },
          "com.example.TemperatureProcessor:pubsub:2": {
            "policyDescription": "Allows access to publish to alert topics",
            "operations": [
              "aws.greengrass#PublishToTopic"
            ],
            "resources": [
              "component/alerts"
            ]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux",
        "runtime": "*"
      },
      "Lifecycle": {
        "run": "python3 -u {artifacts:path}/temperature_processor.py"
      },
      "Artifacts": [
        {
          "Uri": "s3://YOUR-BUCKET/artifacts/com.example.TemperatureProcessor/1.0.0/temperature_processor.py"
        }
      ]
    }
  ]
}
```

------
#### [ Java ]

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.TemperatureProcessor",
  "ComponentVersion": "1.0.0",
  "ComponentType": "aws.greengrass.generic",
  "ComponentDescription": "Receives sensor data and forwards alerts to AlertHandler",
  "ComponentPublisher": "[Your Company]",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.pubsub": {
          "com.example.TemperatureProcessor:pubsub:1": {
            "policyDescription": "Allows access to subscribe to sensor topics",
            "operations": [
              "aws.greengrass#SubscribeToTopic"
            ],
            "resources": [
              "sensors/temperature"
            ]
          },
          "com.example.TemperatureProcessor:pubsub:2": {
            "policyDescription": "Allows access to publish to alert topics",
            "operations": [
              "aws.greengrass#PublishToTopic"
            ],
            "resources": [
              "component/alerts"
            ]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux",
        "runtime": "*"
      },
      "Lifecycle": {
        "run": "java -jar {artifacts:path}/TemperatureProcessor.jar"
      },
      "Artifacts": [
        {
          "Uri": "s3://YOUR-BUCKET/artifacts/com.example.TemperatureProcessor/1.0.0/TemperatureProcessor.jar"
        }
      ]
    }
  ]
}
```

------
#### [ JavaScript ]

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.TemperatureProcessor",
  "ComponentVersion": "1.0.0",
  "ComponentType": "aws.greengrass.generic",
  "ComponentDescription": "Receives sensor data and forwards alerts to AlertHandler",
  "ComponentPublisher": "[Your Company]",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.pubsub": {
          "com.example.TemperatureProcessor:pubsub:1": {
            "policyDescription": "Allows access to subscribe to sensor topics",
            "operations": [
              "aws.greengrass#SubscribeToTopic"
            ],
            "resources": [
              "sensors/temperature"
            ]
          },
          "com.example.TemperatureProcessor:pubsub:2": {
            "policyDescription": "Allows access to publish to alert topics",
            "operations": [
              "aws.greengrass#PublishToTopic"
            ],
            "resources": [
              "component/alerts"
            ]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux",
        "runtime": "*"
      },
      "Lifecycle": {
        "run": "cd {artifacts:decompressedPath}/TemperatureProcessor && node TemperatureProcessor.js"
      },
      "Artifacts": [
        {
          "Uri": "s3://YOUR-BUCKET/artifacts/com.example.TemperatureProcessor/1.0.0/TemperatureProcessor.zip",
          "Unarchive": "ZIP"
        }
      ]
    }
  ]
}
```

------
#### [ C/C\$1\$1 ]

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.TemperatureProcessor",
  "ComponentVersion": "1.0.0",
  "ComponentType": "aws.greengrass.generic",
  "ComponentDescription": "Receives sensor data and forwards alerts to AlertHandler",
  "ComponentPublisher": "[Your Company]",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.pubsub": {
          "com.example.TemperatureProcessor:pubsub:1": {
            "policyDescription": "Allows access to subscribe to sensor topics",
            "operations": [
              "aws.greengrass#SubscribeToTopic"
            ],
            "resources": [
              "sensors/temperature"
            ]
          },
          "com.example.TemperatureProcessor:pubsub:2": {
            "policyDescription": "Allows access to publish to alert topics",
            "operations": [
              "aws.greengrass#PublishToTopic"
            ],
            "resources": [
              "component/alerts"
            ]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux",
        "runtime": "*"
      },
      "Lifecycle": {
        "run": "{artifacts:path}/temperature_processor"
      },
      "Artifacts": [
        {
          "Uri": "s3://YOUR-BUCKET/artifacts/com.example.TemperatureProcessor/1.0.0/temperature_processor"
        }
      ]
    }
  ]
}
```

------

### シナリオ 2: クラウド通信
<a name="lite-example-cloud-communication"></a>

このシナリオでは、 と通信する V1 Lambda 関数 AWS IoT Core を V2 汎用コンポーネントに変換する方法を示します。

#### アプリケーションのアーキテクチャ
<a name="lite-example-2-scenario"></a>

この例では、クラウド接続アーキテクチャを使用しています。
+ AWS IoT Core がデバイスにコマンドを送信する
+ Controller Lambda がコマンドを受信して処理する
+ Controller Lambda がテレメトリデータを に送信する AWS IoT Core

この例では、 からのメッセージの受信とメッセージの発行の両方を示すコントローラー Lambda に焦点を当てています AWS IoT Core。

##### V1 グループのサブスクリプション
<a name="lite-example-2-v1-subscriptions"></a>

では AWS IoT Greengrass V1、次のグループサブスクリプションにより、Lambda 関数と 間の通信が有効になります AWS IoT Core。

サブスクリプション 1: IoT クラウド → Lambda
+ ソース: IoT クラウド
+ ターゲット: Lambda (DeviceController)
+ トピック: commands/device1

サブスクリプション 2: Lambda → IoT クラウド
+ ソース: Lambda (DeviceController)
+ ターゲット: IoT クラウド
+ トピック: テレメトリ/device1

#### コントローラー Lambda 関数 (V1)
<a name="lite-example-2-v1-code"></a>

------
#### [ Python ]

```
import greengrasssdk
import json
import time

iot_client = greengrasssdk.client('iot-data')

def lambda_handler(event, context):
    """
    Receives commands from IoT Core,
    processes them, and sends telemetry back to cloud
    """
    # Receive command from IoT Core.
    command = event.get('command')
    device_id = event.get('device_id', 'device1')

    print(f"Received command from cloud: {command}")

    # Process command.
    if command == 'get_status':
        status = get_device_status()

        # Send telemetry back to IoT Core.
        telemetry_data = {
            'device_id': device_id,
            'status': status,
            'timestamp': time.time()
        }

        iot_client.publish(
            topic=f'telemetry/{device_id}',
            payload=json.dumps(telemetry_data)
        )

        print(f"Telemetry sent to cloud: {telemetry_data}")

    return {'statusCode': 200}

def get_device_status():
    """Get current device status"""
    # Simulate getting device status.
    return 'online'
```

------
#### [ Java ]

```
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.greengrass.javasdk.IotDataClient;
import com.amazonaws.greengrass.javasdk.model.PublishRequest;
import com.google.gson.Gson;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class DeviceControllerLambda {
    private static final Gson gson = new Gson();
    private final IotDataClient iotDataClient;

    public DeviceControllerLambda() {
        this.iotDataClient = new IotDataClient();
    }

    public String handleRequest(Map<String, Object> event, Context context) {
        /*
         * Receives commands from IoT Core,
         * processes them, and sends telemetry back to cloud
         */

        // Receive command from IoT Core.
        String command = (String) event.get("command");
        String deviceId = event.containsKey("device_id") ? 
            (String) event.get("device_id") : "device1";

        System.out.println("Received command from cloud: " + command);

        // Process command.
        if ("get_status".equals(command)) {
            String status = getDeviceStatus();

            // Send telemetry back to IoT Core.
            Map<String, Object> telemetryData = new HashMap<>();
            telemetryData.put("device_id", deviceId);
            telemetryData.put("status", status);
            telemetryData.put("timestamp", System.currentTimeMillis() / 1000.0);

            String payload = gson.toJson(telemetryData);
            PublishRequest publishRequest = new PublishRequest()
                .withTopic("telemetry/" + deviceId)
                .withPayload(ByteBuffer.wrap(payload.getBytes(StandardCharsets.UTF_8)));

            iotDataClient.publish(publishRequest);

            System.out.println("Telemetry sent to cloud: " + telemetryData);
        }

        return "Success";
    }

    private String getDeviceStatus() {
        // Simulate getting device status.
        return "online";
    }
}
```

------
#### [ JavaScript ]

```
const greengrasssdk = require('aws-greengrass-core-sdk');

const iotClient = new greengrasssdk.IotData();

/**
 * Receives commands from IoT Core and sends telemetry back.
 */
exports.handler = function(event, context) {
    console.log('Received command from IoT Core:', JSON.stringify(event));
    
    const command = event.command;
    const deviceId = event.device_id || 'device1';
    
    console.log(`Processing command: ${command}`);
    
    if (command === 'get_status') {
        const status = 'online';
        
        const telemetryData = {
            device_id: deviceId,
            status: status,
            timestamp: Date.now() / 1000
        };
        
        // Publish telemetry to IoT Core using greengrasssdk.
        const params = {
            topic: `telemetry/${deviceId}`,
            payload: JSON.stringify(telemetryData)
        };
        
        iotClient.publish(params, (err) => {
            if (err) {
                console.error('Error publishing telemetry:', err);
                context.fail(err);
            } else {
                console.log('Telemetry sent to IoT Core:', JSON.stringify(telemetryData));
                context.succeed('Success');
            }
        });
    } else {
        context.succeed('Success');
    }
};
```

------
#### [ C ]

```
#include <aws/greengrass/greengrasssdk.h>
#include <stdio.h>
#include <string.h>
#include <jansson.h>
#include <time.h>

static aws_greengrass_iot_data_client *iot_client = NULL;

const char* get_device_status(void) {
    // Simulate getting device status.
    return "online";
}

void on_cloud_command(const char *topic, const uint8_t *payload, size_t payload_len, void *user_data) {
    // Parse incoming command from IoT Core.
    char *payload_str = strndup((char *)payload, payload_len);
    json_error_t error;
    json_t *event = json_loads(payload_str, 0, &error);
    free(payload_str);
    
    if (!event) {
        fprintf(stderr, "Error parsing JSON: %s\n", error.text);
        return;
    }
    
    // Extract command and device_id.
    json_t *command_obj = json_object_get(event, "command");
    json_t *device_id_obj = json_object_get(event, "device_id");
    
    const char *command = json_string_value(command_obj);
    const char *device_id = device_id_obj ? json_string_value(device_id_obj) : "device1";
    
    printf("Received command from cloud: %s\n", command);
    
    // Process command.
    if (command && strcmp(command, "get_status") == 0) {
        const char *status = get_device_status();
        
        // Send telemetry back to IoT Core.
        json_t *telemetry_data = json_object();
        json_object_set_new(telemetry_data, "device_id", json_string(device_id));
        json_object_set_new(telemetry_data, "status", json_string(status));
        json_object_set_new(telemetry_data, "timestamp", json_real(time(NULL)));
        
        char *telemetry_payload = json_dumps(telemetry_data, JSON_COMPACT);
        
        // Publish telemetry to IoT Core.
        char telemetry_topic[256];
        snprintf(telemetry_topic, sizeof(telemetry_topic), "telemetry/%s", device_id);
        
        aws_greengrass_publish_params params = {
            .topic = telemetry_topic,
            .payload = (uint8_t *)telemetry_payload,
            .payload_len = strlen(telemetry_payload)
        };
        
        aws_greengrass_iot_data_publish(iot_client, &params);
        
        printf("Telemetry sent to cloud: %s\n", telemetry_payload);
    
        free(telemetry_payload);
        json_decref(telemetry_data);
    }
    
    json_decref(event);
}

int main(int argc, char *argv[]) {
    // Initialize Greengrass SDK.
    iot_client = aws_greengrass_iot_data_client_new();
    
    // Subscribe to commands from IoT Core.
    aws_greengrass_subscribe_params subscribe_params = {
        .topic = "commands/device1",
        .callback = on_cloud_command,
        .user_data = NULL
    };
    
    aws_greengrass_iot_data_subscribe(iot_client, &subscribe_params);
    
    printf("Device Controller Lambda started\n");
    printf("Subscribed to commands/device1\n");
    printf("Waiting for commands from IoT Core...\n");
    
    // Keep the Lambda running.
    while (1) {
        sleep(1);
    }
    
    return 0;
}
```

------
#### [ C\$1\$1 ]

```
#include <aws/greengrass/greengrasssdk.h>
#include <iostream>
#include <string>
#include <memory>
#include <jansson.h>
#include <ctime>
#include <unistd.h>

class DeviceController {
private:
    std::unique_ptr<aws_greengrass_iot_data_client, decltype(&aws_greengrass_iot_data_client_destroy)> iot_client;
    
    static void message_callback_wrapper(const char *topic, const uint8_t *payload, 
                                        size_t payload_len, void *user_data) {
        auto* controller = static_cast<DeviceController*>(user_data);
        controller->on_cloud_command(topic, payload, payload_len);
    }
    
    std::string get_device_status() {
        // Simulate getting device status.
        return "online";
    }

public:
    DeviceController() 
        : iot_client(aws_greengrass_iot_data_client_new(), 
                     aws_greengrass_iot_data_client_destroy) {
        if (!iot_client) {
            throw std::runtime_error("Failed to create Greengrass IoT client");
        }
    }
    
    void on_cloud_command(const char *topic, const uint8_t *payload, size_t payload_len) {
        // Parse incoming command from IoT Core.
        std::string payload_str(reinterpret_cast<const char*>(payload), payload_len);
        
        json_error_t error;
        json_t *event = json_loads(payload_str.c_str(), 0, &error);
        
        if (!event) {
            std::cerr << "Error parsing JSON: " << error.text << std::endl;
            return;
        }
        
        // Extract command and device_id.
        json_t *command_obj = json_object_get(event, "command");
        json_t *device_id_obj = json_object_get(event, "device_id");
        
        const char *command = json_string_value(command_obj);
        const char *device_id = device_id_obj ? json_string_value(device_id_obj) : "device1";
        
        std::cout << "Received command from cloud: " << command << std::endl;
        
        // Process command.
        if (command && std::string(command) == "get_status") {
            std::string status = get_device_status();
            
            // Send telemetry back to IoT Core.
            json_t *telemetry_data = json_object();
            json_object_set_new(telemetry_data, "device_id", json_string(device_id));
            json_object_set_new(telemetry_data, "status", json_string(status.c_str()));
            json_object_set_new(telemetry_data, "timestamp", json_real(std::time(nullptr)));
            
            char *telemetry_payload = json_dumps(telemetry_data, JSON_COMPACT);
            
            // Publish telemetry to IoT Core.
            std::string telemetry_topic = "telemetry/" + std::string(device_id);
            
            aws_greengrass_publish_params params = {
                .topic = telemetry_topic.c_str(),
                .payload = reinterpret_cast<uint8_t*>(telemetry_payload),
                .payload_len = strlen(telemetry_payload)
            };
            
            aws_greengrass_iot_data_publish(iot_client.get(), &params);
            
            std::cout << "Telemetry sent to cloud: " << telemetry_payload << std::endl;
            
            free(telemetry_payload);
            json_decref(telemetry_data);
        }
        
        json_decref(event);
    }
    
    void subscribe_to_topic(const std::string& topic) {
        aws_greengrass_subscribe_params subscribe_params = {
            .topic = topic.c_str(),
            .callback = message_callback_wrapper,
            .user_data = this
        };
        
        aws_greengrass_iot_data_subscribe(iot_client.get(), &subscribe_params);
        
        std::cout << "Device Controller Lambda started" << std::endl;
        std::cout << "Subscribed to " << topic << std::endl;
        std::cout << "Waiting for commands from IoT Core..." << std::endl;
    }
    
    void run() {
        // Keep the Lambda running.
        while (true) {
            sleep(1);
        }
    }
};

int main(int argc, char *argv[]) {
    try {
        DeviceController controller;
        controller.subscribe_to_topic("commands/device1");
        controller.run();
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        return 1;
    }
    
    return 0;
}
```

------

#### 汎用コンポーネント (V2)
<a name="lite-example-2-v2-code"></a>

で同じ機能を実現するには AWS IoT Greengrass V2、以下を使用して汎用コンポーネントを作成します。

##### 1. コンポーネントコード
<a name="lite-example-2-component-code"></a>

------
#### [ Python ]

前提条件: このコンポーネントコードを使用する前に、Greengrass デバイスに AWS IoT Device SDK for Python をインストールして検証します。

```
# Install the SDK
pip3 install awsiotsdk

# Verify installation
python3 -c "import awsiot.greengrasscoreipc.clientv2; print('SDK installed successfully')"
```

インストール中に依存関係の競合が発生した場合は、 の特定のバージョンをインストールしてみてください AWS IoT Device SDK。

検証コマンドで「SDK が正常にインストールされました」と表示される場合は、コンポーネントコードを使用する準備が整います。

```
from awsiot.greengrasscoreipc.clientv2 import GreengrassCoreIPCClientV2
from awsiot.greengrasscoreipc.model import QOS
import json
import time

ipc_client = GreengrassCoreIPCClientV2()

def on_command(event):
    """
    Receives commands from IoT Core,
    processes them, and sends telemetry back to cloud
    """
    try:
        # Receive command from IoT Core.
        data = json.loads(event.message.payload.decode('utf-8'))
        command = data.get('command')
        device_id = data.get('device_id', 'device1')

        print(f"Received command from cloud: {command}")

        # Process command.
        if command == 'get_status':
            status = get_device_status()

            # Send telemetry back to IoT Core.
            telemetry_data = {
                'device_id': device_id,
                'status': status,
                'timestamp': time.time()
            }

            ipc_client.publish_to_iot_core(
                topic_name=f'telemetry/{device_id}',
                qos=QOS.AT_LEAST_ONCE,
                payload=json.dumps(telemetry_data).encode('utf-8')
            )

            print(f"Telemetry sent to cloud: {telemetry_data}")

    except Exception as e:
        print(f"Error processing command: {e}")

def get_device_status():
    """Get current device status"""
    # Simulate getting device status.
    return 'online'

def main():
    print("Device Controller component starting...")

    # Subscribe to commands from IoT Core.
    ipc_client.subscribe_to_iot_core(
        topic_name='commands/device1',
        qos=QOS.AT_LEAST_ONCE,
        on_stream_event=on_command
    )

    print("Subscribed to commands/device1 from IoT Core")
    print("Waiting for commands from cloud...")

    # Keep running.
    while True:
        time.sleep(1)

if __name__ == '__main__':
    main()
```

------
#### [ Java ]

```
import software.amazon.awssdk.aws.greengrass.GreengrassCoreIPCClientV2;
import software.amazon.awssdk.aws.greengrass.model.QOS;
import software.amazon.awssdk.aws.greengrass.model.SubscribeToIoTCoreRequest;
import software.amazon.awssdk.aws.greengrass.model.IoTCoreMessage;
import software.amazon.awssdk.aws.greengrass.model.PublishToIoTCoreRequest;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class DeviceController {
    private static GreengrassCoreIPCClientV2 ipcClient;

    public static void main(String[] args) {
        System.out.println("Device Controller component starting...");
        
        try (GreengrassCoreIPCClientV2 client = GreengrassCoreIPCClientV2.builder().build()) {
            ipcClient = client;

            SubscribeToIoTCoreRequest subscribeRequest = new SubscribeToIoTCoreRequest()
                .withTopicName("commands/device1")
                .withQos(QOS.AT_LEAST_ONCE);

            ipcClient.subscribeToIoTCore(
                subscribeRequest,
                DeviceController::onCommand,
                Optional.empty(),
                Optional.empty()
            );

            System.out.println("Subscribed to commands/device1 from IoT Core");
            System.out.println("Waiting for commands from cloud...");

            while (true) {
                Thread.sleep(1000);
            }
        } catch (Exception e) {
            System.err.println("Error: " + e.getMessage());
            e.printStackTrace();
        }
    }

    public static void onCommand(IoTCoreMessage message) {
        try {
            String payload = new String(message.getMessage().getPayload(), StandardCharsets.UTF_8);
            
            // Simple JSON parsing.
            String command = extractJsonValue(payload, "command");
            String deviceId = extractJsonValue(payload, "device_id");
            if (deviceId == null || deviceId.isEmpty()) {
                deviceId = "device1";
            }

            System.out.println("Received command from cloud: " + command);

            if ("get_status".equals(command)) {
                String status = getDeviceStatus();

                // Build JSON manually.
                String telemetryJson = String.format(
                    "{\"device_id\":\"%s\",\"status\":\"%s\",\"timestamp\":%.3f}",
                    deviceId, status, System.currentTimeMillis() / 1000.0
                );
                byte[] telemetryBytes = telemetryJson.getBytes(StandardCharsets.UTF_8);

                PublishToIoTCoreRequest publishRequest = new PublishToIoTCoreRequest()
                    .withTopicName("telemetry/" + deviceId)
                    .withQos(QOS.AT_LEAST_ONCE)
                    .withPayload(telemetryBytes);

                ipcClient.publishToIoTCore(publishRequest);

                System.out.println("Telemetry sent to cloud: " + telemetryJson);
            }
        } catch (Exception e) {
            System.err.println("Error processing command: " + e.getMessage());
        }
    }

    private static String extractJsonValue(String json, String key) {
        Pattern pattern = Pattern.compile("\"" + Pattern.quote(key) + "\"\\s*:\\s*\"([^\"]+)\"");
        Matcher matcher = pattern.matcher(json);
        return matcher.find() ? matcher.group(1) : null;
    }

    private static String getDeviceStatus() {
        return "online";
    }
}
```

------
#### [ JavaScript ]

```
const greengrasscoreipc = require('aws-iot-device-sdk-v2').greengrasscoreipc;

class DeviceController {
    constructor() {
        this.ipcClient = null;
    }

    async start() {
        console.log('Device Controller component starting...');
        
        try {
            this.ipcClient = greengrasscoreipc.createClient();
            await this.ipcClient.connect();
            
            const subscribeRequest = {
                topicName: 'commands/device1',
                qos: 1
            };

            const streamingOperation = this.ipcClient.subscribeToIoTCore(subscribeRequest);
            
            streamingOperation.on('message', (message) => {
                this.onCommand(message);
            });
            
            streamingOperation.on('streamError', (error) => {
                console.error('Stream error:', error);
            });
            
            streamingOperation.on('ended', () => {
                console.log('Subscription stream ended');
            });
            
            await streamingOperation.activate();
            
            console.log('Subscribed to commands/device1 from IoT Core');
            console.log('Waiting for commands from cloud...');
            
        } catch (error) {
            console.error('Error starting component:', error);
            process.exit(1);
        }
    }

    async onCommand(message) {
        try {
            const payload = message.message.payload.toString('utf-8');
            const data = JSON.parse(payload);
            
            const command = data.command;
            const deviceId = data.device_id || 'device1';
            
            console.log(`Received command from cloud: ${command}`);
            
            if (command === 'get_status') {
                const status = this.getDeviceStatus();
                
                const telemetryData = {
                    device_id: deviceId,
                    status: status,
                    timestamp: Date.now() / 1000
                };
                
                const telemetryJson = JSON.stringify(telemetryData);
                
                const publishRequest = {
                    topicName: `telemetry/${deviceId}`,
                    qos: 1,
                    payload: Buffer.from(telemetryJson, 'utf-8')
                };
                
                await this.ipcClient.publishToIoTCore(publishRequest);
                console.log(`Telemetry sent to cloud: ${telemetryJson}`);
            }
            
        } catch (error) {
            console.error('Error processing command:', error);
        }
    }

    getDeviceStatus() {
        return 'online';
    }
}

// Start the component.
const controller = new DeviceController();
controller.start();
```

------
#### [ C ]

```
#include <gg/buffer.h>
#include <gg/error.h>
#include <gg/ipc/client.h>
#include <gg/map.h>
#include <gg/object.h>
#include <gg/sdk.h>
#include <unistd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <pthread.h>

#define COMMAND_TOPIC "commands/device1"
#define TELEMETRY_TOPIC "telemetry/device1"

typedef struct {
    char device_id[64];
    char command[64];
} CommandData;

static pthread_mutex_t command_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t command_cond = PTHREAD_COND_INITIALIZER;
static CommandData pending_command;
static bool has_pending_command = false;

const char* get_device_status(void) {
    // Simulate getting device status.
    return "online";
}

static void *telemetry_publisher_thread(void *arg) {
    (void) arg;
    
    while (true) {
        pthread_mutex_lock(&command_mutex);
        while (!has_pending_command) {
            pthread_cond_wait(&command_cond, &command_mutex);
        }
        
        CommandData cmd = pending_command;
        has_pending_command = false;
        pthread_mutex_unlock(&command_mutex);
        
        // Process command.
        if (strcmp(cmd.command, "get_status") == 0) {
            const char *status = get_device_status();
            
            // Create telemetry JSON string.
            char telemetry_json[512];
            snprintf(telemetry_json, sizeof(telemetry_json),
                     "{\"device_id\":\"%s\",\"status\":\"%s\",\"timestamp\":%ld}",
                     cmd.device_id, status, time(NULL));
            
            GgBuffer telemetry_buf = {
                .data = (uint8_t *)telemetry_json,
                .len = strlen(telemetry_json)
            };
            
            // Publish telemetry to IoT Core.
            GgError ret = ggipc_publish_to_iot_core(GG_STR(TELEMETRY_TOPIC), telemetry_buf, 0);
            
            if (ret != GG_ERR_OK) {
                fprintf(stderr, "Failed to publish telemetry to IoT Core\n");
            } else {
                printf("Telemetry sent to cloud: device_id=%s, status=%s\n", cmd.device_id, status);
            }
        }
    }
    
    return NULL;
}

static void on_cloud_command(
    void *ctx, GgBuffer topic, GgBuffer payload, GgIpcSubscriptionHandle handle
) {
    (void) ctx;
    (void) topic;
    (void) handle;
    
    printf("Received command from IoT Core: %.*s\n", (int)payload.len, payload.data);
    
    // Parse JSON payload (comes as raw buffer from IoT Core).
    // For simplicity, we'll do basic string parsing.
    
    // Extract command and device_id from JSON string.
    char payload_str[512];
    snprintf(payload_str, sizeof(payload_str), "%.*s", (int)payload.len, payload.data);
    
    // Simple JSON parsing (looking for "command":"get_status").
    char *command_start = strstr(payload_str, "\"command\"");
    char *device_id_start = strstr(payload_str, "\"device_id\"");
    
    if (command_start) {
        pthread_mutex_lock(&command_mutex);
        
        char *cmd_value = strstr(command_start, ":");
        if (cmd_value) {
            cmd_value = strchr(cmd_value, '"');
            if (cmd_value) {
                cmd_value++;
                char *cmd_end = strchr(cmd_value, '"');
                if (cmd_end) {
                    size_t cmd_len = cmd_end - cmd_value;
                    if (cmd_len < sizeof(pending_command.command)) {
                        strncpy(pending_command.command, cmd_value, cmd_len);
                        pending_command.command[cmd_len] = '\0';
                    }
                }
            }
        }
        
        // Extract device_id or use default.
        if (device_id_start) {
            char *dev_value = strstr(device_id_start, ":");
            if (dev_value) {
                dev_value = strchr(dev_value, '"');
                if (dev_value) {
                    dev_value++;
                    char *dev_end = strchr(dev_value, '"');
                    if (dev_end) {
                        size_t dev_len = dev_end - dev_value;
                        if (dev_len < sizeof(pending_command.device_id)) {
                            strncpy(pending_command.device_id, dev_value, dev_len);
                            pending_command.device_id[dev_len] = '\0';
                        }
                    }
                }
            }
        } else {
            strcpy(pending_command.device_id, "device1");
        }
        
        printf("Received command from cloud: %s\n", pending_command.command);
        
        has_pending_command = true;
        pthread_cond_signal(&command_cond);
        pthread_mutex_unlock(&command_mutex);
    }
}

int main(void) {
    setvbuf(stdout, NULL, _IONBF, 0);
    printf("Device Controller component starting...\n");
    
    gg_sdk_init();
    
    GgError ret = ggipc_connect();
    if (ret != GG_ERR_OK) {
        fprintf(stderr, "Failed to connect to Greengrass nucleus\n");
        exit(1);
    }
    printf("Connected to Greengrass IPC\n");
    
    // Start telemetry publisher thread.
    pthread_t telemetry_thread;
    if (pthread_create(&telemetry_thread, NULL, telemetry_publisher_thread, NULL) != 0) {
        fprintf(stderr, "Failed to create telemetry publisher thread\n");
        exit(1);
    }
    
    // Subscribe to commands from IoT Core.
    GgIpcSubscriptionHandle handle;
    ret = ggipc_subscribe_to_iot_core(
        GG_STR(COMMAND_TOPIC),
        0,
        &on_cloud_command,
        NULL,
        &handle
    );
    
    if (ret != GG_ERR_OK) {
        fprintf(stderr, "Failed to subscribe to IoT Core topic\n");
        exit(1);
    }
    
    printf("Subscribed to %s\n", COMMAND_TOPIC);
    printf("Waiting for commands from IoT Core...\n");
    
    while (true) {
        sleep(1);
    }
    
    return 0;
}
```

------
#### [ C\$1\$1 ]

```
#include <gg/ipc/client.hpp>
#include <gg/buffer.hpp>
#include <gg/object.hpp>
#include <gg/types.hpp>

#include <chrono>
#include <condition_variable>
#include <ctime>
#include <iostream>
#include <mutex>
#include <string>
#include <string_view>
#include <thread>

constexpr std::string_view COMMAND_TOPIC = "commands/device1";
constexpr std::string_view TELEMETRY_TOPIC = "telemetry/device1";

struct CommandData {
    std::string device_id;
    std::string command;
};

static std::mutex command_mutex;
static std::condition_variable command_cv;
static CommandData pending_command;
static bool has_pending_command = false;

std::string get_device_status() {
    // Simulate getting device status.
    return "online";
}

void telemetry_publisher_thread() {
    auto& client = gg::ipc::Client::get();
    
    while (true) {
        std::unique_lock<std::mutex> lock(command_mutex);
        command_cv.wait(lock, [] { return has_pending_command; });
        
        CommandData cmd = pending_command;
        has_pending_command = false;
        lock.unlock();
        
        // Process command.
        if (cmd.command == "get_status") {
            std::string status = get_device_status();
            
            // Get current timestamp.
            auto now = std::time(nullptr);
            
            // Create telemetry JSON payload.
            std::string telemetry_payload = "{\"device_id\":\"" + cmd.device_id + 
                                          "\",\"status\":\"" + status + 
                                          "\",\"timestamp\":" + std::to_string(now) + "}";
            
            // Publish telemetry to IoT Core.
            gg::Buffer telemetry_buffer(telemetry_payload);
            auto error = client.publish_to_iot_core(TELEMETRY_TOPIC, telemetry_buffer);
            
            if (error) {
                std::cerr << "Failed to publish telemetry to IoT Core: " 
                         << error.message() << std::endl;
            } else {
                std::cout << "Telemetry sent to cloud: device_id=" << cmd.device_id 
                         << ", status=" << status << std::endl;
            }
        }
    }
}

class CloudCommandCallback : public gg::ipc::IoTCoreTopicCallback {
    void operator()(
        std::string_view topic,
        gg::Object payload,
        gg::ipc::Subscription& handle
    ) override {
        (void) topic;
        (void) handle;
        
        // Payload is a Buffer containing JSON string from IoT Core.
        if (payload.index() != GG_TYPE_BUF) {
            std::cerr << "Expected Buffer message\n";
            return;
        }
        
        // Extract buffer.
        auto buffer = gg::get<std::span<uint8_t>>(payload);
        std::string json_str(reinterpret_cast<const char*>(buffer.data()), buffer.size());
        
        std::cout << "Received command from IoT Core: " << json_str << std::endl;
        
        // Simple JSON parsing for demo.
        std::string command;
        std::string device_id = "device1";  // Default
        
        // Extract command.
        size_t cmd_pos = json_str.find("\"command\":");
        if (cmd_pos != std::string::npos) {
            size_t start = json_str.find("\"", cmd_pos + 10) + 1;
            size_t end = json_str.find("\"", start);
            if (end != std::string::npos) {
                command = json_str.substr(start, end - start);
            }
        }
        
        // Extract device_id if present.
        size_t dev_pos = json_str.find("\"device_id\":");
        if (dev_pos != std::string::npos) {
            size_t start = json_str.find("\"", dev_pos + 12) + 1;
            size_t end = json_str.find("\"", start);
            if (end != std::string::npos) {
                device_id = json_str.substr(start, end - start);
            }
        }
        
        if (!command.empty()) {
            std::lock_guard<std::mutex> lock(command_mutex);
            pending_command = {device_id, command};
            has_pending_command = true;
            command_cv.notify_one();
            
            std::cout << "Received command from cloud: " << command << std::endl;
        }
    }
};

int main() {
    // Disable stdout buffering for real-time logging in systemd/Greengrass.
    std::cout.setf(std::ios::unitbuf);
    
    std::cout << "Device Controller component starting..." << std::endl;
    
    auto& client = gg::ipc::Client::get();
    
    auto error = client.connect();
    if (error) {
        std::cerr << "Failed to connect to Greengrass nucleus: " 
                 << error.message() << std::endl;
        return 1;
    }
    
    std::cout << "Connected to Greengrass IPC" << std::endl;
    
    // Start telemetry publisher thread.
    std::thread telemetry_thread(telemetry_publisher_thread);
    telemetry_thread.detach();
    
    // Subscribe to commands from IoT Core.
    static CloudCommandCallback handler;
    error = client.subscribe_to_iot_core(COMMAND_TOPIC, handler);
    
    if (error) {
        std::cerr << "Failed to subscribe to IoT Core topic: " 
                 << error.message() << std::endl;
        return 1;
    }
    
    std::cout << "Subscribed to " << COMMAND_TOPIC << std::endl;
    std::cout << "Waiting for commands from IoT Core..." << std::endl;
    
    // Keep running.
    while (true) {
        using namespace std::chrono_literals;
        std::this_thread::sleep_for(1s);
    }
    
    return 0;
}
```

------

##### 2. コンポーネントの構築とパッケージ化
<a name="lite-example-2-build-component"></a>

一部の言語では、デプロイ前に構築またはパッケージ化が必要です。

------
#### [ Python ]

Python ではコンパイルは必要ありません。コンポーネントは .py ファイルを直接使用できます。

------
#### [ Java ]

すべての依存関係がバンドルされた実行可能 JAR を構築するには:

1. プロジェクトディレクトリに `pom.xml` ファイルを作成します。

   ```
   <?xml version="1.0" encoding="UTF-8"?>
   <project xmlns="http://maven.apache.org/POM/4.0.0"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
       <modelVersion>4.0.0</modelVersion>
   
       <!-- Basic project information: organization, component name, and version -->
       <groupId>com.example</groupId>
       <artifactId>device-controller</artifactId>
       <version>1.0.0</version>
   
       <properties>
           <!-- Java 11 LTS (Long Term Support) is recommended for Greengrass v2 components -->
           <maven.compiler.source>11</maven.compiler.source>
           <maven.compiler.target>11</maven.compiler.target>
       </properties>
   
       <dependencies>
           <!-- AWS IoT Device SDK for Java - provides IPC client for Greengrass v2 cloud communication -->
           <dependency>
               <groupId>software.amazon.awssdk.iotdevicesdk</groupId>
               <artifactId>aws-iot-device-sdk</artifactId>
               <version>1.25.1</version>
           </dependency>
       </dependencies>
   
       <build>
           <plugins>
               <!-- Maven Shade Plugin - creates a standalone JAR with all dependencies included for Greengrass deployment -->
               <plugin>
                   <groupId>org.apache.maven.plugins</groupId>
                   <artifactId>maven-shade-plugin</artifactId>
                   <version>3.2.4</version>
                   <executions>
                       <execution>
                           <phase>package</phase>
                           <goals>
                               <goal>shade</goal>
                           </goals>
                           <configuration>
                               <transformers>
                                   <!-- Set the main class for the executable JAR -->
                                   <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                       <mainClass>DeviceController</mainClass>
                                   </transformer>
                               </transformers>
                               <filters>
                                   <!-- Exclude signature files to avoid security exceptions -->
                                   <filter>
                                       <artifact>*:*</artifact>
                                       <excludes>
                                           <exclude>META-INF/*.SF</exclude>
                                           <exclude>META-INF/*.DSA</exclude>
                                           <exclude>META-INF/*.RSA</exclude>
                                       </excludes>
                                   </filter>
                               </filters>
                           </configuration>
                       </execution>
                   </executions>
               </plugin>
           </plugins>
       </build>
   </project>
   ```

1. JAR を構築します。

   ```
   mvn clean package
   ```

   これにより、すべての依存関係を含む `target/device-controller-1.0.0.jar` が作成されます。

1. デプロイのために JAR を S3 バケットにアップロードします。

------
#### [ JavaScript ]

Node.js コンポーネントをすべての依存関係でパッケージ化するには:

1. `package.json` ファイルを作成します。

   ```
   {
     "name": "device-controller",
     "version": "1.0.0",
     "description": "Device controller component for Greengrass v2",
     "main": "DeviceController.js",
     "dependencies": {
       "aws-iot-device-sdk-v2": "^1.21.0"
     },
     "engines": {
       "node": ">=14.0.0"
     }
   }
   ```

1. 開発マシンに依存関係をインストールします。

   ```
   npm install
   ```

   これにより、v2 AWS AWS IoT Device SDK を含む`node_modules`フォルダが作成されます。

1. デプロイ用のパッケージ:

   ```
   zip -r DeviceController.zip DeviceController.js node_modules/ package.json
   ```

1. zip ファイルを S3 バケットにアップロードしてデプロイします。

**注記**  
Greengrass デバイスには Node.js ランタイムがインストールされている必要があります (バージョン 14 以降）。コンポーネントアーティファクト`npm install`にはバンドルされた`node_modules`フォルダ内のすべての依存関係が含まれているため、Greengrass コアデバイスで を実行する必要はありません。

------
#### [ C ]

**前提条件**:

SDK と コンポーネントを構築するには、次のビルド依存関係が必要です。
+ GCC または Clang
+ CMake (バージョン 3.22 以上)
+ または Ninja を作成する

**ビルドの依存関係をインストールします。**

Ubuntu/Debian の場合:

```
sudo apt install build-essential cmake
```

Amazon Linux で

```
sudo yum install gcc cmake make
```

**コンポーネントの CMakeLists.txt ファイルを作成します。**

```
cmake_minimum_required(VERSION 3.10)
project(DeviceController C)

set(CMAKE_C_STANDARD 11)

# Add AWS Greengrass Component SDK
add_subdirectory(aws-greengrass-component-sdk)

# Build your component executable
add_executable(device_controller device_controller.c)
target_link_libraries(device_controller gg-sdk)
```

**ビルドステップ:**

```
# Clone the AWS Greengrass Component SDK into your project
git clone https://github.com/aws-greengrass/aws-greengrass-component-sdk.git

# Build your component
cmake -B build -D CMAKE_BUILD_TYPE=MinSizeRel
make -C build -j$(nproc)

# The binary 'device_controller' is in ./build/
# Upload this binary to S3 for deployment
```

------
#### [ C\$1\$1 ]

**前提条件**:

SDK と コンポーネントを構築するには、次のビルド依存関係が必要です。
+ C\$1\$120 をサポートする GCC または Clang
+ CMake (バージョン 3.22 以上)
+ または Ninja を作成する

**ビルドの依存関係をインストールします。**

Ubuntu/Debian の場合:

```
sudo apt install build-essential cmake
```

Amazon Linux で

```
sudo yum install gcc-c++ cmake make
```

**コンポーネントの CMakeLists.txt ファイルを作成します。**

```
cmake_minimum_required(VERSION 3.10)
project(DeviceController CXX)

set(CMAKE_CXX_STANDARD 20)

# Add SDK as subdirectory
add_subdirectory(aws-greengrass-component-sdk)

# Add C++ SDK subdirectory
add_subdirectory(aws-greengrass-component-sdk/cpp)

add_executable(device_controller device_controller.cpp)
target_link_libraries(device_controller gg-sdk++)
```

**ビルドステップ:**

```
# Clone the AWS Greengrass Component SDK into your project
git clone https://github.com/aws-greengrass/aws-greengrass-component-sdk.git

# Build your component
cmake -B build -D CMAKE_BUILD_TYPE=MinSizeRel
make -C build -j$(nproc)

# The binary 'device_controller' will be in ./build/
# Upload this binary to S3 for deployment
```

------

##### 3. コンポーネントレシピ
<a name="lite-example-2-component-recipe"></a>

コンポーネントが使用する実際のトピックで「リソース」配列を更新します。

------
#### [ Python ]

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.DeviceController",
  "ComponentVersion": "1.0.0",
  "ComponentType": "aws.greengrass.generic",
  "ComponentDescription": "Receives commands from IoT Core and sends telemetry back to cloud",
  "ComponentPublisher": "[Your Company]",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.mqttproxy": {
          "com.example.DeviceController:mqttproxy:1": {
            "policyDescription": "Allows access to subscribe to IoT Core topics",
            "operations": [
              "aws.greengrass#SubscribeToIoTCore"
            ],
            "resources": [
              "commands/device1"
            ]
          },
          "com.example.DeviceController:mqttproxy:2": {
            "policyDescription": "Allows access to publish to IoT Core topics",
            "operations": [
              "aws.greengrass#PublishToIoTCore"
            ],
            "resources": [
              "telemetry/device1"
            ]
          }
        }
      }
    }
  },
  "ComponentDependencies": {
    "aws.greengrass.TokenExchangeService": {
      "VersionRequirement": ">=2.0.0",
      "DependencyType": "HARD"
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux",
        "runtime": "*"
      },
      "Lifecycle": {
        "run": "python3 -u {artifacts:path}/device_controller.py"
      },
      "Artifacts": [
        {
          "Uri": "s3://YOUR-BUCKET/artifacts/com.example.DeviceController/1.0.0/device_controller.py"
        }
      ]
    }
  ]
}
```

------
#### [ Java ]

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.DeviceController",
  "ComponentVersion": "1.0.0",
  "ComponentType": "aws.greengrass.generic",
  "ComponentDescription": "Receives commands from IoT Core and sends telemetry back to cloud",
  "ComponentPublisher": "[Your Company]",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.mqttproxy": {
          "com.example.DeviceController:mqttproxy:1": {
            "policyDescription": "Allows access to subscribe to IoT Core topics",
            "operations": [
              "aws.greengrass#SubscribeToIoTCore"
            ],
            "resources": [
              "commands/device1"
            ]
          },
          "com.example.DeviceController:mqttproxy:2": {
            "policyDescription": "Allows access to publish to IoT Core topics",
            "operations": [
              "aws.greengrass#PublishToIoTCore"
            ],
            "resources": [
              "telemetry/device1"
            ]
          }
        }
      }
    }
  },
  "ComponentDependencies": {
    "aws.greengrass.TokenExchangeService": {
      "VersionRequirement": ">=2.0.0",
      "DependencyType": "HARD"
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux",
        "runtime": "*"
      },
      "Lifecycle": {
        "run": "java -jar {artifacts:path}/DeviceController.jar"
      },
      "Artifacts": [
        {
          "Uri": "s3://YOUR-BUCKET/artifacts/com.example.DeviceController/1.0.0/DeviceController.jar"
        }
      ]
    }
  ]
}
```

------
#### [ JavaScript ]

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.DeviceController",
  "ComponentVersion": "1.0.0",
  "ComponentType": "aws.greengrass.generic",
  "ComponentDescription": "Receives commands from IoT Core and sends telemetry back to cloud",
  "ComponentPublisher": "[Your Company]",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.mqttproxy": {
          "com.example.DeviceController:mqttproxy:1": {
            "policyDescription": "Allows access to subscribe to command topics from IoT Core",
            "operations": [
              "aws.greengrass#SubscribeToIoTCore"
            ],
            "resources": [
              "commands/device1"
            ]
          },
          "com.example.DeviceController:mqttproxy:2": {
            "policyDescription": "Allows access to publish telemetry to IoT Core",
            "operations": [
              "aws.greengrass#PublishToIoTCore"
            ],
            "resources": [
              "telemetry/*"
            ]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux",
        "runtime": "*"
      },
      "Lifecycle": {
        "run": "cd {artifacts:decompressedPath}/DeviceController && node DeviceController.js"
      },
      "Artifacts": [
        {
          "Uri": "s3://YOUR-BUCKET/artifacts/com.example.DeviceController/1.0.0/DeviceController.zip",
          "Unarchive": "ZIP"
        }
      ]
    }
  ]
}
```

------
#### [ C/C\$1\$1 ]

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.DeviceController",
  "ComponentVersion": "1.0.0",
  "ComponentType": "aws.greengrass.generic",
  "ComponentDescription": "Receives commands from IoT Core and sends telemetry back to cloud",
  "ComponentPublisher": "[Your Company]",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "accessControl": {
        "aws.greengrass.ipc.mqttproxy": {
          "com.example.DeviceController:mqttproxy:1": {
            "policyDescription": "Allows access to subscribe to IoT Core topics",
            "operations": ["aws.greengrass#SubscribeToIoTCore"],
            "resources": ["commands/device1"]
          },
          "com.example.DeviceController:mqttproxy:2": {
            "policyDescription": "Allows access to publish to IoT Core topics",
            "operations": ["aws.greengrass#PublishToIoTCore"],
            "resources": ["telemetry/device1"]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux",
        "runtime": "*"
      },
      "Lifecycle": {
        "run": "{artifacts:path}/device_controller"
      },
      "Artifacts": [
        {
          "Uri": "s3://YOUR-BUCKET/artifacts/com.example.DeviceController/1.0.0/device_controller"
        }
      ]
    }
  ]
}
```

------

# Greengrass V1 コアデバイスを Greengrass V2 にアップグレードします。
<a name="upgrade-v1-core-devices"></a>

アプリケーションとコンポーネントが AWS IoT Greengrass V2 コアデバイスで動作することを確認したら、本番稼働用デバイスなど、現在 v1.x を実行しているデバイスに AWS IoT Greengrass Core ソフトウェア v2.x をインストールできます。次に、Greengrass V2 コンポーネントをデプロイして、Greengrass アプリケーションをデバイスで実行します。

デバイスのフリートを V1 から V2 にアップグレードするには、アップグレードするデバイスごとに次の手順を実行します。モノグループを使用して、V2 コンポーネントをコアデバイスのフリートにデプロイできます。

**ヒント**  
デバイスのフリートに対するアップグレードプロセスを自動化するスクリプトを作成することをお勧めします。[AWS Systems Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/what-is-systems-manager.html) を使用してフリートを管理する場合、システムマネージャーを使用し、各デバイスにそのスクリプトを実行してフリートを V1 から V2 にアップグレードできます。  
アップグレードプロセスの最適な自動化方法については、 AWS エンタープライズサポート担当者にお問い合わせください。



## ステップ 1: AWS IoT Greengrass Core ソフトウェア v2.x をインストールする
<a name="install-v2-on-v1"></a>

次のオプションから選択して、 AWS IoT Greengrass Core ソフトウェア v2.x を V1 コアデバイスにインストールします。
+ **[より少ないステップでアップグレード](#install-v2-after-uninstall)**

  より少ない手順でアップグレードするには、v2.x ソフトウェアをインストールする前に v1.x ソフトウェアをアンインストールできます。
+ **[最小限のダウンタイムでアップグレード](#install-v2-side-by-side)**

  最小限のダウンタイムでアップグレードするには、両方のバージョンの AWS IoT Greengrass Core ソフトウェアを同時にインストールできます。 AWS IoT Greengrass Core ソフトウェア v2.x をインストールし、V2 アプリケーションが正しく動作することを確認したら、 AWS IoT Greengrass Core ソフトウェア v1.x をアンインストールします。このオプションを選択する前に、両方のバージョンの AWS IoT Greengrass Core ソフトウェアを同時に実行するために必要な追加の RAM を検討してください。

### v2.x をインストールする前に AWS IoT Greengrass Core v1.x をアンインストールする
<a name="install-v2-after-uninstall"></a>

順次アップグレードする場合は、デバイスに v2.x をインストールする前に AWS IoT Greengrass Core ソフトウェア v1.x をアンインストールします。

**AWS IoT Greengrass Core ソフトウェア v1.x をアンインストールするには**

1.  AWS IoT Greengrass Core ソフトウェア v1.x がサービスとして実行されている場合は、サービスを停止、無効化、削除する必要があります。

   1. 実行中の AWS IoT Greengrass Core ソフトウェア v1.x サービスを停止します。

      ```
      sudo systemctl stop greengrass 
      ```

   1. サービスが停止するまで待ちます。`list` コマンドを使用してサービスの状況を確認できます。

      ```
      sudo systemctl list-units --type=service | grep greengrass
      ```

   1. サービスを無効にします。

      ```
      sudo systemctl disable greengrass
      ```

   1. サービスを削除します。

      ```
      sudo rm /etc/systemd/system/greengrass.service
      ```

1.  AWS IoT Greengrass Core ソフトウェア v1.x がサービスとして実行されていない場合は、次のコマンドを使用してデーモンを停止します。*greengrass-root* を Greengrass ルートフォルダの名前に置き換えます。デフォルトの場所は `/greengrass` です。

   ```
   cd /greengrass-root/ggc/core/
   sudo ./greengrassd stop
   ```

1. (オプション) Greengrass ルートフォルダをバックアップし、該当する場合、[カスタム書き込みフォルダ](https://docs.aws.amazon.com/greengrass/v1/developerguide/gg-core.html#write-directory)をデバイスの別のフォルダにバックアップします。

   1. 次のコマンドを使用し、現在の Greengrass ルートフォルダを別のフォルダにコピーして、ルートフォルダを削除します。

      ```
      sudo cp -r /greengrass-root /path/to/greengrass-backup
      rm -rf /greengrass-root
      ```

   1. 次のコマンドを使用し、書き込みフォルダを別のフォルダに移動して、書き込みフォルダを削除します。

      ```
      sudo cp -r /write-directory /path/to/write-directory-backup
      rm -rf /write-directory
      ```

Greengrass nucleus の場合: [のインストール手順 AWS IoT Greengrass V2](install-greengrass-core-v2.md)を使用して、デバイスに Greengrass nucleus をインストールできます。

Greengrass nucleus lite の場合: [Greengrass nucleus lite のインストール手順](greengrass-nucleus-lite-component.md)を使用して、Greengrass nucleus lite をインストールできます。

**ヒント**  <a name="tip-migrate-reuse-core-device-identity"></a>
V1 から V2 に移行するときにコアデバイスの ID を再利用するには、手順に従って、[手動プロビジョニングで AWS IoT Greengrass Core ソフトウェアをインストールします](manual-installation.md)。まずデバイスから V1 コアソフトウェアを削除し、次に V1 コアデバイスの AWS IoT モノと証明書を再利用し、証明書の AWS IoT ポリシーを更新して v2.x ソフトウェアに必要なアクセス許可を付与します。

### 既に v1.x を実行しているデバイスに AWS IoT Greengrass Core ソフトウェア v2.x をインストールする
<a name="install-v2-side-by-side"></a>

 AWS IoT Greengrass Core ソフトウェア v1.x を既に実行しているデバイスに AWS IoT Greengrass Core v2.x ソフトウェアをインストールする場合は、次の点に注意してください。
+ V2 コアデバイスの AWS IoT モノの名前は一意である必要があります。V1 コアデバイスと同じモノ名を使用しないでください。
+  AWS IoT Greengrass Core ソフトウェア v2.x に使用するポートは、v1.x に使用するポートとは異なる必要があります。
  + 8088 以外のポートを使用するように V1 ストリームマネージャーを設定します。詳細については、「[ストリームマネージャーの設定](https://docs.aws.amazon.com/greengrass/v1/developerguide/configure-stream-manager.html)」を参照してください。
  + 8883 以外のポートを使用するように V1 MQTT ブローカを設定します。詳細については、「[ローカルメッセージング用に MQTT ポートの設定](https://docs.aws.amazon.com/greengrass/v1/developerguide/gg-core.html#config-local-mqtt-port)」を参照してください。
+ AWS IoT Greengrass V2 には、Greengrass システムサービスの名前を変更するオプションはありません。Greengrass をシステムサービスとして実行する場合、システムサービス名の不一致を避けるため、次のいずれかの操作を行う必要があります。
  + v2.x をインストールする前に、v1.x の Greengrass サービスの名前を変更します。
  + Core AWS IoT Greengrass ソフトウェア v2.x をシステムサービスなしでインストールし、 以外の名前で[ソフトウェアをシステムサービスとして手動で設定します](configure-greengrass-core-v2.md#configure-system-service)`greengrass`。

**v1.x の Greengrass サービスの名前を変更するには**

  1.  AWS IoT Greengrass Core ソフトウェア v1.x サービスを停止します。

     ```
     sudo systemctl stop greengrass
     ```

  1. サービスが停止するのを待ちます。サービスの停止に数分かかることがあります。`list-units` コマンドを実行して、サービスが停止したかどうか調べられます。

     ```
     sudo systemctl list-units --type=service | grep greengrass
     ```

  1. サービスを無効にします。

     ```
     sudo systemctl disable greengrass
     ```

  1. サービスの名前を変更します。

     ```
     sudo mv /etc/systemd/system/greengrass.service /etc/systemd/system/greengrass-v1.service
     ```

  1. サービスをリロードして起動します。

     ```
     sudo systemctl daemon-reload
     sudo systemctl reset-failed
     sudo systemctl enable greengrass-v1 
     sudo systemctl start greengrass-v1
     ```

次に、[AWS IoT Greengrass V2のインストール手順](install-greengrass-core-v2.md)を使用して、デバイスにソフトウェアをインストールします。

**ヒント**  <a name="tip-migrate-reuse-core-device-identity"></a>
V1 から V2 に移行するときにコアデバイスの ID を再利用するには、手順に従って、[手動プロビジョニングで AWS IoT Greengrass Core ソフトウェアをインストールします](manual-installation.md)。まずデバイスから V1 コアソフトウェアを削除し、次に V1 コアデバイスの AWS IoT モノと証明書を再利用し、証明書の AWS IoT ポリシーを更新して v2.x ソフトウェアに必要なアクセス許可を付与します。

## ステップ 2: コアデバイスに AWS IoT Greengrass V2 コンポーネントをデプロイする
<a name="deploy-v2-resources"></a>

 AWS IoT Greengrass Core ソフトウェア v2.x をデバイスにインストールしたら、選択したランタイムに基づいてコンポーネントをデプロイします。

### Greengrass nucleus の場合:
<a name="deploy-nucleus-components"></a>

次のリソースを含むデプロイを作成します。コンポーネントを同様なデバイスのフリートにデプロイするには、それらのデバイスを含むモノグループのデプロイを作成します。
+ V1 Lambda 関数から作成した Lambda 関数のコンポーネント。詳細については、「[AWS Lambda 関数を実行する](run-lambda-functions.md)」を参照してください。
+ V1 サブスクリプションを使用する場合、[レガシー サブスクリプション ルータ コンポーネント](legacy-subscription-router-component.md)。
+ ストリームマネージャーを使用する場合、[ストリーム マネージャー コンポーネント](stream-manager-component.md)。詳細については、「[Greengrass コアデバイスでのデータストリームの管理](manage-data-streams.md)」を参照してください。
+ ローカルシークレットを使う場合、[シークレットマネージャーコンポーネント](secret-manager-component.md)。
+ V1 コネクタを使用する場合、[AWSが提供するコネクタコンポーネント](set-up-v2-test-device.md#use-v1-connectors)。
+ Docker コンテナを使用する場合、[Docker アプリケーション マネージャー コンポーネント](docker-application-manager-component.md)。詳細については、「[Docker コンテナの実行](run-docker-container.md)」を参照してください。
+ 接続されたデバイスを使用する場合、[クライアント デバイス サポート用コンポーネント](client-device-components.md)。クライアントデバイスのサポートを有効にして、クライアントデバイスをコアデバイスに関連付ける必要があります。詳細については、「[ローカル IoT デバイスとやり取りする](interact-with-local-iot-devices.md)」を参照してください。
+ デバイスシャドウを使用する場合、[シャドウ マネージャー コンポーネント](shadow-manager-component.md)。詳細については、「[デバイスシャドウとやり取り](interact-with-shadows.md)」を参照してください。
+ Greengrass コアデバイスから Amazon CloudWatch Logs にログをアップロードする場合、[ログマネージャーコンポーネント](log-manager-component.md)。詳細については、「[AWS IoT Greengrass ログのモニタリング](monitor-logs.md)」を参照してください。
+ と統合する場合は AWS IoT SiteWise、[手順に従って](https://docs.aws.amazon.com/iot-sitewise/latest/userguide/configure-gateway-ggv2.html) V2 コアデバイスを AWS IoT SiteWise ゲートウェイとしてセットアップします。 は、 AWS IoT SiteWise コンポーネントをデプロイするインストールスクリプト AWS IoT SiteWise を提供します。
+ カスタム機能を実装するために開発したユーザー定義のコンポーネント。

デプロイの作成と改訂の情報については、「[AWS IoT Greengrass コンポーネントをデバイスにデプロイする](manage-deployments.md)」を参照してください。

### Greengrass nucleus lite の場合:
<a name="deploy-nucleus-lite-components"></a>

[移行ガイドのステップ 2 ](set-up-v2-test-device-lite.md#lite-step-2-convert-lambda)で作成した汎用コンポーネントを Greengrass nucleus lite デバイスにデプロイします。

1. 作成したコンポーネントレシピを使用して でコンポーネントを作成する

1. 汎用コンポーネントを含む Greengrass nucleus lite デバイスを対象とするデプロイを作成する

1. コンポーネントが正しく実行されていることを確認します。