Get output of a Lambda function back to IoT Core MQTT broker

0

We're using IoT LoRaWAN and have a number of test devices publishing to a Lambda LoRa decoder. The payloads arrive at the message broker, an IoT rule catches them and sends them to Lambda where it is decoded and the resulting message pushed to cloudwatch logs. However, I need to get the decoded payload BACK to the message broker since the broker is connected to our own application which handles the dashboarding and alerting.

Lambda easily connects to IoT on the trigger (input) side, but does not offer a direct connection on the destination (output side). At least I don't see it as part of the default options. I'd rather not add SNS or SQS in between to avoid the additional management, especially since we're really just testing at the moment.

What is the ideal way to do this? Am I missing something?

3 Answers
1
Accepted Answer

I sugggest to use the approach described in this sample as it provides the features which you describe above: https://github.com/aws-samples/aws-iot-core-lorawan/tree/main/transform_binary_payload

Instead of adding Lambda as an Action to the AWS IoT Rule, you should use aws_lambda function of AWS IoT SQL and use a Republish Action in AWS IoT Rule.

Further docs:

answered a year ago
  • Got it thank you. I didn't get it to work yet, I'm still a little confused by the whole SQL rules concept. Especially confusing is the interplay between rules, destinations and the 'other' destinations. I see the power of rules, but things get complex pretty quickly when you stack them up - gets hard to keep track. The github link you shared was very useful thank you.

0

Hi, I've spent more time looking at the Rules docs, I see how powerful it could be but I'm hitting a wall trying to figure out how to use the aws_lambda function within a rule.

Here's my rule SQL:

SELECT *, aws_lambda("arn:aws:lambda:us-east-1:<<REDACTED>>:function:<<REDACTED>>",*) as output, topic() as RuleMetadata.originalTopic, timestamp() as RuleMetadata.timestamp, clientid() as RuleMetadata.clientid FROM 'test/lorawan/uplink'

I've followed the instructions to grant invoke permissions (using the CLI command in the docs) and can see it was successfully granted in the Lambda's Resource-based policy settings:

Statement ID
TestRepub
Principal
iot.amazonaws.com
Effect
Allow
Action
lambda:InvokeFunction
Conditions
{
 "StringEquals": {
  "AWS:SourceAccount": "<<REDACTED>>"
 },
 "ArnLike": {
  "AWS:SourceArn": "arn:aws:iam::<<REDACTED>>:role/service-role/testrepub"
 }
}

The rule works like a charm when I remove the aws_lambda function from the SQL and can see it on the MQTT tester with the republish action to test/repub. But when I add the lambda function back in, no messages come through MQTT tester and nothing occurs in the logs of the Lambda function. I also have a republish to topic test/error for Error action on the rule, but nothing appears there either making it really hard to debug!

I assume its a permission issue, but I followed the instructions very specifically. Any help would be really appreciated!

answered a year ago
  • My mistake! I use the the arn for the role, not the rule! AWS naming conventions are pretty confusing. I needed: "arn:aws:iot:us-east-1:<<REDACTED>>:rule/TestRepub", not "arn:aws:iam::<<REDACTED>>:role/service-role/testrepub"

0

Hi Andrei, I'm trying to get this to work using your response, the docs, and this video as a guide. I have a simple Lambda transformer for a simple LoRa based button device that I cannot reach using this rule:

SELECT aws_lambda("arn:aws:lambda:us-east-1:<<REDACTED>>:function:TransformerRakButtonUplink", *) as event FROM 'devices/lorawan/uplink'

I'm trying to send the entire incoming payload below in its original form (using the , * in the rule) since my Lambda function expects this payload in its entirety.

However, my rule does not appear to even be able to reach the Lambda function. I can see the below payload on the MQTT tester no problem, so the device is able to connect to IoT Core. I just don't understand the rule issue. I checked the Lambda logs and it hasn't been invoked at all.

Example payload I want to get to Lambda using the rule to then republish to a topic like devices/lorawan/transformed

{
  "WirelessDeviceId": "<<REDACTED>>",
  "PayloadData": "Ag==",
  "WirelessMetadata": {
    "LoRaWAN": {
      "ADR": true,
      "Bandwidth": 125,
      "ClassB": false,
      "CodeRate": "4/5",
      "DataRate": "3",
      "DevAddr": "<<REDACTED>>",
      "DevEui": "<<REDACTED>>",
      "FCnt": 337,
      "FOptLen": 0,
      "FPort": 2,
      "Frequency": "904300000",
      "Gateways": [
        {
          "GatewayEui": "<<REDACTED>>",
          "Rssi": -85,
          "Snr": 7.5
        }
      ],
      "MIC": "16613db6",
      "MType": "UnconfirmedDataUp",
      "Major": "LoRaWANR1",
      "Modulation": "LORA",
      "PolarizationInversion": false,
      "SpreadingFactor": 7,
      "Timestamp": "2021-12-24T02:41:19Z"
    }
  }
}
answered a year ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions