Every receiver, whatever it is built from, ends up doing the same thing: publishing raw 802.11p frames to one central MQTT broker, which feeds the live map. That broker is the OpenTrafficMap server, and this page covers both directions — how data gets there, and how to read it back.
This is the machine side. The things you click are on Your Node.
All nodes publish to a single broker. It runs MQTT over TLS, and the connection is verified against the server certificate.
Publishing requires no username and no password, and no registration. If you build a receiver and point it at the broker, its data arrives. Registration exists only so that you can be given a friendly name, a place on the map and read access to your own node — none of which is required for contributing data.
This deliberate lack of a barrier is why the various independent projects on Other receiver projects can all feed the same map without any coordination beyond agreeing on the format.
Nodes publish the raw 802.11p frame, unmodified. No decoding, no JSON, no re-packing happens on the node.
That has two consequences worth knowing:
There is no offline buffer. C-ITS is a live data stream by design, and a frame that arrives late is of no use to a live map. If the node loses its network connection, the frames received during the outage are gone. As of firmware 0.5.1 there is no local logging to the SD card either.
cits1.opentrafficmap.org, reached over MQTT with TLS on port 8883. The host is compiled into the firmware — main/config.c always has the current value.aabbccddeeff. If we have given you a friendly name, that is used instead — see Friendly name.
Everything belonging to a node lives under its/<node>/, where <node> is the node name described above. Most of it comes from the node itself; the decoded JSON is added by the server.
| Topic | Comes from | Content |
|---|---|---|
its/<node>/packet | the node | One message per received frame: the raw 802.11p frame. QoS 0, not retained. |
its/<node>/packet/json | the server | The same frames, decoded to JSON. This is the one to use if you do not want to write a C-ITS parser yourself. |
its/<node>/status | the node | online on connect, offline as the last will. Retained, so it always reflects the current state. |
its/<node>/info | the node | Sent once on connect: the MAC address, the firmware version and the hardware variant. |
its/<node>/stats | the node | Telemetry, published periodically: temperature and seconds since boot. |
its/<node>/command | the portal | The node subscribes here. This is how the self-service portal configures a node remotely — the payload is run on the node's console. |
its/<node>/command_result | the node | The result or error message of a command. |
To follow everything belonging to a node, subscribe to the wildcard its/<node>/#.
While publishing is open, reading is not: you need credentials, and the self-service portal shows you the ones for your own node.
Any MQTT client will do:
| Client | Platforms | Homepage |
|---|---|---|
| MQTTX | Linux, Windows, macOS | https://mqttx.app |
| MQTT Explorer | Linux, Windows, macOS | https://mqtt-explorer.com |
| MQTT Viewer | Linux, macOS | https://mqttviewer.app |
| MQTT.fx | Windows | https://mqttfx.jensd.de |
Subscribe to its/<node>/# and you will see your node's frames and telemetry as they happen. Note that packet carries the raw frame and is binary — most clients will show it as hex. If you want something readable, subscribe to packet/json instead, where the server has already decoded it.
Nothing else. The node has no microphone, no GPS and no knowledge of your network beyond what it needs to reach the broker.
If you already run Home Assistant, you can watch your node from there. The node keeps doing its own job and publishes its telemetry to the broker; Home Assistant simply reads along through the MQTT integration, using the credentials from the self-service portal. From there you can build sensors, automations and dashboards — an alert when the node has been offline for an hour, for example, or a graph of its temperature over the summer.
This is monitoring only. It does not change what the node does.
Not to be confused with running the receiver on ESPHome, where Home Assistant becomes the receiver itself and the node is an ESPHome device. That is a different setup, described under ESPHome firmware.