Skip to main content

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.

ParameterValue
Baud rate115200
Data bits8
Stop bits1
ParityNone
EncodingUTF-8 JSON array

How It Works

  1. The board connects via USB to the server machine
  2. DEJA Server auto-detects the serial port
  3. Server opens the port at 115200 baud via the serialport Node.js package
  4. JSON command arrays are written to the port; responses are read line-by-line
  5. 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.

ParameterValue
Default port1883 (unencrypted)
ProtocolMQTT v3.1.1
QoS0 (at most once)
EncodingUTF-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.

ParameterValue
Default port8082 (configurable via VITE_WS_PORT)
ProtocolWebSocket (RFC 6455)
EncodingUTF-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.