shadow manager get event when changed

0

Hello, i've got a shadow manager component on my core device and the named shadow arrives now when things change.

In my custom python component I can read the shadow using the GetThingShadowRequest() ipc call..
all good.

I am trying to listen to the delta topic to react if something has changed so i can request the updated shadow (like above) and do something.
I tried :

g_ipc_client            = awsiot.greengrasscoreipc.connect()  
responserequest = SubscribeToTopicRequest()  
responserequest.topic_name = g_uri_shadow_delta_topic  # "$aws/things/mythingname/shadow/name/streamcontrol/update/delta"  
responserequest.qos = QOS.AT_LEAST_ONCE  
g_shadow_handler = shadow_delta_handler()  
g_delta_subscribe_operation = g_ipc_client.new_subscribe_to_topic(g_shadow_handler)  
future = g_delta_subscribe_operation.activate(responserequest)  
future.result()  

but the shadow_delta_handler never gets called when i update the shadow on the IoT Core Thing
should I be using

new_subscribe_to_topic (handler)
or
new_subscribe_to_iot_core (handler) ?

future.result() seems to return immediately, does that mean it has stopped subscribing ?
how can i stay subscribed to the topic indefinitely ?

Edited by: clogwog on Oct 27, 2021 2:01 PM

clogwog
已提問 3 年前檢視次數 429 次
6 個答案
2
已接受的答案

I may have found the issue. topic_name is not a member of SubscribeToTopicRequest, it should be just topic.

So the line:
responserequest.topic_name = g_uri_shadow_delta_topic

Should be:
responserequest.name = g_uri_shadow_delta_topic

Unfortunately the flexibility of Python is hurting you as nothing will complain or warn you about adding a member to that SubscribeToTopicRequest class even though it will go unused.

If I'm right about this then you should considering making GitHub issues with details of how you got stuck. I think your IPC client was making a subscription request without any topics, which probably should be an error. Further, the Nucleus should return a useful error when it receives a bad subscription request rather than fail with a NullPointer. It's not acceptable for devs to get stuck on such minor issues because of a lack of useful error messages.

The link for Nucleus (which contains the IPC code): https://github.com/aws-greengrass/aws-greengrass-nucleus/issues
The link for Python v2 IoT SDK: https://github.com/aws/aws-iot-device-sdk-python-v2/issues

AdamVDR
已回答 3 年前
0

Hey. The IPC client runs in a separate thread and will make calls to your shadow_delta_handler when a message is received. However, you need the main thread to stay alive after you subscribe, otherwise the Python process finishes and you'll never get messages. Make sure you have a bit of code like:

while True: # Keep the main thread alive, or the process will exit.
time.sleep(10)

after you subscribe in order to keep the main thread alive. Check out the best practices https://docs.aws.amazon.com/greengrass/v2/developerguide/interprocess-communication.html#ipc-subscription-handler-best-practices section of the Greengrass IPC docs for more info.

Edited by: AdamVDR on Oct 27, 2021 9:21 AM

Edited by: AdamVDR on Oct 27, 2021 9:21 AM

Edited by: AdamVDR on Oct 27, 2021 9:22 AM

AdamVDR
已回答 3 年前
0

Hello Adam,

thank you for thinking along.

I'm also keeping a repeated 20 second timer around to poll for the local shadow (over IPC) and when i get the list of components it stays 'RUNNNING' ( sudo /greengrass/v2/bin/greengrass-cli component list ) so i'm sure the Python custom component isn't finishing.

I'm trying to get rid of the polling by listening to the delta topic of my named shadow ( $aws/things/mythingname/shadow/name/streamcontrol/update/delta )

to get access to that topic from a greengrass component would i need to use

new_subscribe_to_topic (myhandler)
or
new_subscribe_to_iot_core (myhandler) ?

clogwog
已回答 3 年前
0

It's new_subscribe_to_topic since you want to subscribe to the Greengrass IPC. Are any exceptions thrown after you call future.result()? Do you see any error messages in the greengrass.log file? If you see an error message related to permissions keep in mind that your component will require the aws.greengrass#SubscribeToTopic operation.

I believe you will see an info message in greengrass.log if the subscription was properly registered.

AdamVDR
已回答 3 年前
0

I'm seeing an exception in the greengrass.log like:

2021-10-29T01:45:08.264Z [INFO] (Thread-6) software.amazon.awssdk.eventstreamrpc.ServiceOperationMappingContinuationHandler: Sending connect response for au.com.mtdata.smartdvr.gg_shadow_config. {}
2021-10-29T01:45:08.267Z [ERROR] (Thread-6) com.aws.greengrass.ipc.common.ExceptionUtil: Unhandled exception in IPC. {}
java.lang.NullPointerException
at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1690)
at com.aws.greengrass.builtin.services.pubsub.PubSubIPCEventStreamAgent.handleSubscribeToTopicRequest(PubSubIPCEventStreamAgent.java:160)
at com.aws.greengrass.builtin.services.pubsub.PubSubIPCEventStreamAgent.access$300(PubSubIPCEventStreamAgent.java:45)
at com.aws.greengrass.builtin.services.pubsub.PubSubIPCEventStreamAgent$SubscribeToTopicOperationHandler.lambda$handleRequest$1(PubSubIPCEventStreamAgent.java:237)
at com.aws.greengrass.ipc.common.ExceptionUtil.translateExceptions(ExceptionUtil.java:33)
at com.aws.greengrass.builtin.services.pubsub.PubSubIPCEventStreamAgent$SubscribeToTopicOperationHandler.handleRequest(PubSubIPCEventStreamAgent.java:230)
at com.aws.greengrass.builtin.services.pubsub.PubSubIPCEventStreamAgent$SubscribeToTopicOperationHandler.handleRequest(PubSubIPCEventStreamAgent.java:209)
at software.amazon.awssdk.eventstreamrpc.OperationContinuationHandler.onContinuationMessage(OperationContinuationHandler.java:271)
at software.amazon.awssdk.crt.eventstream.ServerConnectionContinuationHandler.onContinuationMessageShim(ServerConnectionContinuationHandler.java:53)

2021-10-29T01:45:08.270Z [INFO] (Thread-6) software.amazon.awssdk.eventstreamrpc.RpcServer: New connection code [AWS_ERROR_SUCCESS] for [Id 3895, Class ServerConnection, Refs 1](2021-10-29T01:45:08.270133Z) - <null>. {}
2021-10-29T01:45:08.272Z [INFO] (Thread-6) software.amazon.awssdk.eventstreamrpc.ServiceOperationMappingContinuationHandler: aws.greengrass#GreengrassCoreIPC authenticated identity: au.com.mtdata.smartdvr.gg_shadow_config. {}

so it doesn't look like a permission problem ?

my subscription is setup as :

def subscribe_to_shadow_delta():
global g_logger
global g_uri_shadow_delta_topic
global g_ipc_client
global g_shadow_handler
g_ipc_client = awsiot.greengrasscoreipc.connect()

try:  
    responserequest = SubscribeToTopicRequest()  
    responserequest.topic_name = g_uri_shadow_delta_topic  # "$aws/things/mythingname/shadow/name/streamcontrol/update/delta"  
    g_shadow_handler = shadow_delta_handler()  
    g_delta_subscribe_operation = g_ipc_client.new_subscribe_to_topic(g_shadow_handler)  
    future = g_delta_subscribe_operation.activate(responserequest)  
    future.result()  
except BaseException as err:  
    g_logger.error("EXCEPTION get_download_uri_from_server : " + str(err))  
except:  
    g_logger.info("subscribe to shadow delta  -- EXCPETION ");  

and the handler class SubscribeToTopicRequest looks like:

class shadow_delta_handler(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")  
    except:  
        traceback.print_exc()  

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

I'm not sure if
future.result()
is alright.. I want to keep listening to the delta topic 'forever'

clogwog
已回答 3 年前
0

Hello Adam,

thank you for your reply. You are correct. I specified the wrong topic_name instead of topic.
I've raised a raise an issue (https://github.com/aws/aws-iot-device-sdk-python-v2/issues/247) with your description in github.

It would be nice to have an error message that points me in the right direction, but it was mainly my fault for not seeing the difference in the API spec.

Kind Regards,
Tom

Edited by: clogwog on Nov 3, 2021 9:34 AM

Edited by: clogwog on Nov 3, 2021 9:35 AM

clogwog
已回答 2 年前

您尚未登入。 登入 去張貼答案。

一個好的回答可以清楚地回答問題並提供建設性的意見回饋,同時有助於提問者的專業成長。

回答問題指南