

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Tutorial: interagir com dispositivos de IoT locais por meio do MQTT
<a name="client-devices-tutorial"></a>

É possível concluir este tutorial para configurar um dispositivo principal para interagir com dispositivos de IoT locais, chamados de *dispositivos cliente*, que se conectam ao dispositivo principal por meio do MQTT. Neste tutorial, você configura AWS IoT as coisas para usar a *descoberta na nuvem* para se conectar ao dispositivo principal como dispositivos clientes. Quando você configura a descoberta na nuvem, um dispositivo cliente pode enviar uma solicitação ao serviço de AWS IoT Greengrass nuvem para descobrir os dispositivos principais. A resposta do AWS IoT Greengrass inclui informações de conectividade e certificados para os dispositivos principais que você configura o dispositivo cliente para descobrir. Em seguida, o dispositivo cliente pode usar essas informações para se conectar a um dispositivo principal disponível, onde ele pode se comunicar por meio do MQTT.

Neste tutorial, você faz o seguinte:

1. Revisa e atualiza as permissões do dispositivo principal, se necessário.

1. Associa dispositivos cliente ao dispositivo principal para que eles possam descobrir o dispositivo principal usando a descoberta na nuvem.

1. Implanta componentes do Greengrass no dispositivo principal para permitir o suporte ao dispositivo cliente.

1. Conecta dispositivos cliente ao dispositivo principal e testa a comunicação com o serviço de nuvem do AWS IoT Core .

1. Desenvolve um componente personalizado do Greengrass que se comunica com os dispositivos cliente.

1. Desenvolve um componente personalizado que interage com as [Sombras do dispositivo do AWS IoT](https://docs.aws.amazon.com/iot/latest/developerguide/iot-device-shadows.html) do dispositivo cliente.

Este tutorial usa um único dispositivo principal e um único dispositivo cliente. Também é possível seguir o tutorial para conectar e testar vários dispositivos cliente.

Você deve levar de 30 a 60 minutos para concluir este tutorial.

## Pré-requisitos
<a name="client-devices-tutorial-prerequisites"></a>

Para concluir este tutorial, você precisará do seguinte:
+ Um Conta da AWS. Se você não tiver uma, consulte [Configurar um Conta da AWS](setting-up.md#set-up-aws-account).
+ Um usuário AWS Identity and Access Management (IAM) com permissões de administrador.
+ Um dispositivo principal do Greengrass. Para obter informações sobre como configurar um dispositivo principal, consulte [Configurando dispositivos AWS IoT Greengrass principais](setting-up.md).
  + O dispositivo principal deve executar a versão 2.6.0 ou posterior do núcleo do Greengrass. Essa versão inclui suporte para curingas na publish/subscribe comunicação local e suporte para sombras de dispositivos clientes.
**nota**  
O suporte ao dispositivo cliente requer a versão 2.2.0 ou posterior do núcleo do Greengrass. No entanto, este tutorial explora recursos mais recentes, como suporte para curingas MQTT no local publish/subscribe e suporte para sombras de dispositivos clientes. Esses recursos exigem a versão 2.6.0 ou posterior do núcleo do Greengrass.
  + Para se conectar, o dispositivo principal deve estar na mesma rede que os dispositivos cliente.
  + (Opcional) Para concluir os módulos em que você desenvolve componentes personalizados do Greengrass, o dispositivo principal deve executar a CLI do Greengrass. Para obter mais informações, consulte [Instalar a Greengrass CLI](install-gg-cli.md).
+ Qualquer AWS IoT coisa para se conectar como um dispositivo cliente neste tutorial. Para obter mais informações, consulte [Criar AWS IoT recursos](https://docs.aws.amazon.com/iot/latest/developerguide/create-iot-resources.html) no *Guia do AWS IoT Core desenvolvedor*.
  + A AWS IoT política do dispositivo cliente deve permitir a `greengrass:Discover` permissão. Para obter mais informações, consulte [AWS IoT Política mínima para dispositivos clientes](device-auth.md#client-device-minimal-iot-policy).
  + O dispositivo cliente deve estar na mesma rede que o dispositivo principal.
  + O dispositivo cliente deve executar o [Python 3](https://www.python.org/).
  + O dispositivo cliente deve executar o [Git](https://git-scm.com/).

## Etapa 1: revisar e atualizar a AWS IoT política do dispositivo principal
<a name="update-core-device-iot-policy-client-devices"></a>

Para oferecer suporte a dispositivos cliente, a AWS IoT política de um dispositivo principal deve permitir as seguintes permissões:
+ <a name="core-device-iot-policy-client-device-permissions-putcertificateauthorities"></a>`greengrass:PutCertificateAuthorities`
+ <a name="core-device-iot-policy-client-device-permissions-verifyclientdeviceidentity"></a>`greengrass:VerifyClientDeviceIdentity`
+ <a name="core-device-iot-policy-client-device-permissions-verifyclientdeviceiotcertificateassociation"></a>`greengrass:VerifyClientDeviceIoTCertificateAssociation`
+ <a name="core-device-iot-policy-client-device-permissions-getconnectivityinfo"></a>`greengrass:GetConnectivityInfo`
+ <a name="core-device-iot-policy-client-device-permissions-updateconnectivityinfo"></a>`greengrass:UpdateConnectivityInfo`— (Opcional) Essa permissão é necessária para usar o [componente detector de IP](ip-detector-component.md), que reporta as informações de conectividade de rede do dispositivo principal ao serviço de AWS IoT Greengrass nuvem.

Para obter mais informações sobre essas permissões e AWS IoT políticas para dispositivos principais, consulte [AWS IoT políticas para operações de plano de dados](device-auth.md#iot-policies) [AWS IoT Política mínima para oferecer suporte aos dispositivos do cliente](device-auth.md#client-device-support-minimal-iot-policy) e.

Nesta seção, você revisa as AWS IoT políticas do seu dispositivo principal e adiciona as permissões necessárias que estão faltando. Se você usou o [instalador de software AWS IoT Greengrass Core para provisionar recursos](quick-installation.md), seu dispositivo principal tem uma AWS IoT política que permite acesso a todas as AWS IoT Greengrass ações (`greengrass:*`). Nesse caso, você deve atualizar a AWS IoT política somente se planeja configurar o componente do gerenciador de sombras para sincronizar as sombras do dispositivo. AWS IoT Core Caso contrário, você pode pular esta seção.

**Para revisar e atualizar a AWS IoT política de um dispositivo principal**

1. <a name="update-iot-policy-console-open-greengrass-console"></a>No menu de navegação do [console do AWS IoT Greengrass](https://console.aws.amazon.com/greengrass), selecione **Dispositivos principais**.

1. <a name="update-iot-policy-console-choose-core-device"></a>Na página **Dispositivos principais**, escolha o dispositivo principal a ser atualizado.

1. <a name="update-iot-policy-console-choose-core-device-thing"></a>Na página de detalhes do dispositivo principal, escolha o link para o **Objeto** do dispositivo principal. Esse link abre a página de detalhes do objeto no console da AWS IoT .

1. <a name="update-iot-policy-console-choose-thing-security"></a>Na página de detalhes do objeto, escolha **Certificados**.

1. <a name="update-iot-policy-console-choose-thing-certificate"></a>Na guia **Certificados**, escolha o certificado ativo do objeto.

1. <a name="update-iot-policy-console-choose-certificate-policies"></a>Na página de detalhes do certificado, escolha **Políticas**.

1. <a name="update-iot-policy-console-choose-policy"></a>Na guia **Políticas**, escolha a AWS IoT política a ser revisada e atualizada. É possível adicionar as permissões necessárias a toda política anexada ao certificado ativo do dispositivo principal.
**nota**  <a name="quick-installation-iot-policies-note"></a>
Se você usou o [instalador de software AWS IoT Greengrass Core para provisionar recursos](quick-installation.md), você tem duas AWS IoT políticas. Recomendamos que você escolha a política com o nome **GreengrassV2IoTThingPolicy**, se ela existir. Os dispositivos principais que você cria com o instalador rápido usam esse nome de política por padrão. Se você adicionar permissões a essa política, também estará concedendo essas permissões a outros dispositivos principais que usam essa política.

1. <a name="update-iot-policy-console-edit-policy"></a>Na visão geral da política, escolha **Editar versão ativa**.

1. Revise a política quanto às permissões necessárias e adicione as permissões necessárias que estiverem faltando.

1. <a name="update-iot-policy-console-set-as-active-version"></a>Para definir uma nova versão da política como a versão ativa, em **Status da versão da política**, selecione **Definir a versão editada como a versão ativa desta política**.

1. <a name="update-iot-policy-console-save-policy"></a>Selecione **Salvar como nova versão**.

## Etapa 2: habilitar o suporte ao dispositivo cliente
<a name="enable-client-device-support"></a>

Para que um dispositivo cliente use a descoberta na nuvem para se conectar a um dispositivo principal, é necessário associar os dispositivos. Ao associar um dispositivo cliente a um dispositivo principal, você permite que esse dispositivo cliente recupere os endereços IP e certificados do dispositivo principal para usar na conexão.

Para permitir que os dispositivos cliente se conectem com segurança a um dispositivo principal e se comuniquem com os componentes do Greengrass AWS IoT Core, você implanta os seguintes componentes do Greengrass no dispositivo principal:
+ <a name="client-device-component-overview-client-device-auth"></a>[Autenticação do dispositivo cliente](client-device-auth-component.md) (`aws.greengrass.clientdevices.Auth`)

  Implante o componente de autenticação do dispositivo cliente para autenticar dispositivos cliente e autorizar ações dele. Esse componente permite que suas AWS IoT coisas se conectem a um dispositivo principal.

  Esse componente requer algumas configurações para ser usado. É necessário especificar grupos de dispositivos cliente e as operações que cada grupo está autorizado a realizar, como se conectar e se comunicar pelo MQTT. Para obter mais informações, consulte a [configuração do componente de autenticação do dispositivo cliente](client-device-auth-component.md#client-device-auth-component-configuration).
+ <a name="client-device-component-overview-mqtt-broker-moquette"></a>[Agente MQTT 3.1.1 (Moquette)](mqtt-broker-moquette-component.md) (`aws.greengrass.clientdevices.mqtt.Moquette`)

  Implante o componente do agente Moquette MQTT para executar um agente MQTT leve. O agente Moquette MQTT é compatível com o MQTT 3.1.1 e inclui suporte local para QoS 0, QoS 1, QoS 2, mensagens retidas, mensagens de último testamento e assinaturas persistentes.

  Não é necessário configurar esse componente para usá-lo. No entanto, você pode configurar a porta na qual esse componente opera o agente MQTT. Por padrão, ele usa a porta 8883.
+ <a name="client-device-component-overview-mqtt-bridge"></a>[Ponte MQTT](mqtt-bridge-component.md) (`aws.greengrass.clientdevices.mqtt.Bridge`)

  (Opcional) Implante o componente de ponte MQTT para retransmitir mensagens entre dispositivos cliente (MQTT local), publicação/assinatura local e MQTT. AWS IoT Core Configure esse componente para sincronizar dispositivos cliente AWS IoT Core e interagir com dispositivos clientes a partir dos componentes do Greengrass.

  Esse componente requer configuração para ser usado. Você deve especificar os mapeamentos de tópicos em que esse componente retransmite mensagens. Para obter mais informações, consulte [Configuração do componente de ponte MQTT](mqtt-bridge-component.md#mqtt-bridge-component-configuration).
+ <a name="client-device-component-overview-ip-detector"></a>[Detector IP](ip-detector-component.md) (`aws.greengrass.clientdevices.IPDetector`)

  (Opcional) Implante o componente detector de IP para reportar automaticamente os endpoints do broker MQTT do dispositivo principal ao serviço de AWS IoT Greengrass nuvem. Não é possível usar esse componente se você tiver uma configuração de rede complexa, como quando um roteador encaminha a porta do agente MQTT para o dispositivo principal.

  Não é necessário configurar esse componente para usá-lo.

Nesta seção, você usa o AWS IoT Greengrass console para associar dispositivos cliente e implantar componentes do dispositivo cliente em um dispositivo principal.

**Como habilitar o suporte ao dispositivo cliente**

1. <a name="navigate-greengrass-console"></a>Navegue até o [console do AWS IoT Greengrass](https://console.aws.amazon.com/greengrass).

1. No menu de navegação esquerdo, escolha **Dispositivos principais**.

1. Na página **Dispositivos principais**, escolha o dispositivo principal em que deseja ativar o suporte ao dispositivo cliente.

1. Na página de detalhes do dispositivo principal, escolha a guia **Dispositivos cliente**.

1. Na guia **Dispositivos cliente**, escolha **Configurar a descoberta na nuvem**.

   A página **Configurar a descoberta de dispositivos principais** é aberta. Nessa página, você pode associar dispositivos cliente a um dispositivo principal e implantar componentes do dispositivo cliente. Essa página seleciona o dispositivo principal para você na **Etapa 1: selecionar dispositivos principais de destino**.
**nota**  
Também é possível usar essa página para configurar a descoberta de dispositivos principais para um grupo de coisas. Se você escolher essa opção, poderá implantar componentes do dispositivo cliente em todos os dispositivos principais em um grupo de coisas. No entanto, se escolher essa opção, deverá associar manualmente os dispositivos cliente a cada dispositivo principal depois de criar a implantação. Neste tutorial, você configura um único dispositivo principal.

1. Na **Etapa 2: Associar dispositivos cliente**, associe a AWS IoT coisa do dispositivo cliente ao dispositivo principal. Isso permite que o dispositivo cliente use a descoberta na nuvem para recuperar as informações e os certificados de conectividade do dispositivo principal. Faça o seguinte:

   1. Escolha **Associar dispositivos cliente**.

   1. No modal **Associar dispositivos cliente ao dispositivo principal**, insira o nome da AWS IoT coisa a ser associada.

   1. Escolha **Adicionar**.

   1. Selecione **Associar **.

1. Na **Etapa 3: configurar e implantar componentes do Greengrass**, implante componentes para habilitar o suporte ao dispositivo cliente. Se o dispositivo principal de destino tiver uma implantação prévia, essa página revisará essa implantação. Caso contrário, essa página criará uma nova implantação para o dispositivo principal. Faça o seguinte para configurar e implantar os componentes do dispositivo cliente:

   1. O dispositivo principal deve executar a versão 2.6.0 ou posterior do [núcleo do Greengrass](greengrass-nucleus-component.md) para concluir este tutorial. Se o dispositivo principal executar uma versão anterior, faça o seguinte:

      1. Selecione a caixa para implantar o componente **aws.greengrass.Nucleus**.

      1. Para o componente **aws.greengrass.Nucleus**, escolha **Editar configuração**.

      1. Para **Versão do componente**, escolha a versão 2.6.0 ou posterior.

      1. Escolha **Confirmar**.
**nota**  
Se você atualizar o núcleo do Greengrass de uma versão secundária anterior e o dispositivo principal executar [componentes AWS fornecidos](public-components.md) que dependem do núcleo, você também deverá atualizar os AWS componentes fornecidos para versões mais recentes. É possível configurar a versão desses componentes ao analisar a implantação posteriormente neste tutorial. Para obter mais informações, consulte [Atualizar o software de núcleo do AWS IoT Greengrass (OTA)](update-greengrass-core-v2.md).

   1. Para o componente **aws.greengrass.clientdevices.Auth**, escolha **Editar configuração**.

   1. No modal **Editar configuração** do componente de autenticação do dispositivo cliente, configure uma política de autorização que permita que os dispositivos cliente publiquem e assinem o agente MQTT no dispositivo principal. Faça o seguinte:

      1. Em **Configuração**, no bloco de código **Configuração a ser mesclada**, insira a configuração a seguir, que contém uma *política de autorização de dispositivo cliente*. Cada política de autorização de grupo de dispositivos especifica um conjunto de ações e os recursos nos quais um dispositivo cliente pode realizar essas ações.
         + Essa política permite que dispositivos cliente cujos nomes começam com `MyClientDevice` se conectem e se comuniquem em todos os tópicos do MQTT. *MyClientDevice\$1*Substitua pelo nome do AWS IoT item a ser conectado como dispositivo cliente. Também é possível especificar um nome com o curinga `*` que corresponda ao nome do dispositivo cliente. O curinga `*` deve estar no final do nome.

           Se você tiver um segundo dispositivo cliente para se conectar, *MyOtherClientDevice\$1* substitua pelo nome desse dispositivo cliente ou por um padrão curinga que corresponda ao nome desse dispositivo cliente. Caso contrário, você pode remover ou manter essa seção da regra de seleção que permite que dispositivos cliente com nomes que correspondam a `MyOtherClientDevice*` se conectem e se comuniquem.
         + Essa política usa um operador `OR` para também permitir que dispositivos cliente cujos nomes comecem com `MyOtherClientDevice` se conectem e se comuniquem em todos os tópicos do MQTT. É possível remover essa cláusula na regra de seleção ou modificá-la para corresponder aos dispositivos cliente a serem conectados.
         + Essa política permite que os dispositivos cliente publiquem e assinem em todos os tópicos do MQTT. Para seguir as práticas recomendadas de segurança, restrinja as operações `mqtt:publish` e `mqtt:subscribe` ao conjunto mínimo de tópicos que os dispositivos cliente usam para se comunicar.

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

         Para obter mais informações, consulte a [configuração do componente de autenticação do dispositivo cliente](client-device-auth-component.md#client-device-auth-component-configuration).

      1. Escolha **Confirmar**.

   1. Para o componente **aws.greengrass.clientdevices.mqtt.Bridge**, escolha **Editar configuração**.

   1. No modal **Editar configuração** para o componente de ponte MQTT, configure um mapeamento de tópicos que retransmita mensagens MQTT dos dispositivos do cliente para o AWS IoT Core. Faça o seguinte:

      1. Em **Configuração**, no bloco de código **Configuração a ser mesclada**, insira a configuração a seguir. Essa configuração especifica a retransmissão de mensagens MQTT no filtro de tópico `clients/+/hello/world` dos dispositivos cliente para o serviço de nuvem do AWS IoT Core . Por exemplo, esse filtro de tópico corresponde ao tópico `clients/MyClientDevice1/hello/world`.

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

         Para obter mais informações, consulte [MQTT bridge component configuration](mqtt-bridge-component.md#mqtt-bridge-component-configuration).

      1. Escolha **Confirmar**.

1. <a name="choose-review-and-deploy-configure-discovery-step"></a>Escolha **Analisar e implantar** para analisar a implantação que essa página cria para você.

1. Se você ainda não configurou o [perfil de serviço do Greengrass](greengrass-service-role.md) nessa região, o console abre um modal para configurar o perfil de serviço para você. O componente de autenticação do dispositivo cliente usa esse perfil de serviço para verificar a identidade dos dispositivos cliente, e o componente detector de IP usa esse perfil de serviço para gerenciar informações de conectividade do dispositivo principal. Escolha **Conceder permissões**.

1. <a name="choose-deploy-configure-discovery-step"></a>Na página **Revisar**, escolha **Implantar** para iniciar a implantação no dispositivo principal.

1. <a name="verify-deployment-success-step"></a>Para verificar se a implantação foi bem-sucedida, verifique o status da implantação e verifique os logs no dispositivo principal. Para verificar o status da implantação no dispositivo principal, escolha **Destino** na **Visão geral** da implantação. Para saber mais, consulte:
   + [Verificar o status da implantação](check-deployment-status.md)
   + [Monitore AWS IoT Greengrass logs](monitor-logs.md)

## Etapa 3: conectar dispositivos cliente
<a name="connect-client-devices-tutorial"></a>

Os dispositivos cliente podem usar o AWS IoT Device SDK para descobrir, conectar e se comunicar com um dispositivo principal. O dispositivo cliente deve ser AWS IoT alguma coisa. Para obter mais informações, consulte [Criar um objeto](https://docs.aws.amazon.com/iot/latest/developerguide/create-iot-resources.html#create-aws-thing) no *Guia do desenvolvedor do AWS IoT Core *.

Nesta seção, você instala o [AWS IoT Device SDK v2 para Python](https://github.com/aws/aws-iot-device-sdk-python-v2) e executa a aplicação de amostra de descoberta do Greengrass a partir do AWS IoT Device SDK.

**nota**  
Também AWS IoT Device SDK está disponível em outras linguagens de programação. Este tutorial usa a AWS IoT Device SDK v2 para Python, mas você pode explorar a SDKs outra para seu caso de uso. Para obter mais informações, consulte [AWS IoT Dispositivo SDKs](https://docs.aws.amazon.com/iot/latest/developerguide/iot-sdks.html) no *Guia do AWS IoT Core desenvolvedor*.

**Como conectar um dispositivo cliente a um dispositivo principal**

1. <a name="download-iot-device-sdk-python-v2"></a>Baixe e instale a [AWS IoT Device SDK v2 para Python](https://github.com/aws/aws-iot-device-sdk-python-v2) AWS IoT na coisa para se conectar como um dispositivo cliente.

   No dispositivo cliente, faça o seguinte:

   1. Clone o repositório AWS IoT Device SDK v2 for Python para baixá-lo.

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

   1. Instale a AWS IoT Device SDK v2 para Python.

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

1. <a name="cd-iot-device-sdk-python-v2"></a>Mude para a pasta de amostras na AWS IoT Device SDK v2 para Python.

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

1. <a name="test-client-device-communications-application-intro"></a>Execute a aplicação de amostra de descoberta do Greengrass. Essa aplicação espera argumentos que especifiquem o nome do item do dispositivo cliente, o tópico e a mensagem MQTT que serão usados e os certificados que autenticam e protegem a conexão. O exemplo a seguir envia a mensagem “Hello World\$1” para o tópico `clients/MyClientDevice1/hello/world`.
**nota**  
Este tópico corresponde ao tópico para o qual você configurou a ponte MQTT para retransmitir mensagens anteriores. AWS IoT Core <a name="test-client-device-communications-application-command-replace"></a>
   + *MyClientDevice1*Substitua pelo nome do item do dispositivo cliente.
   + *\$1/certs/AmazonRootCA1.pem*Substitua pelo caminho para o certificado CA raiz da Amazon no dispositivo cliente.
   + *\$1/certs/device.pem.crt*Substitua pelo caminho para o certificado do dispositivo no dispositivo cliente.
   + *\$1/certs/private.pem.key*Substitua pelo caminho para o arquivo de chave privada no dispositivo cliente.
   + *us-east-1*Substitua pela AWS região em que seu dispositivo cliente e dispositivo principal operam.

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

   <a name="test-client-device-communications-application-output-intro"></a>A aplicação de amostra de descoberta envia a mensagem dez vezes e se desconecta. Ela também assina o mesmo tópico em que publica as mensagens. Se a saída indicar que a aplicação recebeu mensagens MQTT no tópico, o dispositivo cliente poderá se comunicar com êxito com o dispositivo principal.

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

   <a name="test-client-device-communications-application-troubleshooting"></a>Em vez disso, se a aplicação gerar um erro, consulte [Solução de problemas de descoberta do Greengrass](troubleshooting-client-devices.md#greengrass-discovery-issues).

   <a name="test-client-device-communications-application-view-core-logs"></a>Também é possível ver os logs do Greengrass no dispositivo principal para verificar se o dispositivo cliente se conecta e envia mensagens com êxito. Para obter mais informações, consulte [Monitore AWS IoT Greengrass logs](monitor-logs.md).

1. Verifique se a ponte MQTT retransmite as mensagens do dispositivo cliente para o. AWS IoT Core Você pode usar o cliente de teste MQTT no AWS IoT Core console para assinar um filtro de tópicos do MQTT. Faça o seguinte:

   1. Navegue até o [console do AWS IoT](https://console.aws.amazon.com/iot).

   1. No painel de navegação esquerdo, em **Testar**, escolha **Cliente de teste MQTT**.

   1. Na guia **Assinar um tópico**, em **Filtro de tópicos**, insira `clients/+/hello/world` para assinar as mensagens do dispositivo cliente do dispositivo principal.

   1. Escolha **Assinar**.

   1. Execute o publish/subscribe aplicativo no dispositivo cliente novamente.

      O cliente de teste MQTT exibe as mensagens enviadas do dispositivo cliente em tópicos que correspondem a esse filtro de tópicos.

## Etapa 4: desenvolver um componente que se comunique com os dispositivos cliente
<a name="develop-client-device-subscriber-component"></a>

É possível desenvolver componentes do Greengrass que se comunicam com dispositivos cliente. Os componentes usam [comunicação entre processos (IPC)](interprocess-communication.md) e a [ publish/subscribe interface local](ipc-publish-subscribe.md) para se comunicar em um dispositivo principal. Para interagir com dispositivos clientes, configure o componente de ponte MQTT para retransmitir mensagens entre dispositivos clientes e a interface local publish/subscribe .

Nesta seção, você atualiza o componente de ponte MQTT para retransmitir mensagens dos dispositivos cliente para a interface local publish/subscribe . Em seguida, você desenvolve um componente que assina essas mensagens e as imprime quando as recebe.

**Como desenvolver um componente que se comunica com os dispositivos cliente**

1. Analise a implantação no dispositivo principal e configure o componente de ponte MQTT para retransmitir mensagens dos dispositivos do cliente para a publicação/assinatura local. Faça o seguinte:

   1. <a name="navigate-greengrass-console"></a>Navegue até o [console do AWS IoT Greengrass](https://console.aws.amazon.com/greengrass).

   1. No menu de navegação esquerdo, escolha **Dispositivos principais**.

   1. Na página **Dispositivos principais**, escolha o dispositivo principal que você está usando para este tutorial.

   1. Na página de detalhes do dispositivo principal, escolha a guia **Dispositivos cliente**.

   1. Na guia **Dispositivos cliente**, escolha **Configurar a descoberta na nuvem**.

      A página **Configurar a descoberta de dispositivos principais** é aberta. Nessa página, é possível alterar ou configurar quais componentes do dispositivo cliente são implantados no dispositivo principal.

   1. Na **Etapa 3**, para o componente **aws.greengrass.clientdevices.mqtt.Bridge**, escolha **Editar configuração**.

   1. No modal **Editar configuração** para o componente de ponte MQTT, configure um mapeamento de tópicos que retransmita mensagens MQTT dos dispositivos do cliente para a interface local. publish/subscribe Faça o seguinte:

      1. Em **Configuração**, no bloco de código **Configuração a ser mesclada**, insira a configuração a seguir. Essa configuração especifica a retransmissão de mensagens MQTT em tópicos que correspondam ao filtro de `clients/+/hello/world` tópicos dos dispositivos do cliente para o serviço de AWS IoT Core nuvem e para o agente local do Greengrass. publish/subscribe 

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

         Para obter mais informações, consulte [MQTT bridge component configuration](mqtt-bridge-component.md#mqtt-bridge-component-configuration).

      1. Escolha **Confirmar**.

   1. <a name="choose-review-and-deploy-configure-discovery-step"></a>Escolha **Analisar e implantar** para analisar a implantação que essa página cria para você.

   1. <a name="choose-deploy-configure-discovery-step"></a>Na página **Revisar**, escolha **Implantar** para iniciar a implantação no dispositivo principal.

   1. <a name="verify-deployment-success-step"></a>Para verificar se a implantação foi bem-sucedida, verifique o status da implantação e verifique os logs no dispositivo principal. Para verificar o status da implantação no dispositivo principal, escolha **Destino** na **Visão geral** da implantação. Para saber mais, consulte:
      + [Verificar o status da implantação](check-deployment-status.md)
      + [Monitore AWS IoT Greengrass logs](monitor-logs.md)

1. Desenvolva e implante um componente do Greengrass que assine mensagens Hello World a partir de dispositivos cliente. Faça o seguinte:

   1. Crie pastas para fórmulas e artefatos no dispositivo principal.

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

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

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

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

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

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

------
**Importante**  <a name="local-artifact-folder-name-requirements"></a>
É necessário usar o formato a seguir para o caminho da pasta de artefatos. Inclua o nome e a versão do componente que você especificar na fórmula.  

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

   1. Use um editor de texto para criar uma fórmula de componente com o conteúdo a seguir. Esta receita especifica a instalação da AWS IoT Device SDK v2 para Python e a execução de um script que assina o tópico e imprime mensagens.

      <a name="nano-command-intro"></a>Por exemplo, em um sistema baseado em Linux, você pode executar o comando a seguir para usar o GNU nano para criar o arquivo.

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

      Copie a fórmula a seguir no arquivo.

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

   1. Use um editor de texto para criar um artefato de script Python chamado `hello_world_subscriber.py` com o conteúdo a seguir. Esse aplicativo usa o serviço publish/subscribe IPC para assinar o `clients/+/hello/world` tópico e imprimir as mensagens recebidas.

      <a name="nano-command-intro"></a>Por exemplo, em um sistema baseado em Linux, você pode executar o comando a seguir para usar o GNU nano para criar o arquivo.

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

      Copie o código Python a seguir no arquivo.

      ```
      import sys
      import time
      import traceback
      
      from awsiot.greengrasscoreipc.clientv2 import GreengrassCoreIPCClientV2
      
      CLIENT_DEVICE_HELLO_WORLD_TOPIC = 'clients/+/hello/world'
      TIMEOUT = 10
      
      
      def on_hello_world_message(event):
          try:
              message = str(event.binary_message.message, 'utf-8')
              print('Received new message: %s' % message)
          except:
              traceback.print_exc()
      
      
      try:
          ipc_client = GreengrassCoreIPCClientV2()
      
          # SubscribeToTopic returns a tuple with the response and the operation.
          _, operation = ipc_client.subscribe_to_topic(
              topic=CLIENT_DEVICE_HELLO_WORLD_TOPIC, on_stream_event=on_hello_world_message)
          print('Successfully subscribed to topic: %s' %
                CLIENT_DEVICE_HELLO_WORLD_TOPIC)
      
          # Keep the main thread alive, or the process will exit.
          try:
              while True:
                  time.sleep(10)
          except InterruptedError:
              print('Subscribe interrupted.')
      
          operation.close()
      except Exception:
          print('Exception occurred when using IPC.', file=sys.stderr)
          traceback.print_exc()
          exit(1)
      ```
**nota**  
Esse componente usa o cliente IPC V2 na v2 [AWS IoT Device SDK para Python para](https://github.com/aws/aws-iot-device-sdk-python-v2) se comunicar com o software Core. AWS IoT Greengrass Em comparação com o cliente de IPC original, o cliente V2 de IPC reduz a quantidade de código que você precisa escrever para usar o IPC em componentes personalizados.

   1. Use a CLI do Greengrass para implantar o componente.

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

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

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

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

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

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

------

1. Visualize os logs do componente para verificar se o componente foi instalado com êxito e assinou o tópico.

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

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

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

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

------

   É possível manter o feed de log aberto para verificar se o dispositivo principal recebe mensagens.

1. No dispositivo cliente, execute novamente a aplicação de amostra de descoberta do Greengrass para enviar mensagens ao dispositivo principal.

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

1. Visualize os logs do componente novamente para verificar se o componente recebe e imprime as mensagens do dispositivo cliente.

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

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

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

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

------

## Etapa 5: desenvolver um componente que interaja com as sombras do dispositivo cliente
<a name="develop-client-device-shadow-component"></a>

É possível desenvolver componentes do Greengrass que interajam com as [sombras do dispositivo do AWS IoT](https://docs.aws.amazon.com/iot/latest/developerguide/iot-device-shadows.html) do dispositivo cliente. Uma *sombra* é um documento JSON que armazena as informações de estado atuais ou desejadas de AWS IoT algo, como um dispositivo cliente. Os componentes personalizados podem acessar as sombras dos dispositivos cliente para gerenciar seu estado, mesmo quando o dispositivo cliente não está conectado ao AWS IoT. Cada AWS IoT coisa tem uma sombra sem nome, e você também pode criar várias sombras nomeadas para cada coisa.

Nesta seção, você implanta o [componente gerenciador de sombras](shadow-manager-component.md) para gerenciar sombras no dispositivo principal. Você também atualiza o componente de ponte MQTT para retransmitir mensagens de sombra entre dispositivos cliente e o componente gerenciador de sombras. Em seguida, você desenvolve um componente que atualiza as sombras dos dispositivos cliente e executa uma aplicação de amostra nos dispositivos cliente que responde às atualizações de sombra do componente. Esse componente representa uma aplicação de gerenciamento de luz inteligente, em que o dispositivo principal gerencia o estado das cores das luzes inteligentes que se conectam a ele como dispositivos cliente.

**Como desenvolver um componente que interaja com as sombras do dispositivo cliente**

1. Revise a implantação no dispositivo principal para implantar o componente gerenciador de sombras e configure o componente de ponte MQTT para retransmitir mensagens de sombra entre os dispositivos cliente e a publicação/assinatura local, onde o gerenciador de sombrar se comunica. Faça o seguinte:

   1. <a name="navigate-greengrass-console"></a>Navegue até o [console do AWS IoT Greengrass](https://console.aws.amazon.com/greengrass).

   1. No menu de navegação esquerdo, escolha **Dispositivos principais**.

   1. Na página **Dispositivos principais**, escolha o dispositivo principal que você está usando para este tutorial.

   1. Na página de detalhes do dispositivo principal, escolha a guia **Dispositivos cliente**.

   1. Na guia **Dispositivos cliente**, escolha **Configurar a descoberta na nuvem**.

      A página **Configurar a descoberta de dispositivos principais** é aberta. Nessa página, é possível alterar ou configurar quais componentes do dispositivo cliente são implantados no dispositivo principal.

   1. Na **Etapa 3**, para o componente **aws.greengrass.clientdevices.mqtt.Bridge**, escolha **Editar configuração**.

   1. No modal **Editar configuração** para o componente de ponte MQTT, configure um mapeamento de tópicos que retransmita mensagens MQTT em [tópicos de sombra do dispositivo](https://docs.aws.amazon.com/iot/latest/developerguide/reserved-topics.html#reserved-topics-shadow) entre dispositivos cliente e a interface de publicação/assinatura local. Você também confirma que a implantação especifica uma versão de ponte MQTT compatível. O suporte à sombra do dispositivo cliente requer a versão 2.2.0 ou posterior da ponte MQTT . Faça o seguinte:

      1. Para **Versão do componente**, escolha a versão 2.2.0 ou posterior.

      1. Em **Configuração**, no bloco de código **Configuração a ser mesclada**, insira a configuração a seguir. Essa configuração especifica a retransmissão de mensagens MQTT em tópicos de sombra.

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

         Para obter mais informações, consulte [MQTT bridge component configuration](mqtt-bridge-component.md#mqtt-bridge-component-configuration).

      1. Escolha **Confirmar**.

   1. Na **Etapa 3**, selecione o componente **aws.greengrass.ShadowManager** para implantá-lo.

   1. <a name="choose-review-and-deploy-configure-discovery-step"></a>Escolha **Analisar e implantar** para analisar a implantação que essa página cria para você.

   1. <a name="choose-deploy-configure-discovery-step"></a>Na página **Revisar**, escolha **Implantar** para iniciar a implantação no dispositivo principal.

   1. <a name="verify-deployment-success-step"></a>Para verificar se a implantação foi bem-sucedida, verifique o status da implantação e verifique os logs no dispositivo principal. Para verificar o status da implantação no dispositivo principal, escolha **Destino** na **Visão geral** da implantação. Para saber mais, consulte:
      + [Verificar o status da implantação](check-deployment-status.md)
      + [Monitore AWS IoT Greengrass logs](monitor-logs.md)

1. Desenvolva e implante um componente do Greengrass que gerencia dispositivos cliente de luz inteligente. Faça o seguinte:

   1. Crie uma pasta com os artefatos do componente no dispositivo principal.

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

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

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

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

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

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

------
**Importante**  <a name="local-artifact-folder-name-requirements"></a>
É necessário usar o formato a seguir para o caminho da pasta de artefatos. Inclua o nome e a versão do componente que você especificar na fórmula.  

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

   1. Use um editor de texto para criar uma fórmula de componente com o conteúdo a seguir. Esta receita especifica a instalação da AWS IoT Device SDK v2 para Python e a execução de um script que interage com as sombras dos dispositivos cliente de luz inteligente para gerenciar suas cores.

      <a name="nano-command-intro"></a>Por exemplo, em um sistema baseado em Linux, você pode executar o comando a seguir para usar o GNU nano para criar o arquivo.

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

      Copie a fórmula a seguir no arquivo.

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

   1. Use um editor de texto para criar um artefato de script Python chamado `smart_light_manager.py` com o conteúdo a seguir. Esse aplicativo usa o serviço IPC paralelo para obter e atualizar as sombras do dispositivo cliente e o serviço publish/subscribe IPC local para receber atualizações paralelas relatadas.

      <a name="nano-command-intro"></a>Por exemplo, em um sistema baseado em Linux, você pode executar o comando a seguir para usar o GNU nano para criar o arquivo.

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

      Copie o código Python a seguir no arquivo.

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

      Essa aplicação Python faz o seguinte:
      + Lê a configuração do componente para obter a lista de dispositivos cliente de luz inteligente para gerenciar.
      + Assina as notificações de atualização de configuração usando a operação de IPC [SubscribeToConfigurationUpdate](ipc-component-configuration.md#ipc-operation-subscribetoconfigurationupdate). O software AWS IoT Greengrass Core envia notificações sempre que a configuração do componente é alterada. Quando o componente recebe uma notificação de atualização de configuração, ele atualiza a lista de dispositivos cliente de luz inteligente que ele gerencia.
      + Obtém a sombra de cada dispositivo cliente de luz inteligente para obter seu estado de cor inicial.
      + Define a cor de cada dispositivo cliente de luz inteligente para uma cor aleatória a cada 15 segundos. O componente atualiza a sombra da coisa do dispositivo cliente para mudar sua cor. Essa operação envia um evento delta de sombra para o dispositivo cliente pelo MQTT.
      + Assina as mensagens aceitas de atualização de sombra na interface de publicação/assinatura local usando a operação de IPC [SubscribeToTopic](ipc-publish-subscribe.md#ipc-operation-subscribetotopic). Esse componente recebe essas mensagens para rastrear a cor de cada dispositivo cliente de luz inteligente. Quando um dispositivo cliente de luz inteligente recebe uma atualização de sombra, ele envia uma mensagem MQTT para confirmar que recebeu a atualização. A ponte MQTT retransmite essa mensagem para a interface local publish/subscribe .

   1. Use a CLI do Greengrass para implantar o componente. Ao implantar esse componente, você especifica a lista de dispositivos cliente, `smartLightDeviceNames`, cujas sombras ele gerencia. *MyClientDevice1*Substitua pelo nome do item do dispositivo cliente.

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

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

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

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

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

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

------

1. Visualize os logs do componente para verificar se o componente foi instalado e executado com êxito.

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

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

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

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

------

   O componente envia solicitações para alterar a cor do dispositivo cliente de luz inteligente. O gerenciador de sombras recebe a solicitação e define o estado `desired` da sombra. No entanto, o dispositivo cliente de luz inteligente ainda não está funcionando, então o estado `reported` da sombra não muda. Os logs do componente incluem as mensagens a seguir.

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

   É possível manter o feed de log aberto para ver quando o componente imprime mensagens.

1. Baixe e execute uma aplicação de amostra que usa a descoberta do Greengrass e assina as atualizações da sombra do dispositivo. No dispositivo cliente, faça o seguinte:

   1. Use um editor de texto para criar um script Python chamado `basic_discovery_shadow.py` com o conteúdo a seguir. Essa aplicação usa a descoberta e as sombras do Greengrass para manter uma propriedade sincronizada entre o dispositivo cliente e o dispositivo principal.

      <a name="nano-command-intro"></a>Por exemplo, em um sistema baseado em Linux, você pode executar o comando a seguir para usar o GNU nano para criar o arquivo.

      ```
      nano basic_discovery_shadow.py
      ```

      Copie o código Python a seguir no arquivo.

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

      Essa aplicação Python faz o seguinte:
      + Usa a descoberta do Greengrass para descobrir e se conectar ao dispositivo principal.
      + Solicita o documento de nuvem do dispositivo principal para obter o estado inicial da propriedade.
      + Assina eventos delta de sombra, que o dispositivo principal envia quando o valor `desired` da propriedade é diferente de seu valor `reported`. Quando a aplicação recebe um evento delta de sombra, ela altera o valor da propriedade e envia uma atualização para o dispositivo principal para definir o novo valor como seu valor `reported`.

      Essa aplicação combina as amostras de descoberta e sombra do Greengrass do AWS IoT Device SDK v2.

   1. Execute as aplicações de exemplo. Essa aplicação espera argumentos que especifiquem o nome da coisa do dispositivo cliente, a propriedade de sombra a ser usada e os certificados que autenticam e protegem a conexão.<a name="test-client-device-communications-application-command-replace"></a>
      + *MyClientDevice1*Substitua pelo nome do item do dispositivo cliente.
      + *\$1/certs/AmazonRootCA1.pem*Substitua pelo caminho para o certificado CA raiz da Amazon no dispositivo cliente.
      + *\$1/certs/device.pem.crt*Substitua pelo caminho para o certificado do dispositivo no dispositivo cliente.
      + *\$1/certs/private.pem.key*Substitua pelo caminho para o arquivo de chave privada no dispositivo cliente.
      + *us-east-1*Substitua pela AWS região em que seu dispositivo cliente e dispositivo principal operam.

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

      A aplicação de amostra assina os tópicos de sombra e espera receber eventos delta de sombra do dispositivo principal. Se a saída indicar que a aplicação recebe e responde aos eventos delta de sombra, o dispositivo cliente pode interagir com sucesso com sua sombra no dispositivo principal.

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

      <a name="test-client-device-communications-application-troubleshooting"></a>Se, em vez disso, a aplicação gerar um erro, consulte [Troubleshooting Greengrass discovery issues](troubleshooting-client-devices.md#greengrass-discovery-issues).

      <a name="test-client-device-communications-application-view-core-logs"></a>Também é possível ver os logs do Greengrass no dispositivo principal para verificar se o dispositivo cliente se conecta e envia mensagens com êxito. Para obter mais informações, consulte [Monitore AWS IoT Greengrass logs](monitor-logs.md).

1. Visualize os logs do componente novamente para verificar se o componente recebe confirmações de atualização de sombra do dispositivo cliente de luz inteligente.

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

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

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

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

------

   O componente registra em log mensagens para confirmar que o dispositivo cliente de luz inteligente mudou de cor.

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

**nota**  
A sombra do dispositivo cliente está sincronizada entre o dispositivo principal e o dispositivo cliente. No entanto, o dispositivo principal não sincroniza com a sombra do dispositivo cliente AWS IoT Core. Você pode sincronizar uma sombra com AWS IoT Core para visualizar ou modificar o estado de todos os dispositivos em sua frota, por exemplo. Para obter mais informações sobre como configurar o componente do gerenciador de sombras para sincronizar sombras AWS IoT Core, consulte[Sincronize sombras do dispositivo local com AWS IoT Core](sync-shadows-with-iot-core.md).

Você concluiu este tutorial. O dispositivo cliente se conecta ao dispositivo principal, envia mensagens MQTT para os componentes do Greengrass AWS IoT Core e recebe atualizações paralelas do dispositivo principal. Para obter mais informações sobre os tópicos abordados neste tutorial, consulte os seguintes tópicos:
+ [Associar dispositivos cliente](associate-client-devices.md)
+ [Gerenciar endpoints do dispositivo principal do](manage-core-device-endpoints.md)
+ [Testar a comunicação entre os dispositivos cliente](test-client-device-communications.md)
+ [API de descoberta do Greengrass RESTful](greengrass-discover-api.md)
+ [Retransmita mensagens MQTT entre dispositivos clientes e AWS IoT Core](relay-client-device-messages.md)
+ [Interaja com dispositivos clientes em componentes](interact-with-client-devices-in-components.md)
+ [Interaja com as sombras do dispositivo](interact-with-shadows.md)
+ [Interagir e sincronizar as sombras do dispositivo cliente](work-with-client-device-shadows.md)