Real-time Data

How to receive real-time energy telemetry from your devices using SSE streams, WebSocket, and NATS.

Novacore provides three ways to receive real-time telemetry from your energy devices. Choose based on your use case.

Server-Sent Events provide a simple, persistent HTTP connection that streams data as it arrives. Works in browsers natively.

JavaScript Example

const BASE_URL = "https://novacore-mainnet.sourceful.dev";

const eventSource = new EventSource(
  `${BASE_URL}/stream/sites/${siteId}`, {
    headers: { Authorization: `Bearer ${token}` }
  }
);

eventSource.onmessage = (event) => {
  const reading = JSON.parse(event.data);

  switch (reading.type) {
    case "pv":
      console.log(`Solar: ${reading.W}W`);
      break;
    case "battery":
      console.log(`Battery: ${reading.W}W (SoC: ${reading.SoC_nom_fract * 100}%)`);
      break;
    case "meter":
      console.log(`Grid: ${reading.W}W`);
      break;
  }
};

eventSource.onerror = () => {
  console.log("Reconnecting...");
  // EventSource automatically reconnects
};

Python Example

import json
import sseclient
import requests

BASE_URL = "https://novacore-mainnet.sourceful.dev"

response = requests.get(
    f"{BASE_URL}/stream/sites/{site_id}",
    headers={"Authorization": f"Bearer {token}"},
    stream=True,
)

client = sseclient.SSEClient(response)

for event in client.events():
    reading = json.loads(event.data)
    der_type = reading.get("type", "unknown")
    power = reading.get("W", "N/A")
    print(f"[{der_type}] Power: {power}W")

Key Points

  • Automatic reconnection on network failure (built into the SSE spec)
  • One stream per site — receives all DER telemetry for that site
  • Readings are JSON objects matching the telemetry schemas

Option 2: WebSocket

For bidirectional real-time communication:

wss://novacore-mainnet.sourceful.dev:4443

Knowledge gap for Johan: Document the WebSocket protocol — connection handshake, subscription messages, and data format.

Option 3: NATS (For Backend Services)

NATS provides the highest-performance option for backend services that need to process telemetry at scale. Requires approved access.

Topic Structure

Subscribe to organization-structured telemetry:

orgs.{org_id}.sites.*.devices.*.ders.*.telemetry.json.v1

Or subscribe to specific DER types:

orgs.{org_id}.sites.{site_id}.devices.*.ders.*.telemetry.json.v1

NATS Connection

EnvironmentConnection
Testnetwss://novacore-testnet.sourceful.dev:4443
Mainnetwss://novacore-mainnet.sourceful.dev:4443

Knowledge gap for Johan: How do developers get NATS access credentials? Is it via an integration identity (ES256 key)? What auth method is used for NATS WebSocket connections?

Data Format

All telemetry follows the schemas documented in Data Models. Each reading includes:

  • type — DER type (pv, battery, meter, v2x_charger)
  • timestamp — Unix epoch milliseconds (applied by the gateway, not the device)
  • read_time_ms — How long the reading took
  • Type-specific fields (power, voltage, SoC, etc.)

Handling Gaps and Reconnection

  • SSE: Automatic reconnection is built into the protocol. Use EventSource.onerror for custom handling.
  • NATS JetStream: Retained for 7 days (ENRICHED_TELEMETRY stream). Use consumer replay to catch up after disconnection.
  • Idempotency: Use (der_id, timestamp) as a unique key for deduplication.
  • Ordering: Events may arrive out of order. Always use the timestamp field, not arrival order.