Protocol Details
DEJA IO supports three communication protocols. All use JSON messages.
๐ Serial USB
Direct wired connection between the DEJA Server and any of the USB-serial Arduino-family device types: deja-arduino (Arduino Mega) or deja-esp32 (ESP32 Dev Module). Both share the same io/src/deja-arduino/ sketch and identical wire format.
| Parameter | Value |
|---|---|
| Baud rate | 115200 |
| Data bits | 8 |
| Stop bits | 1 |
| Parity | None |
| Encoding | UTF-8 JSON array |
How It Works
- The board connects via USB to the server machine
- DEJA Server auto-detects the serial port
- Server opens the port at 115200 baud via the
serialportNode.js package - JSON command arrays are written to the port; responses are read line-by-line
- Auto-reconnect with exponential backoff (1s โ 30s max) on disconnect
Wire Format
Commands arrive as a JSON array (multiple commands can be batched per write):
[
{ "action": "pin", "payload": { "pin": 8, "state": 1 } },
{ "action": "servo", "payload": { "servo": 0, "value": 90, "current": 45 } }
]
Sensor state changes are published back over the same serial line as single objects (e.g. { "sensor": 0, "state": 1 }), debounced with a 500ms minimum between state changes.
Port Detection
The server lists available serial ports and matches them to registered devices. You can also manually specify a port path in your device configuration.
๐ฌ MQTT over WiFi
Wireless publish/subscribe messaging via an MQTT broker (Mosquitto recommended). Used by both wireless device types: deja-mqtt (Raspberry Pi Pico W, CircuitPython) and deja-esp32-wifi (ESP32, Arduino C++). Both share the same topic scheme and the same single-object command format โ the DEJA Server treats them identically on the wire.
| Parameter | Value |
|---|---|
| Default port | 1883 (unencrypted) |
| Protocol | MQTT v3.1.1 |
| QoS | 0 (at most once) |
| Encoding | UTF-8 JSON object |
Topic Structure
{TOPIC_ID}/{LAYOUT_ID}/{DEVICE_ID} โ device subscribes (receives commands)
{TOPIC_ID}/{LAYOUT_ID}/{DEVICE_ID}/messages โ device publishes (sensor events, status)
Default TOPIC_ID is DEJA. Example for a device on the "tam" layout:
DEJA/tam/tj-eagle-nest-pico โ commands IN
DEJA/tam/tj-eagle-nest-pico/messages โ sensor events / status OUT
Wire Format
Commands arrive as single JSON objects (one command per MQTT message) with a device field for filtering:
{
"action": "pin",
"device": "my-esp32-wifi",
"payload": { "pin": 18, "state": 1 }
}
Sensor events the device publishes back to โฆ/messages flow through the same Firestore pipeline as USB-serial sensors via the server's writeSensorState() helper.
Device Filtering
Multiple devices can share the same MQTT topic prefix. Each message includes a device field, and devices only process messages matching their own DEVICE_ID. This is true for both deja-mqtt and deja-esp32-wifi.
Broker Setup
Install Mosquitto on your server machine:
# macOS
brew install mosquitto
# Linux (Debian/Ubuntu)
sudo apt install mosquitto mosquitto-clients
# Start the broker
mosquitto -d
Set MQTT_BROKER in your .env to the server's IP address (e.g., mqtt://192.168.1.100).
WebSocket
Real-time bidirectional communication over TCP.
| Parameter | Value |
|---|---|
| Default port | 8082 (configurable via VITE_WS_PORT) |
| Protocol | WebSocket (RFC 6455) |
| Encoding | UTF-8 JSON |
Connection
Connect to ws://{serverHost}:8082. On connection, the server sends an acknowledgment:
{ "action": "ack", "payload": { "layoutId": "tam", "serverId": "DEJA.js" } }
Device Monitoring
Subscribe to a device's serial I/O stream:
{ "action": "subscribe-device", "deviceId": "my-arduino" }
The server forwards serial data for that device:
{
"action": "serial-data",
"payload": {
"deviceId": "my-arduino",
"data": "{ \"sensor\": 0, \"state\": 1 }",
"timestamp": "2026-04-03T12:00:00Z",
"direction": "incoming"
}
}
Unsubscribe when done:
{ "action": "unsubscribe-device", "deviceId": "my-arduino" }
See the WebSocket Integration guide for full message reference and code examples.