Overzicht
De publieke EnerSim Flex API beschrijft twee integratievlakken: het aanleveren van live meetdata vanuit uw EMS en het ontvangen van orders aan BRP/BSP zijde. De interne optimalisatie (solver) is geen publiek endpoint — deze wordt geactiveerd via de Flex pagina nadat EnerSim de EMS-verbinding heeft goedgekeurd.
EMS Bearer Token
Statisch token gekoppeld aan een locatie. Genereer via het EMS-paneel in de locatiedetails.
JWT Sessie Token
Gebruikers-JWT van Supabase Auth. Gebruik na inloggen via supabase.auth.signIn().
WebSocket integratie
Naast REST ondersteunt het platform twee optionele WebSocket-kanalen per locatie: een inbound stream (uw EMS → EnerSim) voor real-time telemetrie, en een outbound stream (EnerSim → uw EMS) voor directe setpoint-updates. REST blijft de canonieke fallback: als de WebSocket wegvalt, blijft het EMS op het laatst via ems-setpoints-push ontvangen volledige dagprofiel doordraaien.
Optioneel
WS is niet verplicht. Activeer per locatie via transport-modus REST / WS / beide.
Zelfde token
Inbound WS gebruikt het bestaande EMS Bearer token — geen extra credentials.
/functions/v1/ems-ws-ingress Bearer Token vereistEMS → EnerSim — Live telemetrie (inbound)
Open een persistente WebSocket vanaf uw EMS naar dit endpoint. Elke binnenkomende frame wordt gevalideerd en in real-time doorgeleverd naar het Flex-dashboard via Supabase Realtime.
Connection URL
wss://fbkhhcsplwxkorfhgqwr.supabase.co/functions/v1/ems-ws-ingressHet token kan op drie manieren worden meegegeven, kies er één:
- HTTP header:
Authorization: Bearer <token> - Query parameter:
?token=<token>(nuttig voor browser-clients) - Sec-WebSocket-Protocol:
bearer, <token>
Frame schema (client → server)
tsstring (ISO 8601)optioneelTimestamp in UTC. Valt terug op server-tijd als leeg.
power_kwnumberoptioneelNetto vermogen in kW (positief = import)
soc_percentnumber (0–100)optioneelBatterij state of charge
pv_kwnumberoptioneelPV productie in kW
load_kwnumberoptioneelSite belasting in kW
battery_kwnumberoptioneelBatterijvermogen in kW (positief = laden)
ev_kwnumberoptioneelEV laadvermogen in kW
grid_kwnumberoptioneelNetuitwisseling in kW
typestringoptioneelGebruik "ping" om een keep-alive te sturen.
Voorbeeld frame
{
"ts": "2026-04-23T08:15:00Z",
"power_kw": 45.2,
"soc_percent": 68.5,
"pv_kw": 32.1,
"load_kw": 77.3,
"battery_kw": -10.0,
"ev_kw": 7.4,
"grid_kw": 45.2
}Server → client messages
Bevestiging per frame
{ "type": "ack", "ts": "2026-04-23T08:15:00Z" }Ping
{ "type": "ping" }Pong
{ "type": "pong", "t": 1745395123456 }Connectie-lifecycle
- Bij open ontvangt u
{ "type": "hello", "location_id": "…", "session_id": "…" }. - Stuur elke 20 seconden een ping om de sessie levend te houden achter load balancers.
- Ongeldige JSON en validatiefouten komen terug als
{ "type": "error", "message": "…" }. De socket wordt niet gesloten. - Implementeer reconnect met exponential backoff (1 s → 30 s cap) en jitter.
- Rate limit: 60 frames per minuut per token (te hoge frequentie resulteert in 429 bij upgrade).
Node.js (ws)
import WebSocket from "ws";
const url = "https://fbkhhcsplwxkorfhgqwr.supabase.co/functions/v1/ems-ws-ingress";
const token = process.env.EMS_BEARER_TOKEN;
const ws = new WebSocket(url, {
headers: { Authorization: `Bearer ${token}` },
});
ws.on("open", () => {
setInterval(() => {
ws.send(JSON.stringify({
ts: new Date().toISOString(),
power_kw: readPowerKw(),
soc_percent: readSoc(),
pv_kw: readPv(),
}));
}, 5000);
});
ws.on("message", data => {
const msg = JSON.parse(data.toString());
if (msg.type === "ack") { /* ok */ }
if (msg.type === "error") console.warn("ingress error:", msg.message);
});
ws.on("close", () => {
// reconnect met exponential backoff
});Browser / Deno
const ws = new WebSocket(
"https://fbkhhcsplwxkorfhgqwr.supabase.co/functions/v1/ems-ws-ingress?token=" + encodeURIComponent(token)
);
ws.onopen = () => ws.send(JSON.stringify({ ts: new Date().toISOString(), power_kw: 12.3 }));
ws.onmessage = e => console.log("msg", JSON.parse(e.data));{uw_ems_ws_url} HMAC-SHA256 signeringEnerSim → EMS — Setpoint-stream (outbound)
EnerSim opent een korte uitgaande WebSocket naar de URL die u op de Flex pagina configureert (transport-modus ws of beide). Na elke solver-run of BRP-override wordt een frame gepubliceerd met het effectieve setpoint voor de komende kwartieren. Uw EMS bevestigt implicit door de setpoints toe te passen.
Connectieparameters
- Uw endpoint moet een
wss://URL zijn. - Configureer optioneel een Bearer token: EnerSim stuurt deze mee als Sec-WebSocket-Protocol
bearer, <token>. - Eerste bericht is het setpoint-frame.
- EnerSim sluit de verbinding 200 ms na verzending; bewaar geen langlevende sessies aan EMS-zijde.
- Bij timeout of foutstatus wordt de verbinding gemarkeerd als
error; het EMS valt terug op het laatst via REST ontvangen dagprofiel.
Frame schema
versionstringverplichtSchema-versie, momenteel "1.0".
typestringverplichtAltijd "setpoint_update".
locationobjectverplichtid + name van de locatie.
generated_atstring (ISO 8601 UTC)verplichtTijdstip waarop EnerSim het frame heeft samengesteld.
horizon_start_utcstring (ISO 8601 UTC)verplichtBegin van het eerste slot (15 minuten).
slotsarrayverplichtTot 8 kwartierslots vanaf horizon_start_utc.
ts_utcstringverplichtStart van het slot (UTC).
effective_kwnumberverplichtSetpoint dat het EMS moet toepassen (positief = import, negatief = export).
scheduled_kwnumberoptioneelOrigineel gepland setpoint voor dit slot.
brp_override_kwnumber | nulloptioneelBRP-override, indien van toepassing.
override_reasonstring | nulloptioneelToelichting op de override.
Voorbeeld setpoint frame
{
"version": "1.0",
"type": "setpoint_update",
"location": { "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "name": "Mijn site" },
"generated_at": "2026-04-23T08:14:58Z",
"horizon_start_utc": "2026-04-23T08:15:00Z",
"slots": [
{
"ts_utc": "2026-04-23T08:15:00Z",
"effective_kw": -12.5,
"scheduled_kw": -12.5,
"brp_override_kw": null,
"override_reason": null
},
{
"ts_utc": "2026-04-23T08:30:00Z",
"effective_kw": 20.0,
"scheduled_kw": 8.0,
"brp_override_kw": 20.0,
"override_reason": "BRP curtailment"
}
]
}/functions/v1/ems-setpoints-push) gepusht. Het EMS moet autonoom op het laatst bekende REST-profiel kunnen doordraaien zodra de WS-verbinding langer dan één slot (15 min) wegvalt.Rate Limits & Best Practices
- Max. 100 records per ingest request
- Max. 1000 ingest requests per uur per locatie
- Stuur data elke 1 minuut voor optimale forecasting
- Gebruik altijd UTC timestamps
- Implementeer exponential backoff bij 429 errors
- Voeg zoveel mogelijk metadata toe voor betere forecasts
- Roteer de Bearer token elke 90 dagen
- Vraag solver-activering pas aan nadat de EMS verbindingstest is geslaagd