如何用Python的MQTT从AWS Lambda向Raspberry Pi发消息?附配置疑问
核心架构说明
首先明确:通过AWS IoT Core中转是最可靠的方案,无需直接获取树莓派的公网地址(树莓派大多处于局域网,无固定公网IP,直接通信会面临端口映射、防火墙等问题)。完整流程为:
- AWS Lambda 调用AWS IoT Core的API将消息发布到指定MQTT主题
- 树莓派通过MQTT协议连接AWS IoT Core,订阅同一主题接收消息
一、树莓派连接所需信息
树莓派连接AWS IoT Core必须准备以下4项内容(你已安装证书,确认路径即可):
- 根CA证书(Amazon Root CA 1)
- 设备证书(
.pem.crt格式文件) - 设备私钥(
.pem.key格式文件) - AWS IoT Core端点地址(控制台路径:IoT Core → 设置 → 设备端点,格式类似
xxxxxxxxxx-ats.iot.us-east-1.amazonaws.com)
二、AWS Lambda配置说明
Lambda无需配置树莓派的证书,只需配置IAM权限以调用AWS IoT Core的Publish API:
- 为Lambda执行角色添加
AWSIoTDataAccess策略(或自定义策略,允许iot:Publish动作指向指定MQTT主题) - Lambda中使用AWS SDK(boto3)调用IoT Core的publish方法,无需手动处理MQTT连接,SDK已封装相关逻辑
三、树莓派端Python订阅代码
先安装依赖库:pip install paho-mqtt,示例代码如下:
import paho.mqtt.client as mqtt import ssl # 替换为你的实际配置 AWS_IOT_ENDPOINT = "xxxxxxxxxx-ats.iot.us-east-1.amazonaws.com" DEVICE_CERT = "/home/pi/certs/device-cert.pem.crt" DEVICE_PRIVATE_KEY = "/home/pi/certs/device-private.pem.key" ROOT_CA = "/home/pi/certs/root-CA.crt" MQTT_TOPIC = "lambda/to/raspberrypi" # 需与Lambda端主题完全一致 def on_connect(client, userdata, flags, rc): print(f"连接成功,返回码: {rc}") client.subscribe(MQTT_TOPIC) print(f"已订阅主题: {MQTT_TOPIC}") def on_message(client, userdata, msg): print(f"收到消息 - 主题: {msg.topic} 内容: {msg.payload.decode('utf-8')}") # 初始化MQTT客户端 client = mqtt.Client(client_id="raspberrypi-client") # client_id需唯一,可自定义 client.tls_set(ROOT_CA, certfile=DEVICE_CERT, keyfile=DEVICE_PRIVATE_KEY, cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1_2) client.on_connect = on_connect client.on_message = on_message # 建立连接并保持监听 client.connect(AWS_IOT_ENDPOINT, port=8883, keepalive=60) client.loop_forever()
四、AWS Lambda端Python发布代码
Lambda默认自带boto3库,示例代码如下:
import boto3 # 替换为你的AWS区域 iot_client = boto3.client('iot-data', region_name='us-east-1') def lambda_handler(event, context): mqtt_topic = "lambda/to/raspberrypi" message = {"content": "Hello from Lambda to Raspberry Pi!"} try: response = iot_client.publish( topic=mqtt_topic, payload=str(message), qos=1 # QoS等级可选0或1,按需选择 ) print(f"消息发布成功: {response}") return {"statusCode": 200, "body": "Message published successfully"} except Exception as e: print(f"发布失败: {str(e)}") return {"statusCode": 500, "body": f"Failed to publish message: {str(e)}"}
五、关键注意事项
- 确保树莓派能访问公网(需连接AWS IoT Core端点)
- AWS IoT Core的区域需与Lambda区域一致,或在Lambda的boto3客户端中指定正确区域
- MQTT主题名称大小写敏感,两端必须完全匹配
- 树莓派的证书需已关联到AWS IoT Core的对应设备(控制台路径:IoT Core → 管理 → 设备,确认设备存在且证书已激活)
内容的提问来源于stack exchange,提问作者sandom
相关产品推荐
相关产品推荐

