DEV Community

Karthikeyan DSK
Karthikeyan DSK

Posted on

How We Translated OpenADR XML to JSON in 47ms — Building the API Layer for the Power Grid

Every critical infrastructure system has been abstracted into programmable primitives.

Banking has Plaid. Payments have Stripe. Communications have Twilio.

The power grid? Nothing.

The grid speaks 8 major protocols — IEC 61850, DNP3, Modbus, OpenADR, OCPP, IEEE 2030.5, and more. They were built by different standards bodies, in different decades. A Modbus register read looks nothing like an OpenADR XML event.

We're building the translation layer.

The OpenADR Challenge

OpenADR 2.0b is the protocol utilities use for demand response. When a utility wants a data center to reduce power consumption, it sends this XML:

<oadr:oadrDistributeEvent>
  <oadr:oadrEvent>
    <ei:eiEvent>
      <ei:eventDescriptor>
        <ei:eventID>EVT-DR-001</ei:eventID>
        <ei:marketContext>http://dewa.gov.ae/DR</ei:marketContext>
      </ei:eventDescriptor>
      <ei:eiEventSignals>
        <ei:eiEventSignal>
          <ei:signalName>SIMPLE</ei:signalName>
          <ei:signalType>level</ei:signalType>
          <ei:currentValue>
            <ei:payloadFloat><ei:value>2.0</ei:value></ei:payloadFloat>
          </ei:currentValue>
        </ei:eiEventSignal>
      </ei:eiEventSignals>
    </ei:eiEvent>
  </oadr:oadrEvent>
</oadr:oadrDistributeEvent>
Enter fullscreen mode Exit fullscreen mode

On the other side, we return:

{
  "eventId": "EVT-DR-001",
  "signalName": "SIMPLE",
  "signalType": "level",
  "signalValue": 2.0,
  "marketContext": "http://dewa.gov.ae/DR",
  "status": "active",
  "startDate": "2026-02-11T10:00:00Z",
  "durationSeconds": 3600
}
Enter fullscreen mode Exit fullscreen mode

47ms. Full semantic translation, not just XML-to-JSON byte conversion.

Why Semantic Translation Matters

A naive XML-to-JSON converter gives you namespace-prefixed nesting five levels deep. Useless for developers.

Our translation engine does four things:

  1. Parse — XML deserialization with namespace handling
  2. Extract — Pull semantically meaningful fields
  3. Normalize — Map to consistent JSON schema across all protocols
  4. Enrich — Add context (what does signal level 2.0 mean?)

8 Protocols, One API

Protocol Era Format Used For
OpenADR 2.0b 2009 XML Utility demand response
Modbus TCP 1979 Binary registers Industrial equipment, BESS
IEC 61850 2003 XML/binary Substation automation
DNP3 1993 Binary SCADA telemetry
OCPP 2.0 2020 JSON EV charging
IEEE 2030.5 2013 XML Smart inverters, DER
IEC 60870-5-104 2000 Binary Wide-area grid telecontrol
ICCP/TASE.2 1996 Binary Inter-utility data exchange

We sit at the intersection of all eight. One API. One JSON schema.

45 MCP Tools for AI Agents

We built 45 tools on Anthropic's Model Context Protocol:

// Dispatch a battery
await mcp.call("dispatch_command", {
  assetId: 42,
  commandType: "discharge",
  parameters: { powerMw: 5, durationMinutes: 60 }
});

// Carbon attestation
await mcp.call("attest_energy", {
  meterId: "MTR-DEWA-01",
  kwh: 1250.5,
  source: "grid"
});

// Find subsidies
await mcp.call("scan_subsidies", {
  facilityId: "fac-001"
});
Enter fullscreen mode Exit fullscreen mode

The agent doesn't need to know the underlying protocol. It just calls tools.

Try It Yourself

Developer sandbox with prizes up to $1,000:

https://app.energyatit.com/journey

  • 5 core primitives: connect, dispatch, settle, comply, intel
  • 6-stage developer journey with auto-progression
  • Leaderboard
  • SDKs in TypeScript, Python, and Go

The grid is the last major infrastructure without an API. We're fixing that.

EnergyAtIthttps://energyatit.com
Built by Karthikeyan DS (ex-AWS, led launch readiness for AWS Hyderabad data center region)

Top comments (0)