

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

# Tutorial: Berinteraksi dengan perangkat IoT lokal melalui MQTT
<a name="client-devices-tutorial"></a>

Anda dapat menyelesaikan tutorial ini untuk mengonfigurasi perangkat inti untuk berinteraksi dengan perangkat IoT lokal, yang disebut *perangkat klien*, yang terhubung ke perangkat inti melalui MQTT. Dalam tutorial ini, Anda mengonfigurasi AWS IoT hal-hal untuk menggunakan *penemuan cloud* untuk terhubung ke perangkat inti sebagai perangkat klien. Saat Anda mengonfigurasi penemuan cloud, perangkat klien dapat mengirim permintaan ke layanan AWS IoT Greengrass cloud untuk menemukan perangkat inti. Tanggapan dari AWS IoT Greengrass mencakup informasi konektivitas dan sertifikat untuk perangkat inti yang Anda konfigurasikan perangkat kliennya untuk ditemukan. Kemudian, perangkat klien dapat menggunakan informasi ini untuk menyambung ke perangkat inti yang tersedia di mana ia dapat berkomunikasi melalui MQTT.

Dalam tutorial ini, Anda melakukan hal-hal berikut:

1. Meninjau dan memperbarui izin perangkat inti, jika diperlukan.

1. Mengaitkan perangkat klien ke perangkat inti, sehingga dapat menemukan perangkat inti menggunakan penemuan cloud.

1. Menyebarkan komponen Greengrass ke perangkat inti untuk mengaktifkan dukungan perangkat klien.

1. Hubungkan perangkat klien ke perangkat inti dan uji komunikasi dengan layanan cloud AWS IoT Core .

1. Kembangkan komponen Greengrass khusus yang berkomunikasi dengan perangkat klien.

1. [Kembangkan komponen khusus yang berinteraksi dengan bayangan perangkat perangkat klien.AWS IoT](https://docs.aws.amazon.com/iot/latest/developerguide/iot-device-shadows.html)

Tutorial ini menggunakan perangkat inti tunggal dan perangkat klien tunggal. Anda juga dapat mengikuti tutorial untuk menghubungkan dan menguji beberapa perangkat klien.

Anda dapat mengharapkan untuk menghabiskan 30-60 menit pada tutorial ini.

## Prasyarat
<a name="client-devices-tutorial-prerequisites"></a>

Untuk menyelesaikan tutorial ini, Anda memerlukan hal berikut:
+ Sebuah Akun AWS. Jika Anda tidak memilikinya, lihat [Mengatur sebuah Akun AWS](setting-up.md#set-up-aws-account).
+ Pengguna AWS Identity and Access Management (IAM) dengan izin administrator.
+ Sebuah perangkat inti Greengrass. Untuk informasi lebih lanjut tentang cara menyiapkan perangkat inti, lihat [Menyiapkan perangkat AWS IoT Greengrass inti](setting-up.md).
  + Perangkat inti harus menjalankan Greengrass nucleus v2.6.0 atau yang lebih baru. Versi ini mencakup dukungan untuk wildcard dalam publish/subscribe komunikasi lokal dan dukungan untuk bayangan perangkat klien.
**catatan**  
Dukungan perangkat klien memerlukan Greengrass nucleus v2.2.0 atau yang lebih baru. Namun, tutorial ini mengeksplorasi fitur yang lebih baru, seperti dukungan untuk wildcard MQTT di lokal publish/subscribe dan dukungan untuk bayangan perangkat klien. Fitur-fitur ini membutuhkan Greengrass nucleus v2.6.0 atau yang lebih baru.
  + Perangkat inti harus berada di jaringan yang sama dengan perangkat klien untuk terhubung.
  + (Opsional) Untuk menyelesaikan modul tempat Anda mengembangkan komponen Greengrass khusus, perangkat inti harus menjalankan CLI Greengrass. Untuk informasi selengkapnya, lihat [Instal Greengrass CLI](install-gg-cli.md).
+ Suatu AWS IoT hal untuk terhubung sebagai perangkat klien dalam tutorial ini. Untuk informasi selengkapnya, lihat [Membuat AWS IoT sumber daya](https://docs.aws.amazon.com/iot/latest/developerguide/create-iot-resources.html) di *Panduan AWS IoT Core Pengembang*.
  +  AWS IoT Kebijakan perangkat klien harus mengizinkan `greengrass:Discover` izin tersebut. Untuk informasi selengkapnya, lihat [AWS IoT Kebijakan minimal untuk perangkat klien](device-auth.md#client-device-minimal-iot-policy).
  + Perangkat klien harus berada di jaringan yang sama dengan perangkat inti.
  + Perangkat klien harus menjalankan [Python 3](https://www.python.org/).
  + Perangkat klien harus menjalankan [Git](https://git-scm.com/).

## Langkah 1: Tinjau dan perbarui AWS IoT kebijakan perangkat inti
<a name="update-core-device-iot-policy-client-devices"></a>

Untuk mendukung perangkat klien, AWS IoT kebijakan perangkat inti harus mengizinkan izin berikut:
+ <a name="core-device-iot-policy-client-device-permissions-putcertificateauthorities"></a>`greengrass:PutCertificateAuthorities`
+ <a name="core-device-iot-policy-client-device-permissions-verifyclientdeviceidentity"></a>`greengrass:VerifyClientDeviceIdentity`
+ <a name="core-device-iot-policy-client-device-permissions-verifyclientdeviceiotcertificateassociation"></a>`greengrass:VerifyClientDeviceIoTCertificateAssociation`
+ <a name="core-device-iot-policy-client-device-permissions-getconnectivityinfo"></a>`greengrass:GetConnectivityInfo`
+ <a name="core-device-iot-policy-client-device-permissions-updateconnectivityinfo"></a>`greengrass:UpdateConnectivityInfo`— (Opsional) Izin ini diperlukan untuk menggunakan [komponen detektor IP](ip-detector-component.md), yang melaporkan informasi konektivitas jaringan perangkat inti ke layanan AWS IoT Greengrass cloud.

Untuk informasi selengkapnya tentang izin dan AWS IoT kebijakan ini untuk perangkat inti, lihat [AWS IoT kebijakan untuk operasi pesawat data](device-auth.md#iot-policies) dan[AWS IoT Kebijakan minimal untuk mendukung perangkat klien](device-auth.md#client-device-support-minimal-iot-policy).

Di bagian ini, Anda meninjau AWS IoT kebijakan untuk perangkat inti Anda dan menambahkan izin yang diperlukan yang tidak ada. Jika Anda menggunakan [penginstal perangkat lunak AWS IoT Greengrass inti untuk menyediakan sumber daya](quick-installation.md), perangkat inti Anda memiliki AWS IoT kebijakan yang memungkinkan akses ke semua AWS IoT Greengrass tindakan (`greengrass:*`). Dalam hal ini, Anda harus memperbarui AWS IoT kebijakan hanya jika Anda berencana untuk mengonfigurasi komponen pengelola bayangan untuk menyinkronkan bayangan perangkat AWS IoT Core. Jika tidak, Anda dapat melewati bagian ini.

**Untuk meninjau dan memperbarui AWS IoT kebijakan perangkat inti**

1. <a name="update-iot-policy-console-open-greengrass-console"></a>Di menu navigasi [konsol AWS IoT Greengrass](https://console.aws.amazon.com/greengrass) tersebut, pilih **Perangkat inti**.

1. <a name="update-iot-policy-console-choose-core-device"></a>Pada halaman **Perangkat inti**, pilih perangkat inti yang akan diperbarui.

1. <a name="update-iot-policy-console-choose-core-device-thing"></a>Pada halaman detail perangkat inti, pilih tautan ke **Objek** perangkat inti. Tautan ini membuka halaman rincian hal di AWS IoT konsol.

1. <a name="update-iot-policy-console-choose-thing-security"></a>Pada halaman detail objek, pilih **Sertifikat**.

1. <a name="update-iot-policy-console-choose-thing-certificate"></a>Di tab **Sertifikat**, pilih sertifikat aktif objek.

1. <a name="update-iot-policy-console-choose-certificate-policies"></a>Pada halaman detail sertifikat, pilih **Kebijakan**.

1. <a name="update-iot-policy-console-choose-policy"></a>Di tab **Kebijakan**, pilih AWS IoT kebijakan yang akan ditinjau dan diperbarui. Anda dapat menambahkan izin yang diperlukan untuk kebijakan yang dilampirkan ke sertifikat aktif perangkat inti.
**catatan**  <a name="quick-installation-iot-policies-note"></a>
Jika Anda menggunakan [penginstal perangkat lunak AWS IoT Greengrass inti untuk menyediakan sumber daya](quick-installation.md), Anda memiliki dua AWS IoT kebijakan. Kami menyarankan Anda memilih kebijakan yang diberi nama **GreengrassV2IoTThingPolicy**, jika ada. Perangkat inti yang Anda buat dengan penginstal cepat menggunakan nama kebijakan ini secara default. Jika Anda menambahkan izin untuk kebijakan ini, Anda juga memberikan izin ini ke perangkat inti lain yang menggunakan kebijakan ini.

1. <a name="update-iot-policy-console-edit-policy"></a>Dalam ikhtisar kebijakan, pilih **Edit versi aktif**.

1. Tinjau kebijakan untuk izin yang diperlukan, dan tambahkan izin yang diperlukan yang hilang.

1. <a name="update-iot-policy-console-set-as-active-version"></a>Untuk menetapkan versi kebijakan baru sebagai versi aktif, di bawah **Status versi Kebijakan**, pilih **Setel versi yang diedit sebagai versi aktif untuk kebijakan ini**.

1. <a name="update-iot-policy-console-save-policy"></a>Pilih **Simpan sebagai versi baru**.

## Langkah 2: Aktifkan dukungan perangkat klien
<a name="enable-client-device-support"></a>

Untuk perangkat klien untuk menggunakan penemuan cloud untuk menyambung ke perangkat inti, Anda harus mengaitkan perangkat itu. Ketika Anda mengaitkan perangkat klien ke perangkat inti, Anda mengaktifkan perangkat klien untuk mengambil alamat IP perangkat inti dan sertifikat untuk digunakan untuk menyambung.

Untuk mengaktifkan perangkat klien terhubung dengan aman ke perangkat inti dan berkomunikasi dengan komponen Greengrass dan AWS IoT Core, Anda menerapkan komponen Greengrass berikut ke perangkat inti:
+ <a name="client-device-component-overview-client-device-auth"></a>[Auth perangkat klien](client-device-auth-component.md) (`aws.greengrass.clientdevices.Auth`)

  Deploy komponen auth perangkat klien untuk mengautentikasi perangkat klien dan mengotorisasi tindakan perangkat klien. Komponen ini memungkinkan AWS IoT barang-barang Anda terhubung ke perangkat inti.

  Komponen ini memerlukan beberapa konfigurasi untuk menggunakannya. Anda harus menentukan grup perangkat klien dan operasi yang setiap grup diotorisasi untuk melakukan, seperti untuk menghubungkan dan berkomunikasi melalui MQTT. Untuk informasi lebih lanjut, lihat [konfigurasi komponen auth perangkat klien](client-device-auth-component.md#client-device-auth-component-configuration).
+ <a name="client-device-component-overview-mqtt-broker-moquette"></a>[MQTT 3.1.1 broker (Moquette)](mqtt-broker-moquette-component.md) (`aws.greengrass.clientdevices.mqtt.Moquette`)

  Menyebarkan komponen broker Moquette MQTT untuk menjalankan broker MQTT ringan. Broker Moquette MQTT patuh pada MQTT 3.1.1 dan mencakup dukungan lokal untuk QoS 0, QoS 1, QoS 2, pesan yang dipertahankan, pesan kehendak terakhir, dan langganan terus-menerus.

  Anda tidak diharuskan mengonfigurasi komponen ini untuk menggunakannya. Namun, Anda dapat mengonfigurasi port di mana komponen ini mengoperasikan broker MQTT. Secara default, ia menggunakan port 8883.
+ <a name="client-device-component-overview-mqtt-bridge"></a>[Jembatan MQTT](mqtt-bridge-component.md) (`aws.greengrass.clientdevices.mqtt.Bridge`)

  (Opsional) Menyebarkan komponen jembatan MQTT untuk menyampaikan pesan antara perangkat klien (MQTT lokal), penerbitan/berlangganan lokal, dan MQTT. AWS IoT Core Konfigurasikan komponen ini untuk menyinkronkan perangkat klien dengan AWS IoT Core dan berinteraksi dengan perangkat klien dari komponen Greengrass.

  Komponen ini memerlukan konfigurasi untuk digunakan. Anda harus menentukan pemetaan topik di mana komponen ini merelai pesan. Untuk informasi lebih lanjut, lihat [konfigurasi komponen jembatan MQTT](mqtt-bridge-component.md#mqtt-bridge-component-configuration).
+ <a name="client-device-component-overview-ip-detector"></a>[Detektor IP](ip-detector-component.md) (`aws.greengrass.clientdevices.IPDetector`)

  (Opsional) Menyebarkan komponen detektor IP untuk secara otomatis melaporkan titik akhir broker MQTT perangkat inti ke layanan cloud. AWS IoT Greengrass Anda tidak dapat menggunakan komponen ini jika Anda memiliki pengaturan jaringan yang kompleks, seperti di mana router meneruskan port broker MQTT ke perangkat inti.

  Anda tidak diharuskan mengonfigurasi komponen ini untuk menggunakannya.

Di bagian ini, Anda menggunakan AWS IoT Greengrass konsol untuk mengaitkan perangkat klien dan menyebarkan komponen perangkat klien ke perangkat inti.

**Untuk mengaktifkan dukungan perangkat klien**

1. <a name="navigate-greengrass-console"></a>Navigasikan ke [konsol AWS IoT Greengrass](https://console.aws.amazon.com/greengrass) tersebut.

1. Di menu navigasi kiri, pilih **Perangkat inti**.

1. Pada halaman **Perangkat Inti**, pilih perangkat inti tempat Anda ingin mengaktifkan dukungan perangkat klien.

1. Pada halaman detail perangkat inti, pilih tab **Perangkat klien**.

1. Pada tab **Perangkat klien**, pilih **Konfigurasikan penemuan cloud**.

   Halaman **Konfigurasikan penemuan perangkat inti** terbuka. Di bagian ini, Anda mengaitkan perangkat klien ke perangkat inti dan men-deploy komponen perangkat klien. Halaman ini memilih perangkat inti untuk Anda di **Langkah 1: Pilih perangkat inti target**.
**catatan**  
Anda juga dapat menggunakan halaman ini untuk mengonfigurasi penemuan perangkat inti untuk grup objek. Jika Anda memilih opsi ini, Anda dapat men-deploy komponen perangkat klien ke semua perangkat inti dalam grup objek. Namun, jika Anda memilih opsi ini, Anda harus secara manual mengaitkan perangkat klien untuk setiap perangkat inti kemudian setelah Anda membuat deployment. Dalam tutorial ini, Anda mengonfigurasi perangkat inti tunggal.

1. Pada **Langkah 2: Mengaitkan perangkat klien**, kaitkan AWS IoT hal perangkat klien ke perangkat inti. Hal ini memungkinkan perangkat klien untuk menggunakan penemuan cloud untuk mengambil informasi konektivitas perangkat inti dan sertifikat. Lakukan hal-hal berikut:

   1. Pilih **Kaitkan perangkat klien**.

   1. Di **perangkat klien Associate dengan modal perangkat inti**, masukkan nama AWS IoT benda yang akan diasosiasikan.

   1. Pilih **Tambahkan**.

   1. Pilih **Kaitkan**.

1. Di **Langkah 3: Konfigurasi dan deploy komponen Greengrass**, deploy komponen untuk mengaktifkan dukungan perangkat klien. Jika perangkat inti target memiliki deployment sebelumnya, halaman ini merevisi deployment tersebut. Jika tidak, halaman ini membuat deployment baru untuk perangkat inti. Lakukan hal berikut untuk mengonfigurasi dan men-deploy komponen perangkat klien:

   1. Perangkat inti harus menjalankan [Greengrass](greengrass-nucleus-component.md) nucleus v2.6.0 atau yang lebih baru untuk menyelesaikan tutorial ini. Jika perangkat inti menjalankan versi sebelumnya, lakukan hal berikut:

      1. Pilih kotak untuk menyebarkan **aws.greengrass.Nucleus**komponen.

      1. Untuk komponen **aws.greengrass.Nucleus**, pilih **Edit konfigurasi**.

      1. Untuk **versi Komponen, pilih versi** 2.6.0 atau yang lebih baru.

      1. Pilih **Konfirmasi**.
**catatan**  
Jika Anda memutakhirkan inti Greengrass dari versi minor sebelumnya, dan perangkat inti [AWS menjalankan komponen yang disediakan](public-components.md) yang bergantung pada nukleus, Anda juga harus memperbarui AWS komponen yang disediakan ke versi yang lebih baru. Anda dapat mengonfigurasi versi komponen ini ketika Anda meninjau deployment nanti dalam tutorial ini. Untuk informasi selengkapnya, lihat [Perbarui perangkat lunak AWS IoT Greengrass Core (OTA)](update-greengrass-core-v2.md).

   1. Untuk komponen **aws.greengrass.clientdevices.Auth**, pilih **Edit konfigurasi**.

   1. Di modal **Edit konfigurasi** untuk komponen auth perangkat klien, konfigurasi kebijakan otorisasi yang memungkinkan perangkat klien untuk mempublikasikan dan berlangganan broker MQTT pada perangkat inti. Lakukan hal-hal berikut:

      1. Di bawah **Konfigurasi**, di blok **Konfigurasi untuk menggabungkan** kode, masukkan konfigurasi berikut, yang berisi kebijakan *otorisasi perangkat klien*. Setiap perangkat grup otorisasi kebijakan menentukan serangkaian tindakan dan sumber daya di mana perangkat klien dapat melakukan tindakan tersebut.
         + Kebijakan ini memungkinkan perangkat klien yang namanya dimulai dengan `MyClientDevice` untuk menghubungkan dan berkomunikasi pada semua topik MQTT. Ganti *MyClientDevice\$1* dengan nama AWS IoT benda yang akan dihubungkan sebagai perangkat klien. Anda juga dapat menentukan nama dengan wldcard `*` yang cocok dengan nama perangkat klien. Wildcard `*` harus di akhir nama.

           Jika Anda memiliki perangkat klien kedua untuk disambungkan, ganti *MyOtherClientDevice\$1* dengan nama perangkat klien tersebut, atau pola wildcard yang cocok dengan nama perangkat klien tersebut. Jika tidak, Anda dapat menghapus atau menyimpan bagian ini dari aturan pemilihan yang memungkinkan perangkat klien dengan nama yang cocok dengan `MyOtherClientDevice*` untuk terhubung dan berkomunikasi.
         + Kebijakan ini menggunakan operator `OR` untuk juga memungkinkan perangkat klien yang namanya dimulai dengan `MyOtherClientDevice` untuk menghubungkan dan berkomunikasi pada semua topik MQTT. Anda dapat menghapus klausul ini dalam aturan seleksi atau memodifikasinya agar cocok dengan perangkat klien untuk terhubung.
         + Kebijakan ini memungkinkan perangkat klien untuk mempublikasikan dan berlangganan pada semua topik MQTT. Untuk mengikuti praktik keamanan terbaik, batasi operasi `mqtt:publish` dan `mqtt:subscribe` ke set minimal topik yang diagunakan oleh perangkat klien untuk berkomunikasi.

         ```
         {
           "deviceGroups": {
             "formatVersion": "2021-03-05",
             "definitions": {
               "MyDeviceGroup": {
                 "selectionRule": "thingName: MyClientDevice* OR thingName: MyOtherClientDevice*",
                 "policyName": "MyClientDevicePolicy"
               }
             },
             "policies": {
               "MyClientDevicePolicy": {
                 "AllowConnect": {
                   "statementDescription": "Allow client devices to connect.",
                   "operations": [
                     "mqtt:connect"
                   ],
                   "resources": [
                     "*"
                   ]
                 },
                 "AllowPublish": {
                   "statementDescription": "Allow client devices to publish to all topics.",
                   "operations": [
                     "mqtt:publish"
                   ],
                   "resources": [
                     "*"
                   ]
                 },
                 "AllowSubscribe": {
                   "statementDescription": "Allow client devices to subscribe to all topics.",
                   "operations": [
                     "mqtt:subscribe"
                   ],
                   "resources": [
                     "*"
                   ]
                 }
               }
             }
           }
         }
         ```

         Untuk informasi lebih lanjut, lihat [Konfigurasi komponen auth perangkat klien](client-device-auth-component.md#client-device-auth-component-configuration).

      1. Pilih **Konfirmasi**.

   1. Untuk komponen **aws.greengrass.clientdevices.mqtt.Bridge**, pilih **Edit konfigurasi**.

   1. Di modal **Edit konfigurasi** untuk komponen jembatan MQTT, konfigurasi pemetaan topik yang menyampaikan pesan MQTT dari perangkat klien ke AWS IoT Core. Lakukan hal-hal berikut:

      1. Di bawah **Konfigurasi**, di blok kode **Konfigurasi yang akan digabungkan**, masukkan konfigurasi berikut. Konfigurasi ini menentukan untuk merelai pesan MQTT pada topik filter `clients/+/hello/world` dari perangkat klien ke layanan cloud AWS IoT Core . Sebagai contoh, filter topik ini cocok dengan topik `clients/MyClientDevice1/hello/world`.

         ```
         {
           "mqttTopicMapping": {
             "HelloWorldIotCoreMapping": {
               "topic": "clients/+/hello/world",
               "source": "LocalMqtt",
               "target": "IotCore"
             }
           }
         }
         ```

         Untuk informasi lebih lanjut, lihat [konfigurasi komponen jembatan MQTT](mqtt-bridge-component.md#mqtt-bridge-component-configuration).

      1. Pilih **Konfirmasi**.

1. <a name="choose-review-and-deploy-configure-discovery-step"></a>Pilih **Tinjau dan deploy** untuk meninjau deployment yang dibuat oleh halaman ini untuk Anda.

1. Jika sebelumnya Anda belum mengatur [Peran layanan Greengrass](greengrass-service-role.md) di Wilayah ini, konsol membuka modal untuk mengatur peran layanan untuk Anda. Komponen autentikasi perangkat klien menggunakan peran layanan ini untuk memverifikasi identitas perangkat klien, dan komponen detektor IP menggunakan peran layanan ini untuk mengelola informasi konektivitas perangkat inti. Pilih **Berikan izin**.

1. <a name="choose-deploy-configure-discovery-step"></a>Pada halaman **Tinjauan**, pilih **Deploy** untuk memulai deployment ke perangkat inti.

1. <a name="verify-deployment-success-step"></a>Untuk memverifikasi bahwa deployment berhasil, periksa status deployment, dan periksa log pada perangkat inti. Untuk memeriksa status deployment pada perangkat inti, Anda dapat memilih **Target** pada **Gambaran Umum** deployment. Untuk informasi selengkapnya, lihat berikut ini:
   + [Periksa status deployment](check-deployment-status.md)
   + [Memantau AWS IoT Greengrass log](monitor-logs.md)

## Langkah 3: Connect perangkat klien
<a name="connect-client-devices-tutorial"></a>

Perangkat klien dapat menggunakan perangkat AWS IoT Device SDK untuk menemukan, menghubungkan, dan berkomunikasi dengan perangkat inti. Perangkat klien harus menjadi AWS IoT sesuatu. Untuk informasi selengkapnya, lihat [Membuat objek benda](https://docs.aws.amazon.com/iot/latest/developerguide/create-iot-resources.html#create-aws-thing) di *Panduan AWS IoT Core Pengembang*.

Di bagian ini, Anda menginstal [v2 for Python AWS IoT Device SDK](https://github.com/aws/aws-iot-device-sdk-python-v2) dan menjalankan aplikasi contoh penemuan Greengrass dari AWS IoT Device SDK.

**catatan**  
 AWS IoT Device SDK Ini juga tersedia dalam bahasa pemrograman lainnya. Tutorial ini menggunakan AWS IoT Device SDK v2 untuk Python, tetapi Anda dapat menjelajahi yang lain SDKs untuk kasus penggunaan Anda. Untuk informasi selengkapnya, lihat [AWS IoT Perangkat SDKs](https://docs.aws.amazon.com/iot/latest/developerguide/iot-sdks.html) di *Panduan AWS IoT Core Pengembang*.

**Untuk menyambungkan perangkat klien ke perangkat inti**

1. <a name="download-iot-device-sdk-python-v2"></a>Unduh dan instal [AWS IoT Device SDK v2 untuk Python](https://github.com/aws/aws-iot-device-sdk-python-v2) ke AWS IoT benda yang akan dihubungkan sebagai perangkat klien.

   Di perangkat klien, lakukan hal berikut:

   1. Kloning AWS IoT Device SDK v2 untuk repositori Python untuk mengunduhnya.

      ```
      git clone https://github.com/aws/aws-iot-device-sdk-python-v2.git
      ```

   1. Instal AWS IoT Device SDK v2 untuk Python.

      ```
      python3 -m pip install --user ./aws-iot-device-sdk-python-v2
      ```

1. <a name="cd-iot-device-sdk-python-v2"></a>Ubah ke folder sampel di AWS IoT Device SDK v2 untuk Python.

   ```
   cd aws-iot-device-sdk-python-v2/samples/greengrass
   ```

1. <a name="test-client-device-communications-application-intro"></a>Jalankan sampel aplikasi penemuan Greengrass. Aplikasi ini mengharapkan argumen yang menentukan nama objek perangkat klien, topik MQTT dan pesan yang akan digunakan, dan sertifikat yang mengautentikasi dan mengamankan sambungan. Contoh berikut mengirimkan pesan Hello World ke topik `clients/MyClientDevice1/hello/world`.
**catatan**  
Topik ini cocok dengan topik tempat Anda mengonfigurasi jembatan MQTT untuk menyampaikan pesan ke yang lebih lama. AWS IoT Core <a name="test-client-device-communications-application-command-replace"></a>
   + Ganti *MyClientDevice1* dengan nama benda perangkat klien.
   + Ganti *\$1/certs/AmazonRootCA1.pem* dengan jalur ke sertifikat CA root Amazon di perangkat klien.
   + Ganti *\$1/certs/device.pem.crt* dengan jalur ke sertifikat perangkat di perangkat klien.
   + Ganti *\$1/certs/private.pem.key* dengan path ke file kunci pribadi pada perangkat klien.
   + Ganti *us-east-1* dengan AWS Wilayah tempat perangkat klien dan perangkat inti Anda beroperasi.

   ```
   python3 basic_discovery.py \\
     --thing_name MyClientDevice1 \\
     --topic 'clients/MyClientDevice1/hello/world' \\
     --message 'Hello World!' \\
     --ca_file ~/certs/AmazonRootCA1.pem \\
     --cert ~/certs/device.pem.crt \\
     --key ~/certs/private.pem.key \\
     --region us-east-1 \\
     --verbosity Warn
   ```

   <a name="test-client-device-communications-application-output-intro"></a>Aplikasi sampel penemuan mengirimkan pesan 10 kali dan terputus. Aplikasi ini juga berlangganan topik yang sama di mana ia menerbitkan pesan. Jika output menunjukkan bahwa aplikasi itu menerima pesan MQTT pada topik, perangkat klien dapat berhasil berkomunikasi dengan perangkat inti.

   ```
   Performing greengrass discovery...
   awsiot.greengrass_discovery.DiscoverResponse(gg_groups=[awsiot.greengrass_discovery.GGGroup(gg_group_id='greengrassV2-coreDevice-MyGreengrassCore', cores=[awsiot.greengrass_discovery.GGCore(thing_arn='arn:aws:iot:us-east-1:123456789012:thing/MyGreengrassCore', connectivity=[awsiot.greengrass_discovery.ConnectivityInfo(id='203.0.113.0', host_address='203.0.113.0', metadata='', port=8883)])], certificate_authorities=['-----BEGIN CERTIFICATE-----\
   MIICiT...EXAMPLE=\
   -----END CERTIFICATE-----\
   '])])
   Trying core arn:aws:iot:us-east-1:123456789012:thing/MyGreengrassCore at host 203.0.113.0 port 8883
   Connected!
   Published topic clients/MyClientDevice1/hello/world: {"message": "Hello World!", "sequence": 0}
   
   Publish received on topic clients/MyClientDevice1/hello/world
   b'{"message": "Hello World!", "sequence": 0}'
   Published topic clients/MyClientDevice1/hello/world: {"message": "Hello World!", "sequence": 1}
   
   Publish received on topic clients/MyClientDevice1/hello/world
   b'{"message": "Hello World!", "sequence": 1}'
   
   ...
   
   Published topic clients/MyClientDevice1/hello/world: {"message": "Hello World!", "sequence": 9}
   
   Publish received on topic clients/MyClientDevice1/hello/world
   b'{"message": "Hello World!", "sequence": 9}'
   ```

   <a name="test-client-device-communications-application-troubleshooting"></a>Jika aplikasi mengeluarkan kesalahan, lihat [Pemecahan masalah penemuan Greengrass](troubleshooting-client-devices.md#greengrass-discovery-issues).

   <a name="test-client-device-communications-application-view-core-logs"></a>Anda juga dapat melihat log Greengrass pada perangkat inti untuk memverifikasi apakah perangkat klien berhasil menghubungkan dan mengirim pesan. Untuk informasi selengkapnya, lihat [Memantau AWS IoT Greengrass log](monitor-logs.md).

1. Verifikasi bahwa jembatan MQTT menyampaikan pesan dari perangkat klien ke. AWS IoT Core Anda dapat menggunakan klien pengujian MQTT di AWS IoT Core konsol untuk berlangganan filter topik MQTT. Lakukan hal-hal berikut:

   1. Navigasikan ke [konsol AWS IoT](https://console.aws.amazon.com/iot) tersebut.

   1. Di menu navigasi sebelah kiri, di bawah **Pengujian** pilih **klien uji MQTT**.

   1. Pada tab **Berlangganan topik**, untuk **Filter topik**, masukkan `clients/+/hello/world` untuk berlangganan pesan perangkat klien dari perangkat inti.

   1. Pilih **Langganan**.

   1. Jalankan publish/subscribe aplikasi di perangkat klien lagi.

      Klien tes MQTT menampilkan pesan yang Anda kirim dari perangkat klien pada topik yang cocok dengan filter topik ini.

## Langkah 4: Kembangkan komponen yang berkomunikasi dengan perangkat klien
<a name="develop-client-device-subscriber-component"></a>

Anda dapat mengembangkan komponen Greengrass yang berkomunikasi dengan perangkat klien. Komponen menggunakan [komunikasi antarproses (IPC)](interprocess-communication.md) dan [ publish/subscribe antarmuka lokal](ipc-publish-subscribe.md) untuk berkomunikasi pada perangkat inti. Untuk berinteraksi dengan perangkat klien, konfigurasikan komponen jembatan MQTT untuk menyampaikan pesan antara perangkat klien dan antarmuka lokal. publish/subscribe 

Di bagian ini, Anda memperbarui komponen jembatan MQTT untuk menyampaikan pesan dari perangkat klien ke antarmuka lokal. publish/subscribe Kemudian, Anda mengembangkan komponen yang berlangganan pesan ini dan mencetak pesan ketika menerimanya.

**Untuk mengembangkan komponen yang berkomunikasi dengan perangkat klien**

1. Revisi deployment ke perangkat inti dan konfigurasikan komponen jembatan MQTT untuk menyampaikan pesan dari perangkat klien ke antarmuka lokal. Lakukan hal-hal berikut:

   1. <a name="navigate-greengrass-console"></a>Navigasikan ke [konsol AWS IoT Greengrass](https://console.aws.amazon.com/greengrass) tersebut.

   1. Di menu navigasi kiri, pilih **Perangkat inti**.

   1. Pada halaman **Perangkat inti**, pilih perangkat inti yang Anda gunakan untuk tutorial ini.

   1. Pada halaman detail perangkat inti, pilih tab **Perangkat klien**.

   1. Pada tab **Perangkat klien**, pilih **Konfigurasikan penemuan cloud**.

      Halaman **Konfigurasikan penemuan perangkat inti** terbuka. Pada halaman ini, Anda dapat mengubah atau mengonfigurasi komponen perangkat klien mana yang di-deploy ke perangkat inti.

   1. Di **Langkah 3**, untuk komponen **aws.greengrass.clientdevices.mqtt.Bridge**, pilih **Edit konfigurasi**.

   1. Dalam modal **konfigurasi Edit** untuk komponen jembatan MQTT, konfigurasikan pemetaan topik yang menyampaikan pesan MQTT dari perangkat klien ke antarmuka lokal. publish/subscribe Lakukan hal-hal berikut:

      1. Di bawah **Konfigurasi**, di blok kode **Konfigurasi yang akan digabungkan**, masukkan konfigurasi berikut. Konfigurasi ini menetapkan untuk menyampaikan pesan MQTT pada topik yang cocok dengan filter `clients/+/hello/world` topik dari perangkat klien ke layanan AWS IoT Core cloud dan broker Greengrass lokal. publish/subscribe 

         ```
         {
           "mqttTopicMapping": {
             "HelloWorldIotCoreMapping": {
               "topic": "clients/+/hello/world",
               "source": "LocalMqtt",
               "target": "IotCore"
             },
             "HelloWorldPubsubMapping": {
               "topic": "clients/+/hello/world",
               "source": "LocalMqtt",
               "target": "Pubsub"
             }
           }
         }
         ```

         Untuk informasi lebih lanjut, lihat [konfigurasi komponen jembatan MQTT](mqtt-bridge-component.md#mqtt-bridge-component-configuration).

      1. Pilih **Konfirmasi**.

   1. <a name="choose-review-and-deploy-configure-discovery-step"></a>Pilih **Tinjau dan deploy** untuk meninjau deployment yang dibuat oleh halaman ini untuk Anda.

   1. <a name="choose-deploy-configure-discovery-step"></a>Pada halaman **Tinjauan**, pilih **Deploy** untuk memulai deployment ke perangkat inti.

   1. <a name="verify-deployment-success-step"></a>Untuk memverifikasi bahwa deployment berhasil, periksa status deployment, dan periksa log pada perangkat inti. Untuk memeriksa status deployment pada perangkat inti, Anda dapat memilih **Target** pada **Gambaran Umum** deployment. Untuk informasi selengkapnya, lihat berikut ini:
      + [Periksa status deployment](check-deployment-status.md)
      + [Memantau AWS IoT Greengrass log](monitor-logs.md)

1. Kembangkan dan deploy komponen Greengrass yang berlangganan pesan Hello World dari perangkat klien. Lakukan hal-hal berikut:

   1. Buat folder untuk resep dan artefak pada perangkat inti.

------
#### [ Linux or Unix ]

      ```
      mkdir recipes
      mkdir -p artifacts/com.example.clientdevices.MyHelloWorldSubscriber/1.0.0
      ```

------
#### [ Windows Command Prompt (CMD) ]

      ```
      mkdir recipes
      mkdir artifacts\com.example.clientdevices.MyHelloWorldSubscriber\1.0.0
      ```

------
#### [ PowerShell ]

      ```
      mkdir recipes
      mkdir artifacts\com.example.clientdevices.MyHelloWorldSubscriber\1.0.0
      ```

------
**penting**  <a name="local-artifact-folder-name-requirements"></a>
Anda harus menggunakan format berikut untuk jalur folder artifact. Sertakan nama dan versi komponen yang Anda tentukan dalam resep.  

      ```
      artifacts/componentName/componentVersion/
      ```

   1. Gunakan editor teks untuk membuat resep komponen dengan konten berikut. Resep ini menentukan untuk menginstal AWS IoT Device SDK v2 untuk Python dan menjalankan skrip yang berlangganan topik dan mencetak pesan.

      <a name="nano-command-intro"></a>Misalnya, pada sistem berbasis Linux, Anda dapat menjalankan perintah berikut untuk menggunakan GNU nano untuk membuat file.

      ```
      nano recipes/com.example.clientdevices.MyHelloWorldSubscriber-1.0.0.json
      ```

      Salin resep berikut ke dalam file.

      ```
      {
        "RecipeFormatVersion": "2020-01-25",
        "ComponentName": "com.example.clientdevices.MyHelloWorldSubscriber",
        "ComponentVersion": "1.0.0",
        "ComponentDescription": "A component that subscribes to Hello World messages from client devices.",
        "ComponentPublisher": "Amazon",
        "ComponentConfiguration": {
          "DefaultConfiguration": {
            "accessControl": {
              "aws.greengrass.ipc.pubsub": {
                "com.example.clientdevices.MyHelloWorldSubscriber:pubsub:1": {
                  "policyDescription": "Allows access to subscribe to all topics.",
                  "operations": [
                    "aws.greengrass#SubscribeToTopic"
                  ],
                  "resources": [
                    "*"
                  ]
                }
              }
            }
          }
        },
        "Manifests": [
          {
            "Platform": {
              "os": "linux"
            },
            "Lifecycle": {
              "install": "python3 -m pip install --user awsiotsdk",
              "Run": "python3 -u {artifacts:path}/hello_world_subscriber.py"
            }
          },
          {
            "Platform": {
              "os": "windows"
            },
            "Lifecycle": {
              "install": "py -3 -m pip install --user awsiotsdk",
              "Run": "py -3 -u {artifacts:path}/hello_world_subscriber.py"
            }
          }
        ]
      }
      ```

   1. Gunakan editor teks untuk membuat artefak skrip Python bernama `hello_world_subscriber.py` dengan konten berikut. Aplikasi ini menggunakan layanan publish/subscribe IPC untuk berlangganan `clients/+/hello/world` topik dan mencetak pesan yang diterimanya.

      <a name="nano-command-intro"></a>Misalnya, pada sistem berbasis Linux, Anda dapat menjalankan perintah berikut untuk menggunakan GNU nano untuk membuat file.

      ```
      nano artifacts/com.example.clientdevices.MyHelloWorldSubscriber/1.0.0/hello_world_subscriber.py
      ```

      Salin kode Python berikut ke dalam file.

      ```
      import sys
      import time
      import traceback
      
      from awsiot.greengrasscoreipc.clientv2 import GreengrassCoreIPCClientV2
      
      CLIENT_DEVICE_HELLO_WORLD_TOPIC = 'clients/+/hello/world'
      TIMEOUT = 10
      
      
      def on_hello_world_message(event):
          try:
              message = str(event.binary_message.message, 'utf-8')
              print('Received new message: %s' % message)
          except:
              traceback.print_exc()
      
      
      try:
          ipc_client = GreengrassCoreIPCClientV2()
      
          # SubscribeToTopic returns a tuple with the response and the operation.
          _, operation = ipc_client.subscribe_to_topic(
              topic=CLIENT_DEVICE_HELLO_WORLD_TOPIC, on_stream_event=on_hello_world_message)
          print('Successfully subscribed to topic: %s' %
                CLIENT_DEVICE_HELLO_WORLD_TOPIC)
      
          # Keep the main thread alive, or the process will exit.
          try:
              while True:
                  time.sleep(10)
          except InterruptedError:
              print('Subscribe interrupted.')
      
          operation.close()
      except Exception:
          print('Exception occurred when using IPC.', file=sys.stderr)
          traceback.print_exc()
          exit(1)
      ```
**catatan**  
Komponen ini menggunakan klien IPC V2 di [AWS IoT Device SDK v2 untuk Python untuk](https://github.com/aws/aws-iot-device-sdk-python-v2) berkomunikasi dengan AWS IoT Greengrass perangkat lunak Core. Dibandingkan dengan klien IPC asli, klien IPC V2 mengurangi jumlah kode yang perlu Anda tulis untuk menggunakan IPC dalam komponen khusus.

   1. Gunakn Greengrass CLI untuk men-deploy komponen.

------
#### [ Linux or Unix ]

      ```
      sudo /greengrass/v2/bin/greengrass-cli deployment create \
        --recipeDir recipes \
        --artifactDir artifacts \
        --merge "com.example.clientdevices.MyHelloWorldSubscriber=1.0.0"
      ```

------
#### [ Windows Command Prompt (CMD) ]

      ```
      C:\greengrass\v2/bin/greengrass-cli deployment create ^
        --recipeDir recipes ^
        --artifactDir artifacts ^
        --merge "com.example.clientdevices.MyHelloWorldSubscriber=1.0.0"
      ```

------
#### [ PowerShell ]

      ```
      C:\greengrass\v2/bin/greengrass-cli deployment create `
        --recipeDir recipes `
        --artifactDir artifacts `
        --merge "com.example.clientdevices.MyHelloWorldSubscriber=1.0.0"
      ```

------

1. Lihat log komponen untuk memverifikasi bahwa komponen berhasil menginstal dan berlangganan topik.

------
#### [ Linux or Unix ]

   ```
   sudo tail -f /greengrass/v2/logs/com.example.clientdevices.MyHelloWorldSubscriber.log
   ```

------
#### [ PowerShell ]

   ```
   gc C:\greengrass\v2/logs/com.example.clientdevices.MyHelloWorldSubscriber.log -Tail 10 -Wait
   ```

------

   Anda dapat menjaga log feed tetap terbuka untuk memverifikasi bahwa inti perangkat menerima pesan.

1. Pada perangkat klien, jalankan sampel aplikasi penemuan Greengrass lagi untuk mengirim pesan ke perangkat inti.

   ```
   python3 basic_discovery.py \\
     --thing_name MyClientDevice1 \\
     --topic 'clients/MyClientDevice1/hello/world' \\
     --message 'Hello World!' \\
     --ca_file ~/certs/AmazonRootCA1.pem \\
     --cert ~/certs/device.pem.crt \\
     --key ~/certs/private.pem.key \\
     --region us-east-1 \\
     --verbosity Warn
   ```

1. Lihat log komponen lagi untuk memverifikasi bahwa komponen menerima dan mencetak pesan dari perangkat klien.

------
#### [ Linux or Unix ]

   ```
   sudo tail -f /greengrass/v2/logs/com.example.clientdevices.MyHelloWorldSubscriber.log
   ```

------
#### [ PowerShell ]

   ```
   gc C:\greengrass\v2/logs/com.example.clientdevices.MyHelloWorldSubscriber.log -Tail 10 -Wait
   ```

------

## Langkah 5: Kembangkan komponen yang berinteraksi dengan bayangan perangkat klien
<a name="develop-client-device-shadow-component"></a>

[Anda dapat mengembangkan komponen Greengrass yang berinteraksi dengan bayangan perangkat perangkat klien.AWS IoT](https://docs.aws.amazon.com/iot/latest/developerguide/iot-device-shadows.html) *Bayangan* adalah dokumen JSON yang menyimpan informasi status saat ini atau yang diinginkan untuk suatu AWS IoT hal, seperti perangkat klien. Komponen khusus dapat mengakses bayangan perangkat klien untuk mengelola statusnya, bahkan ketika perangkat klien tidak terhubung. AWS IoT Setiap AWS IoT benda memiliki bayangan yang tidak disebutkan namanya, dan Anda juga dapat membuat beberapa bayangan bernama untuk setiap hal.

Di bagian ini, Anda menerapkan [komponen shadow manager](shadow-manager-component.md) untuk mengelola bayangan pada perangkat inti. Anda juga memperbarui komponen jembatan MQTT untuk menyampaikan pesan bayangan antara perangkat klien dan komponen shadow manager. Kemudian, Anda mengembangkan komponen yang memperbarui bayangan perangkat klien, dan Anda menjalankan aplikasi sampel pada perangkat klien yang merespons pembaruan bayangan dari komponen. Komponen ini mewakili aplikasi manajemen cahaya pintar, di mana perangkat inti mengelola status warna lampu pintar yang terhubung dengannya sebagai perangkat klien.

**Untuk mengembangkan komponen yang berinteraksi dengan bayangan perangkat klien**

1. Merevisi penerapan ke perangkat inti untuk menyebarkan komponen pengelola bayangan dan mengonfigurasi komponen jembatan MQTT untuk menyampaikan pesan bayangan antara perangkat klien dan penerbitan/langganan lokal, tempat manajer bayangan berkomunikasi. Lakukan hal-hal berikut:

   1. <a name="navigate-greengrass-console"></a>Navigasikan ke [konsol AWS IoT Greengrass](https://console.aws.amazon.com/greengrass) tersebut.

   1. Di menu navigasi kiri, pilih **Perangkat inti**.

   1. Pada halaman **Perangkat inti**, pilih perangkat inti yang Anda gunakan untuk tutorial ini.

   1. Pada halaman detail perangkat inti, pilih tab **Perangkat klien**.

   1. Pada tab **Perangkat klien**, pilih **Konfigurasikan penemuan cloud**.

      Halaman **Konfigurasikan penemuan perangkat inti** terbuka. Pada halaman ini, Anda dapat mengubah atau mengonfigurasi komponen perangkat klien mana yang di-deploy ke perangkat inti.

   1. Di **Langkah 3**, untuk komponen **aws.greengrass.clientdevices.mqtt.Bridge**, pilih **Edit konfigurasi**.

   1. Dalam modal **konfigurasi Edit** untuk komponen jembatan MQTT, konfigurasikan pemetaan topik yang menyampaikan pesan MQTT pada [topik bayangan perangkat antara perangkat](https://docs.aws.amazon.com/iot/latest/developerguide/reserved-topics.html#reserved-topics-shadow) klien dan antarmuka penerbitan/langganan lokal. Anda juga mengonfirmasi bahwa penerapan menentukan versi jembatan MQTT yang kompatibel. Dukungan bayangan perangkat klien memerlukan jembatan MQTT v2.2.0 atau yang lebih baru. Lakukan hal-hal berikut:

      1. Untuk **versi Komponen**, pilih versi 2.2.0 atau yang lebih baru.

      1. Di bawah **Konfigurasi**, di blok kode **Konfigurasi yang akan digabungkan**, masukkan konfigurasi berikut. Konfigurasi ini menentukan untuk menyampaikan pesan MQTT pada topik bayangan.

         ```
         {
           "mqttTopicMapping": {
             "HelloWorldIotCoreMapping": {
               "topic": "clients/+/hello/world",
               "source": "LocalMqtt",
               "target": "IotCore"
             },
             "HelloWorldPubsubMapping": {
               "topic": "clients/+/hello/world",
               "source": "LocalMqtt",
               "target": "Pubsub"
             },
             "ShadowsLocalMqttToPubsub": {
               "topic": "$aws/things/+/shadow/#",
               "source": "LocalMqtt",
               "target": "Pubsub"
             },
             "ShadowsPubsubToLocalMqtt": {
               "topic": "$aws/things/+/shadow/#",
               "source": "Pubsub",
               "target": "LocalMqtt"
             }
           }
         }
         ```

         Untuk informasi lebih lanjut, lihat [konfigurasi komponen jembatan MQTT](mqtt-bridge-component.md#mqtt-bridge-component-configuration).

      1. Pilih **Konfirmasi**.

   1. Pada **Langkah 3**, pilih **aws.greengrass.ShadowManager**komponen untuk menerapkannya.

   1. <a name="choose-review-and-deploy-configure-discovery-step"></a>Pilih **Tinjau dan deploy** untuk meninjau deployment yang dibuat oleh halaman ini untuk Anda.

   1. <a name="choose-deploy-configure-discovery-step"></a>Pada halaman **Tinjauan**, pilih **Deploy** untuk memulai deployment ke perangkat inti.

   1. <a name="verify-deployment-success-step"></a>Untuk memverifikasi bahwa deployment berhasil, periksa status deployment, dan periksa log pada perangkat inti. Untuk memeriksa status deployment pada perangkat inti, Anda dapat memilih **Target** pada **Gambaran Umum** deployment. Untuk informasi selengkapnya, lihat berikut ini:
      + [Periksa status deployment](check-deployment-status.md)
      + [Memantau AWS IoT Greengrass log](monitor-logs.md)

1. Kembangkan dan terapkan komponen Greengrass yang mengelola perangkat klien cahaya pintar. Lakukan hal-hal berikut:

   1. Buat folder artefak komponen pada perangkat inti.

------
#### [ Linux or Unix ]

      ```
      mkdir -p artifacts/com.example.clientdevices.MySmartLightManager/1.0.0
      ```

------
#### [ Windows Command Prompt (CMD) ]

      ```
      mkdir artifacts\com.example.clientdevices.MySmartLightManager\1.0.0
      ```

------
#### [ PowerShell ]

      ```
      mkdir artifacts\com.example.clientdevices.MySmartLightManager\1.0.0
      ```

------
**penting**  <a name="local-artifact-folder-name-requirements"></a>
Anda harus menggunakan format berikut untuk jalur folder artifact. Sertakan nama dan versi komponen yang Anda tentukan dalam resep.  

      ```
      artifacts/componentName/componentVersion/
      ```

   1. Gunakan editor teks untuk membuat resep komponen dengan konten berikut. Resep ini menentukan untuk menginstal AWS IoT Device SDK v2 untuk Python dan menjalankan skrip yang berinteraksi dengan bayangan perangkat klien cahaya pintar untuk mengelola warnanya.

      <a name="nano-command-intro"></a>Misalnya, pada sistem berbasis Linux, Anda dapat menjalankan perintah berikut untuk menggunakan GNU nano untuk membuat file.

      ```
      nano recipes/com.example.clientdevices.MySmartLightManager-1.0.0.json
      ```

      Salin resep berikut ke dalam file.

      ```
      {
        "RecipeFormatVersion": "2020-01-25",
        "ComponentName": "com.example.clientdevices.MySmartLightManager",
        "ComponentVersion": "1.0.0",
        "ComponentDescription": "A component that interacts with smart light client devices.",
        "ComponentPublisher": "Amazon",
        "ComponentDependencies": {
          "aws.greengrass.Nucleus": {
            "VersionRequirement": "^2.6.0"
          },
          "aws.greengrass.ShadowManager": {
            "VersionRequirement": "^2.2.0"
          },
          "aws.greengrass.clientdevices.mqtt.Bridge": {
            "VersionRequirement": "^2.2.0"
          }
        },
        "ComponentConfiguration": {
          "DefaultConfiguration": {
            "smartLightDeviceNames": [],
            "accessControl": {
              "aws.greengrass.ShadowManager": {
                "com.example.clientdevices.MySmartLightManager:shadow:1": {
                  "policyDescription": "Allows access to client devices' unnamed shadows",
                  "operations": [
                    "aws.greengrass#GetThingShadow",
                    "aws.greengrass#UpdateThingShadow"
                  ],
                  "resources": [
                    "$aws/things/MyClientDevice*/shadow"
                  ]
                }
              },
              "aws.greengrass.ipc.pubsub": {
                "com.example.clientdevices.MySmartLightManager:pubsub:1": {
                  "policyDescription": "Allows access to client devices' unnamed shadow updates",
                  "operations": [
                    "aws.greengrass#SubscribeToTopic"
                  ],
                  "resources": [
                    "$aws/things/+/shadow/update/accepted"
                  ]
                }
              }
            }
          }
        },
        "Manifests": [
          {
            "Platform": {
              "os": "linux"
            },
            "Lifecycle": {
              "install": "python3 -m pip install --user awsiotsdk",
              "Run": "python3 -u {artifacts:path}/smart_light_manager.py"
            }
          },
          {
            "Platform": {
              "os": "windows"
            },
            "Lifecycle": {
              "install": "py -3 -m pip install --user awsiotsdk",
              "Run": "py -3 -u {artifacts:path}/smart_light_manager.py"
            }
          }
        ]
      }
      ```

   1. Gunakan editor teks untuk membuat artefak skrip Python bernama `smart_light_manager.py` dengan konten berikut. Aplikasi ini menggunakan layanan shadow IPC untuk mendapatkan dan memperbarui bayangan perangkat klien dan layanan publish/subscribe IPC lokal untuk menerima pembaruan bayangan yang dilaporkan.

      <a name="nano-command-intro"></a>Misalnya, pada sistem berbasis Linux, Anda dapat menjalankan perintah berikut untuk menggunakan GNU nano untuk membuat file.

      ```
      nano artifacts/com.example.clientdevices.MySmartLightManager/1.0.0/smart_light_manager.py
      ```

      Salin kode Python berikut ke dalam file.

      ```
      import json
      import random
      import sys
      import time
      import traceback
      from uuid import uuid4
      
      from awsiot.greengrasscoreipc.clientv2 import GreengrassCoreIPCClientV2
      from awsiot.greengrasscoreipc.model import ResourceNotFoundError
      
      SHADOW_COLOR_PROPERTY = 'color'
      CONFIGURATION_CLIENT_DEVICE_NAMES = 'smartLightDeviceNames'
      COLORS = ['red', 'orange', 'yellow', 'green', 'blue', 'purple']
      SHADOW_UPDATE_TOPIC = '$aws/things/+/shadow/update/accepted'
      SET_COLOR_INTERVAL = 15
      
      
      class SmartLightDevice():
          def __init__(self, client_device_name: str, reported_color: str = None):
              self.name = client_device_name
              self.reported_color = reported_color
              self.desired_color = None
      
      
      class SmartLightDeviceManager():
          def __init__(self, ipc_client: GreengrassCoreIPCClientV2):
              self.ipc_client = ipc_client
              self.devices = {}
              self.client_tokens = set()
              self.shadow_update_accepted_subscription_operation = None
              self.client_device_names_configuration_subscription_operation = None
              self.update_smart_light_device_list()
      
          def update_smart_light_device_list(self):
              # Update the device list from the component configuration.
              response = self.ipc_client.get_configuration(
                  key_path=[CONFIGURATION_CLIENT_DEVICE_NAMES])
              # Identify the difference between the configuration and the currently tracked devices.
              current_device_names = self.devices.keys()
              updated_device_names = response.value[CONFIGURATION_CLIENT_DEVICE_NAMES]
              added_device_names = set(updated_device_names) - set(current_device_names)
              removed_device_names = set(current_device_names) - set(updated_device_names)
              # Stop tracking any smart light devices that are no longer in the configuration.
              for name in removed_device_names:
                  print('Removing %s from smart light device manager' % name)
                  self.devices.pop(name)
              # Start tracking any new smart light devices that are in the configuration.
              for name in added_device_names:
                  print('Adding %s to smart light device manager' % name)
                  device = SmartLightDevice(name)
                  device.reported_color = self.get_device_reported_color(device)
                  self.devices[name] = device
                  print('Current color for %s is %s' % (name, device.reported_color))
      
          def get_device_reported_color(self, smart_light_device):
              try:
                  response = self.ipc_client.get_thing_shadow(
                      thing_name=smart_light_device.name, shadow_name='')
                  shadow = json.loads(str(response.payload, 'utf-8'))
                  if 'reported' in shadow['state']:
                      return shadow['state']['reported'].get(SHADOW_COLOR_PROPERTY)
                  return None
              except ResourceNotFoundError:
                  return None
      
          def request_device_color_change(self, smart_light_device, color):
              # Generate and track a client token for the request.
              client_token = str(uuid4())
              self.client_tokens.add(client_token)
              # Create a shadow payload, which must be a blob.
              payload_json = {
                  'state': {
                      'desired': {
                          SHADOW_COLOR_PROPERTY: color
                      }
                  },
                  'clientToken': client_token
              }
              payload = bytes(json.dumps(payload_json), 'utf-8')
              self.ipc_client.update_thing_shadow(
                  thing_name=smart_light_device.name, shadow_name='', payload=payload)
              smart_light_device.desired_color = color
      
          def subscribe_to_shadow_update_accepted_events(self):
              if self.shadow_update_accepted_subscription_operation == None:
                  # SubscribeToTopic returns a tuple with the response and the operation.
                  _, self.shadow_update_accepted_subscription_operation = self.ipc_client.subscribe_to_topic(
                      topic=SHADOW_UPDATE_TOPIC, on_stream_event=self.on_shadow_update_accepted_event)
                  print('Successfully subscribed to shadow update accepted topic')
      
          def close_shadow_update_accepted_subscription(self):
              if self.shadow_update_accepted_subscription_operation is not None:
                  self.shadow_update_accepted_subscription_operation.close()
      
          def on_shadow_update_accepted_event(self, event):
              try:
                  message = str(event.binary_message.message, 'utf-8')
                  accepted_payload = json.loads(message)
                  # Check for reported states from smart light devices and ignore desired states from components.
                  if 'reported' in accepted_payload['state']:
                      # Process this update only if it uses a client token created by this component.
                      client_token = accepted_payload.get('clientToken')
                      if client_token is not None and client_token in self.client_tokens:
                          self.client_tokens.remove(client_token)
                          shadow_state = accepted_payload['state']['reported']
                          if SHADOW_COLOR_PROPERTY in shadow_state:
                              reported_color = shadow_state[SHADOW_COLOR_PROPERTY]
                              topic = event.binary_message.context.topic
                              client_device_name = topic.split('/')[2]
                              if client_device_name in self.devices:
                                  # Set the reported color for the smart light device.
                                  self.devices[client_device_name].reported_color = reported_color
                                  print(
                                      'Received shadow update confirmation from client device: %s' % client_device_name)
                          else:
                              print("Shadow update doesn't specify color")
              except:
                  traceback.print_exc()
      
          def subscribe_to_client_device_name_configuration_updates(self):
              if self.client_device_names_configuration_subscription_operation == None:
                  # SubscribeToConfigurationUpdate returns a tuple with the response and the operation.
                  _, self.client_device_names_configuration_subscription_operation = self.ipc_client.subscribe_to_configuration_update(
                      key_path=[CONFIGURATION_CLIENT_DEVICE_NAMES], on_stream_event=self.on_client_device_names_configuration_update_event)
                  print(
                      'Successfully subscribed to configuration updates for smart light device names')
      
          def close_client_device_names_configuration_subscription(self):
              if self.client_device_names_configuration_subscription_operation is not None:
                  self.client_device_names_configuration_subscription_operation.close()
      
          def on_client_device_names_configuration_update_event(self, event):
              try:
                  if CONFIGURATION_CLIENT_DEVICE_NAMES in event.configuration_update_event.key_path:
                      print('Received configuration update for list of client devices')
                      self.update_smart_light_device_list()
              except:
                  traceback.print_exc()
      
      
      def choose_random_color():
          return random.choice(COLORS)
      
      def main():
          try:
              # Create an IPC client and a smart light device manager.
              ipc_client = GreengrassCoreIPCClientV2()
              smart_light_manager = SmartLightDeviceManager(ipc_client)
              smart_light_manager.subscribe_to_shadow_update_accepted_events()
              smart_light_manager.subscribe_to_client_device_name_configuration_updates()
              try:
                  # Keep the main thread alive, or the process will exit.
                  while True:
                      # Set each smart light device to a random color at a regular interval.
                      for device_name in smart_light_manager.devices:
                          device = smart_light_manager.devices[device_name]
                          desired_color = choose_random_color()
                          print('Chose random color (%s) for %s' %
                                (desired_color, device_name))
                          if desired_color == device.desired_color:
                              print('Desired color for %s is already %s' %
                                    (device_name, desired_color))
                          elif desired_color == device.reported_color:
                              print('Reported color for %s is already %s' %
                                    (device_name, desired_color))
                          else:
                              smart_light_manager.request_device_color_change(
                                  device, desired_color)
                              print('Requested color change for %s to %s' %
                                    (device_name, desired_color))
                      time.sleep(SET_COLOR_INTERVAL)
              except InterruptedError:
                  print('Application interrupted')
              smart_light_manager.close_shadow_update_accepted_subscription()
              smart_light_manager.close_client_device_names_configuration_subscription()
          except Exception:
              print('Exception occurred', file=sys.stderr)
              traceback.print_exc()
              exit(1)
      
      
      if __name__ == '__main__':
          main()
      ```

      Aplikasi Python ini melakukan hal berikut:
      + Membaca konfigurasi komponen untuk mendapatkan daftar perangkat klien cahaya pintar untuk dikelola.
      + Berlangganan pemberitahuan pembaruan konfigurasi menggunakan operasi [SubscribeToConfigurationUpdate](ipc-component-configuration.md#ipc-operation-subscribetoconfigurationupdate) IPC. Perangkat lunak AWS IoT Greengrass Core mengirimkan pemberitahuan setiap kali konfigurasi komponen berubah. Saat komponen menerima pemberitahuan pembaruan konfigurasi, komponen akan memperbarui daftar perangkat klien cahaya pintar yang dikelolanya.
      + Mendapat bayangan setiap perangkat klien cahaya pintar untuk mendapatkan status warna awalnya.
      + Mengatur warna setiap perangkat klien cahaya pintar ke warna acak setiap 15 detik. Komponen memperbarui bayangan benda perangkat klien untuk mengubah warnanya. Operasi ini mengirimkan peristiwa delta bayangan ke perangkat klien melalui MQTT.
      + Berlangganan pembaruan bayangan pesan yang diterima pada antarmuka penerbitan/berlangganan lokal menggunakan operasi IPC. [SubscribeToTopic](ipc-publish-subscribe.md#ipc-operation-subscribetotopic) Komponen ini menerima pesan-pesan ini untuk melacak warna setiap perangkat klien cahaya pintar. Ketika perangkat klien cahaya pintar menerima pembaruan bayangan, ia mengirimkan pesan MQTT untuk mengonfirmasi bahwa ia menerima pembaruan. Jembatan MQTT menyampaikan pesan ini ke antarmuka lokal. publish/subscribe 

   1. Gunakn Greengrass CLI untuk men-deploy komponen. Saat menerapkan komponen ini, Anda menentukan daftar perangkat klien`smartLightDeviceNames`, yang bayangannya dikelola. Ganti *MyClientDevice1* dengan nama benda perangkat klien.

------
#### [ Linux or Unix ]

      ```
      sudo /greengrass/v2/bin/greengrass-cli deployment create \
        --recipeDir recipes \
        --artifactDir artifacts \
        --merge "com.example.clientdevices.MySmartLightManager=1.0.0" \
        --update-config '{
          "com.example.clientdevices.MySmartLightManager": {
            "MERGE": {
              "smartLightDeviceNames": [
                "MyClientDevice1"
              ]
            }
          }
        }'
      ```

------
#### [ Windows Command Prompt (CMD) ]

      ```
      C:\greengrass\v2/bin/greengrass-cli deployment create ^
        --recipeDir recipes ^
        --artifactDir artifacts ^
        --merge "com.example.clientdevices.MySmartLightManager=1.0.0" ^
        --update-config '{"com.example.clientdevices.MySmartLightManager":{"MERGE":{"smartLightDeviceNames":["MyClientDevice1"]}}}'
      ```

------
#### [ PowerShell ]

      ```
      C:\greengrass\v2/bin/greengrass-cli deployment create `
        --recipeDir recipes `
        --artifactDir artifacts `
        --merge "com.example.clientdevices.MySmartLightManager=1.0.0" `
        --update-config '{
          "com.example.clientdevices.MySmartLightManager": {
            "MERGE": {
              "smartLightDeviceNames": [
                "MyClientDevice1"
              ]
            }
          }
        }'
      ```

------

1. Lihat log komponen untuk memverifikasi bahwa komponen menginstal dan berjalan dengan sukses.

------
#### [ Linux or Unix ]

   ```
   sudo tail -f /greengrass/v2/logs/com.example.clientdevices.MySmartLightManager.log
   ```

------
#### [ PowerShell ]

   ```
   gc C:\greengrass\v2/logs/com.example.clientdevices.MySmartLightManager.log -Tail 10 -Wait
   ```

------

   Komponen mengirimkan permintaan untuk mengubah warna perangkat klien cahaya pintar. Manajer bayangan menerima permintaan dan menetapkan `desired` status bayangan. Namun, perangkat klien cahaya pintar belum berjalan, sehingga `reported` status bayangan tidak berubah. Log komponen menyertakan pesan berikut.

   ```
   2022-07-07T03:49:24.908Z [INFO] (Copier) com.example.clientdevices.MySmartLightManager: stdout. Chose random color (blue) for MyClientDevice1. {scriptName=services.com.example.clientdevices.MySmartLightManager.lifecycle.Run, serviceName=com.example.clientdevices.MySmartLightManager, currentState=RUNNING}
   2022-07-07T03:49:24.912Z [INFO] (Copier) com.example.clientdevices.MySmartLightManager: stdout. Requested color change for MyClientDevice1 to blue. {scriptName=services.com.example.clientdevices.MySmartLightManager.lifecycle.Run, serviceName=com.example.clientdevices.MySmartLightManager, currentState=RUNNING}
   ```

   Anda dapat membiarkan umpan log tetap terbuka untuk melihat kapan komponen mencetak pesan.

1. Unduh dan jalankan contoh aplikasi yang menggunakan penemuan Greengrass dan berlangganan pembaruan bayangan perangkat. Di perangkat klien, lakukan hal berikut:

   1. Gunakan editor teks untuk membuat skrip Python bernama `basic_discovery_shadow.py` dengan konten berikut. Aplikasi ini menggunakan penemuan Greengrass dan bayangan untuk menjaga properti tetap sinkron antara perangkat klien dan perangkat inti.

      <a name="nano-command-intro"></a>Misalnya, pada sistem berbasis Linux, Anda dapat menjalankan perintah berikut untuk menggunakan GNU nano untuk membuat file.

      ```
      nano basic_discovery_shadow.py
      ```

      Salin kode Python berikut ke dalam file.

      ```
      # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
      # SPDX-License-Identifier: Apache-2.0.
      
      from awscrt import io
      from awscrt import mqtt
      from awsiot import iotshadow
      from awsiot.greengrass_discovery import DiscoveryClient
      from awsiot import mqtt_connection_builder
      from concurrent.futures import Future
      import sys
      import threading
      import traceback
      from uuid import uuid4
      
      # --------------------------------- ARGUMENT PARSING -----------------------------------------
      import argparse
      
      def parse_sample_input():
          parser = argparse.ArgumentParser(
              description="AWS IoT Greengrass Discovery Shadow",
              formatter_class=argparse.ArgumentDefaultsHelpFormatter,
          )
      
          # Connection / TLS
          parser.add_argument("--cert", required=True, dest="input_cert",
                              help="Path to the certificate file to use during mTLS connection establishment")
          parser.add_argument("--key", required=True, dest="input_key",
                              help="Path to the private key file to use during mTLS connection establishment")
          parser.add_argument("--ca_file", dest="input_ca", help="Path to optional CA bundle (PEM)")
      
          # Shadow
          parser.add_argument("--thing_name", required=True, dest="input_thing_name", help="The name assigned to your IoT Thing.")
          parser.add_argument("--shadow_property", dest="input_shadow_property", default="color", 
                              help="The name of the shadow property you want to change (optional, default='color'")
          parser.add_argument("--region", dest="input_region", help="The region to connect through.", required=True)
          parser.add_argument("--print_discover_resp_only", dest="input_print_discover_resp_only", default=False)
      
          return parser.parse_args()
      
      args = parse_sample_input()
      
      # --------------------------------- ARGUMENT PARSING END -----------------------------------------
      
      
      # Using globals to simplify sample code
      is_sample_done = threading.Event()
      mqtt_connection = None
      shadow_thing_name = args.input_thing_name
      shadow_property = args.input_shadow_property
      
      SHADOW_VALUE_DEFAULT = "off"
      
      class LockedData:
          def __init__(self):
              self.lock = threading.Lock()
              self.shadow_value = None
              self.disconnect_called = False
              self.request_tokens = set()
      
      locked_data = LockedData()
      
      
      def on_connection_interupted(connection, error, **kwargs):
          print('connection interrupted with error {}'.format(error))
      
      
      def on_connection_resumed(connection, return_code, session_present, **kwargs):
          print('connection resumed with return code {}, session present {}'.format(return_code, session_present))
      
      # Try IoT endpoints until we find one that works
      def try_iot_endpoints():
          for gg_group in discover_response.gg_groups:
              for gg_core in gg_group.cores:
                  for connectivity_info in gg_core.connectivity:
                      try:
                          print('Trying core {} at host {} port {}'.format(gg_core.thing_arn, connectivity_info.host_address, connectivity_info.port))
                          mqtt_connection = mqtt_connection_builder.mtls_from_path(
                              endpoint=connectivity_info.host_address,
                              port=connectivity_info.port,
                              cert_filepath=args.input_cert,
                              pri_key_filepath=args.input_key,
                              ca_bytes=gg_group.certificate_authorities[0].encode('utf-8'),
                              on_connection_interrupted=on_connection_interupted,
                              on_connection_resumed=on_connection_resumed,
                              client_id=args.input_thing_name,
                              clean_session=False,
                              keep_alive_secs=30)
      
                          connect_future = mqtt_connection.connect()
                          connect_future.result()
                          print('Connected!')
                          return mqtt_connection
      
                      except Exception as e:
                          print('Connection failed with exception {}'.format(e))
                          continue
      
          exit('All connection attempts failed')
      
      # Function for gracefully quitting this sample
      def exit(msg_or_exception):
          if isinstance(msg_or_exception, Exception):
              print("Exiting sample due to exception.")
              traceback.print_exception(msg_or_exception.__class__, msg_or_exception, sys.exc_info()[2])
          else:
              print("Exiting sample:", msg_or_exception)
      
          with locked_data.lock:
              if not locked_data.disconnect_called:
                  print("Disconnecting...")
                  locked_data.disconnect_called = True
                  future = mqtt_connection.disconnect()
                  future.add_done_callback(on_disconnected)
      
      def on_disconnected(disconnect_future):
          # type: (Future) -> None
          print("Disconnected.")
      
          # Signal that sample is finished
          is_sample_done.set()
      
      def on_get_shadow_accepted(response):
          # type: (iotshadow.GetShadowResponse) -> None
          try:
              with locked_data.lock:
                  # check that this is a response to a request from this session
                  try:
                      locked_data.request_tokens.remove(response.client_token)
                  except KeyError:
                      return
      
                  print("Finished getting initial shadow state.")
                  if locked_data.shadow_value is not None:
                      print("  Ignoring initial query because a delta event has already been received.")
                      return
      
              if response.state:
                  if response.state.delta:
                      value = response.state.delta.get(shadow_property)
                      if value:
                          print("  Shadow contains delta value '{}'.".format(value))
                          change_shadow_value(value)
                          return
      
                  if response.state.reported:
                      value = response.state.reported.get(shadow_property)
                      if value:
                          print("  Shadow contains reported value '{}'.".format(value))
                          set_local_value_due_to_initial_query(response.state.reported[shadow_property])
                          return
      
              print("  Shadow document lacks '{}' property. Setting defaults...".format(shadow_property))
              change_shadow_value(SHADOW_VALUE_DEFAULT)
              return
      
          except Exception as e:
              exit(e)
      
      def on_get_shadow_rejected(error):
          # type: (iotshadow.ErrorResponse) -> None
          try:
              # check that this is a response to a request from this session
              with locked_data.lock:
                  try:
                      locked_data.request_tokens.remove(error.client_token)
                  except KeyError:
                      return
      
              if error.code == 404:
                  print("Thing has no shadow document. Creating with defaults...")
                  change_shadow_value(SHADOW_VALUE_DEFAULT)
              else:
                  exit("Get request was rejected. code:{} message:'{}'".format(
                      error.code, error.message))
      
          except Exception as e:
              exit(e)
      
      def on_shadow_delta_updated(delta):
          # type: (iotshadow.ShadowDeltaUpdatedEvent) -> None
          try:
              print("Received shadow delta event.")
              if delta.state and (shadow_property in delta.state):
                  value = delta.state[shadow_property]
                  if value is None:
                      print("  Delta reports that '{}' was deleted. Resetting defaults...".format(shadow_property))
                      change_shadow_value(SHADOW_VALUE_DEFAULT)
                      return
                  else:
                      print("  Delta reports that desired value is '{}'. Changing local value...".format(value))
                      if (delta.client_token is not None):
                          print ("  ClientToken is: " + delta.client_token)
                      change_shadow_value(value, delta.client_token)
              else:
                  print("  Delta did not report a change in '{}'".format(shadow_property))
      
          except Exception as e:
              exit(e)
      
      def on_publish_update_shadow(future):
          #type: (Future) -> None
          try:
              future.result()
              print("Update request published.")
          except Exception as e:
              print("Failed to publish update request.")
              exit(e)
      
      def on_update_shadow_accepted(response):
          # type: (iotshadow.UpdateShadowResponse) -> None
          try:
              # check that this is a response to a request from this session
              with locked_data.lock:
                  try:
                      locked_data.request_tokens.remove(response.client_token)
                  except KeyError:
                      return
      
              try:
                  if response.state.reported != None:
                      if shadow_property in response.state.reported:
                          print("Finished updating reported shadow value to '{}'.".format(response.state.reported[shadow_property])) # type: ignore
                      else:
                          print ("Could not find shadow property with name: '{}'.".format(shadow_property)) # type: ignore
                  else:
                      print("Shadow states cleared.") # when the shadow states are cleared, reported and desired are set to None
              except:
                  exit("Updated shadow is missing the target property")
      
          except Exception as e:
              exit(e)
      
      def on_update_shadow_rejected(error):
          # type: (iotshadow.ErrorResponse) -> None
          try:
              # check that this is a response to a request from this session
              with locked_data.lock:
                  try:
                      locked_data.request_tokens.remove(error.client_token)
                  except KeyError:
                      return
      
              exit("Update request was rejected. code:{} message:'{}'".format(
                  error.code, error.message))
      
          except Exception as e:
              exit(e)
      
      def set_local_value_due_to_initial_query(reported_value):
          with locked_data.lock:
              locked_data.shadow_value = reported_value
      
      def change_shadow_value(value, token=None):
          with locked_data.lock:
              if locked_data.shadow_value == value:
                  print("Local value is already '{}'.".format(value))
                  return
      
              print("Changed local shadow value to '{}'.".format(value))
              locked_data.shadow_value = value
      
              print("Updating reported shadow value to '{}'...".format(value))
      
              reuse_token = token is not None
              # use a unique token so we can correlate this "request" message to
              # any "response" messages received on the /accepted and /rejected topics
              if not reuse_token:
                  token = str(uuid4())
      
              # if the value is "clear shadow" then send a UpdateShadowRequest with None
              # for both reported and desired to clear the shadow document completely.
              if value == "clear_shadow":
                  tmp_state = iotshadow.ShadowState(reported=None, desired=None, reported_is_nullable=True, desired_is_nullable=True)
                  request = iotshadow.UpdateShadowRequest(
                      thing_name=shadow_thing_name,
                      state=tmp_state,
                      client_token=token,
                  )
              # Otherwise, send a normal update request
              else:
                  # if the value is "none" then set it to a Python none object to
                  # clear the individual shadow property
                  if value == "none":
                      value = None
      
                  request = iotshadow.UpdateShadowRequest(
                  thing_name=shadow_thing_name,
                  state=iotshadow.ShadowState(
                      reported={ shadow_property: value }
                      ),
                      client_token=token,
                  )
      
              future = shadow_client.publish_update_shadow(request, mqtt.QoS.AT_LEAST_ONCE)
      
              if not reuse_token:
                  locked_data.request_tokens.add(token)
      
              future.add_done_callback(on_publish_update_shadow)
      
      
      if __name__ == '__main__':
          tls_options = io.TlsContextOptions.create_client_with_mtls_from_path(args.input_cert,args.input_key)
          if args.input_ca:
              tls_options.override_default_trust_store_from_path(None, args.input_ca)
          tls_context = io.ClientTlsContext(tls_options)
      
          socket_options = io.SocketOptions()
      
          print('Performing greengrass discovery...')
          discovery_client = DiscoveryClient(io.ClientBootstrap.get_or_create_static_default(), socket_options, tls_context, args.input_region)
          resp_future = discovery_client.discover(args.input_thing_name)
          discover_response = resp_future.result()
      
          print(discover_response)
          if args.print_discover_resp_only:
              exit(0)
      
          mqtt_connection = try_iot_endpoints()
          shadow_client = iotshadow.IotShadowClient(mqtt_connection)
      
          try:
              # Subscribe to necessary topics.
              # Note that is **is** important to wait for "accepted/rejected" subscriptions
              # to succeed before publishing the corresponding "request".
              print("Subscribing to Update responses...")
              update_accepted_subscribed_future, _ = shadow_client.subscribe_to_update_shadow_accepted(
                  request=iotshadow.UpdateShadowSubscriptionRequest(thing_name=shadow_thing_name),
                  qos=mqtt.QoS.AT_LEAST_ONCE,
                  callback=on_update_shadow_accepted)
      
              update_rejected_subscribed_future, _ = shadow_client.subscribe_to_update_shadow_rejected(
                  request=iotshadow.UpdateShadowSubscriptionRequest(thing_name=shadow_thing_name),
                  qos=mqtt.QoS.AT_LEAST_ONCE,
                  callback=on_update_shadow_rejected)
      
              # Wait for subscriptions to succeed
              update_accepted_subscribed_future.result()
              update_rejected_subscribed_future.result()
      
              print("Subscribing to Get responses...")
              get_accepted_subscribed_future, _ = shadow_client.subscribe_to_get_shadow_accepted(
                  request=iotshadow.GetShadowSubscriptionRequest(thing_name=shadow_thing_name),
                  qos=mqtt.QoS.AT_LEAST_ONCE,
                  callback=on_get_shadow_accepted)
      
              get_rejected_subscribed_future, _ = shadow_client.subscribe_to_get_shadow_rejected(
                  request=iotshadow.GetShadowSubscriptionRequest(thing_name=shadow_thing_name),
                  qos=mqtt.QoS.AT_LEAST_ONCE,
                  callback=on_get_shadow_rejected)
      
              # Wait for subscriptions to succeed
              get_accepted_subscribed_future.result()
              get_rejected_subscribed_future.result()
      
              print("Subscribing to Delta events...")
              delta_subscribed_future, _ = shadow_client.subscribe_to_shadow_delta_updated_events(
                  request=iotshadow.ShadowDeltaUpdatedSubscriptionRequest(thing_name=shadow_thing_name),
                  qos=mqtt.QoS.AT_LEAST_ONCE,
                  callback=on_shadow_delta_updated)
      
              # Wait for subscription to succeed
              delta_subscribed_future.result()
      
              # The rest of the sample runs asynchronously.
      
              # Issue request for shadow's current state.
              # The response will be received by the on_get_accepted() callback
              print("Requesting current shadow state...")
      
              with locked_data.lock:
                  # use a unique token so we can correlate this "request" message to
                  # any "response" messages received on the /accepted and /rejected topics
                  token = str(uuid4())
      
                  publish_get_future = shadow_client.publish_get_shadow(
                      request=iotshadow.GetShadowRequest(thing_name=shadow_thing_name, client_token=token),
                      qos=mqtt.QoS.AT_LEAST_ONCE)
      
                  locked_data.request_tokens.add(token)
      
              # Ensure that publish succeeds
              publish_get_future.result()
      
          except Exception as e:
              exit(e)
      
          # Wait for the sample to finish (user types 'quit', or an error occurs)
          is_sample_done.wait()
      ```

      Aplikasi Python ini melakukan hal berikut:
      + Menggunakan penemuan Greengrass untuk menemukan dan terhubung ke perangkat inti.
      + Meminta dokumen bayangan dari perangkat inti untuk mendapatkan status awal properti.
      + Berlangganan peristiwa delta bayangan, yang dikirim perangkat inti ketika `desired` nilai properti berbeda dari nilainya`reported`. Ketika aplikasi menerima peristiwa delta bayangan, itu mengubah nilai properti dan mengirimkan pembaruan ke perangkat inti untuk menetapkan nilai baru sebagai `reported` nilainya.

      Aplikasi ini menggabungkan penemuan Greengrass dan sampel bayangan dari v2. AWS IoT Device SDK 

   1. Jalankan aplikasi sampel. Aplikasi ini mengharapkan argumen yang menentukan nama benda perangkat klien, properti bayangan yang akan digunakan, dan sertifikat yang mengautentikasi dan mengamankan koneksi.<a name="test-client-device-communications-application-command-replace"></a>
      + Ganti *MyClientDevice1* dengan nama benda perangkat klien.
      + Ganti *\$1/certs/AmazonRootCA1.pem* dengan jalur ke sertifikat CA root Amazon di perangkat klien.
      + Ganti *\$1/certs/device.pem.crt* dengan jalur ke sertifikat perangkat di perangkat klien.
      + Ganti *\$1/certs/private.pem.key* dengan path ke file kunci pribadi pada perangkat klien.
      + Ganti *us-east-1* dengan AWS Wilayah tempat perangkat klien dan perangkat inti Anda beroperasi.

      ```
      python3 basic_discovery_shadow.py \
        --thing_name MyClientDevice1 \
        --shadow_property color \
        --ca_file ~/certs/AmazonRootCA1.pem \
        --cert ~/certs/device.pem.crt \
        --key ~/certs/private.pem.key \
        --region us-east-1 \
        --verbosity Warn
      ```

      Aplikasi sampel berlangganan topik bayangan dan menunggu untuk menerima peristiwa delta bayangan dari perangkat inti. Jika output menunjukkan bahwa aplikasi menerima dan merespons peristiwa delta bayangan, perangkat klien dapat berhasil berinteraksi dengan bayangannya pada perangkat inti.

      ```
      Performing greengrass discovery...
      awsiot.greengrass_discovery.DiscoverResponse(gg_groups=[awsiot.greengrass_discovery.GGGroup(gg_group_id='greengrassV2-coreDevice-MyGreengrassCore', cores=[awsiot.greengrass_discovery.GGCore(thing_arn='arn:aws:iot:us-east-1:123456789012:thing/MyGreengrassCore', connectivity=[awsiot.greengrass_discovery.ConnectivityInfo(id='203.0.113.0', host_address='203.0.113.0', metadata='', port=8883)])], certificate_authorities=['-----BEGIN CERTIFICATE-----\nMIICiT...EXAMPLE=\n-----END CERTIFICATE-----\n'])])
      Trying core arn:aws:iot:us-east-1:123456789012:thing/MyGreengrassCore at host 203.0.113.0 port 8883
      Connected!
      Subscribing to Update responses...
      Subscribing to Get responses...
      Subscribing to Delta events...
      Requesting current shadow state...
      Received shadow delta event.
        Delta reports that desired value is 'purple'. Changing local value...
        ClientToken is: 3dce4d3f-e336-41ac-aa4f-7882725f0033
      Changed local shadow value to 'purple'.
      Updating reported shadow value to 'purple'...
      Update request published.
      ```

      <a name="test-client-device-communications-application-troubleshooting"></a>Jika aplikasi mengeluarkan kesalahan, lihat [Pemecahan masalah penemuan Greengrass](troubleshooting-client-devices.md#greengrass-discovery-issues).

      <a name="test-client-device-communications-application-view-core-logs"></a>Anda juga dapat melihat log Greengrass pada perangkat inti untuk memverifikasi apakah perangkat klien berhasil menghubungkan dan mengirim pesan. Untuk informasi selengkapnya, lihat [Memantau AWS IoT Greengrass log](monitor-logs.md).

1. Lihat log komponen lagi untuk memverifikasi bahwa komponen menerima konfirmasi pembaruan bayangan dari perangkat klien cahaya pintar.

------
#### [ Linux or Unix ]

   ```
   sudo tail -f /greengrass/v2/logs/com.example.clientdevices.MySmartLightManager.log
   ```

------
#### [ PowerShell ]

   ```
   gc C:\greengrass\v2/logs/com.example.clientdevices.MySmartLightManager.log -Tail 10 -Wait
   ```

------

   Komponen mencatat pesan untuk mengonfirmasi bahwa perangkat klien cahaya pintar berubah warnanya.

   ```
   2022-07-07T03:49:24.908Z [INFO] (Copier) com.example.clientdevices.MySmartLightManager: stdout. Chose random color (blue) for MyClientDevice1. {scriptName=services.com.example.clientdevices.MySmartLightManager.lifecycle.Run, serviceName=com.example.clientdevices.MySmartLightManager, currentState=RUNNING}
   2022-07-07T03:49:24.912Z [INFO] (Copier) com.example.clientdevices.MySmartLightManager: stdout. Requested color change for MyClientDevice1 to blue. {scriptName=services.com.example.clientdevices.MySmartLightManager.lifecycle.Run, serviceName=com.example.clientdevices.MySmartLightManager, currentState=RUNNING}
   2022-07-07T03:49:24.959Z [INFO] (Copier) com.example.clientdevices.MySmartLightManager: stdout. Received shadow update confirmation from client device: MyClientDevice1. {scriptName=services.com.example.clientdevices.MySmartLightManager.lifecycle.Run, serviceName=com.example.clientdevices.MySmartLightManager, currentState=RUNNING}
   ```

**catatan**  
Bayangan perangkat klien disinkronkan antara perangkat inti dan perangkat klien. Namun, perangkat inti tidak menyinkronkan bayangan perangkat klien dengan AWS IoT Core. Anda dapat menyinkronkan bayangan dengan AWS IoT Core untuk melihat atau mengubah status semua perangkat di armada Anda, misalnya. Untuk informasi selengkapnya tentang cara mengonfigurasi komponen shadow manager untuk menyinkronkan bayangan AWS IoT Core, lihat[Sinkronkan bayangan perangkat lokal dengan AWS IoT Core](sync-shadows-with-iot-core.md).

Anda telah menyelesaikan tutorial ini. Perangkat klien terhubung ke perangkat inti, mengirim pesan MQTT ke dan komponen AWS IoT Core Greengrass, dan menerima pembaruan bayangan dari perangkat inti. Untuk informasi lebih lanjut tentang topik yang dibahas dalam tutorial ini, lihat berikut ini:
+ [Mengaitkan perangkat klien](associate-client-devices.md)
+ [Kelola titik akhir perangkat inti](manage-core-device-endpoints.md)
+ [Uji komunikasi perangkat klien](test-client-device-communications.md)
+ [API penemuan Greengrass RESTful](greengrass-discover-api.md)
+ [Relay pesan MQTT antara perangkat klien dan AWS IoT Core](relay-client-device-messages.md)
+ [Berinteraksilah dengan perangkat klien dalam komponen](interact-with-client-devices-in-components.md)
+ [Berinteraksilah dengan bayangan perangkat](interact-with-shadows.md)
+ [Berinteraksi dengan dan menyinkronkan bayangan perangkat klien](work-with-client-device-shadows.md)