

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á.

# Etapa 2: desenvolver um componente que adia as atualizações
<a name="develop-component-defer-updates"></a>

Nesta seção, você desenvolverá um componente Hello World em Python que adia atualizações de componentes quando o nível da bateria do dispositivo principal estiver abaixo de um limite configurado ao implantar o componente. Neste componente, você usa a [interface de comunicação entre processos (IPC)](interprocess-communication.md) na AWS IoT Device SDK v2 para Python. Você usa a operação [SubscribeToComponentUpdates](ipc-component-lifecycle.md#ipc-operation-subscribetocomponentupdates)IPC para receber notificações quando o dispositivo principal recebe uma implantação. Em seguida, você usa a operação [DeferComponentUpdate](ipc-component-lifecycle.md#ipc-operation-defercomponentupdate)IPC para adiar ou confirmar a atualização com base no nível da bateria do dispositivo.

**Para desenvolver um componente Hello World que adie atualizações**

1. No seu computador de desenvolvimento, crie uma pasta para o código-fonte do componente.

   ```
   mkdir com.example.BatteryAwareHelloWorld
   cd com.example.BatteryAwareHelloWorld
   ```

1. Use um editor de texto para criar um arquivo chamado `gdk-config.json`. A CLI do GDK lê o [arquivo de configuração da CLI do GDK](gdk-cli-configuration-file.md), chamado `gdk-config.json`, para criar e publicar componentes. Esse arquivo de configuração existe na raiz da pasta do componente.

   <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 gdk-config.json
   ```

   Copie o seguinte JSON no arquivo.
   + {{Amazon}}Substitua pelo seu nome.
   + {{us-west-2}}Substitua pelo Região da AWS local em que seu dispositivo principal opera. A CLI do GDK publica este componente nessa Região da AWS.
   + {{greengrass-component-artifacts}}Substitua pelo prefixo do bucket do S3 a ser usado. Quando você usa a CLI do GDK para publicar o componente, a CLI do GDK carrega os artefatos do componente para o bucket do S3 cujo nome é formado por esse valor, o, e seu ID usando Região da AWS o seguinte formato:. Conta da AWS `{{bucketPrefix}}-{{region}}-{{accountId}}`

     Por exemplo, se você especificar **greengrass-component-artifacts** e**us-west-2**, e seu Conta da AWS ID for**123456789012**, a CLI do GDK usará o bucket do S3 chamado. `greengrass-component-artifacts-us-west-2-123456789012`

   ```
   {
     "component": {
       "com.example.BatteryAwareHelloWorld": {
         "author": "{{Amazon}}",
         "version": "NEXT_PATCH",
         "build": {
           "build_system" : "zip"
         },
         "publish": {
           "region": "{{us-west-2}}",
           "bucket": "{{greengrass-component-artifacts}}"
         }
       }
     },
     "gdk_version": "1.0.0"
   }
   ```

   O arquivo de configuração especifica o seguinte:
   + A versão a ser usada quando a CLI do GDK publica o componente Greengrass no serviço de nuvem. AWS IoT Greengrass `NEXT_PATCH`especifica a escolha da próxima versão do patch após a versão mais recente disponível no serviço de AWS IoT Greengrass nuvem. Se o componente ainda não tiver uma versão no serviço de AWS IoT Greengrass nuvem, a `1.0.0` CLI do GDK usará.
   + O sistema de compilação do componente. Quando você usa o sistema de compilação `zip`, a CLI do GDK empacota a fonte do componente em um arquivo ZIP que se torna o único artefato do componente.
   + O Região da AWS local onde a CLI do GDK publica o componente Greengrass.
   + O prefixo do bucket do S3 em que a CLI do GDK faz o upload dos artefatos do componente.

1. Use um editor de texto para criar o código-fonte do componente em um arquivo chamado `main.py`.

   <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 main.py
   ```

   Copie o código Python a seguir no arquivo.

   ```
   import json
   import os
   import sys
   import time
   import traceback
   
   from pathlib import Path
   
   from awsiot.greengrasscoreipc.clientv2 import GreengrassCoreIPCClientV2
   
   HELLO_WORLD_PRINT_INTERVAL = 15  # Seconds
   DEFER_COMPONENT_UPDATE_INTERVAL = 30 * 1000  # Milliseconds
   
   
   class BatteryAwareHelloWorldPrinter():
       def __init__(self, ipc_client: GreengrassCoreIPCClientV2, battery_file_path: Path, battery_threshold: float):
           self.battery_file_path = battery_file_path
           self.battery_threshold = battery_threshold
           self.ipc_client = ipc_client
           self.subscription_operation = None
   
       def on_component_update_event(self, event):
           try:
               if event.pre_update_event is not None:
                   if self.is_battery_below_threshold():
                       self.defer_update(event.pre_update_event.deployment_id)
                       print('Deferred update for deployment %s' %
                             event.pre_update_event.deployment_id)
                   else:
                       self.acknowledge_update(
                           event.pre_update_event.deployment_id)
                       print('Acknowledged update for deployment %s' %
                             event.pre_update_event.deployment_id)
               elif event.post_update_event is not None:
                   print('Applied update for deployment')
           except:
               traceback.print_exc()
   
       def subscribe_to_component_updates(self):
           if self.subscription_operation == None:
               # SubscribeToComponentUpdates returns a tuple with the response and the operation.
               _, self.subscription_operation = self.ipc_client.subscribe_to_component_updates(
                   on_stream_event=self.on_component_update_event)
   
       def close_subscription(self):
           if self.subscription_operation is not None:
               self.subscription_operation.close()
               self.subscription_operation = None
   
       def defer_update(self, deployment_id):
           self.ipc_client.defer_component_update(
               deployment_id=deployment_id, recheck_after_ms=DEFER_COMPONENT_UPDATE_INTERVAL)
   
       def acknowledge_update(self, deployment_id):
           # Specify recheck_after_ms=0 to acknowledge a component update.
           self.ipc_client.defer_component_update(
               deployment_id=deployment_id, recheck_after_ms=0)
   
       def is_battery_below_threshold(self):
           return self.get_battery_level() < self.battery_threshold
   
       def get_battery_level(self):
           # Read the battery level from the virtual battery level file.
           with self.battery_file_path.open('r') as f:
               data = json.load(f)
               return float(data['battery_level'])
   
       def print_message(self):
           message = 'Hello, World!'
           if self.is_battery_below_threshold():
               message += ' Battery level (%d) is below threshold (%d), so the component will defer updates' % (
                   self.get_battery_level(), self.battery_threshold)
           else:
               message += ' Battery level (%d) is above threshold (%d), so the component will acknowledge updates' % (
                   self.get_battery_level(), self.battery_threshold)
           print(message)
   
   
   def main():
       # Read the battery threshold and virtual battery file path from command-line args.
       args = sys.argv[1:]
       battery_threshold = float(args[0])
       battery_file_path = Path(args[1])
       print('Reading battery level from %s and deferring updates when below %d' % (
           str(battery_file_path), battery_threshold))
   
       try:
           # Create an IPC client and a Hello World printer that defers component updates.
           ipc_client = GreengrassCoreIPCClientV2()
           hello_world_printer = BatteryAwareHelloWorldPrinter(
               ipc_client, battery_file_path, battery_threshold)
           hello_world_printer.subscribe_to_component_updates()
           try:
               # Keep the main thread alive, or the process will exit.
               while True:
                   hello_world_printer.print_message()
                   time.sleep(HELLO_WORLD_PRINT_INTERVAL)
           except InterruptedError:
               print('Subscription interrupted')
           hello_world_printer.close_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ê o nível da bateria do dispositivo principal a partir de um arquivo virtual de nível de bateria que você criará posteriormente no dispositivo principal. Esse arquivo virtual de nível de bateria imita uma bateria real, então você pode concluir este tutorial em dispositivos principais que não têm bateria.
   + Lê os argumentos da linha de comando para o limite da bateria e o caminho para o arquivo virtual do nível da bateria. A fórmula do componente define esses argumentos de linha de comando com base nos parâmetros de configuração, para que você possa personalizar esses valores ao implantar o componente.
   + Usa o cliente IPC V2 na [AWS IoT Device SDK v2 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.
   + Se inscreve para atualizar as notificações usando a operação [SubscribeToComponentUpdates](ipc-component-lifecycle.md#ipc-operation-subscribetocomponentupdates)IPC. O software AWS IoT Greengrass Core envia notificações antes e depois de cada implantação. O componente chama a função a seguir sempre que recebe uma notificação. Se a notificação for para uma implantação futura, o componente verificará se o nível da bateria está abaixo do limite. Se o nível da bateria estiver abaixo do limite, o componente adia a atualização por 30 segundos usando a operação [DeferComponentUpdate](ipc-component-lifecycle.md#ipc-operation-defercomponentupdate)IPC. Caso contrário, se o nível da bateria não estiver abaixo do limite, o componente confirma a atualização, para que ela possa continuar.

     ```
     def on_component_update_event(self, event):
         try:
             if event.pre_update_event is not None:
                 if self.is_battery_below_threshold():
                     self.defer_update(event.pre_update_event.deployment_id)
                     print('Deferred update for deployment %s' %
                           event.pre_update_event.deployment_id)
                 else:
                     self.acknowledge_update(
                         event.pre_update_event.deployment_id)
                     print('Acknowledged update for deployment %s' %
                           event.pre_update_event.deployment_id)
             elif event.post_update_event is not None:
                 print('Applied update for deployment')
         except:
             traceback.print_exc()
     ```
**nota**  
O software AWS IoT Greengrass Core não envia notificações de atualização para implantações locais, então você implanta esse componente usando o serviço de AWS IoT Greengrass nuvem para testá-lo.

1. Use um editor de texto para criar a fórmula do componente em um arquivo chamado `recipe.json` ou `recipe.yaml`. A *fórmula* do componente define os metadados do componente, os parâmetros de configuração padrão e os scripts de ciclo de vida específicos da plataforma.

------
#### [ JSON ]

   <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 recipe.json
   ```

   Copie o JSON a seguir no arquivo.

   ```
   {
     "RecipeFormatVersion": "2020-01-25",
     "ComponentName": "COMPONENT_NAME",
     "ComponentVersion": "COMPONENT_VERSION",
     "ComponentDescription": "This Hello World component defers updates when the battery level is below a threshold.",
     "ComponentPublisher": "COMPONENT_AUTHOR",
     "ComponentConfiguration": {
       "DefaultConfiguration": {
         "BatteryThreshold": 50,
         "LinuxBatteryFilePath": "/home/ggc_user/virtual_battery.json",
         "WindowsBatteryFilePath": "C:\\Users\\ggc_user\\virtual_battery.json"
       }
     },
     "Manifests": [
       {
         "Platform": {
           "os": "linux"
         },
         "Lifecycle": {
           "install": "python3 -m pip install --user awsiotsdk --upgrade",
           "Run": "python3 -u {artifacts:decompressedPath}/com.example.BatteryAwareHelloWorld/main.py \"{configuration:/BatteryThreshold}\" \"{configuration:/LinuxBatteryFilePath}\""
         },
         "Artifacts": [
           {
             "Uri": "s3://BUCKET_NAME/COMPONENT_NAME/COMPONENT_VERSION/com.example.BatteryAwareHelloWorld.zip",
             "Unarchive": "ZIP"
           }
         ]
       },
       {
         "Platform": {
           "os": "windows"
         },
         "Lifecycle": {
           "install": "py -3 -m pip install --user awsiotsdk --upgrade",
           "Run": "py -3 -u {artifacts:decompressedPath}/com.example.BatteryAwareHelloWorld/main.py \"{configuration:/BatteryThreshold}\" \"{configuration:/WindowsBatteryFilePath}\""
         },
         "Artifacts": [
           {
             "Uri": "s3://BUCKET_NAME/COMPONENT_NAME/COMPONENT_VERSION/com.example.BatteryAwareHelloWorld.zip",
             "Unarchive": "ZIP"
           }
         ]
       }
     ]
   }
   ```

------
#### [ YAML ]

   <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 recipe.yaml
   ```

   Copie o seguinte YAML no arquivo .

   ```
   ---
   RecipeFormatVersion: "2020-01-25"
   ComponentName: "COMPONENT_NAME"
   ComponentVersion: "COMPONENT_VERSION"
   ComponentDescription: "This Hello World component defers updates when the battery level is below a threshold."
   ComponentPublisher: "COMPONENT_AUTHOR"
   ComponentConfiguration:
     DefaultConfiguration:
       BatteryThreshold: 50
       LinuxBatteryFilePath: "/home/ggc_user/virtual_battery.json"
       WindowsBatteryFilePath: "C:\\Users\\ggc_user\\virtual_battery.json"
   Manifests:
     - Platform:
         os: linux
       Lifecycle:
         install: python3 -m pip install --user awsiotsdk --upgrade
         Run: python3 -u {artifacts:decompressedPath}/com.example.BatteryAwareHelloWorld/main.py "{configuration:/BatteryThreshold}" "{configuration:/LinuxBatteryFilePath}"
       Artifacts:
         - Uri: "s3://BUCKET_NAME/COMPONENT_NAME/COMPONENT_VERSION/com.example.BatteryAwareHelloWorld.zip"
           Unarchive: ZIP
     - Platform:
         os: windows
       Lifecycle:
         install: py -3 -m pip install --user awsiotsdk --upgrade
         Run: py -3 -u {artifacts:decompressedPath}/com.example.BatteryAwareHelloWorld/main.py "{configuration:/BatteryThreshold}" "{configuration:/WindowsBatteryFilePath}"
       Artifacts:
         - Uri: "s3://BUCKET_NAME/COMPONENT_NAME/COMPONENT_VERSION/com.example.BatteryAwareHelloWorld.zip"
           Unarchive: ZIP
   ```

------

   Esta fórmula especifica o seguinte:
   + Os parâmetros de configuração padrão para o limite da bateria, o caminho do arquivo da bateria virtual nos dispositivos principais do Linux e o caminho do arquivo da bateria virtual nos dispositivos principais do Windows.
   + Um ciclo de vida `install` que instala a versão mais recente do AWS IoT Device SDK v2 para Python.
   + Um ciclo de vida `run` que executa a aplicação Python em `main.py`.
   + Espaços reservados, como `COMPONENT_NAME` e `COMPONENT_VERSION`, em que a CLI do GDK substitui as informações ao criar a fórmula do componente.

   Para ter mais informações sobre fórmulas de componentes, consulte [AWS IoT Greengrass referência de receita de componente](component-recipe-reference.md).