aws / aws-iot-device-sdk-python-v2

Next generation AWS IoT Client SDK for Python using the AWS Common Runtime
Apache License 2.0
408 stars 213 forks source link

Updates made to a device shadow in IoT Core do not reach the topic in the component. #282

Closed jfduque closed 2 years ago

jfduque commented 2 years ago

``Confirm by changing [ ] to [x] below:

Platform/OS/Device Debian 11 amd64

Describe the question I understand that when there is a change to a named shadow in AWS IoT Core, the GreenGrass core can use its IPC to broadcast events through its internal pubsub to subscribed components.

In my component's Python code I have the following:

import os
import awsiot.greengrasscoreipc
import awsiot.greengrasscoreipc.client as client
from awsiot.greengrasscoreipc.model import SubscribeToTopicRequest
from awsiot.greengrasscoreipc.model import SubscriptionResponseMessage

TIMEOUT = 10

class StreamHandler(client.SubscribeToTopicStreamHandler):
    def __init__(self):
        super().__init__()

    def on_stream_event(self, event: SubscriptionResponseMessage) -> None:
        try:
            message_string = str(event.binary_message.message, "utf-8")
            # Handle message.
        except:
            traceback.print_exc()
        else:
            print("RECEIVED: ", message_string)

    def on_stream_error(self, error: Exception) -> bool:
        return True  # Return True to close stream, False to keep stream open.

    def on_stream_closed(self) -> None:
        # Handle close.
        pass

# subscribe to changes in the "settings" named shadow
ipc_client = awsiot.greengrasscoreipc.connect()
request = SubscribeToTopicRequest()
request.topic = f"$aws/things/{os.getenv('AWS_IOT_THING_NAME')}/shadow/name/settings/update/accepted"
handler = StreamHandler()
operation = ipc_client.new_subscribe_to_topic(handler) 
future = operation.activate(request)
future.result(TIMEOUT)
print(f"Subscribed to stream '{request.topic}'")

The component's recipe.yaml (redacted for readability):

---
RecipeFormatVersion: "2020-01-25"
ComponentName: "{COMPONENT_NAME}"
ComponentVersion: "{COMPONENT_VERSION}"
ComponentPublisher: "{COMPONENT_AUTHOR}"
ComponentDependencies:
  aws.greengrass.TokenExchangeService:
    VersionRequirement: ">= 2.0.3"
    DependencyType: HARD
  aws.greengrass.ShadowManager:
    VersionRequirement: ">= 2.0.6"
    DependencyType: HARD
ComponentConfiguration:
  DefaultConfiguration:
    accessControl:
      aws.greengrass.ShadowManager:
        policy_1:
          operations:
            - aws.greengrass#GetThingShadow
            - aws.greengrass#UpdateThingShadow
            - aws.greengrass#DeleteThingShadow            
            - aws.greengrass#ListNamedShadowsForThing
          resources:
            - "*"
      aws.greengrass.ipc.pubsub:
        policy_1:
          operations:
            - aws.greengrass#SubscribeToTopic
          resources:
            - "*"

And the aws.greengrass.ShadowManager deployment configuration:

{
    "strategy": {
        "type": "realTime"
    },
    "synchronize": {
        "coreThing": {
            "classic": false,
            "namedShadows": [
                "settings"
            ]
        }
    }
}

As far as I know, if I make a change in AWS IoT Core, editing the "settings" named shadow, the component should receive something and execute the line print("INTERNAL EVENT: ", message_string). This isn't happening. Any idea how to solve this? Or how to debug it?

Thanks in advance.

jmklix commented 2 years ago

I don't see the line print("INTERNAL EVENT: ", message_string) in your code sample. Did you correctly copy all of your sample code?

jfduque commented 2 years ago

I don't see the line print("INTERNAL EVENT: ", message_string) in your code sample. Did you correctly copy all of your sample code?

Hi, thanks for the answer. Line 20 of the sample, inside on_stream_event method

jfduque commented 2 years ago

I've updated the policy from:

      aws.greengrass.ipc.pubsub:
        policy_1:
          operations:
            - aws.greengrass#SubscribeToTopic
          resources:
            - "*"

To:

      aws.greengrass.ipc.pubsub:
        <actual_component_name>:pubsub:1:
          operations:
            - aws.greengrass#SubscribeToTopic
          resources:
            - "$aws/things/{iot:thingName}/shadow/name/settings/update/accepted"

And seems to be working now

github-actions[bot] commented 2 years ago

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.