Possible to subscribe to aws IOT topic in lambda?

aws lambda publish to iot topic
aws lambda iot shadow
aws iot subscribe to topic python
aws iot tutorial
aws-iot-device-sdk
aws lambda region
aws lambda console
aws iot core

Newbie question. Can't find a previous answer.

I want to build a simple pump controller with Alexa. Would like Alexa to report pump state.

Simplest approach is Alexa -> lambda -> publish_to_Iot. And then, or perhaps just before the publish, subscribe to another topic to which the local controller would publish pump state that would be passed back thru Alexa.

As near as I can tell its not possible to subscribe to a topic from Lambda... which actually makes sense in the context of a lambda function.

Specific question is, can a lambda function subscribe to an IoT topic?

Yes, I know about IoT shadows, was hoping to avoid some complexity.

You can trigger Lambda functions in response to a matching filter using rules (the filter will match the topic).

Creating a rule with a AWS Lambda action, And does that mean, that devices in my account (eu-west-1:xxxxxxxxxxxx) which are subscribed to that topic (smartHomeTest) are able to get that  Browse to the AWS IoT console, and from the navigation pane, choose Act. Choose Create to create an AWS IoT rule. On the Create a rule page, enter a name for your rule. In Rule query statement, enter the following query: SELECT * FROM "my/lambda/topic". In Set one or more actions, choose Add action.

It's actually possible to do this, it's just not terribly intuitive. The AWS-SDK doesn't have a subscribe method so you need to use aws-iot-device-sdk. This library typically needs a certificate and lot of other config information.

var device = awsIot.jobs({
  keyPath: "./42fc9544f6-private.pem.key",
  certPath: "./42fc9544f6-certificate.pem.crt",
  caPath: "./AmazonRootCA1.pem",
  clientId: "clientPolicy", // name of the policy
  host: "your-endpoint.iot.us-east-1.amazonaws.com"
});

but it doesn't make sense to use a client certificate in a lambda. The lambda is already running under an IAM user so you should just be able to leverage that right? It turns out you can but it took a little digging. The aws-iot-device-sdk.js library will read the credentials out of the environment variables in Lambda (process.env.AWS_ACCESS_KEY_ID, process.env.AWS_SECRET_ACCESS_KEY). But you HAVE to use the wss protocol.

var awsIot = require('aws-iot-device-sdk');

device = awsIot.jobs({
  host: 'a1jcq6m7bg94jb-ats.iot.us-east-1.amazonaws.com',
  protocol: 'wss'});

device
  .on('connect', function() {
    console.log('connected. subscribing to topic...');
    device.subscribe(topic);
    console.log('subscribed to topic');   
});

One of the pitfalls of this approach is that there is natural latency in Lambda and of course additional latency to establish a connection to the topic. This really slows things down. A nice pattern to follow is to have lambda listen on a topic that is specific to that Lambda instance (e.g. lambda/some-uuid/response) and then when you post a message to your device, you can ask it to respond on that topic. The benefit is that the topic lives as long as the Lambda function is up and running. That could be hours if there is a lot of traffic or if you keep it warm. With this model, there is no latency to establish the connection and subscribe to the topic. In my tests, this is extremely fast with low latency.

This is how I handled the subscription.

var subscriber = null;

const lambdaUUID = uuidv4();
const topic = 'lambda/' + lambdaUUID + '/response';

device.on('message', function(topic, payload) {
  console.log('incoming message on topic' + topic);
  if ( subscriber ) {
    console.log('calling subscriber');
    subscriber(topic, payload);
  } else {
    console.log("no subscriber");
  }
});


exports.handler =  async function(event, context) {
  console.log("EVENT: \n" + JSON.stringify(event, null, 2));

  var deviceRequest = {"some":"stuff", callback: topic};

  const promise = new Promise(function(resolve, reject) {
    subscriber = function(topic, payload ) {
      console.log('subscriber called, resolving promise...');
      resolve("SUCCESS " + payload);
    };
  });  

  device.publish('things/THING1234/incoming', JSON.stringify(deviceRequest,null,''), { qos:0 }, function(err, data) {
    console.log("publishing message to device",err,data);
  });

  return promise;
};

Publish/Subscribe policy examples - AWS IoT, In the Lambda function provided in this post, you'll be able to specify the esDomainArn: your Amazon ES domain. topic: the AWS IoT topic this Choose Subscribe to topic, enter the topic you specified in your Lambda  About the sdk we are using, the aws-iot-device-sdk is designed to use inside of an embedded device. When we are using a Lambda function or trying to publish in a computer, the best practice is use the aws-sdk. Using the aws-sdk we don't need to use the certificates to publish in the AWS IoT, we just use the AWS credentials to do this.

The answer you are looking for is sending the notification from the Device to Alexa. Example: "Hi <<{User}>>, Motor pump <<{nameofpump}>> is Running" based on the actual status of the pump. This is more like a notification feature, please check this link on Alexa Voice Service which would help you to do the same. Hope this helps.

AWS Developer Forums: Publish to AWS IoT topic from AWS Lambda, Create an Amazon SNS topic and subscription. From the AWS IoT console, choose Services, type SNS , and then choose Simple Notification Service. In the first instance I'd like to know if it's possible to publish a message to an AWS IOT MQTT topic from a lambda function? I've found the following python code that I tried but it doesn't seem to

Device Simulation with AWS IoT and AWS Lambda, AWS IoT endpoint. The following is a sample payload with details of a single myThing device to be sent to a specific MQTT topic, which triggers  Must be the last character in the topic to which you are subscribing. Works as a wildcard by matching the current tree and all subtrees. For example, a subscription to Sensor/# receives messages published to Sensor/, Sensor/temp, Sensor/temp/room1, but not the messages published to Sensor.

Create an Amazon SNS topic and subscription, Use rules for AWS IoT so that your devices can interact with other AWS Rules are analyzed and actions are performed based on the MQTT topic stream. Invoke a Lambda function to extract data. Your rules can use MQTT messages that pass through the publish/subscribe Message broker for AWS IoT or, using the  I would suggest try to use AWS IoT console to subscribe the topics and see if you receive the messages. This is to make sure that your lambda function published messages correctly. And then, you could also try to publish messages to the topic using same client and see if your raspberry pi could receive the topics.

Implementing a Serverless AWS IoT Backend with AWS Lambda , Hi I was trying to develop a lambda function which will connect to the AWS thing I would suggest try to use AWS IoT console to subscribe the topics and Regarding the AWS SDK, if I use that can I still use mqtt messaging ? The policy you use depends on how you are connecting to AWS IoT Core. You can connect to AWS IoT Core using an MQTT client, HTTP, or WebSocket. When you connect with an MQTT client, you are authenticating with an X.509 certificate.

Comments
  • This question is not suitable for StackOverFlow, please read how to write a good questuin in SOF. You have to show us what you have tried and where is your problem exactly.
  • I updated with a specific question. But I haven't tried anything yet. Was hoping to get some advice before I started. I guess that's against the rules.
  • Thanks for the comment, but I don't think that works.
  • Sorry, still learning how to use stack-overflow... As far as I can tell, the only way to wake up Alexa is via the wake word. You cannot wake up Alexa via some random lambda function. The whole thing needs to run in the context of the Alexa initiated lambda function, something like: Alexa wake word -> lambda -> iot-publish -> iot-subscribe -> (same) lambda -> return to Alexa
  • Oh, you're looking to have the triggered function publish, subscribe, and receive from an IoT topic? I thought you were looking for Alexa -> lambda -> publish -> lambda. This probably isn't a good fit for IoT. You might look at DynamoDB or SQS to pass data back and forth. You could subscribe a lambda function to topics but that's going to be way more fragile than needed, especially at scale.
  • Very well written answer on an ambiguous question