Add mqtt hackathon - brcon2024-hackathons - Bitreichcon 2024 Hackathons
(HTM) git clone git://bitreich.org/brcon2024-hackathons git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/brcon2024-hackathons
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Tags
(DIR) Submodules
---
(DIR) commit 7ac09da5aedd5b5e3fbbdcc57adadb263f09d011
(DIR) parent 657b359aba0a48bc973a0cffe152a941297f6543
(HTM) Author: Christoph Lohmann <20h@r-36.net>
Date: Thu, 8 Aug 2024 23:01:46 +0200
Add mqtt hackathon
Diffstat:
A mqtt/README.md | 8 ++++++++
A mqtt/brcon2024_adc.md | 483 +++++++++++++++++++++++++++++++
A mqtt/mqtt-wrapper | 59 +++++++++++++++++++++++++++++++
A mqtt/tamagotchi | 1 +
4 files changed, 551 insertions(+), 0 deletions(-)
---
(DIR) diff --git a/mqtt/README.md b/mqtt/README.md
@@ -0,0 +1,8 @@
+# MQTT
+
+## Following the talk of Thursday
+
+brcon2024_adc.md has the challenges
+tamagotchi/ for the tamagotchi source
+mqtt-wrapper for running some command
+
(DIR) diff --git a/mqtt/brcon2024_adc.md b/mqtt/brcon2024_adc.md
@@ -0,0 +1,483 @@
+## brcon2024 - 2024-08-08
+
+ title: Deep C programming - UNIX philosophy in distributed offshore systems
+
+ author: Anders Damsgaard (adc)
+
+ contact: anders@adamsgaard.dk
+ gopher://adamsgaard.dk
+ https://adamsgaard.dk
+
+ slides: gopher://adamsgaard.dk/tmp/brcon2024_adc.md
+
+## brcon2024 - 2024-08-08
+
+ title: Deep C programming - UNIX philosophy in distributed offshore systems
+
+ author: Anders Damsgaard (adc)
+
+ contact: anders@adamsgaard.dk
+ gopher://adamsgaard.dk
+ https://adamsgaard.dk
+ <marquee><blink>
+ slides: gopher://adamsgaard.dk/tmp/brcon2024_adc.md
+ </blink></marquee>
+
+
+## Previously..
+* brcon2020: Energy efficient programming in science
+* brcon2021: Unix principles for science simulations
+* brcon2022: Est. Bitreich Arctic Vault
+* brcon2023: Using Unix and Bitreich tools for preparing scientific papers
+* Today: UNIX philosophy in distributed offshore systems
+#pause
+* Tomorrow: UNOX philosophy in Vitré
+
+## Outline
+* How we can benefit from hyped technology with true and tried principles
+* Overview of the offshore system
+* The talk transitions into hands-on exercises
+* Ask questions along the way in #bitreich-con
+
+## Danish Geotechnical Institute (geo.dk)
+* ~250 employees in Lyngby and Aarhus, Denmark
+* Geotechnical investigations (onshore/offshore)
+* Environmental consultancy
+* Laboratory tests
+* Geodata analysis
+* Geoscientific software development
+
+#pause
+-> New offshore rig built from the ground up
+
+## Offshore geotechnical investigations
+ .* +------------------+
+ \|\ | ,_____. |
+ _============. | | | |
+ \\# # # #/ | | ._______|--|--| |
+ | +.,| | Geo .--|--| |
+ _---------------------|-+-------|--|--|--|\
+ \ MS/Bitreich | +--|--+ | |
+~~~~~~~~~~~~~~~~~\~~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~|~|~~~~~~~~~~~~
+ \ +------------------+'' ~
+ \_________________________________/--+ ~ . ~~
+ ~
+
+
+ ><>
+
+ <><
+
+
+
+----------------------------------------------------------------------
+
+
+## Offshore geotechnical investigations
+ .*
+ \|\ ,_____.
+ _============. | |
+ \\# # # #/ | ._______|--|--|
+ | +., | Geo .--|--|
+ _---------------------+-+-------|--|--|---\
+ \ MS/Bitreich +--|--+ |
+~~~~~~~~~~~~~~~~~\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~
+ \ .-'' ~
+ \_________________________________/--+ ~ . ~~
+ ~
+
+
+ ><>
+
+ <><
+
+
+
+----------------------------------------------------------------------
+
+
+
+## Offshore geotechnical investigations
+ .*
+ \|\ ,_____.
+ _============. | |
+ \\# # # #/ | ._______|--|--|
+ | +., | Geo | | |
+ _---------------------+-+-------|--|--|---\
+ \ MS/Bitreich | |
+~~~~~~~~~~~~~~~~~\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~|~~~~~~~~~~~~
+ \ | .-'' ~
+ \_____________________________|___/--x~ ~ . ~~
+ .--|--. ~
+ | v |
+ +-----+
+ ><>
+
+ <><
+
+
+
+----------------------------------------------------------------------
+
+
+
+
+## Offshore geotechnical investigations
+ .*
+ \|\ ,_____.
+ _============. | |
+ \\# # # #/ | ._______|--|--|
+ | +., | Geo | | |
+ _---------------------+-+-------|--|--|---\
+ \ MS/Bitreich | |
+~~~~~~~~~~~~~~~~~\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~|~~~~~~~~~~~~
+ \ | .-'~ ~ . ~~
+ \_____________________________|___/--x ~
+ |
+ |
+ |
+ ><> |
+ |
+ <>< |
+ |
+ .--|--.
+ | v |
+----------------------------------------------+-----+-----------------
+
+
+
+
+## Offshore geotechnical investigations
+ .*
+ \|\ ,_____.
+ _============. | |
+ \\# # # #/ | ._______|--|--|
+ | +., | Geo | | |
+ _---------------------+-+-------|--|--|---\
+ \ MS/Bitreich | |
+~~~~~~~~~~~~~~~~~\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~|~~~~~~~~~~~~
+ \ | .-'' ~
+ \_____________________________|___/--x
+ |
+ |
+ |
+ ><> |
+ |
+ <>< |
+ |
+ .--|--.
+ | | |
+----------------------------------------------+--|--+-----------------
+ |
+ |
+ |
+ v
+
+## Offshore geotechnical investigations
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~|~~~~~~~~~~~~
+ | |
+ | |
+ | |
+ | |
+ ? | |
+ ><> | |
+ | |
+ | | !
+ | | <><
+ | |
+ | |
+-----------------------------------------|---------------|------------
+ | |
+ | |
+ | |
+ | |
+ |_______________|
+
+https://www.mdpi.com/energies/energies-17-01964/article_deploy/html/images/energies-17-01964-g001.png
+
+## Offshore systems overview
+* Up to 800 sensors, usually 1-10 Hz
+* SCADA, PLCs, environmental sensors, navigation, scientific results,
+ calibration data, ...
+* Control messages
+* Asynchronous data streams
+* Event driven logic
+* Raw sensor output into physical units
+* Aggregation of time series and combination of sources
+* Time series databases
+* Development project with many involved partners
+
+## Approaches: Unix philosophy vs. Microsoft mentality
+* Does the client know what they want?
+* Do we know everything about what we want to solve?
+* Do we know if our assumptions are valid, in particular in complex systems?
+* Do we have full specifications?
+* Should we produce a big integrated C# monolith to handle computations,
+ flow, storage, logic?
+
+#pause
+ > yes no | head -n 5
+
+
+## Data routing system
+* MQTT: Message Queuing Telemetry Transport
+* Started as a proprietary protocol for SCADA systems in O&G
+* Lightweight, publish-subscribe network protocol
+* Constrained devices and low-bandwidth, high-latency networks
+* Publish/Subscribe Model: Decouples message producers from consumers
+* Data accessible via network, not living internally in an obscure program
+
+Specifications:
+- MQTT v5.0: https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html
+- MQTT v3.1.1: http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html
+- https://github.com/mqtt/mqtt.org/wiki/Differences-between-3.1.1-and-5.0
+- MQTT and TLS: https://www.rfc-editor.org/rfc/rfc9431.txt
+
+## Central concepts
+* Broker: Central server that routes messages
+* Clients: Devices that publish or subscribe to one or more topics
+* Messages: Data packets sent between clients via the broker
+* Topics: Hierarchical and dynamic name space for message
+
+Libs for many languages, e.g.,
+ - https://github.com/eclipse/paho.mqtt.c
+ - https://github.com/eclipse/paho.mqtt.golang
+
+## DISCLAIMER
+
+The coming exercises mainly to demonstrate fundamentals and principles
+
+Most are suboptimal or bad practice
+
+But, let's have some #fun ...
+
+## MQTT use cases
+* Home thermometers and weather stations (if you ask the web)
+* IoT Devices: Smart homes, wearables, and industrial automation
+* Mobile Applications: Real-time messaging and notifications
+* Remote Monitoring: Environmental sensors, health monitoring
+* Connected Vehicles: Telematics and fleet management
+
+## MQTT messages
+* TCP/IP
+* Limit to message size configurable
+
+* New subscribers receive only new messages (no backlog)
+* Retained Messages: Last known good value for new subscribers
+* Last Will and Testament (LWT): Notifies other clients about an ungraceful disconnection
+
+* Quality of Service (QoS): Three levels to ensure message delivery
+* QoS 0: At most once delivery (fire and forget)
+* QoS 1: At least once delivery (acknowledged delivery)
+* QoS 2: Exactly once delivery (assured delivery)
+
+## Why MQTT for the offshore project?
+* Hierarchial data structure through topics
+* A node in the topic tree exists as soon as someone publishes or
+ subscribes to it
+* Data accessible via network and all clients can read or publish
+ (by default)
+
+#pause
+ rig/sensor1/raw
+ rig/sensor1/phys
+ rig/sensor2/raw
+ rig/sensor2/phys
+ ...
+ ship/navigation/easting
+ ship/navigation/northing
+ ...
+
+## Topic examples
+Wildcards: #, + (subscribe only)
+
+Subscription examples:
+ 1) rig/sensor1/raw
+ 2) ship/#: Subscribe to everything from the ship
+ 3) rig/+/phys: Subscribe to all physical values
+
+## Example: Subscribe and publish
+$ cat bin/timestamp # in case you don't have ts(1)
+#!/bin/sh
+while read -r REPLY
+do
+ printf '%s %s\n' "$(date '+%Y-%m-%d %Z %H:%M:%S')" "$REPLY"
+done
+#pause
+$ export MQTTURI='mqtt://bitreich:bitreich@mx2.adamsgaard.dk:65431/'
+#pause
+$ mosquitto_sub -L "${MQTTURI}#" -v -t '#' | timestamp | grep -v hatesensor
+#pause
+
+$ date | mosquitto_pub -L "${MQTTURI}$(hostname)/$(whoami)" -l
+
+## Reporting online status via last will and retain, reporting some metrics
+
+gophers://duckless.org/0/tmp/mqtt-online
+
+#!/bin/sh
+online_topic="${ONLINE_TOPIC:-$(hostname)/online}"
+mqtt_broker="${MQTT_BROKER:-mx2.adamsgaard.dk}"
+mqtt_port="${MQTT_PORT:-65431}"
+mqtt_user="${MQTT_USER:-bitreich}"
+mqtt_password="${MQTT_PASSWORD:-bitreich}"
+args="-h ${mqtt_broker} -p ${mqtt_port} -u ${mqtt_user} -P ${mqtt_password}"
+mosquitto_pub ${args} -t "${online_topic}" -r -m "1"
+while :
+do
+ printf '%s\t%s\t%s\t%s\n' "$(date +%s)" "$(date)" "$(hostname)" "$(uptime)"
+ sleep 360
+done | mosquitto_pub ${args} --will-topic "${online_topic}" \
+ --will-retain --will-payload "0" -t "${online_topic}" -r -l
+
+## Data structure on the network
+Interact with data hierarchy via small modular clients.
+Brings all benefits of UNIX design into play.
+
+The tenents of the UNIX philosophy:
+
+ - Small is beautiful
+ - Make each program do one thing well
+ - Build a prototype as soon as possible
+ - Choose portability over efficiency
+ - Store numerical data in flat ASCII files
+ - Use software leverage to your advantage
+ - Use shell scripts to increase leverage and portability
+ - Avoid captive user interfaces
+ - Make every program a filter
+
+src: Make Gancarz 1995 "The UNIX Philosophy", ISBN 1-55558-123-4
+
+## Distributed computing
+Assign small modular programs to read stdin from topics and post their
+result to another topic
+
+* Rudimentary distributed computing
+* Each program acts as a text filter
+* Each program can contribute local data
+
+(disclaimer: for 1:1 connections, netcat or named pipes over SSH is simpler)
+
+Broker statistics: $SYS/broker
+ mosquitto_sub -L "${MQTTURI}\$SYS/broker/#" -v
+
+## Connecting stdin, stdout, and stderr with MQTT topics
+Full script: gophers://duckless.org/0/tmp/mqtt-wrapper
+
+ fifodir="$(mktemp -d)" || die 'mktemp'
+ fin="${fifodir}/in"
+ fout="${fifodir}/out"
+ ferr="${fifodir}/err"
+ mkfifo "$fin" "$fout" "$ferr" || die 'mkfifo'
+
+#pause
+ mosquitto_sub ${mosquitto_args} -t $subscribe_args >"${fin}" &
+ mosquitto_pub ${mosquitto_args} -t "${output_topic}" -l <"${fout}" &
+ mosquitto_pub ${mosquitto_args} -t "${error_topic}" -l <"${ferr}" &
+ trap -- 'cleanup' ERR INT HUP EXIT CHLD
+
+#pause
+ while :
+ do
+ $runtime $runtime_args <"${fin}" >"${fout}" 2>"${ferr}"
+ done
+
+## Connecting stdin, stdout, and stderr with MQTT topics (cont.)
+
+Works if input is continuously evaluated (i.e., does not wait for EOF)
+
+ RUNTIME=bc ARGS="-l" sh -x ./mqtt-wrapper
+ RUNTIME=sh ARGS="your-favorite-cgi-script" sh -x ./mqtt-wrapper
+ RUNTIME=sh ARGS="your-sd-program" sh -x ./mqtt-wrapper
+
+## Outlook
+* Lots of possibilities coupling pub/sub with text streams
+* Use existing client/broker implementations and libraries
+* Minimal C implementation would be nice, aiming at a subset of features
+* Represent topic structure with virtual file system representation
+ (i.e., plan9 or /proc in linux)
+
+## Challenge 0: Installing a MQTT broker/client
+Mosquitto (mostly C, BSD-like license).
+Pretty bloated, a minimal alternative would be nice.
+You just need the client for these exercises.
+
+ https://github.com/eclipse/mosquitto
+
+Package names in common OS:
+
+ OpenBSD mosquitto broker+client
+ Arch mosquitto broker+client
+ Gentoo app-misc/mosquitto broker+client
+ Debian mosquitto-clients client
+
+## Challenge agenda
+First one to post a working solution will get points towards a
+price.
+
+## Challenge 1: Let's write a chat
+Hints:
+
+ mosquitto_pub(1): Publish a message to a named topic
+ Useful flags:
+ -d: Show debug info
+ -l: Read messages from stdin (each line 1 message)
+ mosquitto_sub(1): Subscribe to a path in the topic hierarchy
+ -d: Show debug info
+ -v: Print topic for each received message as first field
+
+ Connection URI:
+ -L 'mqtt://bitreich:bitreich@mx2.adamsgaard.dk:65431/testtopic'
+
+Let's use the message format: "nick\tmessage"
+
+## Challenge 2: Write a script that records the chat
+Hint: The '#' wild card
+
+What is the best choice for a time stamp?
+* Time as the sender reports it?
+* Time as the subscriber sees it?
+
+## Challenge 3: Let the data flow
+Anyone has a funky data source?
+
+* USB body thermometer?
+* spoon -t
+* while :; do printf '%s\t%s' "$(hostname)" "$(uptime)"; sleep 10; done
+* ii/annna?
+* vmstat(8)
+
+Task: Publish some data and let the others guess what it is.
+The funkier, the better.
+
+Message format ideas:
+ TSV, JSON, XLSX? sfeed(5)?
+ VT100 control codes??
+
+## Challenge 4: Raise an alert!
+Set up a script that monitors one of the data sources, and triggers
+an alert upon a condition (email, xmessage, log line, ...).
+
+## Challenge 5: Make some gnuplot
+Monitor one of the sensors from the previous, and create a continuously
+updating gnuplot (-t dumb) with a rolling window.
+
+## Challenge 6: Health check reporting
+Write a script that monitors some gopher and reports their status to
+
+ gopherstatus/<uri>
+ up|down
+
+## Challenge 7: Tamagotchi
+Make script that imitates a virtual pet, expecting to be feed
+"cookies" as messages on stdin every 30 s. It should die if it gets to much or too little food.
+
+Report its happyness to a topic with ASCII smileys.
+
(DIR) diff --git a/mqtt/mqtt-wrapper b/mqtt/mqtt-wrapper
@@ -0,0 +1,59 @@
+#!/bin/sh
+set -x
+#
+# $input_topic | $runtime $runtime_args | $output_topic
+# 2>$error_topic
+#
+# application to run
+runtime="${RUNTIME:-cat}"
+# arguments to $runtime
+runtime_args="${ARGS}"
+# stdin for $runtime; where others send to
+input_topics="${INPUT_TOPICS:-$$/in}"
+# stdout of $runtime; where others need to subscribe
+output_topic="${OUTPUT_TOPIC:-$$/out}"
+# stderr of $runtime; where others can subscribe
+error_topic="${ERROR_TOPIC:-$$/err}"
+
+mqtt_broker="${MQTT_BROKER:-mx2.adamsgaard.dk}"
+mqtt_port="${MQTT_BROKER:-65431}"
+mqtt_user="${MQTT_USER:-bitreich}"
+mqtt_password="${MQTT_PASSWORD:-bitreich}"
+mosquitto_args="-h ${mqtt_broker} -p ${mqtt_port} -u ${mqtt_user} -P ${mqtt_password}"
+
+cleanup() {
+ kill -TERM -- -$$
+ rm -f "$fin" "$fout" "$ferr"
+ rmdir "$fifodir"
+ exit 1
+}
+
+die() {
+ printf '%s: %s\n' "${0##*/}" "${1}" >&2
+ cleanup
+ exit "${2:-1}"
+}
+
+fifodir="$(mktemp -d)" || die 'mktemp'
+fin="${fifodir}/in"
+fout="${fifodir}/out"
+ferr="${fifodir}/err"
+mkfifo "$fin" "$fout" "$ferr" || die 'mkfifo'
+
+# split multiple input topics separated by "," into separate args
+subscribe_args="$(printf '%s' "$input_topics" | sed 's/,/ -t /g')"
+
+# subscribe to input topic(s), add -v option if you want message topic as first field
+mosquitto_sub ${mosquitto_args} -t $subscribe_args >"${fin}" &
+
+# create named pipes for output streams
+mosquitto_pub ${mosquitto_args} -t "${output_topic}" -l <"${fout}" &
+mosquitto_pub ${mosquitto_args} -t "${error_topic}" -l <"${ferr}" &
+trap -- 'cleanup' ERR INT HUP EXIT CHLD
+
+# run the program (lossy restart if it fails), connecting to named pipes
+while :
+do
+ $runtime $runtime_args <"${fin}" >"${fout}" 2>"${ferr}"
+done
+
(DIR) diff --git a/mqtt/tamagotchi b/mqtt/tamagotchi
@@ -0,0 +1 @@
+Subproject commit 61808fed51f116f4c1b5ab622a9e3e76738b303b