Addressing sites by EAN
Look up a site and read its current meter state using the Czech metering-point EAN — no internal IDs or mapping tables required.
Overview
Every Voke site can carry up to two Czech-market metering-point identifiers:
eanCons— consumption EAN (odběrný EAN), where electricity flows in from the grid.eanProd— production EAN (výrobní EAN), where electricity flows out to the grid.
Both are exactly 18 digits (e.g. 859182400123456789). If your system models customers by EAN — for example from an EDC sharing export — you can address Voke sites directly by EAN without maintaining any EAN → site mapping table.
The canonical site identifier on the wire stays the site UUID (siteId in AMQP envelopes and
REST paths). EANs are lookup attributes: resolve once, cache the UUID, and fall back to a fresh
lookup if a site disappears.
One-call meter state — GET /vcp/meter-state?ean=
The fastest path from "I have an EAN" to "what does the meter say right now":
curl -H "X-API-Key: <your-key>" \
"https://api.voke.turena.cz/api/v1/vcp/meter-state?ean=859182400123456789"{
"siteId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"eanCons": "859182400123456789",
"eanProd": "859182400987654321",
"reading": {
"readingAt": "2026-06-13T15:49:50.355Z",
"meters": [
{
"deviceId": "GRID",
"role": "GRID",
"importRegisterKwh": 34897.145,
"productionRegisterKwh": 109018.273
}
],
"dataQuality": "GOOD"
}
}This is a real response captured from a live plant. Which register fields appear depends on what
the meter physically exposes — a grid meter may report importRegisterKwh / exportRegisterKwh /
productionRegisterKwh, a battery chargeRegisterKwh / dischargeRegisterKwh, etc. Only the
registers the device actually has are included.
Behavior:
- The EAN matches either
eanConsoreanProdof a site in your organization. - Registers are absolute, monotonically increasing kWh counters — derive deltas by subtracting a previous reading.
readingisnullwhen no telemetry is fresh enough (site offline or no register-tagged signals yet).- An unknown EAN (or one belonging to another organization) returns 404
SITE_NOT_FOUND. - A malformed EAN (not exactly 18 digits) returns 400
VALIDATION_ERROR.
Requires the vcp:read scope — the same key you use for all /vcp/sites/* reads.
Catalog lookup — GET /vcp/sites?ean=
To resolve an EAN to the full site record (sub-devices, supported commands, status):
curl -H "X-API-Key: <your-key>" \
"https://api.voke.turena.cz/api/v1/vcp/sites?ean=859182400123456789"The response is the standard plant list filtered to the matching site. Every site in the unfiltered catalog also carries its eanCons / eanProd, so a single unfiltered GET /vcp/sites at boot gives you the complete EAN ↔ siteId map.
An unknown EAN returns an empty plants array (it is a filter, not a lookup — no 404).
EANs on the AMQP meter stream
The 1-minute MeterReadingPayload on routing key {slug}.event.telemetry.meter.{siteId} carries the site's eanCons / eanProd directly in the payload:
{
"version": "1.1",
"siteId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"payload": {
"readingAt": "2026-06-12T09:00:00.000Z",
"eanCons": "859182400123456789",
"eanProd": "859182400987654321",
"meters": [{ "deviceId": "GRID", "role": "GRID", "importRegisterKwh": 124530.487 }],
"dataQuality": "GOOD"
}
}Consumers can route readings into an EAN-keyed model with zero extra calls. Fields are null for sites that have no EAN configured.
Can I subscribe to one EAN's stream?
Not by EAN directly — but you can subscribe per site, which gets you the same result. The telemetry routing key now ends with the site UUID (…telemetry.realtime.{siteId} / …telemetry.meter.{siteId}), and the vcp exchange is a topic exchange, so you can bind a dedicated queue to one PLC's siteId instead of consuming the shared firehose. See Subscribe to one PLC for the binding example.
The EAN is not in the routing key (it's nullable, can change with a metering-point contract, and is absent on realtime). The mapping is one stable boot-time step:
- Call
GET /vcp/sitesonce and build your EAN →siteIdmap (every site carrieseanCons/eanProd). - Bind a queue to the
siteId(s) you care about — or keep the default firehose queue and route in-process.
Whichever you choose, key your business logic on what's in every message:
envelope.siteId— the plant UUID, present on every message (stable, never changes).payload.eanCons/payload.eanProd— present on meter readings, for your EAN-keyed accounting.
Bind and route by siteId: it's a stable UUID that's on every message type and is the only
thing in the routing key. EANs are only on meter readings, can be unset (null), and can change if
a metering point's contract changes — so they stay in the payload, not the routing key.
Identifier cheat sheet
| Identifier | Where | Meaning |
|---|---|---|
siteId | REST paths, AMQP envelope | Voke site (plant) UUID — the canonical wire id. |
eanCons / eanProd | /vcp/sites, /vcp/meter-state, meter payloads | Czech metering-point EANs (18 digits) — lookup attributes. |
deviceId | subDevices[], DeviceTelemetry, MeterEntry, command targets | Sub-device externalId (e.g. GRID, PV1) — one rule, everywhere. |
externalPlantId | /vcp/sites | Optional partner-assigned alias for your own catalog reconciliation. |