Created
October 16, 2017 00:17
-
-
Save ccooper21/cf956344c0a1428a0c1a9aa71edd4205 to your computer and use it in GitHub Desktop.
Example MicroPython MQTT over WebSocket script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This example script requires the MicroPython changes in the following branches: | |
# | |
# https://github.com/ccooper21/micropython/tree/websocket-client-support | |
# https://github.com/ccooper21/micropython-lib/tree/umqtt.simple-websocket-support | |
import usocket as socket | |
import utime as time | |
from websocket import websocket | |
from umqtt.simple import MQTTClient | |
# Create a TCP socket and connect it to the MQTT broker | |
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
addr = socket.getaddrinfo(b'broker.mqttdashboard.com', 8000)[0][-1] | |
s.connect(addr) | |
# Negotiate the WebSocket protocol upgrade via HTTP. This is most easily | |
# done by simulating an HTTP request with the necessary headers. There is no | |
# need to bust out a full HTTP implementation. | |
# | |
# TODO: Generate the value for the "Sec-WebSocket-Key" header dynamically. | |
s.write(b'''\ | |
GET /mqtt HTTP/1.1\r | |
Host: broker.mqttdashboard.com:8000\r | |
Connection: Upgrade\r | |
Upgrade: websocket\r | |
Sec-WebSocket-Key: aSk+xCH/A9ZbxvqjxF8itg==\r | |
Sec-WebSocket-Version: 13\r | |
\r | |
''') | |
# TODO: Validate the response to the websocket upgrade request. This can be | |
# done by checking the HTTP response code and validating the | |
# "Sec-WebSocket-Accept" header. | |
l = s.readline() | |
while l: | |
if l == b'\r\n': | |
break | |
l = s.readline() | |
# Now that the WebSocket protocol upgrade negotiation is complete, create a | |
# WebSocket from the TCP socket connected to the MQTT broker. | |
ws = websocket(s) | |
# Create an MQTT client | |
# | |
# TODO: Generate the client ID dynamically. | |
keepalive = 60 | |
client = MQTTClient('clientId-g47Izb6dPK', sock=ws, keepalive=keepalive) | |
def on_message_received(topic, message): | |
print('Message received: topic=%s, message=%s' % (topic, message)) | |
client.set_callback(on_message_received) | |
# Publish messages to and receive messages from the MQTT broker forever | |
connected = False | |
topic = b'testtopic/1' | |
while True: | |
if not connected: | |
print('Connecting...') | |
client.connect() | |
connected = True | |
last_publish = 0 | |
last_ping = time.ticks_ms() | |
print('Connected') | |
print('Subscribing to topic %s...' % (topic,)) | |
client.subscribe(topic) | |
print('Subscribed') | |
else: | |
# Periodically ping the broker consistently with the "keepalive" | |
# argument used when connecting. If this isn't done, the broker will | |
# disconnect when the client has been idle for 1.5x the keepalive | |
# time. | |
if time.ticks_ms() - last_ping >= keepalive * 1000: | |
client.ping() | |
last_ping = time.ticks_ms() | |
# Every 5 minutes publish a message for fun. | |
if time.ticks_ms() - last_publish >= 5 * 60 * 1000: | |
print('Publishing a message to topic %s...' % (topic,)) | |
client.publish(topic, 'Coming from MicroPython via a websocket @%d' % (time.ticks_ms(),)) | |
last_publish = time.ticks_ms() | |
print('Published') | |
# Receive the next message if one is available, and handle the case that | |
# the broker has disconnected. | |
try: | |
client.check_msg() | |
except OSError as e: | |
if str(e) == '-1': | |
ws.close() | |
connected = False | |
print('Connection closed') | |
continue | |
# Sleep a little to not needlessly burn processor cycles. | |
#time.sleep(0.5) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment