如何在 Amazon AWS Lambda 函数中发布到 MQTT 主题?

Posted

技术标签:

【中文标题】如何在 Amazon AWS Lambda 函数中发布到 MQTT 主题?【英文标题】:How can I publish to a MQTT topic in a Amazon AWS Lambda function? 【发布时间】:2016-06-14 11:08:35 【问题描述】:

我想要一个简单的命令,就像我在 bash 中使用的那样,在 AWS Lambda 函数内向 MQTT 上的主题发布一些内容。沿着: mosquitto_pub -h my.server.com -t "light/set" -m "on"

背景:我想用 Alexa 打开和关闭一盏灯。 Alexa 可以启动一个 Lambda 函数,在这个 Lambda 函数内部我想启动一个 MQTT 发布,因为灯可以监听 MQTT 主题并对那里的消息做出反应。(也许有更简单的解决方案,但我们处于复杂的(大学)网络,这使得许多其他方法更加困难)

【问题讨论】:

请接受以下答案之一,以便其他人知道您认为哪个有用。 【参考方案1】:

如果您使用的是 Python,我可以使用我的处理程序函数中的以下内容获取 AWS Lambda 函数以将消息发布到 AWS IoT:

import boto3
import json

client = boto3.client('iot-data', region_name='us-east-1')

# Change topic, qos and payload
response = client.publish(
        topic='$aws/things/pi/shadow/update',
        qos=1,
        payload=json.dumps("foo":"bar")
    )

您还需要确保角色(在您的 Lambda 函数配置中)附加了一个策略以允许访问 IoT 发布函数。在 IAM -> 角色下,您可以将内联策略添加到您的 Lambda 函数角色中,例如:


   "Version": "2016-6-25",
   "Statement": [
    
        "Effect": "Allow",
        "Action": [
            "iot:Publish"
        ],
        "Resource": [
            "*"
        ]
    
   ]

【讨论】:

感谢您的帮助罗伊。最后我们使用了 Ponte,通过一个 http 请求从 AWS lambda 中退出,该请求被发送到 ponte,然后将其传输到 mqtt 并将其发送到灯。 @xtra 这也是我的问题,在 javascript 中,我们需要端点很烦人,而在 Python 中则不需要。你知道如何在不通过端点的情况下在 JS 中做到这一点吗?【参考方案2】:

AWS SDK 有两个类可用于 IoT:Iot 和 IotData。 IotData.publish 是您正在寻找的方法。看起来 Iot 对象用于处理事物,而 IotData 用于处理 MQTT 和阴影。这应该在 MQTT 和 shadows 的文档中直接引用,但事实并非如此。

此服务(IotData)也可用in the CLI。

【讨论】:

感谢您的回答。通过从 bash 发布一个事件,它让我走上了正轨:aws iot-data publish --cli-input-json '"topic":"myTopic", "qos": 0, "payload": "\"myKey\": 54321, \"myOtherKey\": 12345"'。 Payload 的键必须用双引号括起来并用反斜杠转义。【参考方案3】:

如果您使用的是 Node.js,这将起作用 -

var AWS = require('aws-sdk');
var iotdata = new AWS.IotData( endpoint: '*****************.iot.us-east-1.amazonaws.com' );

exports.handler = async(event) => 
    console.log("Event => " + JSON.stringify(event));
    var params = 
        topic: "MyTopic",
        payload: JSON.stringify(event),
        qos: 0
    ;

    return iotdata.publish(params, function(err, data) 
        if (err) 
            console.log("ERROR => " + JSON.stringify(err));
        
        else 
            console.log("Success");
        
    ).promise();
;

记得给这个 lambda 函数使用的角色添加 iot:publish 权限。

【讨论】:

为什么我们需要在JS中指定端点,而在python中我们只能简单地传递区域? @MohammedNoureldin 我们可以在同一个区域有多个端点。 哦,我不知道,我需要检查这怎么可能。或者你能告诉我这怎么可能?或者要搜索的关键字是什么?因为我在快速搜索中找不到这个。但显然 Python boto3 可以在不指定的情况下获取“默认”端点? @MohammedNoureldin 我对 Python boto3 没有任何经验,因此无法提供帮助。【参考方案4】:

上一篇关于 nodeJS 的帖子为我发送了 2 次消息。 更正在这里

    var mqttParams = 
        topic: topicName,
        payload: JSON.stringify(event),
        qos: 1
    ;
    
    const request = iotdata.publish(mqttParams);
    request
        .on('success', () => console.log("Success"))
        .on('error', () => console.log("Error"))
    return new Promise(() => request.send());

【讨论】:

传奇。我一直在为双重消息而苦苦挣扎。【参考方案5】:

如果你使用 Node.js,你需要安装 mqtt 库。以下步骤可帮助您在 AWS Lambda 上下载和安装 mqtt 库。

    Download and install Node.js and npm 在您的 PC 上。

    Download MQTT library for node.js.

    在安装了 Node.js 的 nodejs 目录下解压。 (在 Windows 10 x64 中,nodejs 目录为C:\Program Files\nodejs

    创建一个文件夹来存储 mqtt 安装的文件。例如,D:\lambda_function

    以管理员身份运行命令提示符,将目录更改为 nodejs 目录。

    安装mqtt库到D:\lambda_function

    C:\Program Files\nodejs>npm install --prefix "D:\lambda_function” mqtt 
    

Here's a similar project.

【讨论】:

【参考方案6】:

这是一个使用 async await 的简单 JavaScript 代码:

const AWS = require("aws-sdk");

exports.handler = async event => 
  try 
    const iotData = new AWS.IotData( endpoint: "IOT_SERVICE_ID-ats.iot.eu-central-1.amazonaws.com" );

    const params = 
      topic: 'some/topic',
      payload: JSON.stringify( var1: "val1" )
    

    result = await iotData.publish(params).promise();

    console.log(result);

    return  statusCode: 200, body: `IoT message published.` ;
   catch (e) 
    console.error(e);
    return  statusCode: 500, body: `IoT message could not be published.` ;
  
;

不要忘记给这个 lambda 提供发布到这个 IoT 主题所需的 iot:publish 权限。

【讨论】:

以上是关于如何在 Amazon AWS Lambda 函数中发布到 MQTT 主题?的主要内容,如果未能解决你的问题,请参考以下文章