====== MQTT Message Bus ======
Hostname: mqtt.hacklab\\
Port: 1883
===== Warning =====
* Do not use the MQTT network for evil.
* Do not annoy other lab users (especially with sound or lighting).
* Do not be the reason for new rules.
===== Quick Example =====
mosquitto_sub -h mqtt.hacklab -t '#' -v # listen to all messages
mosquitto_sub -h mqtt.hacklab -t 'sensor/g1/temperature' -v # listen to a single topic
mosquitto_pub -h mqtt.hacklab -t 'display/g1/leds' -m red # send a message
mosquitto_pub -h mqtt.hacklab -t 'dali/g1/preset/harmony' -n # send an empty message
===== Devices =====
[[private:mqtt_devices|MQTT Smart devices login/Documentation]]
===== Sensors =====
^ Topic ^ Payload ^ Notes ^
| sensor/g1/lightlevel | 0-100 | |
| sensor/g1/temperature | float, deg-C | |
| sensor/g11/temperature/28767aa8040000cf | float, deg-C | Store Room, supply fan |
| sensor/g11/temperature/28c483a704000069 | float, deg-C | Store Room, extract fan |
| sensor/g11/temperature/28c893a704000068 | float, deg-C | Store Room, corridor outside |
^ Topic ^ Payload ^ Notes ^
| sensor/g1/pir | (none) | Sent when PIR sensor is triggered in G1 |
| sensor/g2/pir | (none) | Sent when PIR sensor is triggered in G2 |
| sensor/g8/pir | (none) | Sent when PIR sensor is triggered in G8 |
| sensor/g11/pir | (none) | Sent when PIR sensor is triggered in G11 |
| sensor/g1/presence | active/idle/empty | |
| sensor/g2/presence | active/idle/empty | |
| sensor/g8/presence | active/idle/empty | |
| sensor/g11/presence | active/idle/empty | |
| sensor/global/presence | active/idle/empty | Summary of the per-room status (e.g. if any room is "active" then the global output is also "active") |
| sensor/g1/door | open/closed/secure | closed="closed but unlocked", secure="closed and locked" |
| sensor/g2/door | open/closed/secure | |
| sensor/g8/door | open/closed/secure | |
| sensor/g11/door | open/closed/secure | |
| sensor/entrance/door | open/closed/secure | Do not use. No door sensor so always reports "open" |
| sensor/hgt/door | open/closed/secure | Do not use. No door sensor so always reports "open" |
| sensor/g1/window | open/secure | |
| sensor/g11/current/1 | float, amps | |
^ Topic ^ Payload ^ Notes ^
| sensor/discobot/input/ | low, high | General purpose inputs from the "discobot" board in G1 |
===== Lab Status =====
This sets the labs public open/closed status. Changing the value will cause an IRC notification and changes on SpaceAPI and the website. A notification will also appear on [[https://twitter.com/edinhacklabopen]].
^ Topic ^ Payload ^ Notes ^
| labstatus | open, closed | |
When updating, the message should be sent with retain=True.
===== Tools =====
^ Topic ^ Payload ^ Notes ^
| tool/lasercutter/active | 0=no, 1=yes | Is the laser cutter running a job? |
| tool/lasercutter/power | 0-1023 | |
| tool/lasercutter/temperature/ambient | float, deg-C | Air temperature near the device |
| tool/lasercutter/temperature/reservoir | float, deg-C | Water temperature in the main reservoir |
| tool/lasercutter/temperature/chiller | float, deg-C | Water temperature in the chiller reservoir |
| tool/lasercutter/time/power | float, seconds | Time spent powered-up |
| tool/lasercutter/time/session | float, seconds | Time spent in a cutting session |
| tool/lasercutter/time/cutting | float, seconds | Time spent with the laser active |
| tool/lasercutter/time/analog | float, seconds | Time spent with the laser active, adjusted by power level |
| tool/lasercutter/pulse_count | integer | |
| tool/lasercutter/error_count | integer | |
| tool/lasercutter/combined_laser_stats | json | Legacy formatted data for compatibility with existing script |
| tool/lasercutter/combined_temperature_stats | json | Legacy formatted data for compatibility with existing script |
| tool/dustextractor | 0=off, 1=on | Control the big dust extractor in the workshop |
Access-controlled tools (read-only values):
^ Topic ^ Payload ^ Notes ^
| tool//status | active, standby, idle, offline | |
| tool//user | string, username | current or previous username |
| tool//current | float, amps | |
| tool//sketch_md5 | string | md5 of currently-running firmware |
===== Environment =====
^ Topic ^ Payload ^ Notes ^
| environment/g1/extractor | 0=off, 1=on | [[https://github.com/edinburghhacklab/circuitpython_remote_relay|Controlled]] by {{:23-10-24_21-50-40_2656.jpg?linkonly|ESP32-S2 relay board}}. Debugging feedback availble on //debug/esp-487f307d5dad// |
| environment/g1/heating | 0-30, off | Send a numeric value to set a target temperature for G1, off to turn the heating off. Mark the message as retained in case the thermostat script is restarted. |
| environment/g2/heating | 0-30, off | Send a numeric value to set a target temperature for G2, off to turn the heating off. Mark the message as retained in case the thermostat script is restarted. |
| environment/g8/extraction | off/on | Wall extractor in workshop |
| environment/g14/heating | 0-30, off | Send a numeric value to set a target temperature for G14, off to turn the heating off. Mark the message as retained in case the thermostat script is restarted. |
| espurna/g1-ceiling-air-purifier/relay/0/set | 0=off, 1=on | G1 Ceiling Air purifier (Smart Air Sqair) |
===== Lighting =====
^ Topic ^ Payload ^ Notes ^
| display/mirrorball/lights | 0=off, 1=on | |
| display/mirrorball/speed | 0-75 | |
The ceiling lights in the main (G1) room are connected via a DALI bus. They can be controlled by selecting a preset, setting individual light levels or by passing a script.
^ Topic ^ Payload ^ Notes ^
| dali/g1/preset/ | (none) | preset=off/dim/bright/corners/movie/comfort/presentation/harmony/random or preset= |
| dali/g1/set/ | [[g1_lighting#dali_light_level_presets|0-254]] | light-id=[[g1_lighting#dali_addresses|0-17]], light-id=all, or light-id=social (just the end of the room with the kitchen) |
| dali/g1/script | json-formatted script | [["set", 5,0], ["delay",2000], ["set_all",254]]
will set light number 5 to zero, wait for 2 seconds, then set everything to 254|
^ Topic ^ Payload ^ Notes ^
| display/g1/blacklights/relay/0/set | 0=off 1=on | Switch the G1 blacklight on/off |
| display/g1/big_fricking_bulb | 0=off 1=on 2=toggle | Switch the giant 5W LED bulb on/off |
===== Displays =====
==== Ferrograph Rhapsody LED Display ====
The [[rhapsodydisplay|Ferrograph Rhapsody LED Display]] is configured to display a list of message chunks on it's main scrolling area. Use the //submessage// topic below to add a message to the scroller. Messages time out after 10 minutes, so resend the message every 1-5 minutes using the same //id//.
^ Topic ^ Payload ^ Notes ^
| display/rhapsody/submessage | {"id": "", "message": "text..."} | Optional attributes: colour: red/yellow/green/multi, priority: 1-100 (low values will be shown first, default=10). Max length 169 chars, 170+ crashes the script (length limit is lower for multi-colour). |
| display/rhapsody/raw | raw data | Send raw messages to Rhapsody display (not recommended) |
| display/rhapsody/reset | | Reset the Rhapsody display (only required if the display is corrupted) |
==== Doorbot ====
The wooden box by the door in G1, with two buttons and a 16x2 LCD:
^ Topic ^ Payload ^ Notes ^
| display/doorbot/message | text | Two lines of 16 characters each. Use \n to separate lines. |
| display/doorbot/flash | text | As for //message//, but original message will be restored after 2 seconds. |
| display/doorbot/contrast | 0-255 | |
| display/doorbot/backlight | 0-255 | |
| display/doorbot/buttons/red/shortpress | (none) | Sent by device, do not write |
| display/doorbot/buttons/red/longpress | (none) | Sent by device, do not write |
| display/doorbot/buttons/red/state | up, down | Sent by device, do not write |
| display/doorbot/buttons/green/shortpress | (none) | Sent by device, do not write |
| display/doorbot/buttons/green/longpress | (none) | Sent by device, do not write |
| display/doorbot/buttons/green/state | up, down | Sent by device, do not write |
==== G1 LED strip (the one that goes around the edge of the room) ====
^ Topic ^ Payload ^ Notes ^
| display/g1/leds | | css3 web colours or hex values (e.g. ff0000) |
| display/g1/leds | | choose name from list below |
| display/g1/leds/brightness | [0-100] | changes the brightness of the leds to //n// percent |
| display/g1/leds/picker/json | | When in the pixelpicker preset send the following example payload, '{"1":[255, 255, 0], "2":[0, 0, 255]}' , this will set LED 1 to yellow, and LED 2 to blue |
=== Presets ===
* rainbow
* zap
* chase
* test
* pixelpicker
* redalert
* emergency
* xmas
* cyber
== Pride flags ==
* lessbeans / lesbinyan
* nyanbinary
* pan
* trains / trams
The LEDs can also be addressed in real time via a UDP network protocol. See [[https://gist.github.com/timhawes/910ee6b5bf9c36833235b0e075f01cbf|this example]].
The strip is controlled by ledpi.hacklab, a pi 2 in the corner of the ceiling of G1. All code is in /opt/leds/. See README there for more info.
==== G1 LED String ====
The one that goes across the ceiling in the middle of the room.
These are running the WLED firmware, which is ridiculously comprehensive and can talk to basically everything. However, MQTT seems to have been disabled.
There is a web interface at http://wled-ceiling-string.hacklab.
Full MQTT docs at https://github.com/Aircoookie/WLED/wiki/MQTT
^ Topic ^ Payload ^ Notes ^
| display/g1/wled/$STRIP_NAME | 0-255, "ON", "OFF", or "T" | "T" means toggle |
| display/g1/wled/$STRIP_NAME/col | #RRGGBB | |
|||STRIP_NAME can be replaced with "dangle" for the strip dangling in G1 or "all" for every strip running this firmware in G1|
==== G1 Warning Turret ====
^ Topic ^ Payload ^ Notes ^
| display/g1/turret/red | 0=off 1=on | Turns on the red band on the Turret light |
| display/g1/turret/amber| 0=off 1=on | Turns on the amber band on the Turret light |
| display/g1/turret/green| 0=off 1=on | Turns on the green band on the Turret light |
==== NEC Digital Signage Display ====
^ Topic ^ Payload ^ Notes ^
| display/nec/image | Image URL | Display an image on the screen |
==== Shorekarn scrolling display (in G1 window) ====
^ Topic ^ Payload ^ Notes ^
| display/shorekarn/message | text | |
| Not currently set up |||
==== New Window display ====
^ Topic ^ Payload ^ Notes ^
| display/g1/windowled/text | text | seems to slow down render with large text|
| display/g1/windowled/colour | r,g,b | comma separated string of red, green, and blue (0-255) Takes effect on next text change |
==== G1 Projector ====
^ Topic ^ Payload ^ Notes ^
| display/g1/projector/on | empty | Turns on projector |
| display/g1/projector/off | empty | Turns off projector |
| display/g1/projector/channel | text | Changes channel of radio to one of hdmi, vga, or svideo |
==== Chart ====
The blinky chart of the West of Scotland in G1.
Note: Lighting mode may be overriden by hardware nya nya switch.
^ Topic ^ Payload ^ Notes ^
| display/chart/mode | rainbow, normal | Engage nya nya rainbow mode, or normal light colours / patterns. |
===== Access Control =====
Code for this can be found on ehl-vm-things:/srv/docker/py3scripts/entrance-handler
The door is opened by a small ESP8266 and a relay connected to the intercom phone under the IRC terminal in G1
| access/entrance/request | | Button has been pressed at the entrance //read only// |
| access/entrance/release | | Release the entrance door (for 2 seconds) |
===== Sound =====
^ Topic ^ Payload ^ Notes ^
| sound/[room]/play | filename | Sound files must be installed on [[squawk]] |
| sound/[room]/speak | text | |
| sound/[room]/announce | text | |
| sound/[room]/polly/[voice] | text | See voice list at https://docs.aws.amazon.com/polly/latest/dg/voicelist.html |
| sound/kill | empty message | Kills all queued and/or playing sounds |
| sound/voice/change | voice name | Changes the voice to the one specified |
| sound/time-out | seconds | Kill all playing sounds and remain silent for N seconds |
Replace [room] with one of g1, g2, g8, g11, or all. Room names can also be combined. e.g. "g1-g2-g8"
Sound effects get annoying **fast**. Don't say we didn't warn you.
===== MQTT -> IR =====
Cazagen recently add a toy wiimote to G1 that allows for MQTT -> IR.
It has the following commands.
^ Topic ^ Payload ^ Notes ^
| ir/g1/amp/channel | pi, hdmi, mordred, table, laserdisc | Changes channel on amp to the chosen payload |
| ir/g1/amp | volumeup, volumedown, mute, poweron, poweroff, powertoggle | Transmits the obvious command |
| ir/g1/laserdisc | poweron, poweroff, powertoggle |
| ir/g1/raw | | not implemented |
| ir/g1/globalcache | | not implemented |
| ir/g1/... | | not implemented |
===== JeeNode Radios =====
^ Topic ^ Payload ^ Notes ^
| rf/jeenode868/received// | {"node": 10, "line": "OK 10 77 8 160 2", "data": "TQigAg==", "network": 38} | Received message |
| rf/jeenode868/send | binary data | Transmit a message |
===== OOK Radios =====
On-Off keying for remote controlled mains sockets.
^ Topic ^ Payload ^ Notes ^
| rf/ook433/send/homeeasy2// | 0, 1 | controller=0-67108863 device=0-15 |
| rf/ook433/send/homeeasy2/program// | 0, 1 | |
===== Space API =====
[[http://spaceapi.net/|Space API]] is a standard for publishing data about Hackerspaces. Our data is generated at [[http://spaceapi.edinburghhacklab.com/spaceapi.json]]. The sensors section of the data can be extended by sending messages:
^ Topic ^ Payload ^ Notes ^
| spaceapi/sensors/ | json | //type// is the sensor type as specified in the Space API specification. The payload is a JSON dictionary of the format given in the Space API specification. |
e.g. a temperature reading - type=temperature
{
"_ttl": 300,
"location": "In a deep dark hole",
"value": 3.14,
"unit": "\u00b0C"
}
_ttl=300 will cause the entry to expire after 5 minutes (change this to be 2-3x your update interval).
===== IRC =====
^ Topic ^ Payload ^ Notes ^
| irc/send | JSON | {"to": "#edinhacklab", "message": "Hello World"} |
| irc/receive | JSON | {"channel": "#edinhacklab", "sender": "timvik", "message": "Hello World", "action": false} |
| irc/status/connected | (none) | //Read Only// |
| irc/status/join | JSON | {"channel": "#edinhacklab", "user": "timvik"} //Read Only// |
===== Time Signals =====
These are beacons that can be used as time-based callbacks. This allows simple scripts to be written, driven only by incoming MQTT events.
^ Topic ^ Payload ^ Notes ^
| timesignal/60 | (none) | Sent every 60 seconds by the "timesignal" script |
| timesignal/300 | (none) | Sent every 5 minutes |
| timesignal/600 | (none) | ... |
| timesignal/1800 | (none) | ... |
| timesignal/3600 | (none) | ... |
| timesignal/86400 | (none) | ... |
===== G1 Amp =====
^ Topic ^ Payload ^ Notes ^
| sound/g1/amp/channel | channel_name | channel name, all caps e.g. HDMI1/AUDIO1. Some macros are stored such as pi/table |
| sound/g1/amp/power | on/off | |
| sound/g1/amp/volume | up/down | currently this fades up/down the volume by 5dBm, this could be made to set the volume to a specific number, but that could go wrong... |
===== Misc =====
^ Topic ^ Payload ^ Notes ^
| stats/member_count | n | Number of members |
===== TODO =====
* Network devices\\
* Door and window status\\
* Shorekarn scrolling LED sign\\
* IRC bot\\