

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Schritt 2: Entwickeln Sie eine Komponente, die Updates verzögert
<a name="develop-component-defer-updates"></a>

In diesem Abschnitt entwickeln Sie eine Hello World-Komponente in Python, die Komponenten-Updates verzögert, wenn der Akkuladestand des Kerngeräts unter einem Schwellenwert liegt, den Sie bei der Bereitstellung der Komponente konfigurieren. In dieser Komponente verwenden Sie die [IPC-Schnittstelle (Interprocess Communication)](interprocess-communication.md) in der AWS IoT Device SDK Version 2 für Python. Sie verwenden den [SubscribeToComponentUpdates](ipc-component-lifecycle.md#ipc-operation-subscribetocomponentupdates)IPC-Vorgang, um Benachrichtigungen zu erhalten, wenn das Kerngerät eine Bereitstellung empfängt. Anschließend verwenden Sie den [DeferComponentUpdate](ipc-component-lifecycle.md#ipc-operation-defercomponentupdate)IPC-Vorgang, um das Update je nach Akkuladestand des Geräts zu verzögern oder zu bestätigen.

**Um eine Hello World-Komponente zu entwickeln, die Updates verzögert**

1. Erstellen Sie auf Ihrem Entwicklungscomputer einen Ordner für den Quellcode der Komponente.

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

1. Verwenden Sie einen Texteditor, um eine Datei mit dem Namen zu erstellen`gdk-config.json`. Die GDK-CLI liest aus der benannten [GDK-CLI-Konfigurationsdatei](gdk-cli-configuration-file.md), um `gdk-config.json` Komponenten zu erstellen und zu veröffentlichen. Diese Konfigurationsdatei befindet sich im Stammverzeichnis des Komponentenordners.

   <a name="nano-command-intro"></a>Auf einem Linux-basierten System können Sie beispielsweise den folgenden Befehl ausführen, um die Datei mit GNU Nano zu erstellen.

   ```
   nano gdk-config.json
   ```

   Kopieren Sie den folgenden JSON-Code in die Datei.
   + Ersetze es {{Amazon}} durch deinen Namen.
   + {{us-west-2}}Ersetzen Sie durch den AWS-Region Ort, an dem Ihr Kerngerät betrieben wird. Die GDK-CLI veröffentlicht die Komponente darin AWS-Region.
   + Ersetzen Sie es {{greengrass-component-artifacts}} durch das zu verwendende S3-Bucket-Präfix. Wenn Sie die GDK-CLI verwenden, um die Komponente zu veröffentlichen, lädt die GDK-CLI die Artefakte der Komponente in den S3-Bucket hoch, dessen Name aus diesem Wert AWS-Region, dem und Ihrer AWS-Konto ID im folgenden Format gebildet wird:. `{{bucketPrefix}}-{{region}}-{{accountId}}`

     Wenn Sie beispielsweise **greengrass-component-artifacts** und angeben und Ihre AWS-Konto ID lautet **us-west-2****123456789012**, verwendet die GDK-CLI den S3-Bucket mit dem Namen`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"
   }
   ```

   Die Konfigurationsdatei spezifiziert Folgendes:
   + Die Version, die verwendet werden soll, wenn die GDK-CLI die Greengrass-Komponente im AWS IoT Greengrass Cloud-Dienst veröffentlicht. `NEXT_PATCH`gibt an, dass die nächste Patch-Version nach der neuesten im AWS IoT Greengrass Cloud-Dienst verfügbaren Version ausgewählt werden soll. Wenn die Komponente noch keine Version im AWS IoT Greengrass Cloud-Dienst hat, verwendet `1.0.0` die GDK-CLI.
   + Das Build-System für die Komponente. Wenn Sie das `zip` Build-System verwenden, packt die GDK-CLI die Quelle der Komponente in eine ZIP-Datei, die zum einzigen Artefakt der Komponente wird.
   + Der AWS-Region Ort, an dem die GDK-CLI die Greengrass-Komponente veröffentlicht.
   + Das Präfix für den S3-Bucket, in den die GDK-CLI die Artefakte der Komponente hochlädt.

1. Verwenden Sie einen Texteditor, um den Quellcode der Komponente in einer Datei mit dem Namen zu erstellen. `main.py`

   <a name="nano-command-intro"></a>Auf einem Linux-basierten System können Sie beispielsweise den folgenden Befehl ausführen, um die Datei mit GNU Nano zu erstellen.

   ```
   nano main.py
   ```

   Kopieren Sie den folgenden Python-Code in die Datei.

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

   Diese Python-Anwendung macht Folgendes:
   + Liest den Akkustand des Kerngeräts aus einer virtuellen Batteriestanddatei, die Sie später auf dem Kerngerät erstellen werden. Diese virtuelle Batteriestanddatei ahmt einen echten Akku nach, sodass Sie dieses Tutorial auf Kerngeräten ohne Batterie durchführen können.
   + Liest Befehlszeilenargumente für den Akkugrenzwert und den Pfad zur virtuellen Batteriestanddatei. Das Komponentenrezept legt diese Befehlszeilenargumente auf der Grundlage von Konfigurationsparametern fest, sodass Sie diese Werte bei der Bereitstellung der Komponente anpassen können.
   + Verwendet den IPC-Client V2 in der Version [AWS IoT Device SDK 2 für Python](https://github.com/aws/aws-iot-device-sdk-python-v2), um mit der AWS IoT Greengrass Core-Software zu kommunizieren. Im Vergleich zum ursprünglichen IPC-Client reduziert der IPC-Client V2 die Menge an Code, die Sie schreiben müssen, um IPC in benutzerdefinierten Komponenten zu verwenden.
   + Abonniert Aktualisierungsbenachrichtigungen mithilfe der IPC-Operation. [SubscribeToComponentUpdates](ipc-component-lifecycle.md#ipc-operation-subscribetocomponentupdates) Die AWS IoT Greengrass Core-Software sendet vor und nach jeder Bereitstellung Benachrichtigungen. Die Komponente ruft bei jedem Empfang einer Benachrichtigung die folgende Funktion auf. Wenn sich die Benachrichtigung auf eine bevorstehende Bereitstellung bezieht, prüft die Komponente, ob der Akkuladestand unter einem Schwellenwert liegt. Wenn der Akkuladestand unter dem Schwellenwert liegt, verschiebt die Komponente das Update mithilfe des [DeferComponentUpdate](ipc-component-lifecycle.md#ipc-operation-defercomponentupdate)IPC-Vorgangs für 30 Sekunden. Andernfalls bestätigt die Komponente das Update, wenn der Akkuladestand nicht unter dem Schwellenwert liegt, sodass das Update fortgesetzt werden kann.

     ```
     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()
     ```
**Anmerkung**  
Die AWS IoT Greengrass Core-Software sendet keine Aktualisierungsbenachrichtigungen für lokale Bereitstellungen. Sie stellen diese Komponente daher mithilfe des AWS IoT Greengrass Cloud-Dienstes bereit, um sie zu testen.

1. Verwenden Sie einen Texteditor, um das Komponentenrezept in einer Datei mit dem Namen `recipe.json` oder `recipe.yaml` zu erstellen. Das *Komponentenrezept* definiert die Metadaten der Komponente, die Standardkonfigurationsparameter und die plattformspezifischen Lebenszyklusskripts.

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

   <a name="nano-command-intro"></a>Auf einem Linux-basierten System können Sie beispielsweise den folgenden Befehl ausführen, um die Datei mit GNU Nano zu erstellen.

   ```
   nano recipe.json
   ```

   Kopieren Sie den folgenden JSON-Code in die Datei.

   ```
   {
     "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>Auf einem Linux-basierten System können Sie beispielsweise den folgenden Befehl ausführen, um die Datei mit GNU Nano zu erstellen.

   ```
   nano recipe.yaml
   ```

   Kopieren Sie das folgende YAML in die Datei.

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

------

   Dieses Rezept spezifiziert Folgendes:
   + Standardkonfigurationsparameter für den Akkugrenzwert, den virtuellen Batteriedateipfad auf Linux-Kerngeräten und den virtuellen Batteriedateipfad auf Windows-Kerngeräten.
   + Ein `install` Lebenszyklus, der die neueste Version von AWS IoT Device SDK v2 für Python installiert.
   + Ein `run` Lebenszyklus, in dem die Python-Anwendung ausgeführt wird`main.py`.
   + Platzhalter wie `COMPONENT_NAME` und`COMPONENT_VERSION`, bei denen die GDK-CLI Informationen ersetzt, wenn sie das Komponentenrezept erstellt.

   Weitere Informationen zu Komponentenrezepten finden Sie unter. [AWS IoT Greengrass Referenz zum Komponentenrezept](component-recipe-reference.md)