# MQTT-topics en berichtschema

Het MQTT-contract op apparaatniveau tussen Edge-wifi-modules en het platform. Topics per locatie, sleutels voor settings en config, de eventtypen die een wifi-module publiceert, eenheden en de gebruikte identifiers.

Canonical: https://edgetech.eu/nl/docs/mqtt-topics  
Bijgewerkt: 2026-10-13

Wifi-modules verbinden met de EdgeTech-broker via MQTT 3.1.1 met TLS en een pre-shared key per apparaat. Klanten met hun eigen platform krijgen hetzelfde contract op hun eigen broker.

## Identifiers

| Identifier | Formaat | Waar |
|---|---|---|
| Site ID | 24 hexadecimale tekens (het apparaat-ID van de wifi-module) | Topicprefix, `coreid` in events |
| Socket ID | 20 hexadecimale tekens (het serienummer van de laadmodule) | Achtervoegsel `@<socketId>` bij socket-events |
| External ID | Getal van 10 cijfers in de QR-code op het apparaat | App, facturen, support |

## Server naar apparaat

Alle topics beginnen met `<siteId>/`.

| Topic | Payload | Betekenis |
|---|---|---|
| `settings` | string | `logondebug`, `logoff`, `p1charge` (alle laadpunten 1-fase), `p3charge`, `reset`, `silence`, `unsilence`, `streaming` |
| `config` | JSON | Configuratie per locatie en per laadpunt, sleutels hieronder |
| `discover` | string of JSON | `clearsockets`, `quietclearsockets`, `clear`, `recover`, `{"restart":"<socketId>"}` |
| `routing` | string, retained | Waar de forwarder de events van deze locatie naartoe stuurt, bijvoorbeeld `ev.edgetech.nl:8443` |

### `config`-sleutels

| Sleutel | Waarde | Betekenis |
|---|---|---|
| `allowcharging@<socket>` | 0/1 | Laadpunt ingeschakeld |
| `startcharging@<socket>` | 0/1 | Nu een laadsessie starten (start vanuit de app) |
| `settings@<socket>` | bits | Bit 0: 3-fase |
| `cptype@<socket>` | 0/1 | CP-type, zie register 0x020A |
| `maxcurrent` | `"3x25"` | Locatielimiet per fase, ampère |
| `maxsitecurrent` | 0–255 | Locatielimiet, 255 = onbegrensd |
| `minstartc` | A | Minimale stroom om een laadsessie te starten, standaard 8 |
| `minc` | A | Minimale laadstroom, standaard 6 |
| `solar` | 0/1 | Zonnemodus aan |
| `charge_solar` | 0/1 | Alleen zon (1) of zonne-ondersteuning (0) |
| `plugandcharge` | 0/1 | Starten zonder autorisatie in de app |

## Apparaat naar server

Events worden als JSON gepubliceerd: `{"coreid": "<siteId>", "event": "pwh_<type>[@<socketId>]", "data": {...}, "published_at": "<ISO 8601>"}`.

| Event | Wanneer | Inhoud |
|---|---|---|
| `pwh_spark/status` | verbinden / last will | `online` of `offline`; offline-detectie na ongeveer 90 s |
| `pwh_site_status` | elke 5 min en bij wijziging | `site_current_1..3` (A), `pwh_day_budget`, `board_errors`, `crc_errors`, `mb_quality` (%), WAN- en LAN-IP |
| `pwh_site_config` | bij opstarten en bij wijziging, retained | `firmware`, `hardware` (hardwarerevisie), lijst van laadpunten |
| `pwh_socket_status@<id>` | bij wijziging | `state` (1–4), `error` (bitmasker), `current_1..3` (ruw 1/256 A), `maxcurrent`, `temperature` |
| `pwh_socket_config@<id>` | één keer per opstart | `socketfwversion` (verpakt: `10769` = 0x2A11 = 2.10.17), instellingen, fasen |
| `pwh_data@<id>` | einde van de laadsessie | `session_kwh` (wattuur, ondanks de naam), begin- en eindtijd |
| `pwh_health` | elke 5 min | Heap, uptime, wifi-RSSI, reden van de reset |
| `pwh_log` | gebundeld, QoS 0 | Logregels op afstand met headers `[rlog seq=N dropped=M]` |
| `pwh_spark/flash/status` | tijdens OTA | `started`, `success`, `failed` |

## Eenheden, precies

| Veld | Eenheid |
|---|---|
| `current_1..3` in de socketstatus | 1/256 A (5632 = 22,0 A) |
| `site_current_1..3` | A, decimaal |
| `session_kwh`, `kwh_h`, `kwh_l` | Wh |
| `temperature` | °C |
| `mb_quality` | % geslaagde Modbus-transacties |
| `pwh_day_budget` | resterende berichten vandaag, van de 100 |

## Extra's aan de kant van de broker

- `<siteId>/wip`, retained: het WAN-IP van waaruit de broker het apparaat zag verbinden, gezet door een broker-plugin bij het verbinden. Handig om een locatie achter een gedeelde router te vinden.
- De last will op `pwh_spark/status` geeft offline-detectie zonder polling.
- Berichtenbudget: 100 berichten per apparaat per dag, zodat een locatie die zich misdraagt het platform niet kan overspoelen.

## Provisioning

Elk apparaat authenticeert met TLS-PSK: identiteit = apparaat-ID, sleutel per apparaat afgeleid van een hoofdsleutel van het platform. Nieuwe apparaten worden aan de broker toegevoegd voordat ze voor het eerst verbinden; zelfregistratie bestaat niet. Klanten met hun eigen platform krijgen de afleidingstool.
