Connect your own gateway (software gateway)

Updated

A gateway does not have to be an ESP32 running our firmware. Anything that can open an MQTT connection and publish JSON — a Raspberry Pi, a Linux box next to your SCADA, a PLC with an MQTT client, a container, a Node-RED flow — can be a Synacl gateway. The contract it speaks is public: the Synacl Gateway Protocol. And you do not have to write one: the open-source reference gateway, synacl-gateway, runs on any machine with Node.js.

Register it

  1. Open Gateways → Add gateway and choose Software gateway.
  2. Give it a name and save. Leave Gateway ID blank to get one of the form gw_…, or type your own — letters, digits and _ . : -, 3–64 characters, starting with a letter or digit (/, + and # would break MQTT topics; an invalid id is refused with GATEWAY_CHIP_INVALID, a duplicate with 409). The gateway appears in your list as offline.
  3. The connection details are shown right after saving, and again any time from the gateway's Connection Info:
Field What it is
Broker mqtt.synacl.com, port 8883, TLS
Username The gateway's broker username — this is its identity
Password 24 characters, generated. Shown when you register the gateway; after that, Connection Info → Show password reveals it again (needs Edit gateways; each reveal is recorded, and there's a limit of 20 an hour). Rotate password issues a new one — see below.
Topic prefix tenants/{tenantId}/sources/gateway/{gw_…} — every topic the gateway uses starts with this
Quick start (Node.js) A ready-to-paste line that runs the reference gateway with these credentials (below)

The tenantId in the prefix is the account owner's id. Team members registering a gateway get the same prefix.

A software gateway has no firmware we manage: Flash, Firmware update and Channel are hidden for it, and calling those actions on it answers FIRMWARE_NOT_APPLICABLE. Restart, resend config, reset and delete work as for any gateway.

Run the reference gateway

synacl-gateway is an Apache-2.0 Node.js implementation of the protocol, published on npm. It ships with three drivers — Host metrics (CPU, memory, disk and network of the machine it runs on), a Local MQTT bridge from a broker you already have, and Modbus TCP — buffers readings while its connection is down and replays them afterwards, and can evaluate alert thresholds locally like the ESP32 firmware — by default, though, a device behind a software gateway has its alarms evaluated in the cloud; set the device to On the gateway if you want it alarming while the uplink is down (see Normal, Watch and Alert). It needs Node.js 20.11 or newer (22 LTS recommended).

Try it in one line

After registering, Connection Info shows a Quick start (Node.js) line. Paste it into a terminal on the machine that will be the gateway:

npx -y synacl-gateway@latest init --broker mqtts://mqtt.synacl.com:8883 --tenant <account id> --gateway <gw_…> --user <username> --pass <password> && npx -y synacl-gateway@latest run

init saves the settings to ~/.synacl-gateway/config.json (readable by you only) and proves them against the broker; run starts the gateway in the foreground, and it shows online in the app within seconds. Ctrl-C stops it. The line contains the gateway's password — start it with a space so most shells keep it out of their history.

Keep it running

Install it globally and register it as a systemd service (Linux):

sudo npm i -g synacl-gateway
synacl-gateway init --broker … --tenant … --gateway … --user … --pass …   # the same flags as the line above
sudo synacl-gateway service install

The service starts at boot and restarts on failure; journalctl -u synacl-gateway -f follows its log. Run init as the user the service should run as. service install --user writes a per-user unit instead (no sudo; enable lingering for it to start without a login), and service uninstall removes the unit and keeps the settings.

Docker

docker run --rm -it -v synacl:/data ghcr.io/synacl-iot/synacl-gateway init --broker … --tenant … --gateway … --user … --pass …
docker run -d --init --restart unless-stopped -v synacl:/data --name synacl-gateway ghcr.io/synacl-iot/synacl-gateway

The image is built for amd64 and arm64. The settings and any buffered readings live on the /data volume, and the Host metrics driver reports that volume's disk usage. Add --network host if you want the machine's real network counters (net.rx_bps / net.tx_bps).

Raspberry Pi

Start the gateway before adding devices

The app only offers the Software gateway device types — Host metrics and Local MQTT bridge — and Modbus TCP on this gateway once the gateway has connected and reported which protocols it supports. So: register, run, then Devices → Add device. Device changes reach a software gateway on their own: when you add, edit, move or delete a device under it, or change a device's interval, Synacl pushes the new device list immediately — there is no Resend config step, and nothing restarts.

If something is wrong

Rotate the password

Open the gateway → Connection Info → Rotate password (needs Edit gateways). The old password stops working at once, so the gateway drops offline and stays there until it has the new one: re-run init with the new --pass (everything else on the line unchanged), then restart it — sudo systemctl restart synacl-gateway for the service; for Docker, re-run the init line and restart the container. Rotate when the password was pasted somewhere it shouldn't have been, or when someone who had it leaves.

Only software gateways can be rotated from the app. An ESP32 gateway gets new credentials only by being flashed and provisioned again over USB.

Or write your own

The minimum a gateway does, in order:

  1. Connect with a Last Will on {prefix}/status = {"online":false} (retained).
  2. Publish {prefix}/status = {"online":true,"ts":…} retained, and repeat every 60 s.
  3. Publish a capability report on {prefix}/firmware/response — the protocols list decides which device protocols you can assign to this gateway in the app.
  4. Publish {prefix}/config/request = {"hash":0} and receive the device list on {prefix}/config/push.
  5. For each device, publish readings on {prefix}/devices/{deviceId}/data and presence on {prefix}/devices/{deviceId}/status.

The gateway turns online in the app when its first status arrives. Add devices under it as you would under an ESP32; the protocols offered are the ones your capability report listed.

Apply a config/push whenever one arrives, not only in answer to your own config/request: Synacl publishes a new device list straight away when a device under the gateway changes. (An ESP32 is different: a push restarts it, so there you choose when to resend.) Every payload, number and edge case is on the protocol page, with a JSON Schema per message. If you would rather extend the reference gateway than start from scratch, it takes driver packages: synacl-gateway conformance --driver <package> checks one against the driver contract, and conformance --offline runs the protocol suite whose 23 scenarios double as a checklist for an implementation in any language.

Just a device, not a gateway? A single sensor with its own MQTT client does not need a gateway at all — see connect a direct MQTT device.