

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Migrazione dalla AWS IoT Greengrass versione 1
<a name="migrate-from-v1"></a>

AWS IoT Greengrass Version 2 è una versione principale del software AWS IoT Greengrass Core e della console. APIs AWS IoT Greengrass V2 introduce diversi miglioramenti AWS IoT Greengrass V1, come applicazioni modulari, implementazioni su grandi flotte di dispositivi e supporto per piattaforme aggiuntive.

**Nota**  
Avviso di fine del supporto: il 7 ottobre 2026, AWS terminerà il supporto per. AWS IoT Greengrass Version 1 Dopo il 7 ottobre 2026, non potrai più accedere alla AWS IoT Greengrass V1 console o AWS IoT Greengrass V1 alle risorse.

Segui le istruzioni di questa guida per migrare da AWS IoT Greengrass V1 a. AWS IoT Greengrass V2

## Panoramica sulla migrazione
<a name="migration-overview"></a>

Ad alto livello, è possibile utilizzare la seguente procedura per aggiornare i dispositivi principali da AWS IoT Greengrass V1 a AWS IoT Greengrass V2.

Prima della migrazione, potrai scegliere tra due opzioni di runtime:
+ **Greengrass nucleus** (minore sforzo di migrazione, supporto completo delle funzionalità)
+ **Greengrass nucleus lite** (maggiore sforzo di migrazione, progettato per dispositivi con risorse limitate).

La procedura esatta da seguire dipende dalle risorse del dispositivo, dalle funzionalità richieste e dai requisiti ambientali specifici.

![\[Una panoramica su come migrare da AWS IoT Greengrass V1 a AWS IoT Greengrass V2.\]](http://docs.aws.amazon.com/it_it/greengrass/v2/developerguide/images/migration-workflow-updated.png)


1. 

**[Comprendi le differenze tra V1 e V2](greengrass-v1-concept-differences.md)**

   AWS IoT Greengrass V2 introduce nuovi concetti fondamentali per le flotte di dispositivi e il software implementabile, mentre la V2 semplifica diversi concetti della V1.

   Il servizio AWS IoT Greengrass V2 cloud e il software AWS IoT Greengrass Core v2.x non sono retrocompatibili con il servizio cloud e il software Core v1.x. AWS IoT Greengrass V1 AWS IoT Greengrass Di conseguenza, gli aggiornamenti AWS IoT Greengrass V1 over-the-air (OTA) non possono aggiornare i dispositivi principali dalla V1 alla V2.

1. 

**[Scegli il tuo runtime (Greengrass nucleus o Greengrass nucleus lite)](choose-runtime.md)**

   Scegli tra Greengrass nucleus o Greengrass nucleus lite in base alle risorse del dispositivo e ai requisiti delle funzionalità:
   + **Greengrass nucleus path**: minore sforzo migratorio. Le funzioni Lambda possono essere importate come componenti Lambda con modifiche minime al codice. Supporta le funzionalità della V1 (servizio shadow locale, dispositivi client, connettori).
   + **Greengrass nucleus lite path**: maggiore impegno migratorio. Le funzioni Lambda devono essere convertite in componenti generici, richiedendo modifiche al codice per utilizzare SDK per dispositivi AWS IoT AWS IoT Greengrass V2/Component SDK anziché Core SDK. AWS IoT Greengrass Non supporta il servizio shadow locale, i dispositivi client o i connettori.

1. 

**[Configura un nuovo dispositivo per testare le applicazioni V1 su V2](set-up-test-device.md)**

   Per ridurre al minimo i rischi per i dispositivi in produzione, crea un nuovo dispositivo per testare le applicazioni V1 sulla V2. Scegliete la guida alla configurazione in base alla selezione del runtime:
   + **Opzione A - Greengrass nucleus runtime**: [configura un nuovo dispositivo per testare le applicazioni V1 su V2](set-up-v2-test-device.md). Importa le funzioni Lambda come componenti Lambda con modifiche minime al codice.
   + **Opzione B - Greengrass nucleus lite runtime**: [configura un nuovo dispositivo per testare le applicazioni V1 su V2 (Greengrass](set-up-v2-test-device-lite.md) nucleus lite). Converti le funzioni Lambda in componenti generici utilizzando. SDK per dispositivi AWS IoT

1. 

**[Aggiorna i dispositivi principali V1 per eseguire V2](upgrade-v1-core-devices.md)**

   Dopo aver eseguito il test su un nuovo dispositivo, aggiorna i dispositivi core V1 esistenti per eseguire il software AWS IoT Greengrass Core v2.x e i componenti. AWS IoT Greengrass V2 Per migrare una flotta di dispositivi dalla V1 alla V2, ripeti questo passaggio per ogni dispositivo del parco dispositivi.

# Differenze tra AWS IoT Greengrass V1 e AWS IoT Greengrass V2
<a name="greengrass-v1-concept-differences"></a>

AWS IoT Greengrass V2 introduce nuovi concetti fondamentali per dispositivi, flotte e software implementabile. Questa sezione descrive i concetti della V1 che sono diversi nella V2.


**Concetti e terminologia di Greengrass**  

| Concetto | AWS IoT Greengrass V1 | AWS IoT Greengrass V2 | 
| --- | --- | --- | 
|  Codice dell'applicazione  |  Nel AWS IoT Greengrass V1, le funzioni Lambda definiscono il software che viene eseguito sui dispositivi principali. In ogni gruppo Greengrass, definisci gli abbonamenti e le risorse locali utilizzate dalla funzione. Per le funzioni Lambda eseguite dal software AWS IoT Greengrass Core in un ambiente di runtime Lambda containerizzato, è possibile definire i parametri del contenitore, come i limiti di memoria.  |  In AWS IoT Greengrass V2, *i componenti sono i* moduli software che vengono eseguiti sui dispositivi principali. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/greengrass/v2/developerguide/greengrass-v1-concept-differences.html) È possibile importare le funzioni Lambda V1 come componenti eseguiti in un ambiente di runtime Lambda in. AWS IoT Greengrass V2 Quando si importa la funzione Lambda, si specificano gli abbonamenti, le risorse locali e i parametri del contenitore per la funzione. Per ulteriori informazioni, consulta [Fase 2: Creare e distribuire componenti per migrare le applicazioni AWS IoT Greengrass V2 AWS IoT Greengrass V1](set-up-v2-test-device.md#run-v1-applications). Per ulteriori informazioni su come creare componenti personalizzati, consulta. [Sviluppa AWS IoT Greengrass componenti](develop-greengrass-components.md)  | 
|  AWS IoT Greengrass gruppi e distribuzioni  |  In AWS IoT Greengrass V1, un gruppo definisce il dispositivo principale, le impostazioni e il software per quel dispositivo principale e l'elenco di AWS IoT elementi che possono connettersi a quel dispositivo principale. Si crea una distribuzione per inviare la configurazione di un gruppo a un dispositivo principale.  |  In AWS IoT Greengrass V2, si utilizzano *le distribuzioni* per definire i componenti e le configurazioni software da eseguire sui dispositivi principali. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/greengrass/v2/developerguide/greengrass-v1-concept-differences.html) Per ulteriori informazioni, consulta [Implementazione AWS IoT Greengrass dei componenti sui dispositivi](manage-deployments.md). In AWS IoT Greengrass V2, puoi anche creare distribuzioni locali utilizzando la [CLI](gg-cli.md) di Greengrass per testare componenti software personalizzati sul dispositivo su cui li sviluppi. Per ulteriori informazioni, consulta [Crea AWS IoT Greengrass componenti](create-components.md).  | 
|  AWS IoT Greengrass Software di base  |  Nel AWS IoT Greengrass V1, il software AWS IoT Greengrass Core è un unico pacchetto che contiene il software e tutte le sue funzionalità. Il dispositivo edge su cui si installa il software AWS IoT Greengrass Core è chiamato core Greengrass.   |  In AWS IoT Greengrass V2, il software AWS IoT Greengrass Core è modulare, quindi puoi scegliere cosa installare per controllare l'ingombro della memoria. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/greengrass/v2/developerguide/greengrass-v1-concept-differences.html)  | 
|  Connectors (Connettori)  |  In AWS IoT Greengrass V1, i connettori sono moduli predefiniti che puoi distribuire sui dispositivi AWS IoT Greengrass V1 principali per interagire con l'infrastruttura locale, i protocolli dei dispositivi e altri AWS servizi cloud.  |  In AWS IoT Greengrass V2, AWS fornisce componenti Greengrass che implementano le funzionalità fornite dai connettori in V1. I seguenti AWS IoT Greengrass V2 componenti forniscono la funzionalità del connettore Greengrass V1: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/greengrass/v2/developerguide/greengrass-v1-concept-differences.html) Per ulteriori informazioni, consulta [AWS-componenti forniti](public-components.md).  | 
|  Dispositivi collegati (dispositivi Greengrass)  |  Nel AWS IoT Greengrass V1, i dispositivi connessi sono AWS IoT elementi che si aggiungono a un gruppo Greengrass per connettersi al dispositivo principale di quel gruppo e comunicare tramite MQTT. È necessario distribuire quel gruppo ogni volta che si aggiunge o si rimuove un dispositivo connesso. Gli abbonamenti vengono utilizzati per inoltrare messaggi tra dispositivi connessi e applicazioni sul dispositivo principale. AWS IoT Core  |  Nel AWS IoT Greengrass V2, i dispositivi collegati sono chiamati dispositivi client Greengrass. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/greengrass/v2/developerguide/greengrass-v1-concept-differences.html) In entrambi AWS IoT Greengrass V1 i casi AWS IoT Greengrass V2, i dispositivi possono eseguire [FreerTOS](https://docs.aws.amazon.com/freertos/latest/userguide/freertos-lib-gg-connectivity.html) o utilizzare l'API di [scoperta [SDK per dispositivi AWS IoT](https://docs.aws.amazon.com/iot/latest/developerguide/iot-sdks.html)o Greengrass](greengrass-discover-api.md) per ottenere informazioni sui dispositivi principali a cui possono connettersi. L'API Greengrass discovery è retrocompatibile, quindi se disponi di dispositivi client che si connettono a un dispositivo core V1, puoi collegarli a un dispositivo core V2 senza modificarne il codice. Per ulteriori informazioni sui dispositivi client, vedere. [Interagisci con dispositivi IoT locali](interact-with-local-iot-devices.md)  | 
|  Risorse locali  |  In AWS IoT Greengrass V1, le funzioni Lambda eseguite nei contenitori possono essere configurate per accedere a volumi e dispositivi sul file system del dispositivo principale. Queste risorse del file system sono note come risorse locali.  |  In AWS IoT Greengrass V2, puoi eseguire componenti che sono [funzioni Lambda](run-lambda-functions.md), [contenitori Docker](run-docker-container.md) o [processi nativi del sistema operativo](develop-greengrass-components.md) o runtime personalizzati. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/greengrass/v2/developerguide/greengrass-v1-concept-differences.html)  | 
|  Servizio shadow locale  |  In AWS IoT Greengrass V1, il servizio shadow locale è abilitato per impostazione predefinita e supporta solo ombre classiche senza nome. Utilizzi AWS IoT Greengrass Core SDK nelle funzioni Lambda per interagire con le ombre sui tuoi dispositivi.  |  In AWS IoT Greengrass V2, abiliti il servizio shadow locale distribuendo il componente shadow manager. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/greengrass/v2/developerguide/greengrass-v1-concept-differences.html) Per ulteriori informazioni, consulta [Interagisci con le ombre dei dispositivi](interact-with-shadows.md).  | 
|  Sottoscrizioni  |  Nel AWS IoT Greengrass V1, si definiscono gli abbonamenti per un gruppo Greengrass per specificare i canali di comunicazione tra le funzioni Lambda, i connettori, i dispositivi collegati, il broker MQTT e AWS IoT Core il servizio shadow locale. Gli abbonamenti specificano dove le funzioni Lambda ricevono messaggi di eventi da utilizzare come payload di funzioni.  |  In AWS IoT Greengrass V2, si specificano i canali di comunicazione senza utilizzare abbonamenti. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/greengrass/v2/developerguide/greengrass-v1-concept-differences.html)  | 
|  Accedere ad altri Servizi AWS  |  In AWS IoT Greengrass V1, si assegna un ruolo AWS Identity and Access Management (IAM), chiamato ruolo di gruppo, a un gruppo Greengrass. Il ruolo di gruppo definisce le autorizzazioni che le funzioni AWS IoT Greengrass e le funzionalità Lambda sul dispositivo principale di quel gruppo utilizzano per accedere. Servizi AWS  |  In AWS IoT Greengrass V2, si collega un alias di AWS IoT ruolo a un dispositivo principale Greengrass. L'alias del ruolo rimanda a un ruolo IAM chiamato *token* exchange role. Il ruolo di scambio di token definisce le autorizzazioni utilizzate dai componenti Greengrass sul dispositivo principale per accedere. Servizi AWS Per ulteriori informazioni, consulta [Autorizza i dispositivi principali a interagire con i servizi AWS](device-service-role.md).  | 

# Scegli il tuo runtime (Greengrass nucleus o Greengrass nucleus lite)
<a name="choose-runtime"></a>

La scelta tra Greengrass nucleus e Greengrass nucleus lite dipende dalle risorse del dispositivo e dalle funzionalità utilizzate dalle funzioni Lambda. Esamina la matrice di compatibilità delle sorgenti degli eventi nella tabella seguente, quindi utilizza il diagramma del flusso decisionale per determinare quale runtime è appropriato per la migrazione. [Per un confronto dettagliato delle funzionalità di Greengrass nucleus e Greengrass nucleus lite, vedi Scelta del runtime.](choosing-your-runtime.md)

## Matrice di compatibilità delle sorgenti degli eventi
<a name="event-source-compatibility"></a>

Nel AWS IoT Greengrass V1, le funzioni Lambda possono comunicare con cinque tipi di sorgenti di eventi: altre funzioni Lambda, servizio shadow locale AWS IoT Core, dispositivi client e connettori. La tabella seguente mostra quali di queste sorgenti di eventi sono supportate in ogni runtime V2.

Nota: i nomi delle sorgenti degli eventi utilizzano la AWS IoT Greengrass V1 terminologia. Durante la migrazione alla V2, le funzioni Lambda vengono convertite in componenti Lambda (supportati solo in Greengrass nucleus) o componenti generici (supportati sia in Greengrass nucleus che in Greengrass nucleus lite).


| Origine eventi | Nucleo Greengrass | Greengrass Nucleus Lite | 
| --- | --- | --- | 
|  Altre funzioni Lambda del gruppo  |  ✓ (componenti Lambda e componenti generici)  |  ✓ (solo componenti generici)  | 
|  AWS IoT Core servizio  |  ✓  |  ✓  | 
|  Servizio shadow locale  |  ✓  |  ✗  | 
|  Dispositivo client  |  ✓  |  ✗  | 
|  Connector  |  ✓  |  ✗  | 

## Flusso decisionale di selezione del runtime
<a name="runtime-selection-decision-flow"></a>

![\[Diagramma di flusso decisionale per la scelta tra Greengrass nucleus e Greengrass nucleus lite.\]](http://docs.aws.amazon.com/it_it/greengrass/v2/developerguide/images/runtime-selection-decision-flow.png)


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

1. [Per i requisiti e i dettagli sulla compatibilità di Greengrass nucleus lite, vedere Greengrass nucleus lite.](greengrass-nucleus-lite-component.md) Greengrass nucleus lite richiede un minimo di 5 MB di RAM ed è progettato per dispositivi con risorse limitate.

1. Il flusso decisionale fornisce indicazioni basate su casi d'uso tipici, ma non è un requisito rigoroso. I clienti con dispositivi con risorse limitate e sufficienti possono scegliere di utilizzare un unico runtime su tutti i dispositivi per semplificare le operazioni, anche se alcuni dispositivi sono in grado di supportare entrambi i runtime.

## Fasi successive
<a name="next-steps-runtime"></a>

Dopo aver scelto il runtime, procedi con la configurazione del dispositivo di test:
+ Per Greengrass nucleus runtime: [configura un nuovo dispositivo per testare le applicazioni V1 su V2](set-up-v2-test-device.md)
+ Per Greengrass nucleus lite runtime: [configura un nuovo dispositivo con Greengrass](set-up-v2-test-device-lite.md) nucleus lite

# Configura un nuovo dispositivo per testare le applicazioni V1 su V2
<a name="set-up-test-device"></a>

Per ridurre al minimo i rischi per i dispositivi in produzione, create un nuovo dispositivo per testare le applicazioni V1 sulla V2 prima di aggiornare i dispositivi di produzione.

Scegliete una delle seguenti guide di configurazione in base alla selezione di runtime effettuata nel passaggio precedente:
+ **Opzione A - Greengrass nucleus runtime**: segui [Configura un nuovo dispositivo per testare le applicazioni V1 su V2](set-up-v2-test-device.md) se hai scelto Greengrass nucleus. Con questa opzione, puoi importare le funzioni Lambda come componenti Lambda con modifiche minime al codice e supporta funzionalità V1 come il servizio shadow locale, i dispositivi client e i connettori.
+ **Opzione B - Greengrass nucleus lite runtime**: segui [Configura un nuovo dispositivo per testare le applicazioni V1 su V2 (Greengrass nucleus lite)](set-up-v2-test-device-lite.md) se hai scelto Greengrass nucleus lite. Questa opzione richiede la conversione delle funzioni Lambda in componenti generici utilizzando SDK per dispositivi AWS IoT V2 AWS IoT Greengrass o Component SDK, ma è ottimizzata per i dispositivi con risorse limitate.

# Configura un nuovo dispositivo per testare le applicazioni V1 su V2
<a name="set-up-v2-test-device"></a>

Configura un nuovo dispositivo AWS IoT Greengrass V2 principale per distribuire e testare i componenti e AWS Lambda le funzioni AWS forniti per le tue applicazioni. AWS IoT Greengrass V1 Puoi anche utilizzare questo dispositivo core V2 per sviluppare e testare componenti Greengrass personalizzati aggiuntivi che eseguono processi nativi sui dispositivi principali. Dopo aver testato le applicazioni su un dispositivo core V2, è possibile aggiornare i dispositivi core V1 esistenti alla V2 e distribuire i componenti V2 che forniscono le funzionalità V1.



## Fase 1: Installazione su un nuovo dispositivo AWS IoT Greengrass V2
<a name="install-v2-test-device"></a>

Installa il software AWS IoT Greengrass Core v2.x su un nuovo dispositivo. Puoi seguire il [tutorial introduttivo](getting-started.md) per configurare un dispositivo e imparare a sviluppare e distribuire componenti. Questo tutorial utilizza il [provisioning automatico](quick-installation.md) per configurare rapidamente un dispositivo. Quando installi il software AWS IoT Greengrass Core v2.x, specifica l'`--deploy-dev-tools`argomento per distribuire la [Greengrass CLI](greengrass-cli-component.md), in modo da poter sviluppare, testare ed eseguire il debug dei componenti direttamente sul dispositivo. Per ulteriori informazioni su altre opzioni di installazione, incluso come installare il software AWS IoT Greengrass Core dietro un proxy o utilizzare un modulo di sicurezza hardware (HSM), consulta. [Installare il software AWS IoT Greengrass Core](install-greengrass-core-v2.md)

### (Facoltativo) Abilita la registrazione su Amazon CloudWatch Logs
<a name="enable-cloudwatch-logging-v2"></a>

[Per consentire a un dispositivo core V2 di caricare i log su Amazon CloudWatch Logs, puoi distribuire il componente di gestione dei AWS log fornito.](log-manager-component.md) Puoi utilizzare CloudWatch Logs per visualizzare i log dei componenti, in modo da eseguire il debug e la risoluzione dei problemi senza accedere al file system del dispositivo principale. Per ulteriori informazioni, consulta [Monitora AWS IoT Greengrass i registri](monitor-logs.md).

## Fase 2: Creare e distribuire componenti per migrare le applicazioni AWS IoT Greengrass V2 AWS IoT Greengrass V1
<a name="run-v1-applications"></a>

È possibile eseguire la maggior parte delle applicazioni su. AWS IoT Greengrass V1 AWS IoT Greengrass V2È possibile importare funzioni Lambda come componenti eseguibili AWS IoT Greengrass V2 e utilizzare [componenti AWS forniti](public-components.md) che offrono le stesse funzionalità dei connettori. AWS IoT Greengrass 

Puoi anche sviluppare componenti personalizzati per creare qualsiasi funzionalità o runtime da eseguire sui dispositivi core Greengrass. Per informazioni su come sviluppare e testare i componenti localmente, vedere[Crea AWS IoT Greengrass componenti](create-components.md).

**Topics**
+ [Importa funzioni Lambda V1](#run-v1-lambda-functions)
+ [Usa connettori V1](#use-v1-connectors)
+ [Esecuzione di container Docker](#run-v1-docker-containers)
+ [Dispositivi Connect V1 Greengrass](#connect-v1-greengrass-devices)
+ [Abilita il servizio shadow locale](#enable-shadow-service)
+ [Integrazione con AWS IoT SiteWise](#integrate-with-iot-sitewise)

### Importa funzioni Lambda V1
<a name="run-v1-lambda-functions"></a>

È possibile importare funzioni Lambda come AWS IoT Greengrass V2 componenti. Scegli tra i seguenti approcci:
+ Importa le funzioni Lambda V1 direttamente come componenti Greengrass.
+ Aggiorna le funzioni Lambda per utilizzare le librerie Greengrass nella SDK per dispositivi AWS IoT v2, quindi importa le funzioni Lambda come componenti Greengrass.
+ Crea componenti personalizzati che utilizzano codice non Lambda e SDK per dispositivi AWS IoT v2 per implementare le stesse funzionalità delle tue funzioni Lambda.

Se la tua funzione Lambda utilizza funzionalità, come stream manager o local secret, devi definire le dipendenze dai componenti AWS forniti che racchiudono queste funzionalità. Quando si distribuisce il componente della funzione Lambda, la distribuzione include anche il componente per ogni funzionalità definita come dipendenza. Durante la distribuzione, puoi configurare parametri, ad esempio quali segreti distribuire sul dispositivo principale. Non tutte le funzionalità della V1 richiedono una dipendenza dai componenti per la funzione Lambda sulla V2. L'elenco seguente descrive come utilizzare le funzionalità V1 nel componente della funzione Lambda V2:
+ **Accedere ad altri servizi AWS **

  Se la funzione Lambda utilizza AWS credenziali per effettuare richieste ad altri AWS servizi, il ruolo di scambio di token del dispositivo principale deve consentire al dispositivo principale di eseguire AWS le operazioni utilizzate dalla funzione Lambda. Per ulteriori informazioni, consulta [Autorizza i dispositivi principali a interagire con i servizi AWS](device-service-role.md).
+ **Gestore di flussi**

  Se la tua funzione Lambda utilizza stream manager, specifica `aws.greengrass.StreamManager` come dipendenza del componente quando importi la funzione. Quando distribuisci il componente stream manager, specifica i parametri dello stream manager da impostare per i dispositivi principali di destinazione. Il ruolo di scambio di token del dispositivo principale deve consentire al dispositivo principale di accedere alle Cloud AWS destinazioni utilizzate con stream manager. Per ulteriori informazioni, consulta [Stream manager](stream-manager-component.md).
+ **Segreti locali**

  Se la tua funzione Lambda utilizza segreti locali, specifica `aws.greengrass.SecretManager` come dipendenza del componente quando importi la funzione. Quando distribuisci il componente Secret Manager, specifica le risorse segrete da distribuire sui dispositivi principali di destinazione. Il ruolo di scambio di token del dispositivo principale deve consentire al dispositivo principale di recuperare le risorse segrete da distribuire. Per ulteriori informazioni, consulta [Gestore segreto](secret-manager-component.md).

  Quando distribuisci il componente della funzione Lambda, configuralo in modo che disponga di [una politica di autorizzazione IPC](interprocess-communication.md#ipc-authorization-policies) che conceda il permesso di utilizzare l'operazione [IPC GetSecretValue nella](ipc-secret-manager.md) V2. SDK per dispositivi AWS IoT 
+ **Ombre locali**

  Se la funzione Lambda interagisce con le ombre locali, è necessario aggiornare il codice della funzione Lambda per utilizzare la V2. SDK per dispositivi AWS IoT È inoltre necessario specificare `aws.greengrass.ShadowManager` come componente la dipendenza quando si importa la funzione. Per ulteriori informazioni, consulta [Interagisci con le ombre dei dispositivi](interact-with-shadows.md).

  Quando distribuisci il componente della funzione Lambda, configuralo in modo che disponga di [una politica di autorizzazione IPC che conceda l'autorizzazione](interprocess-communication.md#ipc-authorization-policies) all'uso [delle operazioni IPC shadow nella](ipc-local-shadows.md) V2. SDK per dispositivi AWS IoT 
+ **Sottoscrizioni**
  + Se la tua funzione Lambda sottoscrive i messaggi da una fonte cloud, specifica tali sottoscrizioni come fonti di eventi quando importi la funzione.
  + [Se la funzione Lambda sottoscrive i messaggi di un'altra funzione Lambda o se la funzione Lambda pubblica messaggi verso o AWS IoT Core altre funzioni Lambda, configura e distribuisci il componente legacy del router di abbonamento quando distribuisci la funzione Lambda.](legacy-subscription-router-component.md) Quando distribuisci il componente legacy del router di sottoscrizione, specifica gli abbonamenti utilizzati dalla funzione Lambda.
**Nota**  <a name="legacy-subscription-router-requirement-note"></a>
Il componente legacy del router di abbonamento è richiesto solo se la funzione Lambda utilizza la `publish()` funzione nel AWS IoT Greengrass Core SDK. Se aggiorni il codice della funzione Lambda per utilizzare l'interfaccia di comunicazione tra processi (IPC) nella SDK per dispositivi AWS IoT V2, non è necessario implementare il componente legacy del router di abbonamento. [Per ulteriori informazioni, consulta i seguenti servizi di comunicazione tra processi:](interprocess-communication.md)  
[Pubblicare/sottoscrivere messaggi locali](ipc-publish-subscribe.md)
[AWS IoT Core Pubblicare/sottoscrivere messaggi MQTT](ipc-iot-core-mqtt.md)
  + Se la tua funzione Lambda sottoscrive i messaggi provenienti da dispositivi connessi localmente, specifica tali sottoscrizioni come fonti di eventi quando importi la funzione. È inoltre necessario configurare e distribuire il [componente bridge MQTT](mqtt-bridge-component.md) per inoltrare i messaggi dai dispositivi collegati agli publish/subscribe argomenti locali specificati come fonti di eventi.
  + [Se la funzione Lambda pubblica messaggi su dispositivi connessi localmente, è necessario aggiornare il codice della funzione Lambda per utilizzare la SDK per dispositivi AWS IoT V2 per pubblicare messaggi locali. publish/subscribe ](ipc-publish-subscribe.md) È inoltre necessario configurare e distribuire il [componente bridge MQTT](mqtt-bridge-component.md) per inoltrare i messaggi dal broker di messaggi locale publish/subscribe ai dispositivi collegati.
+ **Volumi e dispositivi locali**

  Se la tua funzione Lambda containerizzata accede a volumi o dispositivi locali, specifica tali volumi e dispositivi quando importi la funzione Lambda. Questa funzionalità non richiede una dipendenza dai componenti.

Per ulteriori informazioni, consulta [Esegui AWS Lambda funzioni](run-lambda-functions.md).

### Usa connettori V1
<a name="use-v1-connectors"></a>

È possibile distribuire componenti AWS forniti che offrono le stesse funzionalità di alcuni connettori. AWS IoT Greengrass Quando si crea la distribuzione, è possibile configurare i parametri dei connettori. 

I seguenti AWS IoT Greengrass V2 componenti forniscono la funzionalità del connettore Greengrass V1:
+ [CloudWatch componente metrico](cloudwatch-metrics-component.md)
+ [AWS IoT Device Defender componente](device-defender-component.md)
+ [Componente Firehose](kinesis-firehose-component.md)
+ [Componente dell'adattatore di protocollo Modbus-RTU](modbus-rtu-protocol-adapter-component.md)
+ [Componente Amazon SNS](sns-component.md)

### Esecuzione di container Docker
<a name="run-v1-docker-containers"></a>

AWS IoT Greengrass V2 non fornisce un componente per sostituire direttamente il connettore di distribuzione delle applicazioni Docker V1. Tuttavia, puoi utilizzare il componente Docker Application Manager per scaricare immagini Docker e quindi creare componenti personalizzati che eseguono contenitori Docker a partire dalle immagini scaricate. Per ulteriori informazioni, consultare [Esegui un contenitore Docker](run-docker-container.md) e [Gestore di applicazioni Docker](docker-application-manager-component.md).

### Dispositivi Connect V1 Greengrass
<a name="connect-v1-greengrass-devices"></a>

I dispositivi collegati AWS IoT Greengrass V1 sono denominati dispositivi client in. AWS IoT Greengrass V2 AWS IoT Greengrass V2 il supporto per i dispositivi client è retrocompatibile con AWS IoT Greengrass V1, quindi è possibile connettere i dispositivi client V1 ai dispositivi core V2 senza modificare il codice dell'applicazione. Per consentire ai dispositivi client di connettersi a un dispositivo core V2, distribuisci i componenti Greengrass che abilitano il supporto dei dispositivi client e associa i dispositivi client al dispositivo principale. [Per inoltrare messaggi tra i dispositivi client, il servizio AWS IoT Core cloud e i componenti Greengrass (incluse le funzioni Lambda), implementate e configurate il componente bridge MQTT.](mqtt-bridge-component.md) È possibile implementare il [componente IP Detector](ip-detector-component.md) per rilevare automaticamente le informazioni di connettività oppure gestire manualmente gli endpoint. Per ulteriori informazioni, consulta [Interagisci con dispositivi IoT locali](interact-with-local-iot-devices.md).

### Abilita il servizio shadow locale
<a name="enable-shadow-service"></a>

In AWS IoT Greengrass V2, il servizio shadow locale è implementato dal componente shadow manager AWS fornito. AWS IoT Greengrass V2 include anche il supporto per le ombre denominate. Per consentire ai componenti di interagire con le ombre locali e sincronizzare gli stati shadow AWS IoT Core, configura e distribuisci il componente Shadow Manager e utilizza le operazioni IPC shadow nel codice del componente. Per ulteriori informazioni, consulta [Interagisci con le ombre dei dispositivi](interact-with-shadows.md). 

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

Se utilizzi il tuo dispositivo core V1 come AWS IoT SiteWise gateway, [segui le istruzioni](https://docs.aws.amazon.com/iot-sitewise/latest/userguide/configure-gateway-ggv2.html) per configurare il tuo nuovo dispositivo core V2 come AWS IoT SiteWise gateway. AWS IoT SiteWise fornisce uno script di installazione che distribuisce i AWS IoT SiteWise componenti per voi.

## Fase 3: testate le vostre applicazioni AWS IoT Greengrass V2
<a name="test-v2-features"></a>

Dopo aver creato e distribuito i componenti V2 sul nuovo dispositivo core V2, verifica che le applicazioni soddisfino le tue aspettative. Puoi controllare i registri del dispositivo per visualizzare i messaggi di output standard (stdout) e di errore standard (stderr) dei componenti. Per ulteriori informazioni, consulta [Monitora AWS IoT Greengrass i registri](monitor-logs.md).

Se hai distribuito la CLI [Greengrass](greengrass-cli-component.md) sul dispositivo principale, puoi utilizzarla per eseguire il debug dei componenti e delle relative configurazioni. Per ulteriori informazioni, consulta [Comandi della CLI di Greengrass](gg-cli-reference.md).

Dopo aver verificato che le applicazioni funzionino su un dispositivo core V2, puoi distribuire i componenti Greengrass dell'applicazione su altri dispositivi principali. Se hai sviluppato componenti personalizzati che eseguono processi nativi o contenitori Docker, devi prima [pubblicare tali componenti](publish-components.md) sul AWS IoT Greengrass servizio per distribuirli su altri dispositivi principali.

# Configura un nuovo dispositivo per testare le applicazioni V1 su V2 (Greengrass nucleus lite)
<a name="set-up-v2-test-device-lite"></a>

Configura un nuovo dispositivo con Greengrass nucleus lite per testare i componenti generici che crei per migrare le tue AWS IoT Greengrass V1 applicazioni alla V2. Greengrass nucleus lite è un runtime leggero ottimizzato per dispositivi con risorse limitate. È possibile utilizzare questo dispositivo per sviluppare e testare componenti Greengrass personalizzati che eseguono processi nativi. Dopo aver testato le applicazioni su un dispositivo Greengrass nucleus lite, è possibile distribuire i componenti V2 su altri dispositivi che eseguono Greengrass nucleus lite o aggiornare i dispositivi core V1 esistenti alla V2.



## Passaggio 1: installa Greengrass nucleus lite su un nuovo dispositivo
<a name="lite-step-1-install"></a>

Installa Greengrass nucleus lite su un nuovo dispositivo. Segui la [guida all'installazione di Greengrass nucleus lite](https://docs.aws.amazon.com/greengrass/v2/developerguide/greengrass-nucleus-lite-component.html#greengrass-nucleus-lite-component-install) per configurare un dispositivo.

**Nota**  
Greengrass nucleus lite non supporta attualmente il servizio shadow locale, i dispositivi client o i connettori. Assicurati che le tue applicazioni V1 non si basino su queste funzionalità prima di procedere con questa guida.

## Fase 2: Creare e distribuire componenti generici per migrare le funzioni AWS IoT Greengrass V1 Lambda
<a name="lite-step-2-convert-lambda"></a>

Per replicare la funzionalità delle funzioni AWS IoT Greengrass V1 Lambda su Greengrass nucleus lite, è necessario convertirle in componenti generici. Ciò comporta la riscrittura del codice della funzione Lambda per utilizzare SDK per dispositivi AWS IoT V2 AWS IoT Greengrass o Component SDK anziché Core SDK. AWS IoT Greengrass 

La tabella seguente elenca gli esempi di componenti SDKs utilizzati negli esempi di componenti V2 di questa guida:


| SDK | Versione minima | 
| --- | --- | 
| [SDK per dispositivi AWS IoT per Python v2](https://github.com/aws/aws-iot-device-sdk-python-v2) | v1.11.3 | 
| [SDK per dispositivi AWS IoT per Java v2](https://github.com/aws/aws-iot-device-sdk-java-v2) | v1.9.3 | 
| [SDK per dispositivi AWS IoT per v2 JavaScript ](https://github.com/aws/aws-iot-device-sdk-js-v2) | v1.12.0 | 
| [AWS IoT Greengrass Component SDK (C/C\$1\$1) (attualmente in anteprima)](https://github.com/aws-greengrass/aws-greengrass-component-sdk) | v0.4.0 | 

Gli esempi seguenti mostrano le funzioni Lambda che utilizzano AWS IoT Greengrass V1 Core SDK e i relativi componenti generici equivalenti, con codice componente, ricette e istruzioni di compilazione in più linguaggi di programmazione per due scenari principali:
+ **Comunicazione locale**: componenti che comunicano con altri componenti sullo stesso dispositivo tramite pub/sub locale
+ **Comunicazione cloud**: componenti che comunicano con AWS IoT Core o altri servizi AWS 

### Scenario 1: Comunicazione locale (editore → processore → abbonato)
<a name="lite-example-local-communication"></a>

Questo scenario dimostra la conversione di una funzione Lambda V1 che utilizza la comunicazione pub/sub locale in un componente generico V2.

#### Architettura dell'applicazione
<a name="lite-example-1-scenario"></a>

Questo esempio include tre componenti:
+ L'editore Lambda pubblica i dati sulla temperatura
+ Il processore Lambda riceve i dati e li elabora
+ Il processore Lambda pubblica il risultato elaborato all'abbonato Lambda

L'esempio di codice riportato di seguito si concentra sul processore Lambda, che dimostra sia la sottoscrizione che la pubblicazione di messaggi per la comunicazione locale.

##### Abbonamenti di gruppo V1
<a name="lite-example-1-v1-subscriptions"></a>

In AWS IoT Greengrass V1, i seguenti abbonamenti di gruppo abilitano la comunicazione tra le funzioni Lambda:

Abbonamento 1: editore → processore
+ Fonte: Lambda (editore)
+ Obiettivo: Lambda (processore)
+ Argomento: sensori/temperatura

Abbonamento 2: processore → abbonato
+ Fonte: Lambda (processore)
+ Target: Lambda (abbonato)
+ Argomento: lambda/alerts

#### Funzione Lambda del processore (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;
}
```

------

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

Per ottenere la stessa funzionalità in AWS IoT Greengrass V2, crea un componente generico con quanto segue:

##### 1. Codice del componente
<a name="lite-example-1-component-code"></a>

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

Prerequisiti: prima di utilizzare questo codice componente, installa e verifica il SDK per dispositivi AWS IoT for Python sul tuo dispositivo Greengrass:

```
# Install the SDK
pip3 install awsiotsdk

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

Se riscontrate conflitti di dipendenza durante l'installazione, provate a installare una versione specifica di. SDK per dispositivi AWS IoT

Se il comando di verifica stampa «SDK installato correttamente», sei pronto per utilizzare il codice del componente:

```
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. Crea e impacchetta il componente
<a name="lite-example-1-build-component"></a>

Alcune lingue richiedono la creazione o la creazione di pacchetti prima della distribuzione.

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

Python non richiede la compilazione. Il componente può utilizzare direttamente il file.py.

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

Per creare un JAR eseguibile con tutte le dipendenze raggruppate:

1. Crea un `pom.xml` file nella directory del tuo progetto:

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

   ```
   mvn clean package
   ```

   Questo crea `target/temperature-processor-1.0.0.jar` con tutte le dipendenze incluse.

1. Carica il JAR nel tuo bucket S3 per la distribuzione.

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

Per impacchettare il componente Node.js con tutte le dipendenze:

1. Crea un `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. Installa le dipendenze sulla tua macchina di sviluppo:

   ```
   npm install
   ```

   Questo crea una `node_modules` cartella contenente la AWS SDK per dispositivi AWS IoT v2.

1. Package per l'implementazione:

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

1. Carica il file zip nel tuo bucket S3 per la distribuzione.

**Nota**  
Sul dispositivo Greengrass deve essere installato il runtime Node.js (versione 14 o successiva). Non è necessario eseguirlo `npm install` sul dispositivo principale Greengrass poiché l'elemento del componente include tutte le dipendenze nella cartella in bundle. `node_modules`

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

**Prerequisiti:**

Per creare l'SDK e il componente, sono necessarie le seguenti dipendenze di compilazione:
+ GCC o Clang
+ CMake (almeno la versione 3.22)
+ Make or Ninja

**Installa le dipendenze di compilazione:**

Su Ubuntu/Debian:

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

Su Amazon Linux:

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

**Crea un CMake file Lists.txt per il tuo componente:**

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

**Procedura di creazione:**

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

**Prerequisiti:**

Per creare l'SDK e il componente, avrai bisogno delle seguenti dipendenze di compilazione:
+ GCC o Clang con supporto C\$1\$120
+ CMake (almeno la versione 3.22)
+ Make or Ninja

**Installa le dipendenze di compilazione:**

Su Ubuntu/Debian:

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

Su Amazon Linux:

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

**Crea un CMake file Lists.txt per il tuo componente:**

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

**Procedura di creazione:**

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

Aggiorna l'array «resources» con gli argomenti effettivi utilizzati dal componente.

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

------

### Scenario 2: Comunicazione nel cloud
<a name="lite-example-cloud-communication"></a>

Questo scenario dimostra la conversione di una funzione Lambda V1 che comunica AWS IoT Core con in un componente generico V2.

#### Architettura dell'applicazione
<a name="lite-example-2-scenario"></a>

Questo esempio utilizza un'architettura connessa al cloud:
+ AWS IoT Core invia comandi al dispositivo
+ Controller Lambda riceve i comandi e li elabora
+ Il controller Lambda invia i dati di telemetria a AWS IoT Core

Questo esempio si concentra sul controller Lambda, che dimostra sia la ricezione di messaggi da che la pubblicazione di messaggi. AWS IoT Core

##### Abbonamenti di gruppo V1
<a name="lite-example-2-v1-subscriptions"></a>

In AWS IoT Greengrass V1, i seguenti abbonamenti di gruppo abilitano la comunicazione tra la funzione Lambda e: AWS IoT Core

Abbonamento 1: IoT Cloud → Lambda
+ Fonte: IoT Cloud
+ Obiettivo: Lambda () DeviceController
+ Argomento: commands/device1

Abbonamento 2: Lambda → IoT Cloud
+ Fonte: Lambda () DeviceController
+ Obiettivo: IoT Cloud
+ Argomento: telemetria/dispositivo1

#### Funzione Lambda del controller (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;
}
```

------

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

Per ottenere la stessa funzionalità in AWS IoT Greengrass V2, crea un componente generico con quanto segue:

##### 1. Codice del componente
<a name="lite-example-2-component-code"></a>

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

Prerequisiti: prima di utilizzare questo codice componente, installa e verifica il SDK per dispositivi AWS IoT for Python sul tuo dispositivo Greengrass:

```
# Install the SDK
pip3 install awsiotsdk

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

Se riscontrate conflitti di dipendenza durante l'installazione, provate a installare una versione specifica di. SDK per dispositivi AWS IoT

Se il comando di verifica stampa «SDK installato correttamente», sei pronto per utilizzare il codice del componente:

```
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. Crea e impacchetta il componente
<a name="lite-example-2-build-component"></a>

Alcune lingue richiedono la creazione o la creazione di pacchetti prima della distribuzione.

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

Python non richiede la compilazione. Il componente può utilizzare direttamente il file.py.

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

Per creare un JAR eseguibile con tutte le dipendenze raggruppate:

1. Crea un `pom.xml` file nella directory del tuo progetto:

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

   ```
   mvn clean package
   ```

   Questo crea `target/device-controller-1.0.0.jar` con tutte le dipendenze incluse.

1. Carica il JAR nel tuo bucket S3 per la distribuzione.

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

Per impacchettare il componente Node.js con tutte le dipendenze:

1. Crea un `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. Installa le dipendenze sulla tua macchina di sviluppo:

   ```
   npm install
   ```

   Questo crea una `node_modules` cartella contenente la AWS SDK per dispositivi AWS IoT v2.

1. Package per l'implementazione:

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

1. Carica il file zip nel tuo bucket S3 per la distribuzione.

**Nota**  
Sul dispositivo Greengrass deve essere installato il runtime Node.js (versione 14 o successiva). Non è necessario eseguirlo `npm install` sul dispositivo principale Greengrass poiché l'elemento del componente include tutte le dipendenze nella cartella in bundle. `node_modules`

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

**Prerequisiti:**

Per creare l'SDK e il componente, sono necessarie le seguenti dipendenze di compilazione:
+ GCC o Clang
+ CMake (almeno la versione 3.22)
+ Make or Ninja

**Installa le dipendenze di compilazione:**

Su Ubuntu/Debian:

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

Su Amazon Linux:

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

**Crea un CMake file Lists.txt per il tuo componente:**

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

**Procedura di creazione:**

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

**Prerequisiti:**

Per creare l'SDK e il componente, avrai bisogno delle seguenti dipendenze di compilazione:
+ GCC o Clang con supporto C\$1\$120
+ CMake (almeno la versione 3.22)
+ Make or Ninja

**Installa le dipendenze di compilazione:**

Su Ubuntu/Debian:

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

Su Amazon Linux:

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

**Crea un CMake file Lists.txt per il tuo componente:**

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

**Procedura di creazione:**

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

Aggiorna l'array «resources» con gli argomenti effettivi utilizzati dal componente.

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

------

# Aggiorna i dispositivi core Greengrass V1 a Greengrass V2
<a name="upgrade-v1-core-devices"></a>

Dopo aver verificato che le applicazioni e i componenti funzionino su un dispositivo AWS IoT Greengrass V2 principale, puoi installare il software AWS IoT Greengrass Core v2.x sui dispositivi che attualmente eseguono la versione 1.x, come i dispositivi di produzione. Quindi, distribuisci i componenti Greengrass V2 per eseguire le tue applicazioni Greengrass sui dispositivi.

Per aggiornare una flotta di dispositivi dalla V1 alla V2, completa questi passaggi per ogni dispositivo da aggiornare. Puoi utilizzare i gruppi di oggetti per distribuire i componenti V2 su una flotta di dispositivi principali.

**Suggerimento**  
Ti consigliamo di creare uno script per automatizzare il processo di aggiornamento per una flotta di dispositivi. Se utilizzi [AWS Systems Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/what-is-systems-manager.html)per gestire la tua flotta, puoi utilizzare Systems Manager per eseguire lo script su ogni dispositivo per aggiornare la tua flotta dalla V1 alla V2.  
Puoi contattare il tuo rappresentante AWS Enterprise Support per domande su come automatizzare al meglio il processo di aggiornamento.



## Fase 1: Installare il software AWS IoT Greengrass Core v2.x
<a name="install-v2-on-v1"></a>

Scegli tra le seguenti opzioni per installare il software AWS IoT Greengrass Core v2.x su un dispositivo core V1:
+ **[Effettua l'upgrade in meno passaggi](#install-v2-after-uninstall)**

  Per eseguire l'aggiornamento in meno passaggi, puoi disinstallare il software v1.x prima di installare il software v2.x.
+ **[Esegui l'upgrade con tempi di inattività minimi](#install-v2-side-by-side)**

  Per eseguire l'aggiornamento con tempi di inattività minimi, puoi installare entrambe le versioni del software AWS IoT Greengrass Core contemporaneamente. Dopo aver installato il software AWS IoT Greengrass Core v2.x e verificato che le applicazioni V2 funzionino correttamente, disinstallate il AWS IoT Greengrass software Core v1.x. Prima di scegliere questa opzione, considerate la RAM aggiuntiva necessaria per eseguire entrambe le versioni del software AWS IoT Greengrass Core contemporaneamente.

### Disinstalla AWS IoT Greengrass Core v1.x prima di installare la v2.x
<a name="install-v2-after-uninstall"></a>

Se desideri eseguire l'aggiornamento in sequenza, disinstalla il software AWS IoT Greengrass Core v1.x prima di installare la v2.x sul tuo dispositivo.

**Per disinstallare il software Core v1.x AWS IoT Greengrass**

1. Se il software AWS IoT Greengrass Core v1.x è in esecuzione come servizio, è necessario arrestare, disabilitare e rimuovere il servizio.

   1. Arrestare il servizio AWS IoT Greengrass Core software v1.x in esecuzione. 

      ```
      sudo systemctl stop greengrass 
      ```

   1. Attendi che il servizio si interrompa. È possibile utilizzare il `list` comando per verificare lo stato del servizio. 

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

   1. Disabilita il servizio. 

      ```
      sudo systemctl disable greengrass
      ```

   1. Rimuovi il servizio. 

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

1. Se il software AWS IoT Greengrass Core v1.x non è in esecuzione come servizio, utilizzate il seguente comando per arrestare il demone. Sostituisci *greengrass-root* con il nome della cartella principale di Greengrass. Il percorso predefinito è `/greengrass`.

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

1. (Facoltativo) Eseguite il backup della cartella principale di Greengrass e, se applicabile, della [cartella di scrittura personalizzata](https://docs.aws.amazon.com/greengrass/v1/developerguide/gg-core.html#write-directory), in un'altra cartella sul dispositivo.

   1. Usa il seguente comando per copiare la cartella principale Greengrass corrente in una cartella diversa, quindi rimuovere la cartella principale.

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

   1. Utilizzate il seguente comando per spostare la cartella di scrittura in una cartella diversa, quindi rimuovete la cartella di scrittura. 

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

Per Greengrass nucleus: puoi usare le [istruzioni di installazione per AWS IoT Greengrass V2](install-greengrass-core-v2.md) installare Greengrass nucleus sul tuo dispositivo.

Per Greengrass nucleus lite: È possibile utilizzare le istruzioni di [installazione di Greengrass nucleus lite per installare Greengrass nucleus lite](greengrass-nucleus-lite-component.md).

**Suggerimento**  <a name="tip-migrate-reuse-core-device-identity"></a>
[Per riutilizzare l'identità di un dispositivo principale durante la migrazione dalla V1 alla V2, segui le istruzioni per installare il software Core con provisioning manuale. AWS IoT Greengrass](manual-installation.md) Rimuovi innanzitutto il software di base V1 dal dispositivo, quindi riutilizza l' AWS IoT oggetto e il certificato del dispositivo principale V1 e aggiorna le AWS IoT politiche del certificato per concedere le autorizzazioni richieste dal software v2.x.

### Installa il software AWS IoT Greengrass Core v2.x su un dispositivo che esegue già la versione 1.x
<a name="install-v2-side-by-side"></a>

Se installi il software AWS IoT Greengrass Core v2.x su un dispositivo su cui è già in esecuzione il software AWS IoT Greengrass Core v1.x, tieni presente quanto segue:
+ Il nome dell' AWS IoT oggetto per il dispositivo core V2 deve essere univoco. Non utilizzare lo stesso nome del dispositivo principale V1.
+ Le porte utilizzate per il software AWS IoT Greengrass Core v2.x devono essere diverse dalle porte utilizzate per la v1.x.
  + Configura lo stream manager V1 per utilizzare una porta diversa dalla 8088. Per ulteriori informazioni, consulta [Configurare lo stream manager](https://docs.aws.amazon.com/greengrass/v1/developerguide/configure-stream-manager.html).
  + Configurate il broker MQTT V1 per utilizzare una porta diversa dalla 8883. Per ulteriori informazioni, vedere [Configurazione della porta MQTT per la](https://docs.aws.amazon.com/greengrass/v1/developerguide/gg-core.html#config-local-mqtt-port) messaggistica locale.
+ AWS IoT Greengrass V2 non offre la possibilità di rinominare il servizio di sistema Greengrass. Se si esegue Greengrass come servizio di sistema, è necessario effettuare una delle seguenti operazioni per evitare conflitti tra i nomi dei servizi di sistema:
  + Rinomina il servizio Greengrass per la v1.x prima di installare la v2.x.
  + Installa il software AWS IoT Greengrass Core v2.x senza un servizio di sistema, quindi [configura manualmente il software come servizio di sistema con un](configure-greengrass-core-v2.md#configure-system-service) nome diverso da. `greengrass`

**Per rinominare il servizio Greengrass per la versione 1.x**

  1. Interrompere il servizio AWS IoT Greengrass Core software v1.x. 

     ```
     sudo systemctl stop greengrass
     ```

  1. Attendi che il servizio si interrompa. L'interruzione del servizio può richiedere fino a qualche minuto. È possibile utilizzare il `list-units` comando per verificare se il servizio è stato interrotto. 

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

  1. Disabilita il servizio. 

     ```
     sudo systemctl disable greengrass
     ```

  1. Rinomina il servizio. 

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

  1. Ricarica il servizio e avvialo. 

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

È quindi possibile utilizzare le [istruzioni di installazione AWS IoT Greengrass V2 per](install-greengrass-core-v2.md) installare il software sul dispositivo.

**Suggerimento**  <a name="tip-migrate-reuse-core-device-identity"></a>
Per riutilizzare l'identità di un dispositivo principale durante la migrazione dalla V1 alla V2, segui le istruzioni per [installare il software AWS IoT Greengrass Core](manual-installation.md) con provisioning manuale. Rimuovi innanzitutto il software di base V1 dal dispositivo, quindi riutilizza l' AWS IoT oggetto e il certificato del dispositivo principale V1 e aggiorna le AWS IoT politiche del certificato per concedere le autorizzazioni richieste dal software v2.x.

## Fase 2: Implementazione dei componenti sui dispositivi principali AWS IoT Greengrass V2
<a name="deploy-v2-resources"></a>

Dopo aver installato il software AWS IoT Greengrass Core v2.x sul dispositivo, distribuisci i componenti in base al runtime scelto.

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

Crea una distribuzione che includa le seguenti risorse. Per distribuire componenti su una flotta di dispositivi simili, crea una distribuzione per un gruppo di oggetti che contiene tali dispositivi.
+ Componenti della funzione Lambda creati dalle funzioni Lambda V1. Per ulteriori informazioni, consulta [Esegui AWS Lambda funzioni](run-lambda-functions.md).
+ [Se utilizzi abbonamenti V1, il componente legacy del router di sottoscrizione.](legacy-subscription-router-component.md)
+ Se usi stream manager, il componente [stream manager](stream-manager-component.md). Per ulteriori informazioni, consulta [Gestisci i flussi di dati sui dispositivi core Greengrass](manage-data-streams.md).
+ Se usi i segreti locali, il [componente del gestore segreto](secret-manager-component.md).
+ Se si utilizzano connettori V1, i componenti del [connettore AWS forniti](set-up-v2-test-device.md#use-v1-connectors).
+ Se utilizzi contenitori Docker, il componente [Docker Application](docker-application-manager-component.md) Manager. Per ulteriori informazioni, consulta [Esegui un contenitore Docker](run-docker-container.md).
+ Se si utilizzano dispositivi connessi, i [componenti per i dispositivi client supportano](client-device-components.md). È inoltre necessario abilitare il supporto per i dispositivi client e associare i dispositivi client al dispositivo principale. Per ulteriori informazioni, consulta [Interagisci con dispositivi IoT locali](interact-with-local-iot-devices.md).
+ Se utilizzate Device Shadows, il [componente Shadow Manager](shadow-manager-component.md). Per ulteriori informazioni, consulta [Interagisci con le ombre dei dispositivi](interact-with-shadows.md).
+ Se carichi i log dai dispositivi core di Greengrass su CloudWatch Amazon Logs, [il](log-manager-component.md) componente di gestione dei log. Per ulteriori informazioni, consulta [Monitora AWS IoT Greengrass i registri](monitor-logs.md).
+ Se esegui l'integrazione con AWS IoT SiteWise, [segui le istruzioni](https://docs.aws.amazon.com/iot-sitewise/latest/userguide/configure-gateway-ggv2.html) per configurare il dispositivo principale V2 come gateway. AWS IoT SiteWise AWS IoT SiteWise fornisce uno script di installazione che distribuisce i AWS IoT SiteWise componenti per voi.
+ componenti definiti dall'utente che avete sviluppato per implementare funzionalità personalizzate.

Per informazioni sulla creazione e la revisione delle distribuzioni, vedere. [Implementazione AWS IoT Greengrass dei componenti sui dispositivi](manage-deployments.md) 

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

Distribuisci i componenti generici che hai creato nella [fase 2 della guida alla migrazione sui](set-up-v2-test-device-lite.md#lite-step-2-convert-lambda) tuoi dispositivi Greengrass nucleus lite:

1. Crea i tuoi componenti utilizzando le ricette dei componenti che hai creato

1. Crea una distribuzione mirata ai tuoi dispositivi Greengrass nucleus lite che includa i tuoi componenti generici

1. Verificate che i componenti funzionino correttamente