树莓派连接普通Mqtt服务器

树莓派连接普通Mqtt服务器

本文介绍如何使用Python语言在树莓派上实现与普通MQTT服务器的连接,并进行双线程的消息发布和订阅。此教程将利用paho-mqtt库来完成MQTT协议下的通信任务,适用于物联网项目和爱好者。

正文

树莓派是一款小型但强大的单板计算机,常用于教育、编程学习和物联网项目。在物联网应用中,MQTT是一种轻量级的消息协议,非常适合于网络带宽受限的情况。本教程将指导您如何在树莓派上使用Python创建一个简单的MQTT客户端,实现消息的发布和订阅。

步骤1:安装paho-mqtt

首先,确保您的树莓派已经安装了paho-mqtt库。如果还未安装,可以使用以下命令进行安装:

pip install paho-mqtt

代码双线程发布订阅

以下是Python脚本的完整代码,该代码创建了一个MQTT客户端,可以连接到普通的MQTT服务器,并在两个线程之间实现消息的发布和订阅:

# -*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
import time
import random
import json
import threading  # 导入线程模块

# MQTT服务器地址和端口
HOST = "broker.emqx.io"
PORT = 1883 

# 发布和订阅的主题
PUB_TOPIC = "test/topic/pub"  # 修改为你的发布主题
SUB_TOPIC = "test/topic/sub"  # 修改为你的订阅主题

# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))
    client.subscribe(SUB_TOPIC)  # 订阅主题

# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
    print(f"Message received on topic {msg.topic}: {str(msg.payload)}")

# 定义发布消息的函数
def publish_data(client):
    while True:  # 创建一个循环来持续发送数据
        payload_json = {
            'id': int(time.time()),
            'params': {
                'temperature': random.randint(20, 30),  # 随机温度
                'humidity': random.randint(40, 50)      # 随机相对湿度
            }
        }
        print('Sending data to IoT server: ' + str(payload_json))
        client.publish(PUB_TOPIC, payload=json.dumps(payload_json), qos=1)
        time.sleep(5)  # 每隔5秒发送一次数据

# 获取MQTT客户端实例
def getMQTTClient():
    client = mqtt.Client()
    return client

if __name__ == '__main__':
    client = getMQTTClient()
    client.on_connect = on_connect
    client.on_message = on_message

    # 连接 MQTT 服务器
    client.connect(HOST, PORT, 300)

    # 启动线程来发布消息
    publish_thread = threading.Thread(target=publish_data, args=(client,))
    publish_thread.start()  # 启动线程

    # 开始 MQTT 客户端的循环,处理接收到的消息和重新连接等
    client.loop_forever()

添加连接失败重新连接以及天气时间上传代码

# -*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
import time
import random
import json
import threading  # 导入线程模块
import datetime#导入时间模块
import pytz#导入时区模块
import requests#导入requests模块


# MQTT服务器地址和端口
HOST = "broker.emqx.io"
PORT = 1883 

# 发布和订阅的主题
PUB_TOPIC = "test/topic/pub"  # 修改为你的发布主题
SUB_TOPIC = "test/topic/sub"  # 修改为你的订阅主题

# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))
    client.subscribe(SUB_TOPIC)  # 订阅主题

LED=0#全局LED状态
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
    global LED#声明全局变量LED
    print(f"Message received on topic {msg.topic}: {str(msg.payload)}")
    if 'LED' in str(msg.payload):#如果收到的消息中包含LED
        # 处理过程: 若信息中包含LED,截取{"LED":0/1},若为1,则点亮LED
        # 代码如下:
        if '1' in str(msg.payload):
            #若LED已经为1,则打印LED has already been on,否则打印LED ON
            if LED==1:
                print('LED has already been on')
            else:
                print('LED ON')
                LED=1#LED状态为1
        else:
            #若LED已经为1,则打印LED has already been off,否则打印LED off
            if LED==0:
                print('LED has already been off')
            else:
                print('LED OFF')#否则LED灭
                LED=0#LED状态为0

#获取当前时间
def get_time():
    tz = pytz.timezone('Asia/Hong_Kong')#设置时区为香港
    now = datetime.datetime.now(tz)#获取当前时间
    return now.strftime("%Y-%m-%d %H:%M:%S")#返回当前时间



# 获取香港室外真实天气
def get_hongkong_wheather():
    try:
        # 使用高德地图天气API(请替换成你的API密钥)
        url =  "https://restapi.amap.com/v3/weather/weatherInfo?city=香港&key=<请替换成你的API密钥>&extensions=base"#获取香港室外返回实况天气
        #url =  "https://restapi.amap.com/v3/weather/weatherInfo?city=香港&key=284cf14fad27d0155fc3502ecbe26064&extensions=all"#获取香港室外返回预报天气
        response = requests.get(url)
        weather_data = response.json()

        # 高德API响应的数据结构不同,需要相应地提取温度和湿度数据
        if weather_data["status"] == '1' and weather_data["info"] == 'OK' and "lives" in weather_data:#若获取成功
            temperature = float(weather_data['lives'][0]['temperature'])#获取温度
            humidity = float(weather_data['lives'][0]['humidity'])#获取湿度
            windpower = float(weather_data['lives'][0]['windpower'])#获取风力
            return temperature, humidity, windpower#返回温度,湿度,风力
        else:
            print("Error in weather data response")#若获取失败,则打印错误信息
            return None, None, None#返回空值
    except Exception as e:#若获取失败,则打印错误信息
        print("Error retrieving weather data from AMap: ", e)#打印错误信息
        return None, None, None#返回空值

# 定义发布消息的函数
def publish_data(client):
    global LED#声明全局变量LED
    count = 0 #计数器
    temperature, humidity, windpower=None, None, None#初始化温度,湿度,风力
    while True:  # 创建一个循环来持续发送数据
        #计入代码如果count为30的倍数以及temperature, humidity, windpower全部为None,则发送数据
        if count % 30 == 0 or (temperature == None and humidity == None and windpower == None):
            temperature, humidity, windpower = get_hongkong_wheather()#获取香港室外真实天气
            count = 0#计数器清零
        payload_json = {
            'id': int(time.time()),
            'params': {
                'temperature': random.randint(20, 30),  # 随机温度
                'humidity': random.randint(40, 50),      # 随机相对湿度
                #加入LED状态
                'LED': LED,
                #加入香港室外真实温度
                'hongkong_temperature': temperature,
                #加入香港室外真实湿度
                'hongkong_humidity': humidity,
                #加入香港室外真实风力
                'hongkong_windpower': windpower,
                #加入当前时间
                'time': get_time()
            }
        }
        print('Sending data to IoT server: ' + str(payload_json))
        client.publish(PUB_TOPIC, payload=json.dumps(payload_json), qos=1)
        count += 1  # 更新计数器
        time.sleep(2)  # 每隔1秒发送一次数据


# 获取MQTT客户端实例
def getMQTTClient():
    client = mqtt.Client()
    return client

if __name__ == '__main__':
    #循环直至连接成功
    while True:
        try:
            client = getMQTTClient()
            client.on_connect = on_connect
            client.on_message = on_message
            # 连接 MQTT 服务器
            client.connect(HOST, PORT, 300)
            break
        except:
            print('Connect failed, reconnecting...')
            time.sleep(1)
    print('Connected successfully!')

    # 启动线程来发布消息
    publish_thread = threading.Thread(target=publish_data, args=(client,))#创建线程,target为线程函数,args为线程函数的参数
    publish_thread.start()  # 启动线程

    # 开始 MQTT 客户端的循环,处理接收到的消息和重新连接等
    client.loop_forever()

步骤3:运行和测试

在您的树莓派上运行上述Python脚本。您将看到程序连接到MQTT服务器,并开始在指定的主题上发布随机生成的温度和湿度数据。同时,程序也订阅了另一个主题,用于接收可能来自其他客户端的消息。

结论

使用paho-mqtt库在树莓派上实现MQTT客户端非常简单。通过本文提供的示例代码,您可以建立一个基础的消息发布和订阅系统,进而可以根据您的项目需求进行扩展和定制。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值