Analytics

Authoring a KPI

Create a KPI definition with the builder, preview real values, and enable it across your assets.

KPI authoring is a draft-first flow: define the calculation, save it as a disabled draft, preview real values computed over your actual history, and only then enable it. Nothing is scheduled or written until you enable.

To start, go to Analytics → KPIs and click New KPI.

Step 1 — Describe the definition

Fill in the Definition card:

FieldDescription
NameHuman-readable name shown in the catalog.
KPI keyThe output key (lowercase snake_case, for example avg_active_power). Unique within your organization and immutable after creation — choose it carefully.
Unit codeThe unit of the result, from the platform unit catalog — for example kW, kWh, %, or 1 for dimensionless values. Unknown unit codes are rejected on save.
CadenceHow often the engine computes: 1m, 5m, 15m, 1h, or daily (site-timezone calendar days).
DescriptionOptional free text.

Step 2 — Pick the population

In the Population card, select one or more asset categories and, optionally, a site to narrow the population. The definition applies to every asset that matches — including assets that match later. You must pick at least one category or a site.

Step 3 — Build the calculation

The Calculation card offers two modes.

Builder mode

The builder covers the most common shape: one input variable key (the telemetry variable to read on each matched asset, for example active_power) followed by a chain of shaping operators. Click Add step to append a step and pick its operator:

  • resample — change the series grain, with an aggregation (avg, min, max, last, sum)
  • fill — fill gaps (prev, zero, or none, with an optional maximum gap)
  • delta — last value minus baseline over the schedule window
  • rate — rate of change over the window
  • counter_delta — sum of in-window increments of a cumulative counter (baseline lookback, rollover-safe)
  • integrate — time-integral of the series over the window

Each step takes its parameters as JSON, for example {"intervalSeconds": 3600}.

JSON mode

Click Edit as JSON for the full spec shape: a directed graph of nodes and edges with an output node. This is where binary math (add, subtract, multiply, divide), comparisons, per-asset parameter nodes, cycle detection, and KPI-on-KPI compositions live. Back to builder returns to builder mode when the spec still fits the linear shape; richer specs stay in JSON mode so nothing is silently discarded.

As you edit, the How the engine reads this spec panel renders the spec as three cards — Inputs, Operators, and Output — so you can confirm the graph before saving.

Step 4 — Save, preview, enable

  1. Click Save draft (disabled). The platform validates the spec — structure, operator rules, unit code, KPI key uniqueness, and whether the matched population actually carries the input variables. Validation errors are shown verbatim so you can fix the spec.
  2. In the Preview the draft panel, pick a time range and click Run preview. The platform computes the calculation over your real history and charts one line per matched asset. A note tells you which storage tier computed the result.
  3. Click Enable. The platform materializes a KPI variable on every matched asset and the engine starts computing on schedule. A confirmation reports how many assets matched and how many KPI variables were created.

Preview runs the same compiled calculation the scheduler runs. What you see in the preview is exactly what the engine will persist once enabled — there is no separate preview approximation.

Enabling is refused while the selector matches no assets, or while matched assets are missing required per-asset parameter values — see Health & Troubleshooting for the exact messages.

Operator reference

The calculation spec is a graph of typed operators:

GroupOperatorsNotes
Sourcesinput, const, parameterinput reads a telemetry variable by key; const is a literal; parameter reads a per-asset value from an asset attribute (dot-namespaced key, for example bess.usable_capacity_kwh).
Shapingresample, fillOperate on series; resample takes intervalSeconds and an agg.
Window aggregationsdelta, rate, counter_delta, integrateProduce one value per asset per schedule window (window scalars).
Event detectionclassify, sessionsclassify maps a series into named states using thresholds, hysteresis, and a minimum-duration debounce; sessions turns state transitions into cycle records.
Arithmeticadd, subtract, multiply, divideTwo inputs connected via named ports (for example numerator and denominator).
Comparison and logicgt, lt, gte, lte, eq, and, or, notProduce boolean series.

Rules the engine enforces:

  • Window scalars are already aggregated. counter_delta, delta, rate, and integrate aggregate the whole schedule window per asset — never feed their output into resample. For a daily total from a cumulative counter, counter_delta on a daily cadence is all you need: the daily window is the day.
  • classify output may only feed a sessions node, and a sessions node must be the spec's output — its cycle records are the result.
  • Binary operators accept series with series (same grain), scalar with scalar, or a scalar broadcast across a series.
  • divide writes no point when the denominator is zero — a not-computable window produces a gap, never a fabricated value.
  • The engine writes one point per asset per window, timestamped at the window start; if the output node is a series, it is averaged over the window.
  • KPI-on-KPI: an input node whose variable key is another definition's KPI key reads that KPI's output series. The spec view marks such inputs with a KPI badge. A definition cannot consume its own output key.

After enabling

The definition detail page shows the spec cards, the live Matched assets list, the Revisions history (every save creates a new immutable revision, with author and timestamp), the health badge, a Preview panel, and Backfills.

To compute history from before the definition was enabled, use the Backfills panel: pick a range and click Queue backfill. Backfills are processed in chunks after live computation ticks, so live results always stay current. Job progress and any errors are listed in the same panel — see Health & Troubleshooting for details.

On this page