Open app

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.target
python3 -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-bridge

Verify 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 true

Then 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 varDefaultWhat it does
PLEXUS_API_KEY(required)your Plexus key
MQTT_HOSTlocalhostbroker host
MQTT_TOPICplexus/+/+topic filter (devices/metrics)