Objectives:
- To serve the teaching goals of Internet of Things (IoT) in the Information Technology (IT) course in senior high schools, include MQTT in the course as a main topic.
- To interact with hardware through MQTT on the Python editor.
- To present MQTT that works behind the user cloud broadcast function; describe the relationships between MQTT and IoT instead of those between user cloud broadcast and IoT; and explain IoT based on the application of MQTT.
- To visualize data through MQTT.
Recommended IoT Learning roadmap:
- Stage 1: user cloud broadcast (use it)
- Stage 2: introductory courses for MQTT (concepts and simple application): mkcloud + cyberpi.mqtt (mkcloud and servers based on mBlock)
- Stage 3: advanced courses for MQTT (advanced application): mqtt.MQTTClient (Hardware) + paha-mqtt (third-party python libraries)
Application scenarios:
In teaching, the MQTT server used is broker.emqx.io (mq.makeblock.com is not recommended by the R&D personnel.).
- CyberPi communicates with the Python editor through MQTT. For example, data collected by sensors of CyberPi can be transmitted to the MQTT server, and the Python editor can receive data from the MQTT server.
- Two CyberPis communicate with each other through MQTT. For example, through MQTT communication, you can use CyberPi A to control the lights of CyberPi B.
- CyberPi can transmit data to and receive data from itself.
Current status:
The MQTT functions have been developed in the mkcloud library.MQTT APIs in the mkcloud library:
The following describes the MQTT APIs in the mkcloud library. You are recommended to add the prefix cyberpi when using them.Note:
The default prefix “MB_PY/“ is added to the topic transmitted by using mkcloud APIs. The prefix is also added when a topic is set to be received.
MQTT APIs in the mkcloud library
# python 3.6
import random
import time
from paho.mqtt import client as mqtt_client
class MqTT:
# default
broker = 'broker.emqx.io'
port = 1883
# generate client ID with pub prefix randomly
client_id = f'py-mqtt-mb-{random.randint(0, 1000)}'
mq_client = mqtt_client.Client(client_id)
is_connect = False
topic_prefix = "MB_PY/"
callback = None
is_on_message = False
def __init__(self):
pass
# version
def version(self):
return "1.0.1"
# set broker
def set_broker(self,client_id,server,port):
if client_id != None:
self.client_id = client_id
self.broker = server
self.port = port
# connect
def connect(self):
self.connect_mq()
self.loop_start()
time.sleep(1.8)
return self.is_connect
# connect server
def connect_mq(self):
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("Connected to MQTT Broker!")
self.is_connect = True
else:
self.is_connect = False
print("Failed to connect, return code %d\n", rc)
self.mq_client = mqtt_client.Client(self.client_id)
self.mq_client.on_connect = on_connect
self.mq_client.connect(self.broker, self.port)
return self.mq_client
# disconnect
def off(self):
self.is_on_message == False
self.is_connect = False
self.mq_client.disconnect()
# publish
def publish_message(self,topic="mb", data="msg"):
topic = self.topic_prefix + topic
result = self.mq_client.publish(topic, data)
# result: [0, 1]
status = result[0] # 0 is ok
return status
def on_message(self,client, userdata, msg):
#print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
self.callback(msg.topic,msg.payload.decode())
# subscribe
def subscribe_message(self,topic):
topic = self.topic_prefix + topic
self.mq_client.subscribe(topic)
if self.is_on_message == False :
self.mq_client.on_message = self.on_message
self.is_on_message = True
# callback
def set_callback(self,callback):
self.callback = callback
self.mq_client.on_message = self.on_message
# loop_start
def loop_start(self):
self.mq_client.loop_start()
# loop_forever
def loop_forever(self):
self.mq_client.loop_forever()
# client
def get_client(self):
return self.mq_client
def get_broker(self):
return self.broker
def get_port(self):
return self.port
def get_topic_prefix(self):
return self.topic_prefix
mqtt = MqTT()
Main APIs:
API | Function |
---|---|
cyberpi.mqtt.set_broker(client_id, server, port) | Sets the MQTT server. Parameters: client_id:(not mandatory) server: str, server address port: int, port number |
cyberpi.mqtt.connect() | Connects to the server. Returned values: True: connected False: connection failed |
cyberpi.mqtt.off() | Disconnects from the server. |
cyberpi.mqtt.publish_message(topic, data) | Publishes messages to specified message queue. Parameters: topic: str, name of the message queue (in functions, the default prefix “MB_PY” is added to the topic automatically). data: str, content in the message |
cyberpi.mqtt.subscribe_message(topic) | Subscribes to the messages of the specified topic. Parameter: topic: str, mq name (in functions, the default prefix “MB_PY” is added to the topic automatically). |
cyberpi.mqtt.set_callback(callback) | Set a callback function to process received messages.(For details, see the MQTT APIs in the mkcloud library.) Parameter: callback: function name. You can define it by yourself. |