Flask Extension for the MQTT protocol. Basically it is a thin wrapper around paho-mqtt and aims to simplify MQTT integration in Flask. MQTT is a machine-to-machine "Internet of Things" protocol and was designed for extremely lightweight publish/subscribe messaging transport.
Find the documentation on http://flask-mqtt.readthedocs.io.
- configuration via Flask config variables
- auto-connect on start of your web application
- publish and subscribe messages
- connect to multiple MQTT servers
- use callbacks for certain topics
- use one callback for all subscribed topics
Flask-MQTT was developed to provide an easy-to-setup solution for interacting with IoT devices. A typical scenario would be a Raspberry Pi running a mosquitto mqtt server combined with a Flask webserver.
Flask-MQTT is currently not suitable for the use with multiple worker instances. So if you use a WSGI server like gevent or gunicorn make sure you only have one worker instance.
Make sure to disable Flasks autoreloader. If activated it spawns two instances of a Flask application. This leads to the same problems as multiple workers. To prevent Flask-MQTT from running code twice it is necessary to deactivate the automatic reloader.
Simply install the package as usual via pip:
$ pip install flask-mqtt
Or with conda from the conda-forge channel:
$ conda config --add channels conda-forge
$ conda install flask-mqtt
from flask import Flask
from flask_mqtt import Mqtt
app = Flask(__name__)
app.config['MQTT_BROKER_URL'] = 'mybroker.com'
app.config['MQTT_BROKER_PORT'] = 1883
app.config['MQTT_USERNAME'] = 'user'
app.config['MQTT_PASSWORD'] = 'secret'
app.config['MQTT_REFRESH_TIME'] = 1.0 # refresh time in seconds
mqtt = Mqtt(app)
@app.route('/')
def index():
return render_template('index.html')
To subscribe to a topic simply use mqtt.subscribe()
. To make sure the
subscription gets handled correctly on startup place the subscription inside
an on_connect()
callback function.
@mqtt.on_connect()
def handle_connect(client, userdata, flags, rc):
mqtt.subscribe('home/mytopic')
To handle the subscribed messages you can define a handling function by
decorating it with @mqtt.on_message()
.
@mqtt.on_message()
def handle_mqtt_message(client, userdata, message):
data = dict(
topic=message.topic,
payload=message.payload.decode()
)
To unsubscribe do:
mqtt.unsubscribe('home/mytopic')
Or if you want to unsubscribe all topics use unsubscribe_all()
.
mqtt.unsubscribe_all()
To publish a message you can use the publish()
method.
mqtt.publish('home/mytopic', 'this is my message')
To connect to multiple servers, you can create multiple mqtt clients in your application by specifying the config_prefix
when initializing Mqtt()
# default mqtt client
app.config["MQTT_broker_url"] = "example.com"
app.config["MQTT_broker_port"] = 8883
mqtt = Mqtt(app)
# create second mqtt client for a different broker
app.config["MQTT2_broker_url"] = "example2.com"
app.config["MQTT_broker_port"] = 1883
mqtt2 = Mqtt(app, config_prefix="MQTT2")
# create third mqtt client for a different broker
app.config["MQTT3_broker_url"] = "example3.com"
app.config["MQTT3_broker_port"] = 1885
mqtt3 = Mqtt(app, config_prefix="MQTT3")
"""
A small Test application to show how to use Flask-MQTT.
"""
import eventlet
import json
from flask import Flask, render_template
from flask_mqtt import Mqtt
from flask_socketio import SocketIO
from flask_bootstrap import Bootstrap
eventlet.monkey_patch()
app = Flask(__name__)
app.config['SECRET'] = 'my secret key'
app.config['TEMPLATES_AUTO_RELOAD'] = True
app.config['MQTT_BROKER_URL'] = 'broker.hivemq.com'
app.config['MQTT_BROKER_PORT'] = 1883
app.config['MQTT_USERNAME'] = ''
app.config['MQTT_PASSWORD'] = ''
app.config['MQTT_KEEPALIVE'] = 5
app.config['MQTT_TLS_ENABLED'] = False
app.config['MQTT_CLEAN_SESSION'] = True
# Parameters for SSL enabled
# app.config['MQTT_BROKER_PORT'] = 8883
# app.config['MQTT_TLS_ENABLED'] = True
# app.config['MQTT_TLS_INSECURE'] = True
# app.config['MQTT_TLS_CA_CERTS'] = 'ca.crt'
mqtt = Mqtt(app)
socketio = SocketIO(app)
bootstrap = Bootstrap(app)
@app.route('/')
def index():
return render_template('index.html')
@socketio.on('publish')
def handle_publish(json_str):
data = json.loads(json_str)
mqtt.publish(data['topic'], data['message'])
@socketio.on('subscribe')
def handle_subscribe(json_str):
data = json.loads(json_str)
mqtt.subscribe(data['topic'])
@socketio.on('unsubscribe_all')
def handle_unsubscribe_all():
mqtt.unsubscribe_all()
@mqtt.on_message()
def handle_mqtt_message(client, userdata, message):
data = dict(
topic=message.topic,
payload=message.payload.decode()
)
socketio.emit('mqtt_message', data=data)
@mqtt.on_log()
def handle_logging(client, userdata, level, buf):
print(level, buf)
if __name__ == '__main__':
# important: Do not use reloader because this will create two Flask instances.
# Flask-MQTT only supports running with one instance
socketio.run(app, host='0.0.0.0', port=5000, use_reloader=False, debug=False)