Skip to content

MQTT

The ingest path: everything a hive measures enters the system here. Two processes that only make sense together โ€” a broker that accepts what the nodes publish, and a handler that decodes those messages and hands them to the core library to be stored.

The broker

Mosquitto, the entry point for sensor data. It is an off-the-shelf eclipse-mosquitto:2.0 image, so mosquitto/ in meshbee-server holds no application code โ€” only configuration and runtime state, bind-mounted into the container.

Ports 1883 MQTT (used) ยท 9001 WebSockets (configured but unused)
Config config/mosquitto.conf โ€” the only tracked source file
Credentials config/passwd, bcrypt-hashed, generated by make mqtt-passwd. Gitignored
Logs stdout, rotated by Docker

The broker will not start without config/passwd

It runs with allow_anonymous false. A missing password file is the single most common cause of a failing stack. make setup generates it on a fresh clone; regenerate it with make mqtt-passwd whenever MQTT_PASSWORD changes, since the file holds a hash and does not follow the variable.

The broker stores nothing of ours โ€” readings live in PostgreSQL, so clearing data/ costs at most undelivered messages. There are no ACLs today and every node shares one credential, so a compromised node cannot be revoked individually.

The handler

A headless subscriber: no HTTP surface, no port, no clients. It is a loop between Mosquitto and meshbee_core that decodes each payload, validates it, and hands it over to be stored.

It writes no SQL of its own. It opens a transaction and calls one service โ€” meshbee_core.services.ingest โ€” and the core library owns every query from there. That is the layer rule the whole server is built on, and it is why a reading arriving over MQTT produces the same database row as one posted to POST /api/admin/letture.

  • Subscribes to beehive/+/data; nodes publish to beehive/<id_nodo>/data.
  • Enforces the measurement ranges โ€” temperature โˆ’50โ€ฆ100 ยฐC, humidity 0โ€ฆ100 %, weight โ‰ฅ 0 kg.
  • Auto-provisions: a node that starts transmitting before anyone registers it gets registered, and an unknown id_sensore creates a hive rather than losing the reading.

A rejected reading is dropped, not retried

The broker is acknowledged before the handler ever looks at the payload, so a message that fails validation is logged as Lettura scartata and gone. There is no dead-letter queue.

Two failure modes worth knowing. + matches exactly one level, so a node publishing to beehive/NODE001/sensors/data connects happily, gets no error, and is silently ignored โ€” check this first when a node "works" but nothing lands in the database. And there is no hot reload: editing a file changes nothing until docker-compose restart mqtt-handler.

The API never touches MQTT. It reads the same database but is not a broker client, so restarting the broker does not affect it.

Full documentation