

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Migrasi dari AWS IoT Greengrass Versi 1
<a name="migrate-from-v1"></a>

AWS IoT Greengrass Version 2 adalah rilis versi utama dari perangkat lunak AWS IoT Greengrass Core, APIs, dan konsol. AWS IoT Greengrass V2 memperkenalkan beberapa perbaikan AWS IoT Greengrass V1, seperti aplikasi modular, penyebaran ke armada perangkat besar, dan dukungan untuk platform tambahan.

**catatan**  
Pemberitahuan akhir dukungan: Pada 7 Oktober 2026, AWS akan mengakhiri dukungan untuk AWS IoT Greengrass Version 1. Setelah 7 Oktober 2026, Anda tidak akan lagi dapat mengakses AWS IoT Greengrass V1 konsol atau AWS IoT Greengrass V1 sumber daya.

Ikuti petunjuk dalam panduan ini untuk bermigrasi dari AWS IoT Greengrass V1 ke AWS IoT Greengrass V2.

## Ikhtisar migrasi
<a name="migration-overview"></a>

Pada tingkat tinggi, Anda dapat menggunakan prosedur berikut untuk meningkatkan perangkat inti dari AWS IoT Greengrass V1 ke AWS IoT Greengrass V2.

Sebelum bermigrasi, Anda akan memilih di antara dua opsi runtime:
+ Inti **Greengrass** (upaya migrasi yang lebih rendah, dukungan fitur lengkap)
+ **Greengrass nucleus** lite (upaya migrasi yang lebih tinggi, dirancang untuk perangkat terbatas sumber daya).

Prosedur pasti yang Anda ikuti bergantung pada sumber daya perangkat Anda, fitur yang diperlukan, dan persyaratan lingkungan tertentu.

![\[Gambaran umum tentang cara bermigrasi dari AWS IoT Greengrass V1 ke AWS IoT Greengrass V2.\]](http://docs.aws.amazon.com/id_id/greengrass/v2/developerguide/images/migration-workflow-updated.png)


1. 

**[Memahami perbedaan antara V1 dan V2](greengrass-v1-concept-differences.md)**

   AWS IoT Greengrass V2 memperkenalkan konsep dasar baru untuk armada perangkat dan perangkat lunak yang dapat digunakan, dan V2 menyederhanakan beberapa konsep dari V1.

   Layanan AWS IoT Greengrass V2 cloud dan perangkat lunak AWS IoT Greengrass Core v2.x tidak kompatibel ke belakang dengan layanan AWS IoT Greengrass V1 cloud dan perangkat lunak AWS IoT Greengrass Core v1.x. Akibatnya, pembaruan AWS IoT Greengrass V1 over-the-air (OTA) tidak dapat memutakhirkan perangkat inti dari V1 ke V2.

1. 

**[Pilih runtime Anda (Greengrass nucleus atau Greengrass nucleus lite)](choose-runtime.md)**

   Tentukan antara Greengrass nucleus atau Greengrass nucleus lite berdasarkan sumber daya perangkat dan persyaratan fitur Anda:
   + Jalur **inti Greengrass**: Upaya migrasi yang lebih rendah. Fungsi Lambda dapat diimpor sebagai komponen Lambda dengan perubahan kode minimal. Mendukung fitur V1 (layanan bayangan lokal, perangkat klien, konektor).
   + **Jalur Greengrass nucleus lite**: Upaya migrasi yang lebih tinggi. Fungsi Lambda perlu dikonversi ke komponen generik, membutuhkan perubahan kode untuk menggunakan AWS IoT Device SDK AWS IoT Greengrass V2/Component SDK alih-alih Core SDK. AWS IoT Greengrass Tidak mendukung layanan bayangan lokal, perangkat klien, atau konektor.

1. 

**[Siapkan perangkat baru untuk menguji aplikasi V1 di V2](set-up-test-device.md)**

   Untuk meminimalkan risiko pada perangkat Anda dalam produksi, buat perangkat baru untuk menguji aplikasi V1 Anda di V2. Pilih panduan penyiapan berdasarkan pilihan runtime Anda:
   + **Opsi A - Greengrass nucleus** runtime[: Siapkan perangkat baru untuk menguji aplikasi V1 di](set-up-v2-test-device.md) V2. Impor Lambda berfungsi sebagai komponen Lambda dengan perubahan kode minimal.
   + **Opsi B - Greengrass nucleus lite** runtime[: Siapkan perangkat baru untuk menguji aplikasi V1 di V2](set-up-v2-test-device-lite.md) (Greengrass nucleus lite). Mengkonversi fungsi Lambda ke komponen generik menggunakan. AWS IoT Device SDK

1. 

**[Tingkatkan perangkat inti V1 untuk menjalankan V2](upgrade-v1-core-devices.md)**

   Setelah menguji pada perangkat baru, tingkatkan perangkat inti V1 Anda yang ada untuk menjalankan perangkat lunak AWS IoT Greengrass Core v2.x dan komponen. AWS IoT Greengrass V2 Untuk memigrasikan armada perangkat dari V1 ke V2, Anda ulangi langkah ini untuk setiap perangkat di armada.

# Perbedaan antara AWS IoT Greengrass V1 dan AWS IoT Greengrass V2
<a name="greengrass-v1-concept-differences"></a>

AWS IoT Greengrass V2 memperkenalkan konsep dasar baru untuk perangkat, armada, dan perangkat lunak yang dapat digunakan. Bagian ini menjelaskan konsep V1 yang berbeda di V2.


**Konsep dan terminologi Greengrass**  

| Konsep | AWS IoT Greengrass V1 | AWS IoT Greengrass V2 | 
| --- | --- | --- | 
|  Kode aplikasi  |  Dalam AWS IoT Greengrass V1, fungsi Lambda mendefinisikan perangkat lunak yang berjalan pada perangkat inti. Dalam setiap grup Greengrass, Anda menentukan langganan dan sumber daya lokal yang menggunakan fungsi tersebut. Untuk fungsi Lambda yang dijalankan oleh perangkat lunak AWS IoT Greengrass Core di lingkungan runtime Lambda dalam kontainer, Anda menentukan parameter kontainer, seperti batas memori.  |  Dalam AWS IoT Greengrass V2, *komponen* adalah modul perangkat lunak yang berjalan pada perangkat inti. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/id_id/greengrass/v2/developerguide/greengrass-v1-concept-differences.html) Anda dapat mengimpor fungsi Lambda V1 Anda sebagai komponen yang berjalan di lingkungan runtime Lambda di. AWS IoT Greengrass V2 Ketika Anda mengimpor fungsi Lambda, Anda menentukan langganan, sumber daya lokal, dan parameter kontainer untuk fungsi tersebut. Untuk informasi selengkapnya, lihat [Langkah 2: Membuat dan menyebarkan AWS IoT Greengrass V2 komponen untuk memigrasi aplikasi AWS IoT Greengrass V1](set-up-v2-test-device.md#run-v1-applications). Untuk informasi selengkapnya tentang cara membuat komponen kustom, lihat[Kembangkan AWS IoT Greengrass komponen](develop-greengrass-components.md).  | 
|  AWS IoT Greengrass grup dan penyebaran  |  Dalam AWS IoT Greengrass V1, grup mendefinisikan perangkat inti, pengaturan dan perangkat lunak untuk perangkat inti itu, dan daftar AWS IoT hal-hal yang dapat terhubung ke perangkat inti itu. Anda membuat penerapan untuk mengirim konfigurasi grup ke perangkat inti.  |  Di AWS IoT Greengrass V2, Anda menggunakan *penerapan* untuk menentukan komponen perangkat lunak dan konfigurasi yang berjalan pada perangkat inti. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/id_id/greengrass/v2/developerguide/greengrass-v1-concept-differences.html) Untuk informasi selengkapnya, lihat [Menyebarkan AWS IoT Greengrass komponen ke perangkat](manage-deployments.md). Di AWS IoT Greengrass V2, Anda juga dapat membuat penerapan lokal menggunakan [CLI Greengrass](gg-cli.md) untuk menguji komponen perangkat lunak khusus pada perangkat tempat Anda mengembangkannya. Untuk informasi selengkapnya, lihat [Buat AWS IoT Greengrass komponen](create-components.md).  | 
|  AWS IoT Greengrass Perangkat lunak inti  |  Di AWS IoT Greengrass V1, perangkat lunak AWS IoT Greengrass Core adalah paket tunggal yang berisi perangkat lunak dan semua fitur-fiturnya. Perangkat tepi tempat Anda menginstal perangkat lunak AWS IoT Greengrass Core disebut inti Greengrass.   |  Di AWS IoT Greengrass V2, perangkat lunak AWS IoT Greengrass Core bersifat modular, sehingga Anda dapat memilih apa yang akan diinstal untuk mengontrol jejak memori. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/id_id/greengrass/v2/developerguide/greengrass-v1-concept-differences.html)  | 
|  Konektor  |  Di AWS IoT Greengrass V1, konektor adalah modul bawaan yang Anda terapkan ke perangkat AWS IoT Greengrass V1 inti untuk berinteraksi dengan infrastruktur lokal, protokol perangkat AWS, dan layanan cloud lainnya.  |  Di AWS IoT Greengrass V2, AWS menyediakan komponen Greengrass yang mengimplementasikan fungsionalitas yang disediakan oleh konektor di V1. AWS IoT Greengrass V2 Komponen-komponen berikut menyediakan fungsionalitas konektor Greengrass V1: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/id_id/greengrass/v2/developerguide/greengrass-v1-concept-differences.html) Untuk informasi selengkapnya, lihat [Komponen yang disediakan oleh AWS](public-components.md).  | 
|  Perangkat yang terhubung (perangkat Greengrass)  |  Di AWS IoT Greengrass V1, perangkat yang terhubung adalah AWS IoT hal-hal yang Anda tambahkan ke grup Greengrass untuk terhubung ke perangkat inti dalam grup itu dan berkomunikasi melalui MQTT. Anda harus menggunakan grup tersebut setiap kali menambahkan atau menghapus perangkat yang tersambung. Anda menggunakan langganan untuk menyampaikan pesan antara perangkat yang terhubung AWS IoT Core, dan aplikasi pada perangkat inti.  |  Di AWS IoT Greengrass V2, perangkat yang terhubung disebut perangkat klien Greengrass. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/id_id/greengrass/v2/developerguide/greengrass-v1-concept-differences.html) Di keduanya AWS IoT Greengrass V1 dan AWS IoT Greengrass V2, perangkat dapat menjalankan [FreeRTOS](https://docs.aws.amazon.com/freertos/latest/userguide/freertos-lib-gg-connectivity.html) atau menggunakan [AWS IoT Device SDK](https://docs.aws.amazon.com/iot/latest/developerguide/iot-sdks.html)atau [Greengrass discovery](greengrass-discover-api.md) API untuk mendapatkan informasi tentang perangkat inti yang dapat mereka sambungkan. Greengrass discovery API kompatibel ke belakang, jadi jika Anda memiliki perangkat klien yang terhubung ke perangkat inti V1, Anda dapat menghubungkannya ke perangkat inti V2 tanpa mengubah kodenya. Untuk informasi selengkapnya tentang perangkat klien, lihat[Berinteraksilah dengan perangkat IoT lokal](interact-with-local-iot-devices.md).  | 
|  Sumber daya lokal  |  Di AWS IoT Greengrass V1, fungsi Lambda yang berjalan dalam kontainer dapat dikonfigurasi untuk mengakses volume dan perangkat pada sistem file perangkat inti. Sumber daya sistem file ini dikenal sebagai sumber daya lokal.  |  Di AWS IoT Greengrass V2, Anda dapat menjalankan komponen yang merupakan [fungsi Lambda](run-lambda-functions.md), [kontainer Docker](run-docker-container.md), atau [proses sistem operasi asli](develop-greengrass-components.md) atau runtime kustom. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/id_id/greengrass/v2/developerguide/greengrass-v1-concept-differences.html)  | 
|  Layanan bayangan lokal  |  Di AWS IoT Greengrass V1, layanan bayangan lokal diaktifkan secara default, dan hanya mendukung bayangan klasik yang tidak disebutkan namanya. Anda menggunakan AWS IoT Greengrass Core SDK di fungsi Lambda Anda untuk berinteraksi dengan bayangan di perangkat Anda.  |  Di AWS IoT Greengrass V2, Anda mengaktifkan layanan bayangan lokal dengan menerapkan komponen manajer bayangan. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/id_id/greengrass/v2/developerguide/greengrass-v1-concept-differences.html) Untuk informasi selengkapnya, lihat [Berinteraksilah dengan bayangan perangkat](interact-with-shadows.md).  | 
|  Langganan  |  Di AWS IoT Greengrass V1, Anda menentukan langganan untuk grup Greengrass untuk menentukan saluran komunikasi antara fungsi Lambda, konektor, perangkat yang terhubung, broker MQTT, dan layanan bayangan lokal AWS IoT Core . Langganan menentukan di mana fungsi Lambda menerima pesan peristiwa untuk digunakan sebagai muatan fungsi.  |  Di AWS IoT Greengrass V2, Anda menentukan saluran komunikasi tanpa menggunakan langganan. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/id_id/greengrass/v2/developerguide/greengrass-v1-concept-differences.html)  | 
|  Mengakses lainnya Layanan AWS  |  Di AWS IoT Greengrass V1, Anda melampirkan peran AWS Identity and Access Management (IAM), yang disebut peran grup, ke grup Greengrass. Peran grup menentukan izin yang digunakan oleh fungsi dan AWS IoT Greengrass fitur Lambda pada perangkat inti grup tersebut untuk mengakses. Layanan AWS  |  Di AWS IoT Greengrass V2, Anda melampirkan alias AWS IoT peran ke perangkat inti Greengrass. Alias peran menunjuk ke peran IAM yang disebut peran *pertukaran token*. Peran pertukaran token mendefinisikan izin yang digunakan komponen Greengrass pada perangkat inti untuk mengakses. Layanan AWS Untuk informasi selengkapnya, lihat [Otorisasi perangkat inti untuk berinteraksi dengan layanan AWS](device-service-role.md).  | 

# Pilih runtime Anda (Greengrass nucleus atau Greengrass nucleus lite)
<a name="choose-runtime"></a>

Memilih antara Greengrass nucleus dan Greengrass nucleus lite bergantung pada sumber daya perangkat Anda dan fitur yang digunakan fungsi Lambda Anda. Tinjau matriks kompatibilitas sumber peristiwa dalam tabel berikut, lalu gunakan diagram alur keputusan untuk menentukan runtime mana yang sesuai untuk migrasi Anda. [Untuk perbandingan mendetail fitur Greengrass nucleus dan Greengrass nucleus lite, lihat Memilih runtime Anda.](choosing-your-runtime.md)

## Matriks kompatibilitas sumber peristiwa
<a name="event-source-compatibility"></a>

Dalam AWS IoT Greengrass V1, fungsi Lambda dapat berkomunikasi dengan lima jenis sumber peristiwa: fungsi Lambda lainnya, layanan bayangan lokal AWS IoT Core, perangkat klien, dan konektor. Tabel berikut menunjukkan sumber peristiwa mana yang didukung di setiap runtime V2.

Catatan: Nama sumber acara menggunakan AWS IoT Greengrass V1 terminologi. Saat bermigrasi ke V2, fungsi Lambda diubah menjadi komponen Lambda (hanya didukung dalam inti Greengrass) atau komponen generik (didukung di nukleus Greengrass dan Greengrass nucleus lite).


| Sumber Acara | Inti Greengrass | Greengrass nucleus lite | 
| --- | --- | --- | 
|  Fungsi Lambda lainnya dalam grup  |  ✓ (Komponen Lambda dan komponen generik)  |  ✓ (Hanya komponen generik)  | 
|  AWS IoT Core layanan  |  ✓  |  ✓  | 
|  Layanan bayangan lokal  |  ✓  |  ✗  | 
|  Perangkat klien  |  ✓  |  ✗  | 
|  Konektor  |  ✓  |  ✗  | 

## Alur keputusan pemilihan runtime
<a name="runtime-selection-decision-flow"></a>

![\[Diagram alir keputusan untuk memilih antara inti Greengrass dan Greengrass nucleus lite.\]](http://docs.aws.amazon.com/id_id/greengrass/v2/developerguide/images/runtime-selection-decision-flow.png)


### Catatan
<a name="runtime-selection-notes"></a>

1. [Untuk persyaratan Greengrass nucleus lite dan detail kompatibilitas, lihat Greengrass nucleus lite.](greengrass-nucleus-lite-component.md) Greengrass nucleus lite membutuhkan RAM minimal 5 MB dan dirancang untuk perangkat yang dibatasi sumber daya.

1. Alur keputusan memberikan panduan berdasarkan kasus penggunaan yang khas, tetapi bukan persyaratan yang ketat. Pelanggan dengan perangkat terbatas sumber daya dan sumber daya yang cukup dapat memilih untuk menggunakan satu runtime di semua perangkat untuk kesederhanaan operasional, bahkan jika beberapa perangkat dapat mendukung runtime mana pun.

## Langkah selanjutnya
<a name="next-steps-runtime"></a>

Setelah memilih runtime Anda, lanjutkan untuk menyiapkan perangkat pengujian Anda:
+ Untuk runtime nukleus Greengrass[: Siapkan perangkat baru untuk menguji aplikasi V1 di](set-up-v2-test-device.md) V2
+ Untuk runtime Greengrass nucleus lite[: Siapkan](set-up-v2-test-device-lite.md) perangkat baru dengan Greengrass nucleus lite

# Siapkan perangkat baru untuk menguji aplikasi V1 di V2
<a name="set-up-test-device"></a>

Untuk meminimalkan risiko pada perangkat Anda dalam produksi, buat perangkat baru untuk menguji aplikasi V1 Anda di V2 sebelum memutakhirkan perangkat produksi Anda.

Pilih salah satu panduan penyiapan berikut berdasarkan pilihan runtime Anda dari langkah sebelumnya:
+ **Opsi A - Runtime nukleus Greengrass: Ikuti [Siapkan perangkat baru untuk menguji aplikasi V1 di V2](set-up-v2-test-device.md) jika Anda memilih inti** Greengrass. Dengan opsi ini, Anda dapat mengimpor fungsi Lambda sebagai komponen Lambda dengan perubahan kode minimal dan mendukung fitur V1 seperti layanan bayangan lokal, perangkat klien, dan konektor.
+ **Opsi B - Greengrass nucleus lite runtime: Ikuti [Siapkan perangkat baru untuk menguji aplikasi V1 di V2 (Greengrass nucleus lite)](set-up-v2-test-device-lite.md) jika Anda memilih Greengrass nucleus lite**. Opsi ini memerlukan konversi fungsi Lambda ke komponen generik menggunakan AWS IoT Device SDK V2 AWS IoT Greengrass atau Component SDK, tetapi dioptimalkan untuk perangkat yang dibatasi sumber daya.

# Siapkan perangkat baru untuk menguji aplikasi V1 di V2
<a name="set-up-v2-test-device"></a>

Siapkan perangkat AWS IoT Greengrass V2 inti baru untuk menyebarkan dan menguji komponen dan AWS Lambda fungsi AWS yang disediakan untuk aplikasi Anda AWS IoT Greengrass V1 . Anda juga dapat menggunakan perangkat inti V2 ini untuk mengembangkan dan menguji komponen Greengrass kustom tambahan yang menjalankan proses asli pada perangkat inti. Setelah menguji aplikasi pada perangkat inti V2, Anda dapat meningkatkan perangkat inti V1 yang ada ke V2 dan menerapkan komponen V2 yang menyediakan fungsionalitas V1 Anda.



## Langkah 1: Instal AWS IoT Greengrass V2 di perangkat baru
<a name="install-v2-test-device"></a>

Instal perangkat lunak AWS IoT Greengrass Core v2.x pada perangkat baru. Anda dapat mengikuti [tutorial memulai](getting-started.md) untuk menyiapkan perangkat dan mempelajari cara mengembangkan dan menyebarkan komponen. Tutorial ini menggunakan [penyediaan otomatis untuk mengatur](quick-installation.md) perangkat dengan cepat. Saat Anda menginstal perangkat lunak AWS IoT Greengrass Core v2.x, tentukan `--deploy-dev-tools` argumen untuk menerapkan [CLI Greengrass](greengrass-cli-component.md), sehingga Anda dapat mengembangkan, menguji, dan men-debug komponen langsung di perangkat. Untuk informasi selengkapnya tentang opsi penginstalan lainnya, termasuk cara menginstal perangkat lunak AWS IoT Greengrass inti di belakang proxy atau menggunakan modul keamanan perangkat keras (HSM), lihat[Instal perangkat lunak AWS IoT Greengrass Core](install-greengrass-core-v2.md).

### (Opsional) Aktifkan logging ke Amazon CloudWatch Logs
<a name="enable-cloudwatch-logging-v2"></a>

Untuk mengaktifkan perangkat inti V2 mengunggah log ke Amazon CloudWatch Logs, Anda dapat menerapkan komponen [pengelola log AWS](log-manager-component.md) yang disediakan. Anda dapat menggunakan CloudWatch Log untuk melihat log komponen, sehingga Anda dapat men-debug dan memecahkan masalah tanpa akses ke sistem file perangkat inti. Untuk informasi selengkapnya, lihat [Memantau AWS IoT Greengrass log](monitor-logs.md).

## Langkah 2: Membuat dan menyebarkan AWS IoT Greengrass V2 komponen untuk memigrasi aplikasi AWS IoT Greengrass V1
<a name="run-v1-applications"></a>

Anda dapat menjalankan sebagian besar AWS IoT Greengrass V1 aplikasi di AWS IoT Greengrass V2. Anda dapat mengimpor fungsi Lambda sebagai komponen yang berjalan AWS IoT Greengrass V2, dan Anda dapat menggunakan [komponen yang AWS disediakan yang](public-components.md) menawarkan fungsionalitas yang sama dengan konektor. AWS IoT Greengrass 

Anda juga dapat mengembangkan komponen khusus untuk membangun fitur atau runtime apa pun untuk dijalankan di perangkat inti Greengrass. Untuk informasi tentang cara mengembangkan dan menguji komponen secara lokal, lihat[Buat AWS IoT Greengrass komponen](create-components.md).

**Topics**
+ [Impor fungsi Lambda V1](#run-v1-lambda-functions)
+ [Gunakan konektor V1](#use-v1-connectors)
+ [Jalankan kontainer Docker](#run-v1-docker-containers)
+ [Hubungkan perangkat Greengrass V1](#connect-v1-greengrass-devices)
+ [Aktifkan layanan bayangan lokal](#enable-shadow-service)
+ [Integrasikan dengan AWS IoT SiteWise](#integrate-with-iot-sitewise)

### Impor fungsi Lambda V1
<a name="run-v1-lambda-functions"></a>

Anda dapat mengimpor fungsi Lambda sebagai AWS IoT Greengrass V2 komponen. Pilih dari pendekatan berikut:
+ Impor V1 Lambda berfungsi langsung sebagai komponen Greengrass.
+ Perbarui fungsi Lambda Anda untuk menggunakan pustaka Greengrass di v2 AWS IoT Device SDK , lalu impor fungsi Lambda sebagai komponen Greengrass.
+ Buat komponen khusus yang menggunakan kode non-Lambda dan AWS IoT Device SDK v2 untuk mengimplementasikan fungsionalitas yang sama dengan fungsi Lambda Anda.

Jika fungsi Lambda Anda menggunakan fitur, seperti pengelola aliran atau rahasia lokal, Anda harus menentukan dependensi pada komponen yang AWS disediakan yang mengemas fitur ini. Ketika Anda menggunakan komponen fungsi Lambda, deployment tersebut juga mencakup komponen untuk setiap fitur yang Anda tetapkan sebagai dependensi. Dalam penerapan, Anda dapat mengonfigurasi parameter, seperti rahasia mana yang akan diterapkan ke perangkat inti. Tidak semua fitur V1 memerlukan dependensi komponen untuk fungsi Lambda Anda pada V2. Daftar berikut menjelaskan cara menggunakan fitur V1 di komponen fungsi Lambda V2 Anda:
+ **Akses AWS layanan lain**

  Jika fungsi Lambda Anda menggunakan AWS kredensional untuk membuat permintaan ke AWS layanan lain, peran pertukaran token perangkat inti harus mengizinkan perangkat inti untuk melakukan operasi AWS yang digunakan fungsi Lambda. Untuk informasi selengkapnya, lihat [Otorisasi perangkat inti untuk berinteraksi dengan layanan AWS](device-service-role.md).
+ **Manajer aliran**

  Jika fungsi Lambda Anda menggunakan stream manager, tentukan `aws.greengrass.StreamManager` sebagai dependensi komponen ketika Anda mengimpor fungsi tersebut. Saat Anda menggunakan komponen stream manager, tentukan parameter stream manager yang akan ditetapkan untuk perangkat inti target. Peran pertukaran token perangkat inti harus memungkinkan perangkat inti mengakses AWS Cloud tujuan yang Anda gunakan dengan pengelola aliran. Untuk informasi selengkapnya, lihat [Manajer pengaliran](stream-manager-component.md).
+ **Rahasia lokal**

  Jika fungsi Lambda Anda menggunakan rahasia lokal, tentukan `aws.greengrass.SecretManager` sebagai dependensi komponen ketika Anda mengimpor fungsi tersebut. Ketika Anda men-deploy komponen secret manager, tentukan sumber daya rahasia yang akan di-deploy ke perangkat inti target. Peran pertukaran token perangkat inti harus memungkinkan perangkat inti untuk mengambil sumber daya rahasia untuk digunakan. Untuk informasi selengkapnya, lihat [Secrets manager](secret-manager-component.md).

  Saat Anda menerapkan komponen fungsi Lambda, konfigurasikan agar memiliki kebijakan [otorisasi IPC yang](interprocess-communication.md#ipc-authorization-policies) memberikan izin untuk menggunakan operasi IPC [GetSecretValue di](ipc-secret-manager.md) V2. AWS IoT Device SDK 
+ **Bayangan lokal**

  Jika fungsi Lambda Anda berinteraksi dengan bayangan lokal, Anda harus memperbarui kode fungsi Lambda untuk menggunakan V2. AWS IoT Device SDK Anda juga harus menentukan `aws.greengrass.ShadowManager` sebagai dependensi komponen ketika Anda mengimpor fungsi tersebut. Untuk informasi selengkapnya, lihat [Berinteraksilah dengan bayangan perangkat](interact-with-shadows.md).

  Saat Anda menerapkan komponen fungsi Lambda Anda, konfigurasikan agar memiliki kebijakan [otorisasi IPC yang](interprocess-communication.md#ipc-authorization-policies) memberikan izin untuk menggunakan operasi IPC [bayangan di](ipc-local-shadows.md) V2. AWS IoT Device SDK 
+ **Langganan**
  + Jika fungsi Lambda Anda berlangganan pesan dari sumber cloud, tentukan langganan tersebut sebagai sumber peristiwa saat Anda mengimpor fungsi tersebut.
  + [Jika fungsi Lambda Anda berlangganan pesan dari fungsi Lambda lain, atau jika fungsi Lambda Anda menerbitkan pesan ke atau fungsi Lambda AWS IoT Core lainnya, konfigurasikan dan terapkan komponen router langganan lama saat Anda menerapkan fungsi Lambda Anda.](legacy-subscription-router-component.md) Saat Anda men-deploy komponen router langganan warisan, tentukan langganan yang digunakan oleh fungsi Lambda tersebut.
**catatan**  <a name="legacy-subscription-router-requirement-note"></a>
Komponen router langganan lama hanya diperlukan jika fungsi Lambda Anda menggunakan fungsi `publish()` di Core AWS IoT Greengrass SDK. Jika Anda memperbarui kode fungsi Lambda Anda untuk menggunakan antarmuka komunikasi antarproses (IPC) di AWS IoT Device SDK V2, Anda tidak perlu menggunakan komponen router langganan lama. Untuk informasi lebih lanjut, lihat layanan [komunikasi antar proses](interprocess-communication.md) berikut ini:  
[Pesan lokal publikasi/berlangganan](ipc-publish-subscribe.md)
[Terbitkan/berlangganan pesan MQTT AWS IoT Core](ipc-iot-core-mqtt.md)
  + Jika fungsi Lambda Anda berlangganan pesan dari perangkat lokal yang terhubung, tentukan langganan tersebut sebagai sumber peristiwa saat Anda mengimpor fungsi tersebut. Anda juga harus mengonfigurasi dan menerapkan [komponen jembatan MQTT](mqtt-bridge-component.md) untuk menyampaikan pesan dari perangkat yang terhubung ke publish/subscribe topik lokal yang Anda tentukan sebagai sumber peristiwa.
  + [Jika fungsi Lambda Anda menerbitkan pesan ke perangkat lokal yang terhubung, Anda harus memperbarui kode fungsi Lambda untuk menggunakan AWS IoT Device SDK V2 untuk mempublikasikan pesan lokal. publish/subscribe ](ipc-publish-subscribe.md) Anda juga harus mengonfigurasi dan menerapkan [komponen jembatan MQTT](mqtt-bridge-component.md) untuk menyampaikan pesan dari broker publish/subscribe pesan lokal ke perangkat yang terhubung.
+ **Volume dan perangkat lokal**

  Jika fungsi Lambda terkontainerisasi Anda mengakses volume atau perangkat lokal, tentukan volume dan perangkat tersebut saat Anda mengimpor fungsi Lambda. Fitur ini tidak memerlukan dependensi komponen.

Untuk informasi selengkapnya, lihat [Jalankan AWS Lambda fungsi](run-lambda-functions.md).

### Gunakan konektor V1
<a name="use-v1-connectors"></a>

Anda dapat menerapkan komponen yang AWS disediakan yang menawarkan fungsionalitas yang sama dari beberapa AWS IoT Greengrass konektor. Bila Anda membuat deployment, Anda dapat mengonfigurasi parameter konektor. 

 AWS IoT Greengrass V2 Komponen-komponen berikut menyediakan fungsionalitas konektor Greengrass V1:
+ [CloudWatch komponen metrik](cloudwatch-metrics-component.md)
+ [AWS IoT Device Defender komponen](device-defender-component.md)
+ [Komponen Firehose](kinesis-firehose-component.md)
+ [Komponen adaptor protokol Modbus-RTU](modbus-rtu-protocol-adapter-component.md)
+ [Komponen Amazon SNS](sns-component.md)

### Jalankan kontainer Docker
<a name="run-v1-docker-containers"></a>

AWS IoT Greengrass V2 tidak menyediakan komponen untuk secara langsung mengganti konektor penerapan aplikasi V1 Docker. Namun, Anda dapat menggunakan komponen manajer aplikasi Docker untuk mengunduh gambar Docker, dan kemudian membuat komponen khusus yang menjalankan wadah Docker dari gambar yang diunduh. Untuk informasi selengkapnya, lihat [Jalankan kontainer Docker](run-docker-container.md) dan [Manajer aplikasi Docker](docker-application-manager-component.md).

### Hubungkan perangkat Greengrass V1
<a name="connect-v1-greengrass-devices"></a>

Perangkat yang AWS IoT Greengrass V1 terhubung di disebut perangkat klien di AWS IoT Greengrass V2. AWS IoT Greengrass V2 dukungan untuk perangkat klien kompatibel ke belakang AWS IoT Greengrass V1, sehingga Anda dapat menghubungkan perangkat klien V1 ke perangkat inti V2 tanpa mengubah kode aplikasinya. Untuk mengaktifkan perangkat klien terhubung ke perangkat inti V2, gunakan komponen Greengrass yang memungkinkan dukungan perangkat klien, dan kaitkan perangkat klien ke perangkat inti. Untuk merelai pesan antara perangkat klien, layanan cloud AWS IoT Core , dan komponen Greengrass (termasuk fungsi Lambda), deploy dan konfigurasikan [Komponen jembatan MQTT](mqtt-bridge-component.md). Anda dapat men-deploy [komponen detektor IP](ip-detector-component.md) untuk secara otomatis mendeteksi informasi konektivitas, atau Anda dapat mengelola titik akhir secara manual. Untuk informasi selengkapnya, lihat [Berinteraksilah dengan perangkat IoT lokal](interact-with-local-iot-devices.md).

### Aktifkan layanan bayangan lokal
<a name="enable-shadow-service"></a>

Di AWS IoT Greengrass V2, layanan bayangan lokal diimplementasikan oleh komponen manajer bayangan AWS yang disediakan. AWS IoT Greengrass V2 juga termasuk dukungan untuk bayangan bernama. Untuk mengaktifkan komponen Anda berinteraksi dengan bayangan lokal dan menyinkronkan status bayangan AWS IoT Core, konfigurasikan dan terapkan komponen pengelola bayangan, dan gunakan operasi IPC bayangan dalam kode komponen Anda. Untuk informasi selengkapnya, lihat [Berinteraksilah dengan bayangan perangkat](interact-with-shadows.md). 

### Integrasikan dengan AWS IoT SiteWise
<a name="integrate-with-iot-sitewise"></a>

Jika Anda menggunakan perangkat inti V1 sebagai AWS IoT SiteWise gateway, [ikuti petunjuk](https://docs.aws.amazon.com/iot-sitewise/latest/userguide/configure-gateway-ggv2.html) untuk menyiapkan perangkat inti V2 baru Anda sebagai AWS IoT SiteWise gateway. AWS IoT SiteWise menyediakan skrip instalasi yang menyebarkan AWS IoT SiteWise komponen untuk Anda.

## Langkah 3: Uji AWS IoT Greengrass V2 aplikasi Anda
<a name="test-v2-features"></a>

Setelah Anda membuat dan menerapkan komponen V2 ke perangkat inti V2 baru Anda, verifikasi bahwa aplikasi Anda memenuhi harapan Anda. Anda dapat memeriksa log perangkat untuk melihat pesan keluaran standar (stdout) dan kesalahan standar (stderr) komponen Anda. Untuk informasi selengkapnya, lihat [Memantau AWS IoT Greengrass log](monitor-logs.md).

Jika Anda menerapkan CLI [Greengrass](greengrass-cli-component.md) ke perangkat inti, Anda dapat menggunakannya untuk men-debug komponen dan konfigurasinya. Untuk informasi selengkapnya, lihat [Perintah Greengrass CLI](gg-cli-reference.md).

Setelah Anda memverifikasi bahwa aplikasi Anda bekerja pada perangkat inti V2, Anda dapat menerapkan komponen Greengrass aplikasi Anda ke perangkat inti lainnya. Jika Anda mengembangkan komponen kustom yang menjalankan proses asli atau kontainer Docker, Anda harus terlebih dahulu [mempublikasikan komponen tersebut](publish-components.md) ke AWS IoT Greengrass layanan untuk menerapkannya ke perangkat inti lainnya.

# Siapkan perangkat baru untuk menguji aplikasi V1 di V2 (Greengrass nucleus lite)
<a name="set-up-v2-test-device-lite"></a>

Siapkan perangkat baru dengan Greengrass nucleus lite untuk menguji komponen generik yang Anda buat untuk memigrasikan aplikasi Anda ke V2. AWS IoT Greengrass V1 Greengrass nucleus lite adalah runtime ringan yang dioptimalkan untuk perangkat terbatas sumber daya. Anda dapat menggunakan perangkat ini untuk mengembangkan dan menguji komponen Greengrass kustom yang menjalankan proses asli. Setelah menguji aplikasi pada perangkat Greengrass nucleus lite, Anda dapat menerapkan komponen V2 ke perangkat lain yang menjalankan Greengrass nucleus lite atau memutakhirkan perangkat inti V1 yang ada ke V2.



## Langkah 1: Instal Greengrass nucleus lite di perangkat baru
<a name="lite-step-1-install"></a>

Instal Greengrass nucleus lite di perangkat baru. Ikuti panduan [instalasi Greengrass nucleus lite](https://docs.aws.amazon.com/greengrass/v2/developerguide/greengrass-nucleus-lite-component.html#greengrass-nucleus-lite-component-install) untuk menyiapkan perangkat.

**catatan**  
Greengrass nucleus lite tidak mendukung layanan bayangan lokal, perangkat klien, atau konektor sekarang. Pastikan aplikasi V1 Anda tidak bergantung pada fitur-fitur ini sebelum melanjutkan dengan panduan ini.

## Langkah 2: Buat dan terapkan komponen generik untuk memigrasi AWS IoT Greengrass V1 fungsi Lambda
<a name="lite-step-2-convert-lambda"></a>

Untuk mereplikasi fungsionalitas fungsi AWS IoT Greengrass V1 Lambda Anda di Greengrass nucleus lite, Anda harus mengonversinya menjadi komponen generik. Ini melibatkan penulisan ulang kode fungsi Lambda Anda untuk menggunakan AWS IoT Device SDK V2 AWS IoT Greengrass atau Component SDK alih-alih AWS IoT Greengrass Core SDK.

Tabel berikut mencantumkan yang SDKs digunakan dalam contoh komponen V2 dalam panduan ini:


| SDK | Versi minimum | 
| --- | --- | 
| [AWS IoT Device SDK untuk Python v2](https://github.com/aws/aws-iot-device-sdk-python-v2) | v1.11.3 | 
| [AWS IoT Device SDK untuk Java v2](https://github.com/aws/aws-iot-device-sdk-java-v2) | v1.9.3 | 
| [AWS IoT Device SDK untuk JavaScript v2](https://github.com/aws/aws-iot-device-sdk-js-v2) | v1.12.0 | 
| [AWS IoT Greengrass Komponen SDK (C/C\$1\$1) (saat ini dalam pratinjau)](https://github.com/aws-greengrass/aws-greengrass-component-sdk) | v0.4.0 | 

Contoh di bawah ini menunjukkan fungsi Lambda yang menggunakan AWS IoT Greengrass V1 Core SDK dan komponen generiknya yang setara, dengan kode komponen, resep, dan instruksi build dalam beberapa bahasa pemrograman untuk dua skenario utama:
+ **Komunikasi lokal** - Komponen yang berkomunikasi dengan komponen lain pada perangkat yang sama menggunakan pub/sub lokal
+ **Cloud Communication** - Komponen yang berkomunikasi dengan AWS IoT Core atau AWS layanan lainnya

### Skenario 1: Komunikasi Lokal (penerbit → prosesor → pelanggan)
<a name="lite-example-local-communication"></a>

Skenario ini menunjukkan konversi fungsi Lambda V1 yang menggunakan komunikasi pub/sub lokal ke komponen generik V2.

#### Arsitektur aplikasi
<a name="lite-example-1-scenario"></a>

Contoh ini melibatkan tiga komponen:
+ Penerbit Lambda menerbitkan data suhu
+ Prosesor Lambda menerima data dan memprosesnya
+ Prosesor Lambda menerbitkan hasil yang diproses ke pelanggan Lambda

Contoh kode di bawah ini berfokus pada prosesor Lambda, yang menunjukkan berlangganan dan menerbitkan pesan untuk komunikasi lokal.

##### Langganan grup V1
<a name="lite-example-1-v1-subscriptions"></a>

Di AWS IoT Greengrass V1, langganan grup berikut memungkinkan komunikasi antara fungsi Lambda:

Langganan 1: penerbit → prosesor
+ Sumber: Lambda (penerbit)
+ Target: Lambda (prosesor)
+ Topik: sensor/suhu

Berlangganan 2: prosesor → pelanggan
+ Sumber: Lambda (prosesor)
+ Target: Lambda (pelanggan)
+ Topik: lambda/alerts

#### Fungsi Prosesor 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;
}
```

------

#### Komponen generik (V2)
<a name="lite-example-1-v2-code"></a>

Untuk mencapai fungsionalitas yang sama di AWS IoT Greengrass V2, buat komponen generik dengan yang berikut ini:

##### 1. Kode komponen
<a name="lite-example-1-component-code"></a>

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

Prasyarat: Sebelum menggunakan kode komponen ini, instal dan verifikasi untuk AWS IoT Device SDK Python di perangkat Greengrass Anda:

```
# Install the SDK
pip3 install awsiotsdk

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

Jika Anda mengalami konflik ketergantungan selama instalasi, coba instal versi tertentu dari file. AWS IoT Device SDK

Jika perintah verifikasi mencetak “SDK berhasil diinstal”, Anda siap menggunakan kode komponen:

```
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. Membangun dan mengemas komponen
<a name="lite-example-1-build-component"></a>

Beberapa bahasa memerlukan pembuatan atau pengemasan sebelum penerapan.

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

Python tidak memerlukan kompilasi. Komponen dapat menggunakan file.py secara langsung.

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

Untuk membangun JAR yang dapat dieksekusi dengan semua dependensi yang dibundel:

1. Buat `pom.xml` file di direktori proyek Anda:

   ```
   <?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. Bangun JAR:

   ```
   mvn clean package
   ```

   Ini dibuat `target/temperature-processor-1.0.0.jar` dengan semua dependensi disertakan.

1. Unggah JAR ke bucket S3 Anda untuk penerapan.

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

Untuk mengemas komponen Node.js Anda dengan semua dependensi:

1. Buat `package.json` file:

   ```
   {
     "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. Instal dependensi pada mesin pengembangan Anda:

   ```
   npm install
   ```

   Ini membuat `node_modules` folder yang berisi AWS AWS IoT Device SDK v2.

1. Package untuk penyebaran:

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

1. Unggah file zip ke bucket S3 Anda untuk penerapan.

**catatan**  
Perangkat Greengrass harus menginstal runtime Node.js (versi 14 atau yang lebih baru). Anda tidak perlu menjalankan `npm install` perangkat inti Greengrass karena artefak komponen menyertakan semua dependensi dalam folder yang dibundel. `node_modules`

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

**Prasyarat:**

Untuk membangun SDK dan komponen, Anda memerlukan dependensi build berikut:
+ GCC atau Dentang
+ CMake (setidaknya versi 3.22)
+ Buat atau Ninja

**Instal dependensi build:**

Di Ubuntu/Debian:

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

Di Amazon Linux:

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

**Buat file CMake Lists.txt untuk komponen Anda:**

```
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)
```

**Membangun langkah-langkah:**

```
# 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 ]

**Prasyarat:**

Untuk membangun SDK dan komponen, Anda memerlukan dependensi build berikut:
+ GCC atau Clang dengan dukungan C\$1\$120
+ CMake (setidaknya versi 3.22)
+ Buat atau Ninja

**Instal dependensi build:**

Di Ubuntu/Debian:

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

Di Amazon Linux:

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

**Buat file CMake Lists.txt untuk komponen Anda:**

```
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++)
```

**Membangun langkah-langkah:**

```
# 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. Resep komponen
<a name="lite-example-1-component-recipe"></a>

Perbarui array “resource” dengan topik aktual yang digunakan komponen Anda.

------
#### [ 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"
        }
      ]
    }
  ]
}
```

------

### Skenario 2: Komunikasi Cloud
<a name="lite-example-cloud-communication"></a>

Skenario ini menunjukkan konversi fungsi Lambda V1 yang berkomunikasi AWS IoT Core dengan ke komponen generik V2.

#### Arsitektur aplikasi
<a name="lite-example-2-scenario"></a>

Contoh ini menggunakan arsitektur yang terhubung dengan cloud:
+ AWS IoT Core mengirim perintah ke perangkat
+ Controller Lambda menerima perintah dan memprosesnya
+ Controller Lambda mengirimkan data telemetri kembali ke AWS IoT Core

Contoh ini berfokus pada pengontrol Lambda, yang menunjukkan penerimaan pesan dari dan penerbitan pesan ke. AWS IoT Core

##### Langganan grup V1
<a name="lite-example-2-v1-subscriptions"></a>

Di AWS IoT Greengrass V1, langganan grup berikut memungkinkan komunikasi antara fungsi Lambda dan: AWS IoT Core

Berlangganan 1: IoT Cloud → Lambda
+ Sumber: IoT Cloud
+ Target: Lambda () DeviceController
+ Topik: perintah/perangkat1

Berlangganan 2: Lambda → IoT Cloud
+ Sumber: Lambda () DeviceController
+ Target: IoT Cloud
+ Topik: telemetri/perangkat1

#### Fungsi Pengontrol 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;
}
```

------

#### Komponen generik (V2)
<a name="lite-example-2-v2-code"></a>

Untuk mencapai fungsionalitas yang sama di AWS IoT Greengrass V2, buat komponen generik dengan yang berikut ini:

##### 1. Kode komponen
<a name="lite-example-2-component-code"></a>

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

Prasyarat: Sebelum menggunakan kode komponen ini, instal dan verifikasi untuk AWS IoT Device SDK Python di perangkat Greengrass Anda:

```
# Install the SDK
pip3 install awsiotsdk

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

Jika Anda mengalami konflik ketergantungan selama instalasi, coba instal versi tertentu dari file. AWS IoT Device SDK

Jika perintah verifikasi mencetak “SDK berhasil diinstal”, Anda siap menggunakan kode komponen:

```
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. Membangun dan mengemas komponen
<a name="lite-example-2-build-component"></a>

Beberapa bahasa memerlukan pembuatan atau pengemasan sebelum penerapan.

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

Python tidak memerlukan kompilasi. Komponen dapat menggunakan file.py secara langsung.

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

Untuk membangun JAR yang dapat dieksekusi dengan semua dependensi yang dibundel:

1. Buat `pom.xml` file di direktori proyek Anda:

   ```
   <?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. Bangun JAR:

   ```
   mvn clean package
   ```

   Ini dibuat `target/device-controller-1.0.0.jar` dengan semua dependensi disertakan.

1. Unggah JAR ke bucket S3 Anda untuk penerapan.

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

Untuk mengemas komponen Node.js Anda dengan semua dependensi:

1. Buat `package.json` file:

   ```
   {
     "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. Instal dependensi pada mesin pengembangan Anda:

   ```
   npm install
   ```

   Ini membuat `node_modules` folder yang berisi AWS AWS IoT Device SDK v2.

1. Package untuk penyebaran:

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

1. Unggah file zip ke bucket S3 Anda untuk penerapan.

**catatan**  
Perangkat Greengrass harus menginstal runtime Node.js (versi 14 atau yang lebih baru). Anda tidak perlu menjalankan `npm install` perangkat inti Greengrass karena artefak komponen menyertakan semua dependensi dalam folder yang dibundel. `node_modules`

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

**Prasyarat:**

Untuk membangun SDK dan komponen, Anda memerlukan dependensi build berikut:
+ GCC atau Dentang
+ CMake (setidaknya versi 3.22)
+ Buat atau Ninja

**Instal dependensi build:**

Di Ubuntu/Debian:

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

Di Amazon Linux:

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

**Buat file CMake Lists.txt untuk komponen Anda:**

```
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)
```

**Membangun langkah-langkah:**

```
# 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 ]

**Prasyarat:**

Untuk membangun SDK dan komponen, Anda memerlukan dependensi build berikut:
+ GCC atau Clang dengan dukungan C\$1\$120
+ CMake (setidaknya versi 3.22)
+ Buat atau Ninja

**Instal dependensi build:**

Di Ubuntu/Debian:

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

Di Amazon Linux:

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

**Buat file CMake Lists.txt untuk komponen Anda:**

```
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++)
```

**Membangun langkah-langkah:**

```
# 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. Resep komponen
<a name="lite-example-2-component-recipe"></a>

Perbarui array “resource” dengan topik aktual yang digunakan komponen Anda.

------
#### [ 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"
        }
      ]
    }
  ]
}
```

------

# Tingkatkan perangkat inti Greengrass V1 ke Greengrass V2
<a name="upgrade-v1-core-devices"></a>

Setelah memverifikasi bahwa aplikasi dan komponen berfungsi pada perangkat AWS IoT Greengrass V2 inti, Anda dapat menginstal perangkat lunak AWS IoT Greengrass Core v2.x di perangkat yang saat ini menjalankan v1.x, seperti perangkat produksi. Kemudian, gunakan komponen Greengrass V2 untuk menjalankan aplikasi Greengrass Anda di perangkat.

Untuk meningkatkan armada perangkat dari V1 ke V2, selesaikan langkah-langkah ini agar setiap perangkat dapat ditingkatkan. Anda dapat menggunakan grup benda untuk menyebarkan komponen V2 ke armada perangkat inti.

**Tip**  
Kami menyarankan Anda membuat skrip untuk mengotomatiskan proses peningkatan untuk armada perangkat. Jika Anda menggunakannya [AWS Systems Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/what-is-systems-manager.html)untuk mengelola armada, Anda dapat menggunakan Systems Manager untuk menjalankan skrip tersebut di setiap perangkat untuk meningkatkan armada Anda dari V1 ke V2.  
Anda dapat menghubungi perwakilan Support AWS Enterprise Anda untuk mengajukan pertanyaan tentang cara terbaik untuk mengotomatisasi proses upgrade.



## Langkah 1: Instal perangkat lunak AWS IoT Greengrass Core v2.x
<a name="install-v2-on-v1"></a>

Pilih dari opsi berikut untuk menginstal perangkat lunak AWS IoT Greengrass Core v2.x pada perangkat inti V1:
+ **[Tingkatkan dalam langkah yang lebih sedikit](#install-v2-after-uninstall)**

  Untuk meningkatkan dalam langkah yang lebih sedikit, Anda dapat menghapus instalasi perangkat lunak v1.x sebelum Anda menginstal perangkat lunak v2.x.
+ **[Upgrade dengan downtime minimal](#install-v2-side-by-side)**

  Untuk meningkatkan dengan downtime minimal, Anda dapat menginstal kedua versi perangkat lunak AWS IoT Greengrass Core secara bersamaan. Setelah Anda menginstal perangkat lunak AWS IoT Greengrass Core v2.x dan memverifikasi bahwa aplikasi V2 Anda beroperasi dengan benar, Anda menghapus instalasi perangkat lunak AWS IoT Greengrass Core v1.x. Sebelum Anda memilih opsi ini, pertimbangkan RAM tambahan yang diperlukan untuk menjalankan kedua versi perangkat lunak AWS IoT Greengrass Core secara bersamaan.

### Copot pemasangan AWS IoT Greengrass Core v1.x sebelum Anda menginstal v2.x
<a name="install-v2-after-uninstall"></a>

Jika Anda ingin memutakhirkan secara berurutan, hapus instalan perangkat lunak AWS IoT Greengrass Core v1.x sebelum Anda menginstal v2.x di perangkat Anda.

**Untuk menghapus instalasi perangkat lunak AWS IoT Greengrass Core v1.x**

1. Jika perangkat lunak AWS IoT Greengrass Core v1.x berjalan sebagai layanan, Anda harus menghentikan, menonaktifkan, dan menghapus layanan.

   1. Hentikan layanan v1.x perangkat lunak AWS IoT Greengrass Core yang sedang berjalan. 

      ```
      sudo systemctl stop greengrass 
      ```

   1. Tunggu sampai layanan berhenti. Anda dapat menggunakan `list` perintah untuk memeriksa status layanan. 

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

   1. Nonaktifkan layanan. 

      ```
      sudo systemctl disable greengrass
      ```

   1. Hapus layanan. 

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

1. Jika perangkat lunak AWS IoT Greengrass Core v1.x tidak berjalan sebagai layanan, gunakan perintah berikut untuk menghentikan daemon. Ganti *greengrass-root* dengan nama folder root Greengrass Anda. Lokasi default adalah `/greengrass`.

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

1. (Opsional) Cadangkan folder root Greengrass Anda dan, jika ada, folder [tulis khusus Anda, ke folder lain](https://docs.aws.amazon.com/greengrass/v1/developerguide/gg-core.html#write-directory) di perangkat Anda.

   1. Gunakan perintah berikut untuk menyalin folder root Greengrass saat ini ke folder lain, lalu hapus folder root.

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

   1. Gunakan perintah berikut untuk memindahkan folder tulis ke folder lain, lalu hapus folder tulis. 

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

Untuk inti Greengrass: Anda dapat menggunakan petunjuk [penginstalan AWS IoT Greengrass V2 untuk](install-greengrass-core-v2.md) menginstal inti Greengrass di perangkat Anda.

Untuk Greengrass nucleus lite: Anda dapat menggunakan [petunjuk pemasangan Greengrass nucleus lite untuk menginstal Greengrass](greengrass-nucleus-lite-component.md) nucleus lite.

**Tip**  <a name="tip-migrate-reuse-core-device-identity"></a>
Untuk menggunakan kembali identitas perangkat inti saat Anda memigrasikannya dari V1 ke V2, ikuti petunjuk untuk [menginstal perangkat lunak AWS IoT Greengrass Core dengan](manual-installation.md) penyediaan manual. Pertama-tama hapus perangkat lunak inti V1 dari perangkat, lalu gunakan kembali AWS IoT barang dan sertifikat perangkat inti V1, dan perbarui AWS IoT kebijakan sertifikat untuk memberikan izin yang dibutuhkan perangkat lunak v2.x.

### Instal perangkat lunak AWS IoT Greengrass Core v2.x pada perangkat yang sudah menjalankan v1.x
<a name="install-v2-side-by-side"></a>

Jika Anda menginstal perangkat lunak AWS IoT Greengrass Core v2.x pada perangkat yang sudah menjalankan perangkat lunak AWS IoT Greengrass Core v1.x, ingatlah hal berikut:
+ Nama AWS IoT benda untuk perangkat inti V2 Anda harus unik. Jangan gunakan nama yang sama dengan perangkat inti V1 Anda.
+ Port yang Anda gunakan untuk perangkat lunak AWS IoT Greengrass Core v2.x harus berbeda dari port yang Anda gunakan untuk v1.x.
  + Konfigurasikan manajer aliran V1 untuk menggunakan port selain 8088. Untuk informasi selengkapnya, lihat [Mengonfigurasi pengelola aliran](https://docs.aws.amazon.com/greengrass/v1/developerguide/configure-stream-manager.html).
  + Konfigurasikan broker V1 MQTT untuk menggunakan port selain 8883. Untuk informasi selengkapnya, lihat [Mengkonfigurasi port MQTT untuk](https://docs.aws.amazon.com/greengrass/v1/developerguide/gg-core.html#config-local-mqtt-port) pesan lokal.
+ AWS IoT Greengrass V2 tidak menyediakan opsi untuk mengganti nama layanan sistem Greengrass. Jika Anda menjalankan Greengrass sebagai layanan sistem, Anda harus melakukan salah satu hal berikut untuk menghindari nama layanan sistem yang bertentangan:
  + Ganti nama layanan Greengrass untuk v1.x sebelum Anda menginstal v2.x.
  + Instal perangkat lunak AWS IoT Greengrass Core v2.x tanpa layanan sistem, lalu [konfigurasikan perangkat lunak secara manual sebagai layanan sistem](configure-greengrass-core-v2.md#configure-system-service) dengan nama selain. `greengrass`

**Untuk mengganti nama layanan Greengrass untuk v1.x**

  1. Hentikan layanan v1.x perangkat lunak AWS IoT Greengrass Core. 

     ```
     sudo systemctl stop greengrass
     ```

  1. Tunggu sampai layanan berhenti. Layanan ini dapat memakan waktu hingga beberapa menit untuk berhenti. Anda dapat menggunakan `list-units` perintah untuk memeriksa apakah layanan berhenti. 

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

  1. Nonaktifkan layanan. 

     ```
     sudo systemctl disable greengrass
     ```

  1. Ganti nama layanan. 

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

  1. Muat ulang layanan dan mulai. 

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

Anda kemudian dapat menggunakan [petunjuk penginstalan AWS IoT Greengrass V2 untuk](install-greengrass-core-v2.md) menginstal perangkat lunak pada perangkat Anda.

**Tip**  <a name="tip-migrate-reuse-core-device-identity"></a>
Untuk menggunakan kembali identitas perangkat inti saat Anda memigrasikannya dari V1 ke V2, ikuti petunjuk untuk [menginstal perangkat lunak AWS IoT Greengrass Core dengan](manual-installation.md) penyediaan manual. Pertama-tama hapus perangkat lunak inti V1 dari perangkat, lalu gunakan kembali AWS IoT barang dan sertifikat perangkat inti V1, dan perbarui AWS IoT kebijakan sertifikat untuk memberikan izin yang dibutuhkan perangkat lunak v2.x.

## Langkah 2: Menyebarkan AWS IoT Greengrass V2 komponen ke perangkat inti
<a name="deploy-v2-resources"></a>

Setelah Anda menginstal perangkat lunak AWS IoT Greengrass Core v2.x di perangkat Anda, terapkan komponen berdasarkan runtime yang Anda pilih.

### Untuk inti Greengrass:
<a name="deploy-nucleus-components"></a>

Buat penyebaran yang mencakup sumber daya berikut. Untuk menyebarkan komponen ke armada perangkat serupa, buat penyebaran untuk grup benda yang berisi perangkat tersebut.
+ Komponen fungsi Lambda yang Anda buat dari fungsi Lambda V1 Anda. Untuk informasi selengkapnya, lihat [Jalankan AWS Lambda fungsi](run-lambda-functions.md).
+ Jika Anda menggunakan langganan V1, komponen router [langganan lama](legacy-subscription-router-component.md).
+ Jika Anda menggunakan stream manager, [komponen stream manager](stream-manager-component.md). Untuk informasi selengkapnya, lihat [Kelola aliran data di perangkat inti Greengrass](manage-data-streams.md).
+ Jika Anda menggunakan rahasia lokal, [komponen manajer rahasia](secret-manager-component.md).
+ Jika Anda menggunakan konektor V1, komponen konektor [AWS yang disediakan](set-up-v2-test-device.md#use-v1-connectors).
+ Jika Anda menggunakan kontainer Docker, komponen [manajer aplikasi Docker](docker-application-manager-component.md). Untuk informasi selengkapnya, lihat [Jalankan kontainer Docker](run-docker-container.md).
+ Jika Anda menggunakan perangkat yang terhubung, [komponen untuk dukungan perangkat klien](client-device-components.md). Anda juga harus mengaktifkan dukungan perangkat klien dan mengaitkan perangkat klien dengan perangkat inti Anda. Untuk informasi selengkapnya, lihat [Berinteraksilah dengan perangkat IoT lokal](interact-with-local-iot-devices.md).
+ Jika Anda menggunakan bayangan perangkat, [komponen pengelola bayangan](shadow-manager-component.md). Untuk informasi selengkapnya, lihat [Berinteraksilah dengan bayangan perangkat](interact-with-shadows.md).
+ [Jika Anda mengunggah log dari perangkat inti Greengrass ke CloudWatch Amazon Logs, komponen pengelola log.](log-manager-component.md) Untuk informasi selengkapnya, lihat [Memantau AWS IoT Greengrass log](monitor-logs.md).
+ Jika Anda mengintegrasikan dengan AWS IoT SiteWise, [ikuti petunjuk](https://docs.aws.amazon.com/iot-sitewise/latest/userguide/configure-gateway-ggv2.html) untuk mengatur perangkat inti V2 sebagai AWS IoT SiteWise gateway. AWS IoT SiteWise menyediakan skrip instalasi yang menyebarkan AWS IoT SiteWise komponen untuk Anda.
+ Komponen yang ditentukan pengguna yang Anda kembangkan untuk mengimplementasikan fungsionalitas khusus.

Untuk informasi tentang membuat dan merevisi penerapan, lihat. [Menyebarkan AWS IoT Greengrass komponen ke perangkat](manage-deployments.md) 

### Untuk Greengrass nucleus lite:
<a name="deploy-nucleus-lite-components"></a>

Terapkan komponen generik yang Anda buat di [Langkah 2 panduan migrasi ke perangkat](set-up-v2-test-device-lite.md#lite-step-2-convert-lambda) Greengrass nucleus lite Anda:

1. Buat komponen Anda dalam menggunakan resep komponen yang Anda buat

1. Buat penerapan yang menargetkan perangkat Greengrass nucleus lite Anda yang menyertakan komponen generik Anda

1. Verifikasi bahwa komponen Anda berjalan dengan benar