可以在lambda中订阅aws IOT主题吗?

时间:2017-12-31 18:12:07

标签: amazon-web-services lambda iot subscribe

新手问题。无法找到之前的答案。

我想用Alexa构建一个简单的泵控制器。希望Alexa报告泵状态。

最简单的方法是Alexa - > lambda - > publish_to_Iot。然后,或者也许就在发布之前,订阅本地控制器将发布泵状态的另一个主题,该状态将通过Alexa传回。

尽可能地告诉它不可能从Lambda订阅一个主题......这实际上在lambda函数的上下文中是有意义的。

具体问题是,lambda函数是否可以订阅IoT主题?

是的,我知道物联网阴影,希望避免一些复杂性。

3 个答案:

答案 0 :(得分:1)

您可以使用rules触发Lambda函数以响应匹配的过滤器(过滤器将与主题匹配)。

答案 1 :(得分:0)

您正在寻找的答案是将通知从设备发送到Alexa。示例:根据泵的实际状态,“您好,<< {用户} >>,电动泵<< {nameofpump} >>正在运行”。这更像是一种通知功能,请在Alexa语音服务上选中此link,以帮助您完成此操作。希望这会有所帮助。

答案 2 :(得分:0)

实际上有可能做到这一点,但这并不是非常直观。 AWS-SDK没有订阅方法,因此您需要使用aws-iot-device-sdk。该库通常需要证书和许多其他配置信息。

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"
});

,但是在lambda中使用客户端证书没有任何意义。 Lambda已经在IAM用户下运行,因此您应该能够利用该权利?事实证明可以,但是花了一些时间。 aws-iot-device-sdk.js库将从Lambda中的环境变量中读取凭据(process.env.AWS_ACCESS_KEY_ID,process.env.AWS_SECRET_ACCESS_KEY)。但是您必须使用wss协议。

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');   
});

此方法的陷阱之一是Lambda中存在自然的延迟,当然还有额外的延迟来建立与主题的连接。这确实减慢了速度。可以遵循的一种很好的模式是让Lambda侦听特定于该Lambda实例的主题(例如lambda / some-uuid / response),然后在将消息发布到设备时,可以要求它对该主题做出响应。好处是,只要Lambda函数启动并运行,该主题就会存在。如果交通繁忙或保持温暖,那可能要花几个小时。使用此模型,建立连接和订阅主题没有等待时间。在我的测试中,这非常快且延迟很短。

这是我处理订阅的方式。

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;
};