MQTT Topic & Payload Reference

(Mesh-Plug / Meshtastic / MQTT Bridge)

1. Topic Structure Overview

Canonical Root

msh/

โš ๏ธ Important
The root must appear once and only once.
A very common failure mode is accidentally using msh/msh/....


2. Primary Topic Patterns

A. JSON Stream (most common; Mesh-Plug default)

msh/<version>/json/<region>/<channel>/<node_id>

Example

msh/2/json/LongFast/!b2a7c7a8
SegmentMeaning
mshRoot topic
2Meshtastic protocol version
jsonJSON payload encoding
LongFastLoRa region / modem profile
!b2a7c7a8Node hex ID

B. MQTT Bridge Relay (when relayed via gateway or API)

msh/2/json/mqtt/<region>/<channel>/<node_id>

Example

msh/2/json/mqtt/LongFast/!b2a7c7a8

Used when:

  • Meshtastic โ†’ Gateway โ†’ MQTT
  • API relays or bridges are enabled
  • Multiple ingestion paths exist

Mesh-Plug should subscribe to both patterns when possible.


3. Message Type Identification

Message type is determined by the type field inside the payload; not by the topic.


4. Position Payload (GPS)

Topic

msh/2/json/.../!nodeid

Payload

{
  "type": "position",
  "from": 2997306284,
  "sender": "!b2a7c7a8",
  "timestamp": 1768083628,
  "payload": {
    "latitude_i": 341049344,
    "longitude_i": -1176240128,
    "altitude": 417,
    "precision_bits": 13,
    "time": 1768083594
  },
  "rssi": -45,
  "snr": 5.75,
  "hop_start": 7,
  "hops_away": 4
}

Notes

  • latitude_i / longitude_i are scaled integers lat = latitude_i / 1e7 lon = longitude_i / 1e7
  • time is GPS time
  • timestamp is broker receive time
  • Drift issues usually come from:
    • Stale GPS fix
    • Node reboot
    • Clock skew

5. Telemetry Payload (Sensors)

Topic

msh/2/json/.../!nodeid

Payload

{
  "type": "telemetry",
  "from": 861943568,
  "sender": "!b2a7c7a8",
  "timestamp": 1768083701,
  "payload": {
    "temperature": 21.4,
    "humidity": 43.1,
    "battery_level": 92,
    "voltage": 4.07
  },
  "rssi": -52,
  "snr": 6.25
}

Notes

  • Only appears if:
    • Sensor exists
    • Telemetry is enabled
  • Absence of telemetry is normal if no sensors are installed

6. Node Info Payload (Identity / Name)

Payload

{
  "type": "nodeinfo",
  "from": 2997306284,
  "sender": "!b2a7c7a8",
  "payload": {
    "long_name": "Mesh-Plug",
    "short_name": "PTR",
    "hardware_model": "HELTEC_V4",
    "role": "ROUTER"
  }
}

Known Issue (macOS)

  • macOS Meshtastic app often does not emit NodeInfo over MQTT
  • Result:
    • ID appears
    • Name missing
  • Workaround
    • Manually set Gateway Hex in Mesh-Plug

7. Chat / Text Messages

Payload

{
  "type": "text",
  "from": 2997306284,
  "sender": "!b2a7c7a8",
  "payload": {
    "text": "Just a text message"
  }
}

Notes

  • Chat messages may:
    • Appear in MQTT
    • Not appear in Meshtastic app
  • This is normal when:
    • Message originated from automation
    • Message type filtered in the app

8. Routing & Diagnostics Fields

FieldMeaning
hop_startInitial hop count
hops_awayDistance from sender
rssiSignal strength
snrSignal-to-noise ratio

Mesh-Plug uses these for:

  • Node table
  • Network health display
  • Debug overlays

9. Common Subscription Patterns

Broad (debugging)

msh/#

All JSON

msh/+/json/#

Only node traffic

msh/+/json/+/!+

Single node

msh/2/json/+/!b2a7c7a8

10. Known Failure Patterns

SymptomRoot Cause
Connected, no dataWrong topic root
Data in CLI but not Mesh-PlugWS vs TLS mismatch
Nodes listed, no namesMissing NodeInfo
Map jumpsStale GPS fix
Telemetry missingNo sensor installed
Duplicate nodesMultiple gateways relaying same node

11. Golden Validation Command

mosquitto_sub -d \
  -h mqtt.the-link-builders.com \
  -p 8883 \
  --cafile /etc/ssl/certs/ca-certificates.crt \
  -u USERNAME -P PASSWORD \
  -t "msh/#"

If data appears here; the broker is not the problem.