ENERGY MONITORING - HYBRID
Hybrid Track: Monitor Without Replacing
You have meters. You have a BMS. Now add OpenX beside them.
You are not replacing your BMS or swapping meters. You are adding a workspace where meter data lands, is organized on surfaces, and is read through saved queries.
What you will have
- One consumption view across your meters and sources
- Saved queries for cost allocation and sustainability
- API endpoints for your reporting tools
- Any AI over MCP, reading the same queries
All without touching your existing metering.
Phase 1: Connect your data
Step 1.1: Add a connection
On the canvas
- Open your workspace.
- Drag a Connection node from the Node Bank onto the canvas.
- In its inspector's Settings tab, set the Connection ID (tick Is IoT Edge Device if an IoT Edge gateway sends for it). There is no connection string to enter: the connection sets up its own device identity.
- Save, then Deploy. Deploy registers the connection as a device on Fathym's shared IoT hub, or your own once your workspace has its IoT fabric.
- Open the inspector's Connection Info tab. It shows the credentials your gateway or BMS integration uses to send data (device, MQTT, AMQP and HTTP details).
Or ask Azi
AZI
Tell me: "Create a connection for our building energy meters." I propose it; accept it, then Deploy builds it.
Step 1.2: How your sources reach OpenX
| Source | How it reaches OpenX |
|---|---|
| Smart meters, submeters | Sent through a gateway to the connection's device (MQTT, AMQP or HTTP) |
| BMS | Through an edge gateway to the connection's device |
| Utility feeds (API or CSV export) | An API Source polling an HTTP endpoint |
When data arrives, it shows in the Live Stream panel.
TIP
Start with your main building meter. Add submeters later; queries that group by meter pick them up.
Phase 2: Create consumption surfaces
Surfaces organize your energy data. A connection feeds a surface when you draw a line from it to the surface.
Step 2.1: A building surface
Ask Azi in the main panel:
"Create a surface for building energy monitoring, fed by the building meters connection."
She proposes a Building-Energy surface wired to the connection. Accept it; a surface is live as soon as it is
accepted.
Step 2.2: Line-level surfaces
For finer allocation, add a surface per area:
| Surface | Fed by | Purpose |
|---|---|---|
Production-Line-1 | Line 1 meters | Line-specific consumption |
HVAC-Systems | Chiller and air-handler meters | Building systems |
Lighting | Lighting circuits | Area lighting |
Phase 3: Build cost allocation queries with Azi
Where your data is
Your workspace's device data lands in one table, Data (Devices in workspaces whose IoT fabric was set up
earlier). Each message's payload is JSON in its RawData column, so a query unpacks it with
todynamic(RawData). The field names below (meterType, kWh, kW, area) are examples; use the ones your
meters send. Ask Azi to sample with Data | take 5 first. The queries below are examples to adapt, not tested against your data.
In the main Azi panel, Azi proposes each warm query together with the surface it sits on; accept it and it is live. Inside the Warm Query Manager, she drafts the query instead and you save it with the canvas Save icon.
Step 3.1: Daily consumption
"Create a warm query for total electricity consumption by day over the last 30 days."
Data
| where EnqueuedTime > ago(30d)
| extend Payload = todynamic(RawData)
| where tostring(Payload.meterType) == "Electric"
| summarize TotalKWh = sum(todouble(Payload.kWh)), PeakKW = max(todouble(Payload.kW)) by bin(EnqueuedTime, 1d)
| order by EnqueuedTime asc
Step 3.2: Cost allocation by area
"Build a query that allocates electricity cost to each area based on consumption."
Data
| where EnqueuedTime > ago(1d)
| extend Payload = todynamic(RawData)
| where tostring(Payload.meterType) == "Electric"
| summarize Consumption = sum(todouble(Payload.kWh)) by Area = tostring(Payload.area)
| extend CostPerKWh = 0.12 // your rate
| extend AllocatedCost = Consumption * CostPerKWh
| order by AllocatedCost desc
Step 3.3: Peak demand
"Create a query for our top 10 peak demand hours in the last month."
Data
| where EnqueuedTime > ago(30d)
| extend Payload = todynamic(RawData)
| where tostring(Payload.meterType) == "Electric"
| summarize PeakKW = max(todouble(Payload.kW)) by Hour = bin(EnqueuedTime, 1h)
| top 10 by PeakKW desc
| project Hour, PeakKW, DayOfWeek = toint(dayofweek(Hour) / 1d) // 0 = Sunday
AZI
Every query I propose waits for you to read it before it is accepted - unless you have turned on Greenfield. When an auditor asks how you calculated your emissions, you show them the saved query.
Phase 4: Call your queries over REST
Every warm query is a REST endpoint.
Step 4.1: Find your endpoint
- Open APIs -> API Manager and its Warm Queries tab.
- Under Configured Queries, each saved warm query has its own card, with ready-to-copy cURL, TypeScript and Python.
- Get a key from APIs -> API Keys.
Step 4.2: Call it
curl -X GET 'https://openx.fathym.com/ox-api/warm-queries/daily-consumption' \
-H 'Authorization: Bearer YOUR_TOKEN'
Step 4.3: Where it plugs in
| Integration | Use |
|---|---|
| ERP | Monthly cost allocation posting |
| Dashboard | Consumption display |
| Sustainability platform | Emissions reporting |
| Alerting | Peak demand notifications |
See APIs for Power BI and Grafana.
Phase 5: Connect any AI over MCP
The OpenX MCP Server is at https://openx.fathym.com/ox-api/mcp. Sign in through the browser:
- Claude.ai or ChatGPT: add a custom connector, paste the URL, sign in with OpenX, pick the workspace and tick the rights to share.
- Coding agents: run
fai mcp install https://openx.fathym.com/ox-api/mcp --name openxand sign in when the browser opens.
Setup for each client is in Bring Any AI. Then ask:
"What's driving our electricity costs this month compared to last month?"
The AI reads your saved queries with call_api. If it wants to build something new, it proposes it with
manage_proposals, and a person accepts.
What you built
| Component | Status |
|---|---|
| Meter connection | Built on Deploy, sending data |
| Consumption surfaces | Organized by building and line |
| Allocation queries | Three saved warm queries |
| API endpoints | One per warm query |
| MCP | Any client reading the same queries |
Before and after
| Before | After |
|---|---|
| "The meter showed this" | The saved query behind the number, there to read |
| Spreadsheet reports | Reports that call the same saved queries |
| Manual allocation | One allocation query, the same for everyone |
Next steps
| If you want to... | Go to... |
|---|---|
| Try the full track | Full track |
| See query patterns | Query Patterns |
| Connect more AI clients | Bring Any AI |
| Explore manufacturing | Manufacturing |
On this page
- Hybrid Track: Monitor Without Replacing