1973浏览
查看: 1973|回复: 1

[教程] 【MQTT教程】树莓派通过MQTT协议连接到Easyiot

[复制链接]

前言

mqtt_log
前几天在mblock为光环板写了一个MQTT的扩展,可以让光环接通过mqtt协议连接到Easyiot物联网平台,可实现发布和订阅消息。当然也可以通过物联网平台,控制其他物联网设备(eg:光环板语音控制掌控板)。

最近不是树莓派日(3.14)嘛!自己也想着为社区做点贡献,就做一个树莓派连接EasyIOT的教程吧!

MQTT的工作原理

MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的"轻量级"通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布。MQTT最大优点在于,可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。作为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用。
MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。
broker、publisher、subscriber
中介承担着转发MQTT 通信的服务器的作用。相对而言,发布者和订阅者则起着客户端的作用。发布者是负责发送消息的客户端,而订阅 者是负责接收消息的客户端。MQTT 交换的消息都附带“主题”地址,各个客户端把这个“主题”视为收信地址,对其执行传输消息的操作。 形象地比喻一下,中介就是接收邮件的邮箱。
MQTT 通信的机制
中介在等待各个客户端对其进行连接。订阅者连接中介,把自己想订阅的主题名称告诉中介。这就叫作订阅。 然后发布者连接中介,以主题为收信地址发送消息。这就是发布。发布者一发布主题,中介就会把消息传递给订阅了该主题的订阅者。
如上图所示,如果订阅者订阅了主题A,那么只有在发布者发布了主题A 的情况下,中介才会把消息传递给订阅者。订阅者和中介总是处于 连接状态,而发布者则只需在发布时建立连接,不过要在短期内数次发布时,就需要保持连接状态了。因为中介起着转发消息的作用,所以各 个客户端彼此之间没有必要知道对方的IP 地址等网络上的收信地址。又因为多个客户端可以订阅同一个主题,所以发布者和订阅者是一 对多的关系。在设备和服务器的通信中,设备相当于发布者,服务器则相当于订阅者。
MQTT 的主题示例
题采用的是分层结构。用“#”和“+”这样的符号能指定多个主题。如上图所示,/Sensor/temperature/# 中使用了“#”符号,这样就 能指定所有开头为/Sensor/temperature/ 的主题。此外,/Sensor/+/room1中使用了符号“+”,这样一来就能指定所有开头是/Sensor/、结尾是/room1 的主题。

MQTT原理转载至 [图解物联网 / 日本NTT DATA集团等著;丁灵译. --北京:人民邮电出版社, 2017.4]

准备阶段

我们在掌控板和光环板这些ESP32或者ESP8266类型芯片中(前提刷入MicroPython-lib),主要用到的是umqtt.simple库具体API及样例程序可以参照此链接
umqtt.simpel
好了废话不多说,现在我们开始配置我们的树莓派环境吧,let's GO
更新下系统,更新前记得改国内源,不知怎么更换的看这贴:http://bbs.hassbian.com/thread-27-1-1.html

sudo apt-get update
sudo apt-get upgrade -y

在终端输入以下命令确认pip是否已经安装:

pip -V

输入以下命令安装mqtt包:

sudo pip install paho-mqtt

这样我们的paho-mqtt库就安装完成,具体Python paho-mqtt 模块使用和API分析请点击此连接里面对paho-mqtt的API讲解很清楚,我这里就不一一概述了,下文中只会针对自己的用到的函数,做简单的讲解

一般客户端使用流程

创建一个客户端实例;
1、使用connect方法连接broker;
2、调用loop方法(注:loop包含loop,loop_forever,loop_start);
3、使用subscribe方法订阅某个主题;
4、使用publish方法向某个主题发布消息到broker;
5、使用disconnect方法断开和broker的链接
6、还有一个重要的概念就是callback,程序可能在某些事件触发时需要做一些操作,这些操作就可以放入回调方法中。

发布程序测试

# encoding: utf-8
import paho.mqtt.client as mqtt
import time

server =  "182.254.130.180"
port = 1883
iot_id = "填写自己的用户名"
iot_pwd = "填写自己的用户密码"
topic = "填写自己的设备名"

def test(msg):
    client_id = time.strftime('%Y%m%d%H%M%S',time.localtime(time.time()))   # 以当前时间作为client_id
    client = mqtt.Client(client_id)    # ClientId不能重复,所以使用当前时间
    client.connect(server,port , 30)  #设置连接的服务器、端口及keepalive
    client.username_pw_set(iot_id, iot_pwd) # 设置连接用户和密码,必须设置,否则会返回Connected with result code 4
    client.publish(topic,msg,1) # 向topic发送msg信息
    client.loop_start()

if __name__ == '__main__':
    while True:
        message = input("please input your message")
        test(message)

测试结果:
运行结果

订阅程序测试

作为一个接收者,同一个主题没有发布(pub)信息的时候,就自己一直等候。

#coding: UTF-8
import paho.mqtt.client as mqtt
import time

server =  "182.254.130.180"
port = 1883
iot_id = "填写自己的用户名"
iot_pwd = "填写自己的用户密码"
topic = "填写自己的设备名"

def on_connect(client, userdata, flags, rc):
    client.subscribe(topic)  # 填写订阅的主题

def on_message(client, userdata, msg):
    print(msg.topic+" " + ":" + str(msg.payload))  # 打印接受的消息

def on_publish(topic, payload, qos):
    client.publish(topic, payload, qos)

def main():
    client_id = time.strftime('%Y%m%d%H%M%S',time.localtime(time.time()))   # 以当前时间作为client_id
    client = mqtt.Client(client_id)    # ClientId不能重复,所以使用当前时间
    client.username_pw_set(iot_id, iot_pwd) # 设置连接用户和密码,必须设置,否则会返回Connected with result code 4
    client.on_connect = on_connect
    client.on_message = on_message
    client.connect(server, port, 30)   # 1883为服务端口号,如果是安全认证,端口号需要修改为1884
    client.loop_forever()

if __name__ == '__main__':
        main()

测试结果:

注意事项

loop()方法在MQTT客户端中也非常重要,它主要是用来去查询消息缓存区。当有新的消息到达时,这些消息会存储在接收缓存区,等待有客户端程序去读取。loop()方法就是一个内置的读取接收和发送缓存区,并分发消息的方法。简单说就是,如果不loop,也不自己去主动读取接收缓存区,就触发不了回调函数,所以要记着写上loop。

Paho python client中提供了3个方法:

loop_forever() --会阻塞程序,其实是周期调用loop()方法,如果程序需要一直处于订阅中的话,可以用这个方法,它也会对客户端进行重连。
loop_start() --会新起一个thread,这个thread会调用loop_forever(),所以也会周期调用loop(),并且会保证客户端自动re-connect
loop() --这个方法只会loop指定的时间(默认1s),只会就结束,不会继续去读取缓存区,所以如果在程序中使用的话,需要自己写个周期调用,并且还要自己处理re-connect上面2个loop方法都可以通过loop.stop()方法来停止。

总结

通过MQTT协议,也就可以让我的树莓派万物互联啦!比如做一个人脸识别小区门禁,实时上传小区业主出入进的数据到物联网平台等等,搞定了物联网部分,其他的创意就留给你们啦!

DFrJ5KYVQaH  中级技匠

发表于 2020-3-16 08:29:49

好文章,收藏学习
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2022 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail