嗨!今天要说明在Flask
使用MQTT
通讯协定做资料传输!
以前我都是使用nodejs
实现,用Flask
是因为我的小伙伴忙着解其他Bug所以我就帮他试了,顺便介绍一下MQTT的基本概念。
nodejs
怎么实现MQTT
:推荐好伙伴的GitHub : node-js protocol MQTT
Summary
MQTT IntroductionInstall MQTT ServerFlask MQTT Getting StartedExampleMQTT Introduction
MQTT是一种 machine-to-machine(M2M)的轻量级通讯协定,可以让各种设备互相沟通,所需要的运算与传输频宽很低。
MQTT的传送方式是藉由MQTT broker做分发,如下图:
Sensor端接收到温度之后,透过Publish
将收到的资料发送,让Subscribe
端接收,一次可能会有好多组Publish与Subscribe,就是透过中间的broker
端去根据不同的主题(Topic)做资料派送。
Install MQTT server
理解MQTT的概念之后就可以来安装broker了,这边我们安装一个叫做Mosquitto
的伺服器。
Mac OS
Mac只需要用brew
安装就好:
$ brew install mosquitto
完成之后,打开伺服器服务:
$ brew services start mosquitto
Ubuntu
$ sudo apt-get install mosquitto mosquitto-clients
好了之后来测试一下Mosquitto
,打开两个终端机:
mosquitto_sub
$ mosquitto_sub -h localhost -t test
发送: mosquitto_pub
$ mosquitto_pub -h localhost -t test -m "Hello world!"
发送之后就可以看到订阅端的终端机收到Hello world!
了
-h
: host 没有特别打的话预设是localhost
。-t
: Topic 主题,订阅跟发送端需要同一个主题,上面我们设定的主题都是test
。-m
: 发送端多了-m
,后面打上要发送的内容。Flask MQTT getting started
介绍MQTT之后,来试着在Flask中加上MQTT的发送与接收吧,Flask的详细这边就不多做解释了,在Flask中有个叫做flask_mqtt
的套件,可以轻鬆的使用MQTT功能。
pip
安装flask_mqtt
:$ pip insatll flask_mqtt
基本的设定:from flask import Flaskfrom flask_mqtt import Mqttapp = Flask(__name__)app.config['MQTT_BROKER_URL'] = 'localhost'app.config['MQTT_BROKER_PORT'] = 1883app.config['MQTT_REFRESH_TIME'] = 1.0 mqtt = Mqtt(app)@app.route('/')def index(): return 'hello world'
MQTT subscribe:MQTT的订阅只需要简单的使用:
mqtt.subscribe('myTopic')
,要让启动(前面的设定)之后正确处理我们的订阅,我们需要将订阅方法放在一个on_connect()
,callback function内:@mqtt.on_connect()def handle_connect(client, userdata, flags, rc): mqtt.subscribe('mytopic')
MQTT publish:mqtt.publish('mytopic', 'any message you want to pubish')
MQTT message :收到讯息后我们可以用
on_message()
,来读取收到的内容:@mqtt.on_message()def handle_mqtt_message(client, userdata, message): topic=message.topic, payload=message.payload.decode()
message.topic
: 收到的主题。message.payload.decode()
: 该主题的内容。Example
最后来看一下範例吧,在这之前我们先基本设定:
Setup:
from flask import Flaskfrom flask_mqtt import Mqttfrom flask import render_templateapp = Flask(__name__)app.config['MQTT_BROKER_URL'] = '127.0.0.1'app.config['MQTT_BROKER_PORT'] = 1883app.config['MQTT_REFRESH_TIME'] = 1.0 mqtt = Mqtt(app)if __name__ == '__main__': app.run(debug=True)
建立一个基本的route
(这里其实可以省略)@app.route('/')def index(): return 'Index Hello World'
Example 1 - publish from GET
建立一个GET API:在URL的部分增加一个
<want_to_pub>
接收变数,function内会先判断是否有内容。有的话mqtt
会将want_to_pub
的内容当作msg发送给订阅mytopic
主题的订阅端。@app.route('/api/v1.0/mqtt/pub/<want_to_pub>', methods=['GET'])def pub_my_msg(want_to_pub): if len(want_to_pub) == 0: abort(404) mqtt.publish('mytopic',want_to_pub ) return want_to_pub
Test Example 1
好了之后来测试是否成功,到 localhost:5000 (此为Flask预设),看是否有看到页面上有Index Hello World
字样。此处成功之后到localhost:5000/api/v1.0/mqtt/pub/会看到Not Found
字样,这是正常的,因为我们后面没有加上任何东西。
$ mosquitto_sub -t mytopic
发送接着
localhost:5000/api/v1.0/mqtt/pub/
后面加上任何想发送的讯息例如我想传送
mymsg
:localhost:5000/api/v1.0/mqtt/pub/mymsg可以看到网页端:
mymsg
这样就成功了!
Example 2 - Subscribe
接下来要来测试订阅功能了,这个範例主要是终端机发布Json讯息,让Flask订阅。
为了解析Json内容,我们要先在程式码内新增:
import json
订阅:@mqtt.on_connect()def handle_connect(client, userdata, flags, rc): mqtt.subscribe('mytopic')
收到讯息解析:@mqtt.on_message()def handle_mqtt_message(client, userdata, message): payload = message.payload.decode() p = json.loads(payload) print("-------msg-------") print('name :', p['name']) print('email :', p['email'])
好了之后就可以执行了。
发布讯息,开启一终端机:mosquitto_pub -t mytopic -m '{"name" : "Jack mqtt", "email":"jack@mqtt.example.com" }'
确认有收到讯息(如下图),就成功了!Flask-MQTT
使用方法可以到:GitHub - stlehmann/Flask-MQTT
谢谢大家!掰掰~