기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
2단계: 업데이트가 지연되는 구성 요소 개발
이 단원에서는 코어 디바이스의 배터리 잔량이 구성 요소를 배포할 때 구성하는 임계값 미만일 때 구성 요소 업데이트가 지연되는 Python의 Hello World 구성 요소를 개발합니다. 이 구성 요소에서는 Python용 AWS IoT Device SDK v2의 프로세스 간 통신(IPC) 인터페이스를 사용합니다. 코어 디바이스에 배포가 수신될 때 SubscribeToComponentUpdates IPC 작업을 사용하여 알림을 받습니다. 그런 다음에 DeferComponentUpdate IPC 작업을 사용하여 디바이스의 배터리 잔량에 따라 업데이트를 연기하거나 승인합니다.
업데이트가 지연되는 Hello World 구성 요소를 개발하려면
-
개발 컴퓨터에서 구성 요소 소스 코드의 폴더를 생성합니다.
mkdir com.example.BatteryAwareHelloWorld cd com.example.BatteryAwareHelloWorld
-
텍스트 편집기를 사용하여
gdk-config.json
이라는 파일을 생성합니다. GDK CLI에서는gdk-config.json
라는 GDK CLI 구성 파일의 구성 요소 읽기, 빌드 및 게시가 진행됩니다. 이 구성 파일은 구성 요소 폴더의 루트에 있습니다.예를 들어 Linux 기반 시스템에서 다음 명령을 실행하면 GNU nano를 사용하여 파일을 생성할 수 있습니다.
nano gdk-config.json
다음 JSON을 파일로 복사합니다.
-
자신의 이름으로
Amazon
을 바꿉니다. -
us-west-2
를 코어 디바이스가 작동하는 AWS 리전 로 바꿉니다. GDK CLI에서는 이 AWS 리전에 구성 요소가 게시됩니다. -
사용할 S3 버킷 접두사로
greengrass-component-artifacts
를 바꿉니다. GDK CLI를 사용하여 구성 요소를 게시하면 GDK CLI는 다음 형식을 사용하여이 값, AWS 리전및 AWS 계정 ID로 이름이 구성된 S3 버킷에 구성 요소의 아티팩트를 업로드합니다
.bucketPrefix
-region
-accountId
예를 들어
greengrass-component-artifacts
및를 지정us-west-2
하고 AWS 계정 ID가 인 경우123456789012
GDK CLI는 라는 S3 버킷을 사용합니다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" }구성 파일에서 다음 구성이 지정됩니다.
-
GDK CLI가 Greengrass 구성 요소를 클라우드 서비스에 게시할 AWS IoT Greengrass 때 사용할 버전입니다.는 AWS IoT Greengrass 클라우드 서비스에서 사용할 수 있는 최신 버전 이후의 다음 패치 버전을 선택하도록
NEXT_PATCH
지정합니다. 구성 요소에 아직 AWS IoT Greengrass 클라우드 서비스에 버전이 없는 경우 GDK CLI는를 사용합니다1.0.0
. -
구성 요소의 빌드 시스템입니다.
zip
빌드 시스템을 사용하면 GDK CLI에서는 구성 요소의 단일 아티팩트가 되는 ZIP 파일로 구성 요소의 소스가 패키징됩니다. -
GDK CLI AWS 리전 가 Greengrass 구성 요소를 게시하는 입니다.
-
GDK CLI에서 구성 요소의 아티팩트가 업로드되는 S3 버킷의 접두사입니다.
-
-
텍스트 편집기를 사용하여
main.py
라는 파일에서 구성 요소 소스 코드를 생성합니다.예를 들어 Linux 기반 시스템에서 다음 명령을 실행하면 GNU nano를 사용하여 파일을 생성할 수 있습니다.
nano main.py
다음 Python 코드를 파일에 복사합니다.
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()
이 Python 애플리케이션에서는 다음이 수행됩니다.
-
나중에 코어 디바이스에서 생성할 가상 배터리 잔량 파일에서 코어 디바이스의 배터리 잔량을 읽습니다. 이 가상 배터리 잔량 파일에서는 실제 배터리가 모방되므로 배터리가 없는 코어 디바이스에서 이 자습서를 완료할 수 있습니다.
-
배터리 임계값 및 가상 배터리 잔량 파일의 경로에 대한 명령줄 인수를 읽습니다. 구성 요소 레시피에서는 구성 파라미터를 기반으로 이러한 명령줄 인수가 설정되므로 구성 요소를 배포할 때 이러한 값을 사용자 지정할 수 있습니다.
-
Python용 vV2의 IPC 클라이언트 V2를 사용하여 AWS IoT Greengrass 코어 소프트웨어와 통신합니다. AWS IoT Device SDK
원래 IPC 클라이언트에 비해 IPC 클라이언트 V2에서는 사용자 지정 구성 요소에서 IPC를 사용하려면 작성해야 할 코드 양이 감소합니다. -
SubscribeToComponentUpdates IPC 작업이 사용되는 업데이트 알림을 구독합니다. AWS IoT Greengrass 코어 소프트웨어는 각 배포 전후에 알림을 보냅니다. 구성 요소에서는 알림을 수신될 때마다 다음 함수가 직접적으로 호출됩니다. 알림이 예정된 배포용이라면 구성 요소에서는 배터리 잔량이 임계값보다 낮은지 확인됩니다. 배터리 잔량이 임계값 미만인 경우 구성 요소에서는 DeferComponentUpdate IPC 작업이 사용되어 30초 동안 업데이트가 지연됩니다. 그렇지 않으면 배터리 잔량이 임계값 미만이 아닌 경우 구성 요소에서 업데이트가 승인되므로 업데이트가 진행될 수 있습니다.
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()
참고
AWS IoT Greengrass 코어 소프트웨어는 로컬 배포에 대한 업데이트 알림을 보내지 않으므로 AWS IoT Greengrass 클라우드 서비스를 사용하여이 구성 요소를 배포하여 테스트합니다.
-
-
텍스트 편집기를 사용하여
recipe.json
또는recipe.yaml
이라는 파일에서 구성 요소 레시피를 생성합니다. 구성 요소 레시피에서는 구성 요소의 메타데이터, 기본 구성 파라미터 및 플랫폼별 수명 주기 스크립트가 정의됩니다.이 레시피에서는 다음이 지정됩니다.
-
배터리 임계값, Linux 코어 디바이스의 가상 배터리 파일 경로 및 Windows 코어 디바이스의 가상 배터리 파일 경로에 대한 기본 구성 파라미터입니다.
-
Python용 AWS IoT Device SDK v2의 최신 버전이 설치되는
install
수명 주기입니다. -
main.py
에서 Python 애플리케이션 실행되는run
수명 주기입니다. -
GDK CLI에서 구성 요소 레시피가 빌드될 때 정보가 바뀌는 자리 표시자(예:
COMPONENT_NAME
및COMPONENT_VERSION
)입니다.
구성 요소 레시피에 대한 자세한 내용은 AWS IoT Greengrass 구성 요소 레시피 참조 단원을 참조하세요.
-