Fase 2: Sviluppare un componente che differisca gli aggiornamenti - AWS IoT Greengrass

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

Fase 2: Sviluppare un componente che differisca gli aggiornamenti

In questa sezione, sviluppi un componente Hello World in Python che posticipa gli aggiornamenti dei componenti quando il livello della batteria del dispositivo principale è inferiore a una soglia configurata quando distribuisci il componente. In questo componente, si utilizza l'interfaccia di comunicazione tra processi (IPC) nella versione 2 SDK per dispositivi AWS IoT per Python. Si utilizza l'operazione SubscribeToComponentUpdatesIPC per ricevere notifiche quando il dispositivo principale riceve una distribuzione. Quindi, si utilizza l'operazione DeferComponentUpdateIPC per posticipare o confermare l'aggiornamento in base al livello della batteria del dispositivo.

Sviluppare un componente Hello World che posticipi gli aggiornamenti
  1. Sul tuo computer di sviluppo, crea una cartella per il codice sorgente del componente.

    mkdir com.example.BatteryAwareHelloWorld cd com.example.BatteryAwareHelloWorld
  2. Utilizzate un editor di testo per creare un file denominatogdk-config.json. La CLI GDK legge dal file di configurazione GDK CLI, gdk-config.json denominato, per creare e pubblicare componenti. Questo file di configurazione esiste nella radice della cartella del componente.

    Ad esempio, su un sistema basato su Linux, è possibile eseguire il comando seguente per utilizzare GNU nano per creare il file.

    nano gdk-config.json

    Copiate il seguente codice JSON nel file.

    • AmazonSostituiscilo con il tuo nome.

    • us-west-2Sostituiscilo con il Regione AWS luogo in cui funziona il tuo dispositivo principale. La CLI GDK pubblica il componente in questo. Regione AWS

    • greengrass-component-artifactsSostituiscilo con il prefisso del bucket S3 da usare. Quando usi la CLI di GDK per pubblicare il componente, la CLI di GDK carica gli artefatti del componente nel bucket S3 il cui nome è formato da questo valore, Regione AWS dal e dal tuo ID utilizzando il seguente formato:. Account AWS bucketPrefix-region-accountId

      Ad esempio, se specifichi greengrass-component-artifacts and e us-west-2 il tuo Account AWS ID è123456789012, la CLI di GDK utilizza il bucket S3 denominato. 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" }

    Il file di configurazione specifica quanto segue:

    • La versione da utilizzare quando la CLI di GDK pubblica il componente Greengrass nel servizio cloud. AWS IoT Greengrass NEXT_PATCHspecifica di scegliere la versione della patch successiva all'ultima versione disponibile nel servizio cloud. AWS IoT Greengrass Se il componente non ha ancora una versione nel servizio AWS IoT Greengrass cloud, utilizza la 1.0.0 CLI di GDK.

    • Il sistema di compilazione del componente. Quando si utilizza il sistema di zip compilazione, la CLI GDK impacchetta il codice sorgente del componente in un file ZIP che diventa il singolo artefatto del componente.

    • Il Regione AWS punto in cui la CLI di GDK pubblica il componente Greengrass.

    • Il prefisso per il bucket S3 in cui la CLI di GDK carica gli artefatti del componente.

  3. Utilizzate un editor di testo per creare il codice sorgente del componente in un file denominato. main.py

    Ad esempio, su un sistema basato su Linux, è possibile eseguire il comando seguente per utilizzare GNU nano per creare il file.

    nano main.py

    Copia il seguente codice Python nel file.

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

    Questa applicazione Python esegue le seguenti operazioni:

    • Legge il livello della batteria del dispositivo principale da un file virtuale del livello di batteria che creerai successivamente sul dispositivo principale. Questo file virtuale del livello della batteria imita una batteria reale, quindi puoi completare questo tutorial sui dispositivi principali che non dispongono di batteria.

    • Legge gli argomenti della riga di comando per la soglia della batteria e il percorso del file virtuale del livello della batteria. La ricetta del componente imposta questi argomenti della riga di comando in base ai parametri di configurazione, in modo da poter personalizzare questi valori quando si distribuisce il componente.

    • Utilizza il client IPC V2 nella versione 2 SDK per dispositivi AWS IoT per Python per comunicare con il software Core. AWS IoT Greengrass Rispetto al client IPC originale, il client IPC V2 riduce la quantità di codice da scrivere per utilizzare IPC nei componenti personalizzati.

    • Si iscrive alle notifiche di aggiornamento utilizzando l'operazione IPC. SubscribeToComponentUpdates Il software AWS IoT Greengrass Core invia notifiche prima e dopo ogni implementazione. Il componente richiama la seguente funzione ogni volta che riceve una notifica. Se la notifica riguarda una distribuzione imminente, il componente verifica se il livello della batteria è inferiore a una soglia. Se il livello della batteria è inferiore alla soglia, il componente posticipa l'aggiornamento di 30 secondi utilizzando l'operazione DeferComponentUpdateIPC. Altrimenti, se il livello della batteria non è inferiore alla soglia, il componente riconosce l'aggiornamento, quindi l'aggiornamento può procedere.

      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

      Il software AWS IoT Greengrass Core non invia notifiche di aggiornamento per le distribuzioni locali, quindi distribuisci questo componente utilizzando il servizio AWS IoT Greengrass cloud per testarlo.

  4. Utilizza un editor di testo per creare la ricetta del componente in un file denominato o. recipe.json recipe.yaml La ricetta del componente definisce i metadati del componente, i parametri di configurazione predefiniti e gli script del ciclo di vita specifici della piattaforma.

    JSON

    Ad esempio, su un sistema basato su Linux, è possibile eseguire il comando seguente per utilizzare GNU nano per creare il file.

    nano recipe.json

    Copiate il seguente codice JSON nel file.

    { "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

    Ad esempio, su un sistema basato su Linux, è possibile eseguire il comando seguente per utilizzare GNU nano per creare il file.

    nano recipe.yaml

    Copiate il seguente codice YAML nel file.

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

    Questa ricetta specifica quanto segue:

    • Parametri di configurazione predefiniti per la soglia della batteria, il percorso del file della batteria virtuale sui dispositivi core Linux e il percorso del file della batteria virtuale sui dispositivi core Windows.

    • Un install ciclo di vita che installa l'ultima versione della SDK per dispositivi AWS IoT v2 per Python.

    • Un run ciclo di vita in cui viene eseguita l'applicazione Python. main.py

    • Segnaposti, come COMPONENT_NAME eCOMPONENT_VERSION, dove la CLI GDK sostituisce le informazioni quando crea la ricetta del componente.

    Per ulteriori informazioni sulle ricette dei componenti, consulta. AWS IoT Greengrass riferimento alla ricetta del componente