3

I am currently fiddeling around with AWS GreenGrass and I have gone through most of the basic examples. Now the problem I have understanding how I would perform different actions in my lambda function depending on the MQTT topic it was triggered by. I could not really find a documentation on how to differentiate which topic triggered the function handler in my python script. The thing I am trying to build is a small controller for my sonos system which uses the following very basic topics:

sonos/play

Which just tries playing a certain song I hardcoded.

sonos/pause

Which should be pausing the system.

I know I could create several lambdas for each command but that seems pretty finicky. Can someone please explain how one would tackle this sort of issue?

johndoe
  • 4,387
  • 2
  • 25
  • 40
John Doe
  • 53
  • 6

4 Answers4

3

Based on this dev guide, in your lambda you can get the topic from the context:

def get_input_topic(context):
    try:
        topic = context.client_context.custom['subject']
    except Exception as e:
        logging.error('Topic could not be parsed. ' + repr(e))
    return topic
action = get_input_topic(context).split('/')[-1]
John S
  • 418
  • 4
  • 9
1

I don't actually think this is possible. If you look at both of the event and context objects passed into your lambda function, neither of them contain the topic address.

What I have had to do is to have a separate lambda function to respond for messages for each MQTT topic.

Happy to be corrected if this can be done.

Remotec
  • 10,304
  • 25
  • 105
  • 147
0

You could check the client context in context object of the lambda handler. Don't think this is documented. But this should solve your ask.

Alex
  • 247
  • 3
  • 12
0

Have you tried to create an AWS IoT Rule?

I faced a similar problem, as I have several AWS IoT Things and I didn't want to create hundreds of subscriptions and lambdas.

Add the following subscription in your GG group:

Source    | Target       | Topic
----------|--------------|---------------------
IoT Cloud | [xyz_lambda] | [xyz_lambda]/trigger

Then go to the Act section on AWS IoT and create a rule , with the following statement:

SELECT topic(2) as action, * from 'sonos/#'

The topic(2) function captures the second segment of the topic (see AWS IoT SQL Reference - Functions). We rename it as action. The * captures the payload sent along with the sonos/play or sonos/pause message (if any).

Add an action to your rule that republishes the message to the [xyz_lambda]/trigger topic.

The JSON event sent to your lambda function handler will have the property action, followed by the JSON payload of the sonos/play or sonos/pause message:

{
  "action": "play",
  ...
}

or

{
  "action": "pause",
  ...
}

Hope this helps!

martip
  • 106
  • 2
  • 4