Data Sources

Connect controls straight to protocols you already run — an MQTT broker or a plain HTTP API — with no MeshSocket bridge and zero server code. MeshSocket stays the power path (dynamic content, rooms, E2EE, readback); sources are the zero-setup path.

A layout declares named sources at the top level; controls bind them through the same standardized connection block (Sync / Actions) they use for MeshSocket. Every control's inputs and outputs are transport-independent: what a Gauge accepts or a Button emits is defined by the control, and method just picks the wire.

Definition

"sources": {
  "broker": { "type": "mqtt", "url": "mqtt://192.168.1.10:1883",
              "username": "ha", "password": "secret" },
  "api":    { "type": "http", "baseURL": "http://192.168.1.5:8080",
              "headers": { "Authorization": "Bearer abc" }, "interval": 5 }
}

When a layout has exactly one source of a kind, sync/action entries may omit source — it resolves automatically. With several, name the one you mean.

MQTT

Subscribe a topic and bind the payload — the entire connection block of the control is:

"sync": [{ "method": "mqtt", "topic": "home/livingroom/temp", "valuePath": "value" }]
  • Topic wildcards work (home/+/temp, sensors/#).
  • Payloads parse naturally: JSON objects work with filter/valuePath exactly like MeshSocket frames; bare 23.5 / true / ON payloads become number / bool / string values directly (leave valuePath empty).
  • Actions publish:
"action": { "method": "mqtt", "topic": "home/lamp/set", "payload": "{{value}}", "retain": false }

String payloads publish raw bytes (ON, not "ON"); objects publish as JSON. mqtt:// is plain TCP (default port 1883), mqtts:// is TLS (default 8883). QoS 0 publish; inbound QoS 1 is acknowledged. The client auto-reconnects with backoff and reports state to the connection console.

HTTP polling

Poll any JSON endpoint on an interval and extract a value:

"sync": [{ "method": "http", "path": "/api/status", "interval": 10, "valuePath": "cpu.load" }]
  • url (absolute) or path (against the source's baseURL).
  • Controls polling the same URL at the same interval share one request — a page of gauges over one status endpoint costs one poll.
  • The response body is JSON; filter and valuePath behave exactly as in Sync. Special receivers work too: point a List at an array endpoint, a Sparkline at a numeric one.
  • Actions fire requests:
"action": { "method": "http", "path": "/api/restart", "httpMethod": "POST",
            "payload": { "service": "media" } }

httpMethod defaults to POST when a payload is present, else GET. Object payloads send as JSON bodies; string payloads send as text.

Full example — an ESP32 + Home Assistant page, no server

{
  "name": "Greenhouse",
  "version": 1,
  "sources": { "broker": { "type": "mqtt", "url": "mqtt://192.168.1.10" } },
  "tabs": [{
    "title": "Climate", "icon": "leaf.fill", "grid": { "columns": 2, "rows": 6 },
    "children": [
      { "type": "gauge", "id": "temp", "position": [0, 0], "min": 0, "max": 40,
        "label": "Temp °C",
        "sync": [{ "method": "mqtt", "topic": "greenhouse/temp" }] },
      { "type": "sparkline", "id": "hum", "position": [0, 1], "label": "Humidity",
        "sync": [{ "method": "mqtt", "topic": "greenhouse/humidity" }] },
      { "type": "toggle", "id": "fan", "position": [2, 0], "label": "Fan",
        "sync": [{ "method": "mqtt", "topic": "greenhouse/fan/state",
                   "valuePath": "" }],
        "action": { "method": "mqtt", "topic": "greenhouse/fan/set",
                    "payload": "{{value}}" } }
    ]
  }]
}

Mixing transports

A layout may use MeshSocket, MQTT, HTTP, and Sensors together — each sync entry picks its own method. A control with several sync entries takes whichever delivered last.

Notes

  • Sources live and die with the layout: leaving it disconnects the broker and stops all polling.
  • MQTT needs a declared source (the broker address); HTTP syncs with an absolute url work with no sources block at all.
  • Diagnostics (connects, failures, reconnects) land in the connection console like MeshSocket's.
  • Sync — the standardized inbound binding
  • Actions — the standardized outbound command
  • Layout Config — where sources sits