MQTT topics and message schema
The device-plane MQTT contract between Edge site controllers and the platform. Topics per site, settings and config keys, the event types a site controller publishes, units, and the identifiers used.
Site controllers connect to the EdgeTech broker over MQTT 3.1.1 with TLS and a per-device pre-shared key. Customers running their own platform get the same contract on their own broker.
Identifiers
| Identifier | Format | Where |
|---|---|---|
| Site ID | 24 hex characters (the site controller’s device ID) | Topic prefix, coreid in events |
| Socket ID | 20 hex characters (the charge controller’s serial) | @<socketId> suffix on socket events |
| External ID | 10-digit number in the QR code on the device | App, invoices, support |
Server to device
All topics are prefixed with <siteId>/.
| Topic | Payload | Meaning |
|---|---|---|
settings |
string | logondebug, logoff, p1charge (all sockets 1-phase), p3charge, reset, silence, unsilence, streaming |
config |
JSON | Per-site and per-socket configuration, keys below |
discover |
string or JSON | clearsockets, quietclearsockets, clear, recover, {"restart":"<socketId>"} |
routing |
string, retained | Where the forwarder posts events for this site, for example ev.edgetech.nl:8443 |
config keys
| Key | Value | Meaning |
|---|---|---|
allowcharging@<socket> |
0/1 | Socket enabled |
startcharging@<socket> |
0/1 | Start a session now (app start) |
settings@<socket> |
bits | Bit 0: 3-phase |
cptype@<socket> |
0/1 | CP type, see register 0x020A |
maxcurrent |
"3x25" |
Site limit per phase, amps |
maxsitecurrent |
0–255 | Site limit, 255 = uncapped |
minstartc |
A | Minimum current to start a session, default 8 |
minc |
A | Minimum charge current, default 6 |
solar |
0/1 | Solar mode on |
charge_solar |
0/1 | Solar-only (1) or solar-assist (0) |
plugandcharge |
0/1 | Start without app authorisation |
Device to server
Events are published as JSON: {"coreid": "<siteId>", "event": "pwh_<type>[@<socketId>]", "data": {...}, "published_at": "<ISO 8601>"}.
| Event | When | Content |
|---|---|---|
pwh_spark/status |
connect / last will | online or offline; offline detection about 90 s |
pwh_site_status |
every 5 min and on change | site_current_1..3 (A), pwh_day_budget, board_errors, crc_errors, mb_quality (%), WAN and LAN IP |
pwh_site_config |
on boot and on change, retained | firmware, hardware (hardware revision), socket list |
pwh_socket_status@<id> |
on change | state (1–4), error (bitmask), current_1..3 (raw 1/256 A), maxcurrent, temperature |
pwh_socket_config@<id> |
once per boot | socketfwversion (packed: 10769 = 0x2A11 = 2.10.17), settings, phases |
pwh_data@<id> |
end of session | session_kwh (watt-hours, despite the name), start and end time |
pwh_health |
every 5 min | Heap, uptime, WiFi RSSI, reset reason |
pwh_log |
batched, QoS 0 | Remote log lines with [rlog seq=N dropped=M] headers |
pwh_spark/flash/status |
during OTA | started, success, failed |
Units, exactly
| Field | Unit |
|---|---|
current_1..3 on socket status |
1/256 A (5632 = 22.0 A) |
site_current_1..3 |
A, decimal |
session_kwh, kwh_h, kwh_l |
Wh |
temperature |
°C |
mb_quality |
% of Modbus transactions succeeded |
pwh_day_budget |
messages left today, of 100 |
Broker-side extras
<siteId>/wip, retained: the WAN IP the broker saw the device connect from, set by a broker plugin on connect. Useful for finding a site behind a shared router.- Last will on
pwh_spark/statusgives offline detection without polling. - Message budget: 100 messages per device per day, to keep a misbehaving site from flooding the platform.
Provisioning
Each device authenticates with TLS-PSK: identity = device ID, key derived per device from a platform master key. New devices are added to the broker before first connect; there is no self-registration. Customers on their own platform receive the derivation tool.