如何在 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 主题?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 AWS Lambda 中使用 Node.js 列出我的所有 Amazon EC2 实例?

如何使用Lambda从Amazon AWS中提取和转换单个dynamodb元素

如何在 Lambda 函数中使用 AWS.CloudFront.Signer

从节点应用程序调用 amazon lambda 函数

如何将AWS API网关阶段指向特定的lambda函数别名?

Amazon Echo Lambda 函数。控制台打印在哪里?