Difference between revisions of "Swagbadge2021 MQTT"
(→About the LCA Swagbadge MQTT server) |
Marcmerlin (talk | contribs) (→Making your badge perform) |
||
(5 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
− | = | + | = About MQTT = |
+ | |||
+ | MQTT is a lightweight message platform that uses individual topics (like a slack channel) that people can send messages to (called publishing) or listen for messages on (called subscribing). | ||
+ | |||
+ | MQTT is designed for use on IoT devices. Check out [https://en.wikipedia.org/wiki/MQTT Wikipedia] for some background or [https://mqtt.org/ mqtt.org] for more information on it generally. | ||
== About the LCA Swagbadge MQTT server == | == About the LCA Swagbadge MQTT server == | ||
Line 8: | Line 12: | ||
* The ''upgrade/'' topic path prefix is public read: only Jon and Andy can update it. | * The ''upgrade/'' topic path prefix is public read: only Jon and Andy can update it. | ||
* The ''aiko/'' topic path prefix is public read/write | * The ''aiko/'' topic path prefix is public read/write | ||
+ | * The ''public/'' topic path prefix is available for everyone to read/write | ||
* The ''secret/'' topic path prefix is write-only | * The ''secret/'' topic path prefix is write-only | ||
− | |||
* We have some server monitoring to look for things snooping for all the channels, or who aren't using aiko/on a badge, and mitigations in the event a badge goes beserk and starts a spamming DOS attack. | * We have some server monitoring to look for things snooping for all the channels, or who aren't using aiko/on a badge, and mitigations in the event a badge goes beserk and starts a spamming DOS attack. | ||
You are welcome to change which MQTT server your badge uses, by updating the mqtt.py configuration file. Some publicly hosted alternatives are provided (commented out) in the config. | You are welcome to change which MQTT server your badge uses, by updating the mqtt.py configuration file. Some publicly hosted alternatives are provided (commented out) in the config. | ||
+ | |||
+ | = Controlling your badge over MQTT = | ||
== Making your badge perform == | == Making your badge perform == | ||
Line 25: | Line 31: | ||
<code> | <code> | ||
− | mosquitto_sub -h 101.181.46.180 -t public/esp32_id/0 | + | mosquitto_sub -h 101.181.46.180 -t public/esp32_id/0/# (will receive messages output by the badge like "(boot v04 swagbadge)") |
+ | |||
+ | mosquitto_sub -h 101.181.46.180 -t public/esp32_id/# (shows message sent to the badge) | ||
+ | |||
+ | mosquitto_sub -h 101.181.46.180 -t public/# (show all messages for all badges) | ||
mosquitto_pub -h 101.181.46.180 -t public/esp32_id/0/in -m "(oled:clear)" | mosquitto_pub -h 101.181.46.180 -t public/esp32_id/0/in -m "(oled:clear)" | ||
Line 45: | Line 55: | ||
If you'd like to make your application MQTT aware, take a look at the [https://github.com/geekscape/aiko_engine_mp/blob/master/lib/aiko/oled.py oled code]. | If you'd like to make your application MQTT aware, take a look at the [https://github.com/geekscape/aiko_engine_mp/blob/master/lib/aiko/oled.py oled code]. | ||
+ | |||
+ | = Using MQTT on your badge = | ||
+ | |||
+ | == Over Aiko == | ||
+ | |||
+ | Aiko has some convenience handlers to make using MQTT easier. | ||
+ | |||
+ | Behind the scenes, Aiko routes messages to the specific handlers matching a given topic and supports multiple handlers “listening” to various specific topics. There is an exception handler wrapped around every message handler, so that the overall MQTT thread doesn’t fail. | ||
+ | |||
+ | === Receiving a message and taking action === | ||
+ | |||
+ | '''Subscribe to a topic''' | ||
+ | Update ''configuration/mqtt.py'' and add in the topic to the <code>topic_subscribe</code> list | ||
+ | "topic_subscribe": [ "$me/in", "$me/exec", upgrade_topic, "YOUR_TOPIC" ], | ||
+ | |||
+ | If you want to listen/subscribe to all sub-topics, use a <code>#</code> at the end. For example <code>public/chocolate/#</code> will listen to public/chocolate and public/chocolate/lindt and public/chocolate/kokoblack and public/chocolate/ganache | ||
+ | |||
+ | See https://github.com/geekscape/aiko_engine_mp/blob/master/configuration/mqtt.py#L13 as well as line 132 and 63 | ||
+ | |||
+ | '''Handle messages on that topic''' | ||
+ | |||
+ | Define a message handler function, which takes a topic argument (in case you use the same message handler for multiple topics), and the payload (the message that was seen) | ||
+ | def on_message(topic, payload_in): | ||
+ | print(topic + ": " + payload_in) | ||
+ | |||
+ | Add this handler function to the MQTT client: this is typically done in your application's initialise() method. | ||
+ | mqtt.add_message_handler(on_message, "YOUR_TOPIC") | ||
+ | |||
+ | '''Example code''' | ||
+ | |||
+ | Here is a complete application example … https://github.com/geekscape/aiko_engine_mp/blob/master/applications/step_controller.py | ||
+ | |||
+ | In this case, Aiko’s general MQTT on_message() handler will route all incoming messages to the specific handlers matching a given topic and supports multiple handlers “listening” to various specific topics. There is an exception handler wrapped around every message handler … so that the MQTT thread doesn’t fail. And over time Aiko’s error handling will improve, e.g re-subscribe to all MQTT topics on reconnection, etc. At some point, Aiko will provide the heavy lifting for encrypted message publish / subscribe. Finally, once Aiko Services (a general purpose distributed / embedded system) is released, then our ESP32 devices can become first-class citizens of a broader distributed service-based network (perhaps a month or so away). Aiko also supports some “dangerous” fun, like opt-in enabling receiving microPython code as an MQTT message and executing it (obviously this is dangerous) | ||
+ | |||
+ | === Publishing a message === | ||
+ | |||
+ | Use the aiko mqtt client object to send a message. | ||
+ | |||
+ | from aiko.mqtt import client | ||
+ | client.publish(topic, message) | ||
+ | |||
+ | Which topic to use? On our LCA server, we are constrained to only use the 'public' and 'aiko' prefixed topics. | ||
+ | |||
+ | To keep things neat and orderly, we recommend using | ||
+ | ;public/esp32_SERIAL_ID/YOUR_TOPIC_HERE: for topics specific to your personal swagbadge | ||
+ | ;public/SUBJECT/YOUR_TOPIC_HERE: for topics intended to share information with multiple swagbadges | ||
+ | |||
+ | == Going direct to MQTT == | ||
+ | |||
+ | Since Aiko already makes an MQTT connection (to our server), you don’t need to make another MQTT connect, unless you want to interact with multiple MQTT servers (beyond the MQTT server already configured in ''configuration/mqtt.py''. | ||
+ | |||
+ | You can use the Aiko MQTT client object reference to access any of the MQTT library functions … | ||
+ | >>> import aiko.mqtt.client as mqttclient | ||
+ | >>> help(aiko.mqtt.client) | ||
+ | |||
+ | [https://github.com/geekscape/aiko_engine_mp/blob/master/lib/umqtt/simple.py All of the available MQTT Client functions] | ||
+ | |||
+ | |||
+ | === MQTT message publishing === | ||
+ | |||
+ | you can always use the Aiko MQTT client object to publish messages to any topic … to which you have access permission. | ||
+ | On our MQTT server, that is read / write access to aiko/# and public/#. By default, each #swagbadge will be using public/esp32_SERIAL_ID/0/# as their own topic path prefix and using specific topic paths under that, e.g public/esp32_SERIAL_ID/0/in (all #swagbadges subscribe to that topic path aka $me/in … where Aiko substitutes the topic path prefix for $me) and publish on public/esp32_SERIAL_ID/0/out: | ||
+ | <pre> | ||
+ | aiko.mqtt.client.publish(topic, payload) | ||
+ | </pre> | ||
+ | |||
+ | So for example, you could use: | ||
+ | * public/esp32_SERIAL_ID/WHATEVER_YOU_LIKE … recommended for topics specific to interacting with your #swagbadge | ||
+ | * public/nicola/WHATEVER_YOU_LIKE … recommended for topics where you’d like to share information with a bunch of #swagbadges, i.e not specific to your #swagbadge | ||
+ | |||
+ | It doesn’t matter too much apart from being tidy and organised. If everyone follows reasonable conventions, then it is more orderly, e.g like taking care of a filesystem layout. | ||
+ | |||
+ | = Encrypting messages with your badge = | ||
+ | |||
+ | Placeholder text. |
Latest revision as of 22:08, 23 January 2021
Contents
About MQTT
MQTT is a lightweight message platform that uses individual topics (like a slack channel) that people can send messages to (called publishing) or listen for messages on (called subscribing).
MQTT is designed for use on IoT devices. Check out Wikipedia for some background or mqtt.org for more information on it generally.
About the LCA Swagbadge MQTT server
The badges have MQTT configured to talk to a dedicated server hosted by Andy Gelme, one of the OHMC organisers. We have done this for security and privacy reasons, and because it gives us an Australian server so it's faster.
This server is at 101.181.46.180
, the configuration for which is held on the badge at configuration/mqtt.py. The server has some special features:
- The upgrade/ topic path prefix is public read: only Jon and Andy can update it.
- The aiko/ topic path prefix is public read/write
- The public/ topic path prefix is available for everyone to read/write
- The secret/ topic path prefix is write-only
- We have some server monitoring to look for things snooping for all the channels, or who aren't using aiko/on a badge, and mitigations in the event a badge goes beserk and starts a spamming DOS attack.
You are welcome to change which MQTT server your badge uses, by updating the mqtt.py configuration file. Some publicly hosted alternatives are provided (commented out) in the config.
Controlling your badge over MQTT
Making your badge perform
The easiest thing to do is send messages to show up on your screens.
- Install an mqtt client on your machine
- Connect to the mqtt server (if you forget what it is, the IP address is shown on bootup)
- Using your badge's topic (public/esp32_your_badge_id/0/in) send it a message
Messages are usually in the form of (component:command arguments)
.
mosquitto_sub -h 101.181.46.180 -t public/esp32_id/0/# (will receive messages output by the badge like "(boot v04 swagbadge)")
mosquitto_sub -h 101.181.46.180 -t public/esp32_id/# (shows message sent to the badge)
mosquitto_sub -h 101.181.46.180 -t public/# (show all messages for all badges)
mosquitto_pub -h 101.181.46.180 -t public/esp32_id/0/in -m "(oled:clear)"
mosquitto_pub -h 101.181.46.180 -t public/esp32_id/0/in -m "(oled:pixel 64 32)"
mosquitto_pub -h 101.181.46.180 -t public/esp32_id/0/in -m "(oled:text 0 50 Hello World)"
OLED messages
- (oled:clear)
- clears both screens
- (oled:log Hello World!)
- writes a message along the bottom of the screens, scrolling up whatever is there out of the way
- (oled:pixel x y)
- lights a pixel at that spot
- (oled:text x y This is a test !)
- Puts some text at the position x,y. It will be displayed over the top of whatever's there.
If you'd like to make your application MQTT aware, take a look at the oled code.
Using MQTT on your badge
Over Aiko
Aiko has some convenience handlers to make using MQTT easier.
Behind the scenes, Aiko routes messages to the specific handlers matching a given topic and supports multiple handlers “listening” to various specific topics. There is an exception handler wrapped around every message handler, so that the overall MQTT thread doesn’t fail.
Receiving a message and taking action
Subscribe to a topic
Update configuration/mqtt.py and add in the topic to the topic_subscribe
list
"topic_subscribe": [ "$me/in", "$me/exec", upgrade_topic, "YOUR_TOPIC" ],
If you want to listen/subscribe to all sub-topics, use a #
at the end. For example public/chocolate/#
will listen to public/chocolate and public/chocolate/lindt and public/chocolate/kokoblack and public/chocolate/ganache
See https://github.com/geekscape/aiko_engine_mp/blob/master/configuration/mqtt.py#L13 as well as line 132 and 63
Handle messages on that topic
Define a message handler function, which takes a topic argument (in case you use the same message handler for multiple topics), and the payload (the message that was seen)
def on_message(topic, payload_in): print(topic + ": " + payload_in)
Add this handler function to the MQTT client: this is typically done in your application's initialise() method.
mqtt.add_message_handler(on_message, "YOUR_TOPIC")
Example code
Here is a complete application example … https://github.com/geekscape/aiko_engine_mp/blob/master/applications/step_controller.py
In this case, Aiko’s general MQTT on_message() handler will route all incoming messages to the specific handlers matching a given topic and supports multiple handlers “listening” to various specific topics. There is an exception handler wrapped around every message handler … so that the MQTT thread doesn’t fail. And over time Aiko’s error handling will improve, e.g re-subscribe to all MQTT topics on reconnection, etc. At some point, Aiko will provide the heavy lifting for encrypted message publish / subscribe. Finally, once Aiko Services (a general purpose distributed / embedded system) is released, then our ESP32 devices can become first-class citizens of a broader distributed service-based network (perhaps a month or so away). Aiko also supports some “dangerous” fun, like opt-in enabling receiving microPython code as an MQTT message and executing it (obviously this is dangerous)
Publishing a message
Use the aiko mqtt client object to send a message.
from aiko.mqtt import client client.publish(topic, message)
Which topic to use? On our LCA server, we are constrained to only use the 'public' and 'aiko' prefixed topics.
To keep things neat and orderly, we recommend using
- public/esp32_SERIAL_ID/YOUR_TOPIC_HERE
- for topics specific to your personal swagbadge
- public/SUBJECT/YOUR_TOPIC_HERE
- for topics intended to share information with multiple swagbadges
Going direct to MQTT
Since Aiko already makes an MQTT connection (to our server), you don’t need to make another MQTT connect, unless you want to interact with multiple MQTT servers (beyond the MQTT server already configured in configuration/mqtt.py.
You can use the Aiko MQTT client object reference to access any of the MQTT library functions …
>>> import aiko.mqtt.client as mqttclient >>> help(aiko.mqtt.client)
All of the available MQTT Client functions
MQTT message publishing
you can always use the Aiko MQTT client object to publish messages to any topic … to which you have access permission. On our MQTT server, that is read / write access to aiko/# and public/#. By default, each #swagbadge will be using public/esp32_SERIAL_ID/0/# as their own topic path prefix and using specific topic paths under that, e.g public/esp32_SERIAL_ID/0/in (all #swagbadges subscribe to that topic path aka $me/in … where Aiko substitutes the topic path prefix for $me) and publish on public/esp32_SERIAL_ID/0/out:
aiko.mqtt.client.publish(topic, payload)
So for example, you could use:
- public/esp32_SERIAL_ID/WHATEVER_YOU_LIKE … recommended for topics specific to interacting with your #swagbadge
- public/nicola/WHATEVER_YOU_LIKE … recommended for topics where you’d like to share information with a bunch of #swagbadges, i.e not specific to your #swagbadge
It doesn’t matter too much apart from being tidy and organised. If everyone follows reasonable conventions, then it is more orderly, e.g like taking care of a filesystem layout.
Encrypting messages with your badge
Placeholder text.