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.6import randomimport timefrom paho.mqtt import client as mqtt_clientclass MqTT:# defaultbroker = 'broker.emqx.io'port = 1883# generate client ID with pub prefix randomlyclient_id = f'py-mqtt-mb-{random.randint(0, 1000)}'mq_client = mqtt_client.Client(client_id)is_connect = Falsetopic_prefix = "MB_PY/"callback = Noneis_on_message = Falsedef __init__(self):pass# versiondef version(self):return "1.0.1"# set brokerdef set_broker(self,client_id,server,port):if client_id != None:self.client_id = client_idself.broker = serverself.port = port# connectdef connect(self):self.connect_mq()self.loop_start()time.sleep(1.8)return self.is_connect# connect serverdef connect_mq(self):def on_connect(client, userdata, flags, rc):if rc == 0:print("Connected to MQTT Broker!")self.is_connect = Trueelse:self.is_connect = Falseprint("Failed to connect, return code %d\n", rc)self.mq_client = mqtt_client.Client(self.client_id)self.mq_client.on_connect = on_connectself.mq_client.connect(self.broker, self.port)return self.mq_client# disconnectdef off(self):self.is_on_message == Falseself.is_connect = Falseself.mq_client.disconnect()# publishdef publish_message(self,topic="mb", data="msg"):topic = self.topic_prefix + topicresult = self.mq_client.publish(topic, data)# result: [0, 1]status = result[0] # 0 is okreturn statusdef on_message(self,client, userdata, msg):#print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")self.callback(msg.topic,msg.payload.decode())# subscribedef subscribe_message(self,topic):topic = self.topic_prefix + topicself.mq_client.subscribe(topic)if self.is_on_message == False :self.mq_client.on_message = self.on_messageself.is_on_message = True# callbackdef set_callback(self,callback):self.callback = callbackself.mq_client.on_message = self.on_message# loop_startdef loop_start(self):self.mq_client.loop_start()# loop_foreverdef loop_forever(self):self.mq_client.loop_forever()# clientdef get_client(self):return self.mq_clientdef get_broker(self):return self.brokerdef get_port(self):return self.portdef get_topic_prefix(self):return self.topic_prefixmqtt = 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. |
