TL;DR
- Push-based device updates via Azure Event Hubs — activate in the Partner Portal, connect with any Event Hubs SDK (C#, Python, JS)
- Each event:
{ deviceId, clientId, timestamp, capabilities[] }— same capability names and data shapes as the REST API - Filter by
clientIdto route events per customer; events are at-least-once — deduplicate ondeviceId+timestamp - 7-day retention, 32 partitions — use checkpointing in production to survive consumer restarts
The Live Telemetry feature delivers real-time device state updates directly to your infrastructure via Azure Event Hubs. Instead of polling the device endpoints, your application receives a continuous stream of telemetry events as soon as device data changes.
Polling vs. Live Telemetry
Polling (GET /devices/{id}) | Live Telemetry (Event Hub) | |
|---|---|---|
| Delivery model | Pull – you request data on demand | Push – data is delivered as it arrives |
| Latency | Depends on your polling interval | Near real-time (seconds) |
| Data scope | Full device snapshot incl. all capabilities | Only telemetry-relevant capabilities with latest values |
| Use case | UI refresh, on-demand reads | Dashboards, monitoring, analytics, alerting |
Live Telemetry does not replace the device REST API. Use both together: the REST API for device management, capability writes, and on-demand reads; the telemetry stream for continuous monitoring.
Activation & credentials
Live Telemetry is activated and managed through the clever-PV Partner Portal. No API calls are required for setup.
Step 1: Activate telemetry
- Log in to the Partner Portal
- Navigate to Connect API > Telemetry
- Click Activate Telemetry
After activation, the portal displays your Event Hub credentials:
- Connection String — a full Azure Event Hubs connection string with listen (read-only) permissions
- Event Hub Name — the name of your dedicated Event Hub (format:
telemetry-{name})
Example connection string:
Code
Important: Store the connection string securely. It grants read access to your entire telemetry stream. You can retrieve it again at any time from the Partner Portal.
Step 2: Use the credentials in your application
Copy the connection string and Event Hub name from the Partner Portal and use them in your consumer application (see Connecting to the Event Hub below).
Connecting to the Event Hub
Use the official Azure Event Hubs SDK in your preferred language to consume events.
C# (.NET)
Install the NuGet package:
Code
Consume events:
Code
For production use, consider the
EventProcessorClientwith Azure Blob Storage for checkpointing. See Microsoft documentation.
Python
Install the package:
Code
Consume events:
Code
JavaScript / Node.js
Install the package:
Code
Consume events:
Code
Event schema
Every telemetry event is a JSON message with the following structure (schema version 1.0):
Code
Top-level fields
| Field | Type | Description |
|---|---|---|
schemaVersion | string | Schema version identifier. Currently "1.0". |
deviceId | string (GUID) | The device ID as returned by the Connect API (same as GET /devices). |
clientId | string or null | The client identifier (OAuth2 client_id) that provisioned this device. null if the device has no client association. |
timestamp | string (ISO 8601 UTC) | Timestamp of the telemetry reading. |
capabilities | array | List of capability readings included in this event. |
Capability object
| Field | Type | Description |
|---|---|---|
name | string | The capability name (e.g., display-grid-power). Same names as in the REST API. |
data | object | Capability-specific data. Structure varies per capability (see reference below). |
Event Hub message properties
Each message also includes these properties on the Event Hub message envelope (accessible via SDK without parsing the body):
| Property | Value |
|---|---|
deviceId | Same as deviceId in the body |
schemaVersion | Same as schemaVersion in the body |
clientId | Same as clientId in the body (only present when not null) |
Tip: Use the
clientIdmessage property for server-side Event Hub routing or filtering without deserializing the event body.
Telemetry capabilities by device type
Not every capability appears in every event. An event only contains capabilities for which new data is available. The following table shows which capabilities can appear per device type.
Electric Meter
| Capability | Fields | Description |
|---|---|---|
core | connectivityStatus, lastUpdate | Device online status |
display-grid-power | gridPower (int, Watt), lastUpdate | Current grid power draw/feed-in |
display-solar-power | solarPower (int, Watt), lastUpdate | Current solar production |
display-community-power | communityPower (int, Watt), lastUpdate | Current community/shared power |
display-soc | soc (int, %), lastUpdate | Battery state of charge (if battery attached) |
display-battery-state | state (string), chargingPower (int, Watt), lastUpdate | Battery state. state is authoritative; treat chargingPower as magnitude — see reference. |
Switch
| Capability | Fields | Description |
|---|---|---|
core | connectivityStatus, lastUpdate | Device online status |
on-off | state ("on" / "off") | Current on/off state |
display-power | power (int, Watt), lastUpdate | Current power consumption |
Wallbox
| Capability | Fields | Description |
|---|---|---|
core | connectivityStatus, lastUpdate | Device online status |
display-charging-state | chargingState (string) | Current charging state (e.g., "charging", "completed", "noCarConnected") |
on-off | state ("on" / "off") | Derived on/off state |
display-power | power (int, Watt), lastUpdate | Current charging power |
display-charging-current | amperage (int, Ampere) | Current charging amperage |
display-charging-phases | phases (int) | Number of active charging phases |
Car (Vehicle)
| Capability | Fields | Description |
|---|---|---|
core | connectivityStatus, lastUpdate | Device online status |
display-charging-state | chargingState (string) | Current charging state |
on-off | state ("on" / "off") | Derived on/off state |
display-power | power (int, Watt), lastUpdate | Current charging power |
display-charging-current | amperage (int, Ampere) | Current charging amperage |
display-charging-phases | phases (int) | Number of active charging phases |
display-soc | soc (int, %), lastUpdate | Battery state of charge |
display-estimated-range | range (int, km) | Estimated remaining range |
Capability data reference
All field names use camelCase. Enums are serialized as strings. Nullable fields may be null or absent — always apply null-tolerance when parsing.
core
Code
connectivityStatus:"online"— always"online"in telemetry events (events are only sent when the device reports data)lastUpdate: ISO 8601 UTC timestamp
display-grid-power
Code
gridPower: integer, Watt. Positive = drawing from grid, negative = feeding into grid.
display-solar-power
Code
solarPower: integer, Watt.
display-community-power
Code
communityPower: integer, Watt.
display-soc
Code
soc: integer, percentage (0–100).
display-battery-state
Code
state: string enum —"idle","charging","discharging","disabled". This is the authoritative direction of the battery flow and is the field you should consume to know what the battery is doing.chargingPower: integer, Watt. Treat as magnitude — useabs(chargingPower). The sign ofchargingPoweris not normalised across vendors: some adapters forward the raw vendor value (where positive may mean discharging), others normalise to "positive = charging". Do not derive direction from the sign — always usestate.
It is therefore valid to receive an event with, for example, state = "discharging" together with chargingPower > 0 (raw vendor sign) — state is correct, and the magnitude is abs(chargingPower).
Recommended client logic:
Code
display-power
Code
power: integer, Watt. Current power consumption of the device.
display-charging-state
Code
chargingState: string enum. Values include"noCarConnected","charging","waitingOnCar","completed","error","awaitingStart","waitingForStatus". Be tolerant of unknown values.
noCarConnecteddoes not mean the device is offline or mis-onboarded. It means the charging cable is currently not plugged into the vehicle — a normal operating state for a car that isn't charging (for VW/Audi/Škoda/Cupra it maps from the vendor'snotReadyForCharging/disconnectedstate). To check whether the device itself is reachable, useconnectivityStatuson thecorecapability (online/offline), not this value: a device can beonlineand reportnoCarConnectedat the same time.
on-off
Code
state:"on"or"off".
display-charging-current
Code
amperage: integer, Ampere.
display-charging-phases
Code
phases: integer (1, 2, or 3).
display-estimated-range
Code
range: integer, kilometers.
Consumer groups
Azure Event Hubs supports consumer groups, which allow multiple independent readers to consume the same telemetry stream at their own pace. Each consumer group maintains its own read position (offset).
Use cases:
- Separate consumer groups for your analytics pipeline, alerting system, and dashboard backend
- Development/testing consumer group alongside production
Default consumer group
Every Event Hub comes with a built-in $Default consumer group. This is sufficient if you only have a single consumer application.
Managing consumer groups
Consumer groups are managed through the Partner Portal:
- Navigate to Connect API > Telemetry
- In the Consumer Groups section, you can:
- View all existing consumer groups
- Create new consumer groups by entering a name
- Delete consumer groups you no longer need
Important: You cannot delete the
$Defaultconsumer group. Deleting a consumer group while consumers are connected will disconnect them.
When creating a consumer in your application, specify the consumer group name from the Partner Portal:
Code
Credential rotation
If you need to rotate the Shared Access Key for your Event Hub (e.g., after a security incident or as part of regular key hygiene), you can do so from the Partner Portal:
- Navigate to Connect API > Telemetry
- Click Rotate Credentials
- Copy the new connection string
Important: The previous key becomes invalid immediately after rotation. All consumers using the old connection string will be disconnected and must be updated with the new connection string.
Zero-downtime rotation strategy:
- Rotate the credentials in the Partner Portal
- Deploy the new connection string to all consumer applications
- Restart consumers to pick up the new credentials
Since there is only one active key at a time, a brief reconnection window is unavoidable. Keep this window as short as possible by automating the credential deployment.
Best practices
-
Single stream per partner: All devices from all your clients share one Event Hub. Use the
clientIdfield to identify which of your clients a device belongs to, and thedeviceIdfield to identify the specific device. This lets you route events to client-specific processing pipelines. -
At-least-once delivery: Events may be delivered more than once (e.g., during Event Hub rebalancing). Design your consumers to be idempotent — use
deviceId+timestampas a deduplication key. -
Null tolerance: Not every capability field is guaranteed to be present in every event. Always handle missing or
nullfields gracefully. -
Schema versioning: Always check
schemaVersionbefore parsing. The current version is"1.0". Future updates will increment the version and may add new fields. Unknown fields should be ignored (forward compatibility). -
Data retention: Events are retained in the Event Hub for 7 days. If your consumer is offline for longer, older events will be lost.
-
Checkpointing: For production consumers, use checkpointing (e.g., Azure Blob Storage for .NET
EventProcessorClient, or equivalent in other SDKs) to resume from the last processed position after restarts. -
Partition count: The Event Hub is provisioned with 32 partitions. You can run up to 32 parallel consumer instances within the same consumer group for maximum throughput.
-
Event frequency: Telemetry events are sent whenever device data changes. The frequency varies by device type and vendor — from every few seconds (e.g., Shelly switches) to every few minutes (e.g., vehicle telemetry).
-
Correlating with the REST API: The
deviceIdin telemetry events matches theidfield fromGET /v1/users/{userId}/devices. Use this to correlate telemetry data with device metadata (name, model, vendor, etc.) from the REST API.