쿠키 기본 설정 선택

당사는 사이트와 서비스를 제공하는 데 필요한 필수 쿠키 및 유사한 도구를 사용합니다. 고객이 사이트를 어떻게 사용하는지 파악하고 개선할 수 있도록 성능 쿠키를 사용해 익명의 통계를 수집합니다. 필수 쿠키는 비활성화할 수 없지만 '사용자 지정' 또는 ‘거부’를 클릭하여 성능 쿠키를 거부할 수 있습니다.

사용자가 동의하는 경우 AWS와 승인된 제3자도 쿠키를 사용하여 유용한 사이트 기능을 제공하고, 사용자의 기본 설정을 기억하고, 관련 광고를 비롯한 관련 콘텐츠를 표시합니다. 필수가 아닌 모든 쿠키를 수락하거나 거부하려면 ‘수락’ 또는 ‘거부’를 클릭하세요. 더 자세한 내용을 선택하려면 ‘사용자 정의’를 클릭하세요.

자습서:를 통해 로컬 IoT 디바이스와 상호 작용 MQTT

포커스 모드
자습서:를 통해 로컬 IoT 디바이스와 상호 작용 MQTT - AWS IoT Greengrass

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

이 자습서를 완료하여를 통해 코어 디바이스에 연결하는 클라이언트 디바이스라는 로컬 IoT 디바이스와 상호 작용하도록 코어 디바이스를 구성할 수 있습니다MQTT. 이 자습서에서는 클라우드 검색을 사용하여 코어 디바이스에 클라이언트 디바이스로 연결하도록 AWS IoT 사물을 구성합니다. 클라우드 검색을 구성할 때 클라이언트 디바이스는 AWS IoT Greengrass 클라우드 서비스에 요청을 보내 코어 디바이스를 검색할 수 있습니다. AWS IoT Greengrass 의 응답에는 검색하도록 클라이언트 디바이스를 구성하는 코어 디바이스에 대한 연결 정보와 인증서가 포함되어 있습니다. 그런 다음 클라이언트 디바이스는이 정보를 사용하여를 통해 통신할 수 있는 사용 가능한 코어 디바이스에 연결할 수 있습니다MQTT.

이 자습서에서는 다음을 수행합니다.

  1. 필요한 경우 코어 디바이스의 권한을 검토하고 업데이트합니다.

  2. 클라우드 검색을 사용하여 코어 디바이스를 검색할 수 있도록 클라이언트 디바이스를 코어 디바이스에 연결합니다.

  3. 클라이언트 디바이스 지원을 활성화할 Greengrass 구성 요소를 코어 디바이스를 배포합니다.

  4. 클라이언트 디바이스를 코어 디바이스에 연결하고 AWS IoT Core 클라우드 서비스와 통신을 테스트합니다.

  5. 클라이언트 디바이스와 통신하는 사용자 지정 Greengrass 구성 요소를 개발합니다.

  6. 클라이언트 디바이스의 AWS IoT 디바이스 섀도와 상호 작용하는 사용자 지정 구성 요소를 개발합니다.

이 자습서에서는 단일 코어 디바이스와 단일 클라이언트 디바이스를 사용합니다. 자습서를 따라 여러 클라이언트 디바이스를 연결하고 테스트할 수도 있습니다.

이 자습서의 예상 소요 시간은 30~60분입니다.

사전 조건

이 자습서를 완료하려면 다음이 필요합니다.

  • AWS 계정. 없으면 설정 AWS 계정 단원을 참조하세요.

  • 관리자 권한이 있는 AWS Identity and Access Management (IAM) 사용자입니다.

  • Greengrass 코어 디바이스. 코어 디바이스 설정 방법에 대한 자세한 내용은 AWS IoT Greengrass 코어 디바이스 설정 단원을 참조하세요.

    • 코어 디바이스에서 Greengrass nucleus v2.6.0 이상이 실행되어야 합니다. 이 버전에는 로컬 게시/구독 통신의 와일드카드에 대한 지원과 클라이언트 디바이스 섀도에 대한 지원이 포함되어 있습니다.

      참고

      클라이언트 디바이스 지원에는 Greengrass nucleus v2.2.0 이상이 필요합니다. 그러나이 자습서에서는 로컬 게시/구독의 MQTT 와일드카드 지원 및 클라이언트 디바이스 섀도우 지원과 같은 최신 기능을 살펴봅니다. 이러한 특성에는 Greengrass nucleus v2.6.0 이상이 필요합니다.

    • 코어 디바이스는 연결할 클라이언트 디바이스와 동일한 네트워크에 있어야 합니다.

    • (선택 사항) 사용자 지정 Greengrass 구성 요소를 개발하는 모듈을 완료하려면 코어 디바이스가 Greengrass를 실행해야 합니다CLI. 자세한 내용은 Greengrass 설치 CLI 단원을 참조하십시오.

  • 이 자습서에서 클라이언트 디바이스로 연결할 AWS IoT 항목입니다. 자세한 내용은 AWS IoT Core 개발자 안내서AWS IoT 리소스 생성을 참조하세요.

    • 클라이언트 디바이스의 AWS IoT 정책은 greengrass:Discover 권한을 허용해야 합니다. 자세한 내용은 클라이언트 디바이스에 대한 최소 AWS IoT 정책 단원을 참조하십시오.

    • 클라이언트 디바이스는 코어 디바이스와 동일한 네트워크에 있어야 합니다.

    • 클라이언트 디바이스에서 Python 3가 실행되어야 합니다.

    • 클라이언트 디바이스에서 Git이 실행되어야 합니다.

1단계: 코어 디바이스 AWS IoT 정책 검토 및 업데이트

클라이언트 디바이스를 지원하려면 코어 디바이스의 AWS IoT 정책에서 다음 권한을 허용해야 합니다.

  • greengrass:PutCertificateAuthorities

  • greengrass:VerifyClientDeviceIdentity

  • greengrass:VerifyClientDeviceIoTCertificateAssociation

  • greengrass:GetConnectivityInfo

  • greengrass:UpdateConnectivityInfo – (선택 사항)이 권한은 코어 디바이스의 네트워크 연결 정보를 AWS IoT Greengrass 클라우드 서비스에 보고하는 IP 감지기 구성 요소를 사용하는 데 필요합니다.

코어 디바이스에 대한 이러한 권한 및 AWS IoT 정책에 대한 자세한 내용은 데이터 영역 작업에 대한 AWS IoT 정책 및 섹션을 참조하세요클라이언트 디바이스가 지원되는 최소 AWS IoT 정책.

이 섹션에서는 코어 디바이스의 AWS IoT 정책을 검토하고 누락된 필수 권한을 추가합니다. AWS IoT Greengrass 코어 소프트웨어 설치 관리자를 사용하여 리소스를 프로비저닝한 경우 코어 디바이스에는 모든 AWS IoT Greengrass 작업()에 대한 액세스를 허용하는 AWS IoT 정책이 있습니다greengrass:*. 이 경우 디바이스 섀도우를 동기화하도록 섀도우 관리자 구성 요소를 구성하려는 경우에만 AWS IoT 정책을 업데이트해야 합니다 AWS IoT Core. 그렇지 않으면 이 단원으로 건너뛰어도 됩니다.

코어 디바이스의 AWS IoT 정책을 검토하고 업데이트하려면
  1. AWS IoT Greengrass 콘솔 탐색 메뉴에서 코어 디바이스를 선택합니다.

  2. 업데이트할 코어 디바이스를 코어 디바이스 페이지에서 선택합니다.

  3. 코어 디바이스 세부 정보 페이지에서 코어 디바이스의 사물에 대한 링크를 선택합니다. 이 링크를 통해 사물 세부 정보 페이지가 AWS IoT 콘솔에서 열립니다.

  4. 사물 세부 정보 페이지에서 인증서를 선택합니다.

  5. 인증서 탭에서 사물의 활성 인증서를 선택합니다.

  6. 인증서 세부 정보 페이지에서 정책을 선택합니다.

  7. 정책 탭에서 검토하고 업데이트할 AWS IoT 정책을 선택합니다. 코어 디바이스의 활성 인증서에 연결된 원하는 정책에 필수 권한을 추가할 수 있습니다.

    참고

    AWS IoT Greengrass Core 소프트웨어 설치 관리자를 사용하여 리소스를 프로비저닝한 경우 두 가지 AWS IoT 정책이 있습니다. 라는 정책을 선택하는 것이 좋습니다. GreengrassV2IoTThingPolicy존재하는 경우 . 빠른 설치 프로그램으로 생성한 코어 디바이스에서는 기본적으로 이 정책 이름이 사용됩니다. 이 정책에 권한을 추가하면 이 정책을 사용하는 다른 코어 디바이스에도 이러한 권한을 부여하는 것입니다.

  8. 정책 개요에서 활성 버전 편집을 선택합니다.

  9. 필수 권한에 대한 정책을 검토하고 누락된 필수 권한이 있으면 추가합니다.

  10. 새 정책 버전을 활성 버전으로 설정하려면 정책 버전 상태에서 편집한 버전을 이 정책의 활성 버전으로 설정을 선택합니다.

  11. 새 버전으로 저장을 선택합니다.

2단계: 클라이언트 디바이스 지원 활성화

클라우드 검색을 사용하여 코어 디바이스에 연결하는 클라이언트 디바이스를 위해 디바이스를 연결해야 합니다. 클라이언트 디바이스를 코어 디바이스에 연결하면 해당 클라이언트 디바이스에서는 코어 디바이스의 IP 주소와 인증서를 검색하여 연결에 사용할 수 있게 됩니다.

클라이언트 디바이스가 코어 디바이스에 안전하게 연결하고 Greengrass 구성 요소와 통신할 수 있도록 하려면 다음 Greengrass 구성 요소를 코어 디바이스에 배포 AWS IoT Core합니다.

  • 클라이언트 디바이스 인증 (aws.greengrass.clientdevices.Auth)

    클라이언트 디바이스를 인증하고 클라이언트 디바이스 작업을 승인할 클라이언트 디바이스 인증 구성 요소를 배포합니다. 이 구성 요소를 사용하면 AWS IoT 사물을 코어 디바이스에 연결할 수 있습니다.

    이 구성 요소를 사용하려면 몇 가지 구성이 필요합니다. 를 통해 연결 및 통신하는 등 각 그룹이 수행할 수 있는 클라이언트 디바이스 그룹과 작업을 지정해야 합니다MQTT. 자세한 내용은 클라이언트 디바이스 인증 구성 요소 구성을 참조하세요.

  • MQTT 3.1.1 브로커(Moquette) (aws.greengrass.clientdevices.mqtt.Moquette)

    Moquette MQTT브로커 구성 요소를 배포하여 경량 MQTT브로커를 실행합니다. Moquette MQTT브로커는 MQTT 3.1.1을 준수하며 QoS 0, QoS QoS 1, QoS 2, 보존된 메시지, last will 메시지 및 영구 구독에 대한 로컬 지원을 포함합니다.

    이 구성 요소는 구성하지 않아도 사용할 수 있습니다. 그러나이 구성 요소가 MQTT브로커를 작동하는 포트를 구성할 수 있습니다. 기본적으로 포트 8883이 사용됩니다.

  • MQTT 브리지 (aws.greengrass.clientdevices.mqtt.Bridge)

    (선택 사항) MQTT 브리지 구성 요소를 배포하여 클라이언트 디바이스(로컬 MQTT), 로컬 게시/구독 및 간에 메시지를 릴레이합니다 AWS IoT Core MQTT. 클라이언트 디바이스를 Greengrass 구성 요소의 클라이언트 디바이스와 동기화 AWS IoT Core 하고 상호 작용하도록이 구성 요소를 구성합니다.

    이 구성 요소는 구성하지 않아도 사용할 수 있습니다. 이 구성 요소에서 메시지를 릴레이하는 주제 매핑을 지정해야 합니다. 자세한 내용은 MQTT 브리지 구성 요소 구성을 참조하세요.

  • IP 감지기 (aws.greengrass.clientdevices.IPDetector)

    (선택 사항) 코어 디바이스의 MQTT브로커 엔드포인트를 AWS IoT Greengrass 클라우드 서비스에 자동으로 보고하도록 IP 감지기 구성 요소를 배포합니다. 라우터가 MQTT브로커 포트를 코어 디바이스로 전달하는 네트워크 설정과 같이 복잡한 네트워크 설정이 있는 경우이 구성 요소를 사용할 수 없습니다.

    이 구성 요소는 구성하지 않아도 사용할 수 있습니다.

이 섹션에서는 AWS IoT Greengrass 콘솔을 사용하여 클라이언트 디바이스를 연결하고 클라이언트 디바이스 구성 요소를 코어 디바이스에 배포합니다.

클라이언트 디바이스 지원을 활성화하려면
  1. 왼쪽 탐색 메뉴에서 코어 디바이스를 선택합니다.

  2. 클라이언트 디바이스 지원을 활성화하려는 코어 디바이스를 코어 디바이스 페이지에서 선택합니다.

  3. 코어 디바이스 세부 정보 페이지에서 클라이언트 디바이스 탭을 선택합니다.

  4. 클라이언트 디바이스 탭에서 클라우드 검색 구성을 선택합니다.

    코어 디바이스 검색 구성 페이지가 열립니다. 이 페이지에서 클라이언트 디바이스를 코어 디바이스에 연결하고 클라이언트 디바이스 구성 요소를 배포할 수 있습니다. 이 페이지의 1단계: 대상 코어 디바이스 선택에서는 코어 디바이스가 자동으로 선택됩니다.

    참고

    이 페이지를 사용하여 사물 그룹에 대한 코어 디바이스 검색을 구성할 수도 있습니다. 이 옵션을 선택하면 사물 그룹의 모든 코어 디바이스에 클라이언트 디바이스 구성 요소를 배포할 수 있습니다. 그러나 이 옵션을 선택하는 경우 나중에 배포를 생성하면 각 코어 디바이스에 수동으로 클라이언트 디바이스를 연결해야 합니다. 이 자습서에서는 단일 코어 디바이스를 구성합니다.

  5. 2단계: 클라이언트 디바이스 연결에서 클라이언트 디바이스의 AWS IoT 사물을 코어 디바이스에 연결합니다. 그러면 클라이언트 디바이스에서는 클라우드 검색을 사용하여 코어 디바이스의 연결 정보와 인증서를 검색할 수 있습니다. 다음을 수행합니다.

    1. 클라이언트 디바이스 연결을 선택합니다.

    2. 클라이언트 디바이스를 코어 디바이스 모달과 연결에 연결할 AWS IoT 사물의 이름을 입력합니다.

    3. 추가를 선택합니다.

    4. 연결을 선택합니다.

  6. 3단계: Greengrass 구성 요소 구성 및 연결에서 구성 요소를 배포하여 클라이언트 디바이스 지원을 활성화합니다. 대상 코어 디바이스에 이전 배포가 있으면 이 페이지에서 해당 배포가 수정됩니다. 그렇지 않으면 이 페이지에서 코어 디바이스에 대한 새 배포가 생성됩니다. 다음을 수행하여 클라이언트 디바이스 구성 요소를 구성하고 배포합니다.

    1. 이 자습서를 완료하려면 코어 디바이스에서 Greengrass nucleus v2.6.0 이상이 실행되어야 합니다. 코어 디바이스에서 이전 버전이 실행되는 경우 다음을 수행합니다.

      1. 상자를 선택하여를 배포합니다. aws.greengrass.Nucleus 구성 요소입니다.

      2. 의 경우 aws.greengrass.Nucleus 구성 요소에서 구성 편집을 선택합니다.

      3. 구성 요소 버전에는 버전 2.6.0 이상을 선택합니다.

      4. 확인을 선택합니다.

      참고

      이전 마이너 버전에서 Greengrass 핵을 업그레이드하고 코어 디바이스가 핵에 따라 AWS제공되는 구성 요소를 실행하는 경우 AWS제공된 구성 요소도 최신 버전으로 업데이트해야 합니다. 이 자습서의 뒷부분에서 배포를 검토할 때 이러한 구성 요소의 버전을 구성할 수 있습니다. 자세한 내용은 AWS IoT Greengrass 코어 소프트웨어(OTA) 업데이트 단원을 참조하십시오.

    2. 의 경우 aws.greengrass.clientdevices.Auth 구성 요소에서 구성 편집을 선택합니다.

    3. 클라이언트 디바이스 인증 구성 요소에 대한 구성 모달 편집에서 클라이언트 디바이스가 코어 디바이스의 MQTT브로커를 게시하고 구독할 수 있도록 허용하는 권한 부여 정책을 구성합니다. 다음을 수행합니다.

      1. 구성에서 클라이언트 디바이스 권한 부여 정책이 있는 다음 구성을 병할할 구성 코드 블록에 입력합니다. 각 디바이스 그룹 권한 부여 정책을 통해 작업 세트 및 클라이언트 디바이스에서 해당 작업을 수행할 수 있는 리소스가 지정됩니다.

        • 이 정책은 이름이 로 시작하는 클라이언트 디바이스가 모든 MQTT 주제에 대해 연결하고 통신MyClientDevice할 수 있도록 허용합니다. MyClientDevice*를 클라이언트 디바이스로 연결할 사물의 AWS IoT 이름으로 바꿉니다. 클라이언트 디바이스의 이름과 일치하는 * 와일드카드가 포함된 이름을 지정할 수도 있습니다. * 와일드카드는 이름 끝에 있어야 합니다.

          연결할 두 번째 클라이언트 디바이스가 있는 경우를 해당 클라이언트 디바이스의 이름 또는 해당 클라이언트 디바이스의 이름과 일치하는 와일드카드 패턴MyOtherClientDevice*으로 바꿉니다. 그렇지 않으면 MyOtherClientDevice*와 이름이 일치하는 클라이언트 디바이스에 연결과 통신을 허용하는 선택 규칙의 이 단원을 제거하거나 유지할 수 있습니다.

        • 이 정책은 OR 연산자를 사용하여 이름이 로 시작하는 클라이언트 디바이스가 모든 MQTT 주제에 대해 연결하고 통신MyOtherClientDevice하도록 허용합니다. 이 절을 선택 규칙에서 제거하거나 연결할 클라이언트 디바이스와 일치하도록 수정할 수 있습니다.

        • 이 정책은 클라이언트 디바이스가 모든 MQTT 주제를 게시하고 구독하도록 허용합니다. 보안 모범 사례를 따르려면 클라이언트 디바이스에서 통신에 사용하는 주제의 최소 세트로 mqtt:publishmqtt:subscribe 작업을 제한합니다.

        { "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": [ "*" ] } } } } }

        자세한 내용은 클라이언트 디바이스 인증 구성 요소 구성을 참조하세요.

      2. 확인을 선택합니다.

    4. 의 경우 aws.greengrass.clientdevices.mqtt.Bridge 구성 요소에서 구성 편집을 선택합니다.

    5. MQTT 브리지 구성 요소에 대한 구성 편집 모달에서 클라이언트 디바이스에서 로 MQTT 메시지를 전달하는 주제 매핑을 구성합니다 AWS IoT Core. 다음을 수행합니다.

      1. 구성에서 다음 구성을 병합할 구성 코드 블록에 입력합니다. 이 구성은 클라이언트 디바이스에서 AWS IoT Core 클라우드 서비스로 clients/+/hello/world 주제 필터의 MQTT 메시지를 릴레이하도록 지정합니다. 예를 들어 이 주제 필터는 clients/MyClientDevice1/hello/world 주제와 일치합니다.

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

        자세한 내용은 MQTT 브리지 구성 요소 구성을 참조하세요.

      2. 확인을 선택합니다.

  7. 검토 및 배포를 선택하여 이 페이지에서 자동으로 생성되는 배포를 검토합니다.

  8. 이전에 이 리전의 Greengrass 서비스 역할을 설정한 적이 없으면 서비스 역할을 자동으로 설정하는 모달이 콘솔에서 열립니다. 클라이언트 디바이스 인증 구성 요소에서는 이 서비스 역할을 사용하여 클라이언트 디바이스의 ID를 확인하고, IP 감지기 구성 요소에서는 이 서비스 역할을 사용하여 코어 디바이스 연결 정보를 관리합니다. 권한 부여를 선택합니다.

  9. 검토 페이지에서 배포를 선택하여 코어 디바이스로 배포를 시작합니다.

  10. 배포에 성공했는지 확인하려면 배포 상태를 확인하고 코어 디바이스에 대한 로그를 확인합니다. 코어 디바이스에서 배포 상태를 확인하려면 배포 개요에서 대상을 선택하면 됩니다. 자세한 내용은 다음을 참조하세요.

3단계: 클라이언트 디바이스 연결

클라이언트 디바이스는를 사용하여 코어 디바이스를 검색, 연결 및 통신 AWS IoT Device SDK 할 수 있습니다. 클라이언트 디바이스는 AWS IoT 사물이어야 합니다. 자세한 내용은 AWS IoT Core 개발자 안내서사물 객체 생성을 참조하세요.

이 단원에서는 Python용AWS IoT Device SDK v2를 설치하고 AWS IoT Device SDK의 Greengrass 검색 샘플 애플리케이션을 실행합니다.

참고

AWS IoT Device SDK 는 다른 프로그래밍 언어로도 사용할 수 있습니다. 이 자습서에서는 Python용 AWS IoT Device SDK v2를 사용하지만 사용 사례에 SDKs 대해 다른 자습서를 살펴볼 수 있습니다. 자세한 내용은 AWS IoT Core 개발자 안내서AWS IoT 디바이스SDKs를 참조하세요.

클라이언트 디바이스를 코어 디바이스에 연결하려면
  1. 클라이언트 디바이스로 연결할 AWS IoT 사물에 AWS IoT Device SDK Python용 v2를 다운로드하여 설치합니다.

    클라이언트 디바이스에서 다음을 수행합니다.

    1. AWS IoT Device SDK v2 for Python 리포지토리를 복제하여 다운로드합니다.

      git clone https://github.com/aws/aws-iot-device-sdk-python-v2.git
    2. Python용 AWS IoT Device SDK v2를 설치합니다.

      python3 -m pip install --user ./aws-iot-device-sdk-python-v2
  2. AWS IoT Device SDK v2 for Python의 샘플 폴더로 변경합니다.

    cd aws-iot-device-sdk-python-v2/samples
  3. 샘플 Greengrass 검색 애플리케이션을 실행합니다. 이 애플리케이션은 클라이언트 디바이스 사물 이름, 사용할 MQTT 주제 및 메시지, 연결을 인증하고 보호하는 인증서를 지정하는 인수를 기대합니다. 다음 예제에서는 Hello World라는 메시지를 clients/MyClientDevice1/hello/world 주제로 보냅니다.

    참고

    이 주제는 메시지를 AWS IoT Core 이전에 릴레이하도록 MQTT 브리지를 구성한 주제와 일치합니다.

    • MyClientDevice1를 클라이언트 디바이스의 사물 이름으로 바꿉니다.

    • 를 클라이언트 디바이스의 Amazon 루트 CA 인증서 경로~/certs/AmazonRootCA1.pem로 바꿉니다.

    • 를 클라이언트 디바이스의 디바이스 인증서 경로~/certs/device.pem.crt로 바꿉니다.

    • 를 클라이언트 디바이스의 프라이빗 키 파일 경로~/certs/private.pem.key로 바꿉니다.

    • 를 클라이언트 디바이스와 코어 디바이스가 작동하는 AWS 리전us-east-1으로 바꿉니다.

    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

    검색 샘플 애플리케이션은 메시지를 10회 전송하고 연결을 해제합니다. 또한 메시지를 게시하는 주제와 동일한 주제를 구독합니다. 출력에서 애플리케이션이 주제에 대한 MQTT 메시지를 수신했음을 나타내는 경우 클라이언트 디바이스는 코어 디바이스와 성공적으로 통신할 수 있습니다.

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

    그 대신에 애플리케이션에서 오류가 출력되면 Greengrass 검색 문제 해결을 참조하세요.

    코어 디바이스에서 Greengrass 로그를 보고 클라이언트 디바이스가 메시지를 성공적으로 연결하고 전송하는지 확인할 수도 있습니다. 자세한 내용은 AWS IoT Greengrass 로그 모니터링 단원을 참조하십시오.

  4. MQTT 브리지가 클라이언트 디바이스의 메시지를 로 릴레이하는지 확인합니다 AWS IoT Core. AWS IoT Core 콘솔에서 MQTT 테스트 클라이언트를 사용하여 MQTT 주제 필터를 구독할 수 있습니다. 다음을 수행합니다.

    1. AWS IoT 콘솔로 이동합니다.

    2. 왼쪽 탐색 메뉴의 테스트에서 MQTT 테스트 클라이언트를 선택합니다.

    3. 주제 구독 탭에서 주제 필터에 대해 코어 디바이스의 클라이언트 디바이스 메시지를 구독할 clients/+/hello/world을 입력합니다.

    4. 구독을 선택합니다.

    5. 다시 클라이언트 디바이스에서 게시/구독 애플리케이션을 실행합니다.

      MQTT 테스트 클라이언트는이 주제 필터와 일치하는 주제에 대해 클라이언트 디바이스에서 보내는 메시지를 표시합니다.

4단계: 클라이언트 디바이스와 통신하는 구성 요소를 개발합니다.

클라이언트 디바이스와 통신하는 Greengrass 구성 요소를 개발할 수 있습니다. 구성 요소는 프로세스 간 통신(IPC)로컬 게시/구독 인터페이스를 사용하여 코어 디바이스에서 통신합니다. 클라이언트 디바이스와 상호 작용하려면 클라이언트 디바이스와 로컬 게시/구독 인터페이스 간에 메시지를 릴레이하도록 MQTT 브리지 구성 요소를 구성합니다.

이 섹션에서는 MQTT 브리지 구성 요소를 업데이트하여 클라이언트 디바이스의 메시지를 로컬 게시/구독 인터페이스로 릴레이합니다. 그런 다음에 이러한 메시지를 구독하고 수신 시 메시지를 인쇄하는 구성 요소를 개발합니다.

클라이언트 디바이스와 통신하는 구성 요소를 개발하려면
  1. 코어 디바이스에 대한 배포를 수정하고 클라이언트 디바이스에서 로컬 게시/구독으로 메시지를 릴레이하도록 MQTT 브리지 구성 요소를 구성합니다. 다음을 수행합니다.

    1. 왼쪽 탐색 메뉴에서 코어 디바이스를 선택합니다.

    2. 코어 디바이스 페이지에서 이 자습서에 사용하는 코어 디바이스를 선택합니다.

    3. 코어 디바이스 세부 정보 페이지에서 클라이언트 디바이스 탭을 선택합니다.

    4. 클라이언트 디바이스 탭에서 클라우드 검색 구성을 선택합니다.

      코어 디바이스 검색 구성 페이지가 열립니다. 이 페이지에서 코어 디바이스에 배포되는 클라이언트 디바이스 구성 요소를 변경하거나 구성할 수 있습니다.

    5. 3단계에서 의 경우 aws.greengrass.clientdevices.mqtt.Bridge 구성 요소에서 구성 편집을 선택합니다.

    6. MQTT 브리지 구성 요소에 대한 구성 편집 모달에서 클라이언트 디바이스의 MQTT 메시지를 로컬 게시/구독 인터페이스로 전달하는 주제 매핑을 구성합니다. 다음을 수행합니다.

      1. 구성에서 다음 구성을 병합할 구성 코드 블록에 입력합니다. 이 구성은 클라이언트 디바이스의 주제 필터와 일치하는 clients/+/hello/world 주제에 대한 MQTT 메시지를 AWS IoT Core 클라우드 서비스 및 로컬 Greengrass 게시/구독 브로커에 전달하도록 지정합니다.

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

        자세한 내용은 MQTT 브리지 구성 요소 구성을 참조하세요.

      2. 확인을 선택합니다.

    7. 검토 및 배포를 선택하여 이 페이지에서 자동으로 생성되는 배포를 검토합니다.

    8. 검토 페이지에서 배포를 선택하여 코어 디바이스로 배포를 시작합니다.

    9. 배포에 성공했는지 확인하려면 배포 상태를 확인하고 코어 디바이스에 대한 로그를 확인합니다. 코어 디바이스에서 배포 상태를 확인하려면 배포 개요에서 대상을 선택하면 됩니다. 자세한 내용은 다음을 참조하세요.

  2. 클라이언트 디바이스의 Hello World 메시지를 구독하는 Greengrass 구성 요소를 개발하고 배포합니다. 다음을 수행합니다.

    1. 코어 디바이스에서 레시피 및 아티팩트 폴더를 생성합니다.

      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
      mkdir recipes mkdir -p artifacts/com.example.clientdevices.MyHelloWorldSubscriber/1.0.0
      중요

      아티팩트 폴더 경로에 다음 형식을 사용해야 합니다. 레시피에서 지정하는 구성 요소 이름과 버전을 포함합니다.

      artifacts/componentName/componentVersion/
    2. 텍스트 편집기를 사용하여 다음 내용으로 레시피를 생성합니다. 이 레시피는 AWS IoT Device SDK v2 for Python을 설치하고 주제를 구독하고 메시지를 인쇄하는 스크립트를 실행하도록 지정합니다.

      예를 들어 Linux 기반 시스템에서 다음 명령을 실행하여 GNU 나노를 사용하여 파일을 생성할 수 있습니다.

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

      다음 레시피를 파일에 복사합니다.

      { "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" } } ] }
    3. 텍스트 편집기를 사용하여 다음 내용이 있는 hello_world_subscriber.py라는 Python 스크립트 아티팩트를 생성합니다. 이 애플리케이션은 게시/구독 IPC 서비스를 사용하여 clients/+/hello/world 주제를 구독하고 수신하는 메시지를 인쇄합니다.

      예를 들어 Linux 기반 시스템에서 다음 명령을 실행하여 GNU 나노를 사용하여 파일을 생성할 수 있습니다.

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

      다음 Python 코드를 파일에 복사합니다.

      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)
      참고

      이 구성 요소는 Python용 vV2의 IPC 클라이언트 V2를 사용하여 AWS IoT Greengrass 코어 소프트웨어와 통신합니다. AWS IoT Device SDK IPC 클라이언트 V2는 원래 IPC 클라이언트와 비교하여 사용자 지정 구성 IPC 요소에 사용하기 위해 작성해야 하는 코드의 양을 줄입니다.

    4. Greengrass를 사용하여 구성 요소를 CLI 배포합니다.

      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"
      sudo /greengrass/v2/bin/greengrass-cli deployment create \ --recipeDir recipes \ --artifactDir artifacts \ --merge "com.example.clientdevices.MyHelloWorldSubscriber=1.0.0"
  3. 구성 요소 로그를 보며 구성 요소가 설치되고 주제가 구독되는지 확인합니다.

    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
    sudo tail -f /greengrass/v2/logs/com.example.clientdevices.MyHelloWorldSubscriber.log

    로그 피드를 열어놓고 코어 디바이스에서 메시지가 수신되는지 확인할 수 있습니다.

  4. 클라이언트 디바이스에서 다시 샘플 Greengrass 검색 애플리케이션을 실행하여 코어 디바이스로 메시지를 보냅니다.

    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
  5. 다시 구성 요소 로그를 보며 구성 요소에서 클라이언트 디바이스의 메시지가 수신되고 인쇄되는지 확인합니다.

    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
    sudo tail -f /greengrass/v2/logs/com.example.clientdevices.MyHelloWorldSubscriber.log

5단계: 클라이언트 디바이스 섀도와 상호 작용하는 구성 요소를 개발합니다.

클라이언트 디바이스의 AWS IoT 디바이스 섀도와 상호 작용하는 Greengrass 구성 요소를 개발할 수 있습니다. 섀도우는 클라이언트 디바이스와 같은 AWS IoT 사물에 대한 현재 또는 원하는 상태 정보를 저장하는 JSON 문서입니다. 사용자 지정 구성 요소에서는 클라이언트 디바이스가 AWS IoT에 연결되지 않았더라도 클라이언트 디바이스의 섀도에 액세스하여 해당 상태를 관리할 수 있습니다. 각 AWS IoT 사물에는 이름이 지정되지 않은 섀도우가 있으며, 각 사물에 대해 여러 개의 명명된 섀도우를 생성할 수도 있습니다.

이 단원에서는 코어 디바이스에서 섀도를 관리할 섀도 관리자 구성 요소를 배포합니다. 또한 MQTT 브리지 구성 요소를 업데이트하여 클라이언트 디바이스와 섀도우 관리자 구성 요소 간에 섀도우 메시지를 릴레이합니다. 그런 다음에 클라이언트 디바이스의 섀도가 업데이트되는 구성 요소를 개발하고, 구성 요소의 섀도 업데이트에 응답하는 클라이언트 디바이스에 샘플 애플리케이션을 실행할 수 있습니다. 이 구성 요소는 클라이언트 디바이스로 연결되는 스마트 조명의 색상 상태를 코어 디바이스에서 관리하는 스마트 조명 관리 애플리케이션을 나타냅니다.

클라이언트 디바이스 섀도와 상호 작용하는 구성 요소를 개발하려면
  1. 코어 디바이스에 대한 배포를 수정하여 섀도우 관리자 구성 요소를 배포하고 섀도우 관리자가 통신하는 클라이언트 디바이스와 로컬 게시/구독 간에 섀도우 메시지를 전달하도록 MQTT 브리지 구성 요소를 구성합니다. 다음을 수행합니다.

    1. 왼쪽 탐색 메뉴에서 코어 디바이스를 선택합니다.

    2. 코어 디바이스 페이지에서 이 자습서에 사용하는 코어 디바이스를 선택합니다.

    3. 코어 디바이스 세부 정보 페이지에서 클라이언트 디바이스 탭을 선택합니다.

    4. 클라이언트 디바이스 탭에서 클라우드 검색 구성을 선택합니다.

      코어 디바이스 검색 구성 페이지가 열립니다. 이 페이지에서 코어 디바이스에 배포되는 클라이언트 디바이스 구성 요소를 변경하거나 구성할 수 있습니다.

    5. 3단계에서 의 경우 aws.greengrass.clientdevices.mqtt.Bridge 구성 요소에서 구성 편집을 선택합니다.

    6. MQTT 브리지 구성 요소에 대한 구성 모달 편집에서 클라이언트 디바이스와 로컬 게시/구독 인터페이스 간에 디바이스 섀도우 주제에 MQTT 메시지를 전달하는 주제 매핑을 구성합니다. https://docs.aws.amazon.com/iot/latest/developerguide/reserved-topics.html#reserved-topics-shadow 또한 배포가 호환되는 MQTT 브리지 버전을 지정하는지 확인합니다. 클라이언트 디바이스 섀도우 지원에는 MQTT 브리지 v2.2.0 이상이 필요합니다. 다음을 수행합니다.

      1. 구성 요소 버전에는 버전 2.2.0 이상을 선택합니다.

      2. 구성에서 다음 구성을 병합할 구성 코드 블록에 입력합니다. 이 구성은 섀도우 주제에 MQTT 메시지를 릴레이하도록 지정합니다.

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

        자세한 내용은 MQTT 브리지 구성 요소 구성을 참조하세요.

      3. 확인을 선택합니다.

    7. 3단계에서 aws.greengrass.ShadowManager 배포하기 위한 구성 요소입니다.

    8. 검토 및 배포를 선택하여 이 페이지에서 자동으로 생성되는 배포를 검토합니다.

    9. 검토 페이지에서 배포를 선택하여 코어 디바이스로 배포를 시작합니다.

    10. 배포에 성공했는지 확인하려면 배포 상태를 확인하고 코어 디바이스에 대한 로그를 확인합니다. 코어 디바이스에서 배포 상태를 확인하려면 배포 개요에서 대상을 선택하면 됩니다. 자세한 내용은 다음을 참조하세요.

  2. 스마트 조명 클라이언트 디바이스를 관리하는 Greengrass 구성 요소를 개발하고 배포합니다. 다음을 수행합니다.

    1. 코어 디바이스에서 구성 요소의 아티팩트 폴더를 생성합니다.

      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
      mkdir -p artifacts/com.example.clientdevices.MySmartLightManager/1.0.0
      중요

      아티팩트 폴더 경로에 다음 형식을 사용해야 합니다. 레시피에서 지정하는 구성 요소 이름과 버전을 포함합니다.

      artifacts/componentName/componentVersion/
    2. 텍스트 편집기를 사용하여 다음 내용으로 레시피를 생성합니다. 이 레시피는 Python용 AWS IoT Device SDK v2를 설치하고 스마트 라이트 클라이언트 디바이스의 섀도우와 상호 작용하는 스크립트를 실행하여 색상을 관리하도록 지정합니다.

      예를 들어 Linux 기반 시스템에서 다음 명령을 실행하여 GNU 나노를 사용하여 파일을 생성할 수 있습니다.

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

      다음 레시피를 파일에 복사합니다.

      { "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" } } ] }
    3. 텍스트 편집기를 사용하여 다음 내용이 있는 smart_light_manager.py라는 Python 스크립트 아티팩트를 생성합니다. 이 애플리케이션은 섀도우 IPC 서비스를 사용하여 클라이언트 디바이스 섀도우를 가져오고 업데이트하며, 로컬 게시/구독 IPC 서비스를 사용하여 보고된 섀도우 업데이트를 수신합니다.

      예를 들어 Linux 기반 시스템에서 다음 명령을 실행하여 GNU 나노를 사용하여 파일을 생성할 수 있습니다.

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

      다음 Python 코드를 파일에 복사합니다.

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

      이 Python 애플리케이션에서는 다음을 수행합니다.

      • 구성 요소의 구성을 읽으며 관리할 스마트 조명 클라이언트 디바이스의 목록을 가져옵니다.

      • SubscribeToConfigurationUpdate IPC 작업을 사용하여 구성 업데이트 알림을 구독합니다. AWS IoT Greengrass 코어 소프트웨어는 구성 요소의 구성이 변경될 때마다 알림을 보냅니다. 구성 요소에서는 구성 업데이트 알림을 받으면 관리하는 스마트 조명 클라이언트 디바이스의 목록을 업데이트합니다.

      • 초기 색상 상태를 가져올 각 스마트 조명 클라이언트 디바이스의 섀도를 가져옵니다.

      • 15초마다 각 스마트 조명 클라이언트 디바이스의 색상을 무작위 색상으로 설정합니다. 구성 요소에서는 클라이언트 디바이스의 사물 섀도를 업데이트하여 색상을 변경합니다. 이 작업은를 통해 클라이언트 디바이스로 섀도우 델타 이벤트를 전송합니다MQTT.

      • SubscribeToTopic IPC 작업을 사용하여 로컬 게시/구독 인터페이스에서 수락된 메시지를 섀도우 업데이트하도록 구독합니다. 이 구성 요소에서는 이러한 메시지를 받아서 각 스마트 조명 클라이언트 디바이스의 색상을 추적합니다. 스마트 라이트 클라이언트 디바이스가 섀도우 업데이트를 수신하면 업데이트를 수신했음을 확인하는 MQTT 메시지를 보냅니다. MQTT 브리지는이 메시지를 로컬 게시/구독 인터페이스에 릴레이합니다.

    4. Greengrass를 사용하여 구성 요소를 CLI 배포합니다. 이 구성 요소를 배포할 때 섀도를 관리하는 클라이언트 디바이스 목록(smartLightDeviceNames)을 지정합니다. MyClientDevice1를 클라이언트 디바이스의 사물 이름으로 바꿉니다.

      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" ] } } }'
      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" ] } } }'
  3. 구성 요소 로그를 보며 구성 요소가 설치되고 실행되는지 확인합니다.

    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
    sudo tail -f /greengrass/v2/logs/com.example.clientdevices.MySmartLightManager.log

    구성 요소에서는 스마트 조명 클라이언트 디바이스의 색상을 변경하라는 요청을 보냅니다. 섀도 관리자에서는 요청을 받고 섀도의 desired 상태를 설정합니다. 그러나 스마트 조명 클라이언트 디바이스가 아직 실행되지 않으므로 섀도의 reported 상태가 변경되지 않습니다. 구성 요소의 로그에는 다음 메시지가 포함되어 있습니다.

    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}

    로그 피드를 열어놓고 언제 구성 요소에서 메시지가 인쇄되는지 참조할 수 있습니다.

  4. Greengrass 검색을 사용하고 디바이스 섀도 업데이트를 구독하는 샘플 애플리케이션을 다운로드하고 실행합니다. 클라이언트 디바이스에서 다음을 수행합니다.

    1. Python용 AWS IoT Device SDK v2의 샘플 폴더로 변경합니다. 이 샘플 애플리케이션에서는 샘플 폴더의 명령줄 구문 분석 모듈을 사용합니다.

      cd aws-iot-device-sdk-python-v2/samples
    2. 텍스트 편집기를 사용하여 다음 내용이 있는 basic_discovery_shadow.py라는 Python 스크립트를 생성합니다. 이 애플리케이션에서는 Greengrass 검색과 섀도를 사용하여 클라이언트 디바이스와 코어 디바이스 사이에 속성을 동기화 상태로 유지합니다.

      예를 들어 Linux 기반 시스템에서 다음 명령을 실행하여 GNU 나노를 사용하여 파일을 생성할 수 있습니다.

      nano basic_discovery_shadow.py

      다음 Python 코드를 파일에 복사합니다.

      # 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 # Parse arguments import utils.command_line_utils; cmdUtils = utils.command_line_utils.CommandLineUtils("Basic Discovery - Greengrass discovery example with device shadows.") cmdUtils.add_common_mqtt_commands() cmdUtils.add_common_topic_message_commands() cmdUtils.add_common_logging_commands() cmdUtils.register_command("key", "<path>", "Path to your key in PEM format.", True, str) cmdUtils.register_command("cert", "<path>", "Path to your client certificate in PEM format.", True, str) cmdUtils.remove_command("endpoint") cmdUtils.register_command("thing_name", "<str>", "The name assigned to your IoT Thing", required=True) cmdUtils.register_command("region", "<str>", "The region to connect through.", required=True) cmdUtils.register_command("shadow_property", "<str>", "The name of the shadow property you want to change (optional, default='color'", default="color") # Needs to be called so the command utils parse the commands cmdUtils.get_args() # Using globals to simplify sample code is_sample_done = threading.Event() mqtt_connection = None shadow_thing_name = cmdUtils.get_command_required("thing_name") shadow_property = cmdUtils.get_command("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=cmdUtils.get_command_required("cert"), pri_key_filepath=cmdUtils.get_command_required("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=cmdUtils.get_command_required("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(cmdUtils.get_command_required("cert"), cmdUtils.get_command_required("key")) if cmdUtils.get_command(cmdUtils.m_cmd_ca_file): tls_options.override_default_trust_store_from_path(None, cmdUtils.get_command(cmdUtils.m_cmd_ca_file)) 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, cmdUtils.get_command_required("region")) resp_future = discovery_client.discover(cmdUtils.get_command_required("thing_name")) discover_response = resp_future.result() print(discover_response) if cmdUtils.get_command("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()

      이 Python 애플리케이션에서는 다음을 수행합니다.

      • Greengrass 검색을 사용하여 검색하고 코어 디바이스에 연결합니다.

      • 코어 디바이스에 섀도 문서를 요청하여 속성의 초기 상태를 가져옵니다.

      • 속성의 desired 값이 자체 reported 값과 다를 때 코어 디바이스에서 보내는 섀도 델타 이벤트를 구독합니다. 애플리케이션에서는 섀도 델타 이벤트를 받으면 속성의 값을 변경하고 해당 reported 값으로 새 값을 설정할 코어 디바이스로 업데이트를 보냅니다.

      이 애플리케이션에서는 Greengrass 검색과 AWS IoT Device SDK v2의 섀도 샘플을 결합합니다.

    3. 샘플 애플리케이션을 실행합니다. 이 애플리케이션에는 클라이언트 디바이스 사물 이름, 사용할 섀도 속성, 연결을 인증하고 보호하는 인증서를 지정하는 인수가 필요합니다.

      • MyClientDevice1를 클라이언트 디바이스의 사물 이름으로 바꿉니다.

      • 를 클라이언트 디바이스의 Amazon 루트 CA 인증서 경로~/certs/AmazonRootCA1.pem로 바꿉니다.

      • 를 클라이언트 디바이스의 디바이스 인증서 경로~/certs/device.pem.crt로 바꿉니다.

      • 를 클라이언트 디바이스의 프라이빗 키 파일 경로~/certs/private.pem.key로 바꿉니다.

      • 를 클라이언트 디바이스와 코어 디바이스가 작동하는 AWS 리전us-east-1으로 바꿉니다.

      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

      샘플 애플리케이션에서는 섀도 주제를 구독하며 코어 디바이스의 섀도 델타 이벤트를 받을 때까지 기다립니다. 애플리케이션에서 섀도 델타 이벤트를 받고 응답하는 것으로 출력에 나타나면 클라이언트 디바이스에서는 코어 디바이스의 섀도와 상호 작용할 수 있습니다.

      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.

      그 대신에 애플리케이션에서 오류가 출력되면 Greengrass 검색 문제 해결을 참조하세요.

      코어 디바이스에서 Greengrass 로그를 보고 클라이언트 디바이스가 메시지를 성공적으로 연결하고 전송하는지 확인할 수도 있습니다. 자세한 내용은 AWS IoT Greengrass 로그 모니터링 단원을 참조하십시오.

  5. 다시 구성 요소 로그를 보며 구성 요소에서 스마트 조명 클라이언트 디바이스의 섀도 업데이트 확인을 받는지 확인합니다.

    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
    sudo tail -f /greengrass/v2/logs/com.example.clientdevices.MySmartLightManager.log

    구성 요소에서는 스마트 조명 클라이언트 디바이스의 색상이 변경되었다는 것이 확인되는 메시지를 로그에 남깁니다.

    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}
참고

코어 디바이스와 클라이언트 디바이스 사이에 클라이언트 디바이스의 섀도가 동기화됩니다. 그러나 코어 디바이스는 클라이언트 디바이스의 섀도우를와 동기화하지 않습니다 AWS IoT Core. 예를 들어 섀도우를와 동기화 AWS IoT Core 하여 플릿에 있는 모든 디바이스의 상태를 보거나 수정할 수 있습니다. 섀도우를 동기화하도록 섀도우 관리자 구성 요소를 구성하는 방법에 대한 자세한 내용은 섹션을 AWS IoT Core참조하세요로컬 디바이스 섀도우를 AWS IoT Core와 동기화.

이 자습서를 완료했습니다. 클라이언트 디바이스는 코어 디바이스에 연결하고, AWS IoT Core 및 Greengrass 구성 요소로 MQTT 메시지를 보내고, 코어 디바이스로부터 섀도우 업데이트를 수신합니다. 이 자습서에서 다룬 주제에 대한 자세한 내용은 다음을 참조하세요.

프라이버시사이트 이용 약관쿠키 기본 설정
© 2025, Amazon Web Services, Inc. 또는 계열사. All rights reserved.