Raspberry Pi Fleet Observer
A Raspberry Pi as a local MQTT gateway for a fleet of ESP32s: a Mosquitto broker on the Pi, plus a small Python bridge that forwards each MQTT message to Plexus with the source_id parsed from the topic.
Prerequisites
- A Raspberry Pi 3B+ or newer running Raspberry Pi OS Lite (64-bit).
- Mosquitto:
sudo apt install -y mosquitto mosquitto-clients. - An API key from the API Keys page.
- One or more MQTT-capable devices on the same LAN (ESP32s are the classic fit).
The bridge
Subscribes to plexus/+/+ and forwards each message to Plexus, one client per source so every device keeps its own identity:
import json, os
import paho.mqtt.client as mqtt
from plexus import Plexus
MQTT_HOST = os.environ.get("MQTT_HOST", "localhost")
TOPIC = os.environ.get("MQTT_TOPIC", "plexus/+/+")
clients = {}
def get_client(source_id):
if source_id not in clients:
clients[source_id] = Plexus(source_id=source_id)
return clients[source_id]
def on_message(_c, _u, msg):
parts = msg.topic.split("/") # plexus/<source_id>/<metric>
if len(parts) != 3 or parts[0] != "plexus":
return
_, source_id, metric = parts
payload = msg.payload.decode("utf-8", errors="replace")
try:
value = float(payload)
except ValueError:
try:
value = json.loads(payload)
except ValueError:
value = payload
get_client(source_id).send(metric, value)
def main():
client = mqtt.Client()
client.on_message = on_message
client.connect(MQTT_HOST)
client.subscribe(TOPIC)
client.loop_forever()
if __name__ == "__main__":
main()Install (run on boot)
Save this as plexus-bridge.service next to the script:
[Unit]
Description=Plexus MQTT bridge
After=network-online.target
Wants=network-online.target
[Service]
Environment=PLEXUS_API_KEY=plx_xxx
ExecStart=/home/pi/plexus-bridge/bin/python /home/pi/bridge.py
Restart=on-failure
[Install]
WantedBy=multi-user.targetpython3 -m venv ~/plexus-bridge && source ~/plexus-bridge/bin/activate
pip install plexus-python "paho-mqtt<2"
cp bridge.py ~/bridge.py
sudo cp plexus-bridge.service /etc/systemd/system/ # systemd unit, restart-on-failure
sudo systemctl daemon-reload
sudo systemctl enable --now plexus-bridgeVerify with sudo systemctl status plexus-bridge and journalctl -u plexus-bridge -f.
Paths above assume the default pi user — adjust /home/pi/... in the unit
if you use a custom username. The pin paho-mqtt<2 matters: paho-mqtt 2.x
changed the callback API (a CallbackAPIVersion argument to mqtt.Client()),
which breaks the bridge script as written.
Open the broker to the LAN
Mosquitto 2.0+ listens on localhost only by default, so the ESP32s can't
connect until you add a listener. Create /etc/mosquitto/conf.d/plexus.conf:
listener 1883
allow_anonymous trueThen sudo systemctl restart mosquitto. allow_anonymous true is fine on a
trusted LAN; configure username/password auth if the broker is reachable
beyond it.
Point the devices at the Pi
Have each device publish readings to the broker at plexus/<SOURCE_ID>/<metric> — a plain float payload (22.3) or a JSON value both work. Any MQTT client library does; on an ESP32, PubSubClient by Nick O'Leary is the usual choice:
- Set the MQTT host to the Pi's LAN IP (e.g.,
192.168.1.42). - Give each device a unique source ID (
esp32-greenhouse,esp32-fridge). - Publish each metric to its own topic:
plexus/esp32-greenhouse/temperature.
Each device publishes plexus/<SOURCE_ID>/<metric> to Mosquitto; the Pi forwards each to Plexus with the right source_id attached.
Tuning knobs
Set in the systemd unit's environment:
| Env var | Default | What it does |
|---|---|---|
PLEXUS_API_KEY | (required) | your Plexus key |
MQTT_HOST | localhost | broker host |
MQTT_TOPIC | plexus/+/+ | topic filter (devices/metrics) |