KPI Expression Language
The KPI engine (packages/kpi-engine/) extends the math
expression grammar with channel-aware intrinsics. KPI expressions
look identical to math expressions — Avg(Channel("RPM")) + Round(...) — but the evaluator has access to a telemetry sample
buffer.
A KPI is always evaluated against:
- A
samplesarray — each sample is{ t: number, channelA: number, channelB: number, … } - A
lapcontext the host sets up before invoking the evaluator
The engine is consumed by:
- The Data Analysis Profiles admin
(
/admin/data-analysis-profiles) for KPIs authored in JSON - The plugin runtime's
kpiProcessorinterface for KPIs authored in TypeScript
Channel intrinsics
| Function | Returns | Description |
|---|---|---|
Channel(name) | channel | Read a named channel from the active sample window. Returns null if the channel is not present. |
Window(seconds, expr) | result of expr | Run expr with the active window restricted to the trailing seconds seconds. The evaluator implements this specially because the inner expression must run in a scoped context. |
The result of Channel(...) is a channel value — an opaque
view over the sample buffer that the reduction functions know how
to traverse.
Scalar reductions over a channel
These all accept a Channel(...) value and reduce it to a
scalar:
| Function | Description |
|---|---|
First(ch) | First finite sample |
Last(ch) | Last finite sample |
Min(ch) | Minimum finite sample (Min(a, b, ...) also works on plain numbers) |
Max(ch) | Maximum finite sample |
Mean(ch) / Average(ch) / Avg(ch) | Arithmetic mean of finite samples |
Sum(ch) | Sum of finite samples |
StdDev(ch) | Sample standard deviation |
Delta(ch) | last - first |
Window-shape reductions
| Function | Description |
|---|---|
RollingAvg(channel, seconds) | Trailing seconds-second rolling average — useful for "RPM rolling 5s" style KPIs |
GateAbove(channel, threshold) | Fraction of samples ≥ threshold |
GateBelow(channel, threshold) | Fraction of samples ≤ threshold |
EdgeCount(channel, threshold) | Number of upward zero-crossings of (channel − threshold) — counts pumps / events |
Filtering
| Function | Description |
|---|---|
Where(channel, predicate) | Returns a new channel restricted to samples for which predicate evaluates truthy in the sample's local scope |
Scalar helpers
The KPI engine inherits a small subset of scalar helpers from the math library:
Abs(x)/Sqrt(x)/Round(x)/Round(x, dp)If(cond, then, else)
The full math function set is not present in the KPI engine
on purpose — KPI expressions are mostly channel reductions
glued together with arithmetic and If. If you need text
mangling or LookupClosest, do it in a math expression that
consumes a KPI value.
Example
// Average RPM over the last 5 seconds of the lap
RPMRolling5s = RollingAvg(Channel("RPM"), 5)
// Fraction of the lap spent above 95% throttle
ThrottleGate95 = GateAbove(Channel("Throttle"), 0.95)
// Throttle pump count (zero-crossings of throttle − 50%)
ThrottlePumps = EdgeCount(Channel("Throttle"), 0.5)
// Last 5s peak RPM
PeakRPMLast5s = Window(5, Max(Channel("RPM")))
Where to read the source
| What | File |
|---|---|
| Function table | packages/kpi-engine/src/functions.ts |
| Parser | packages/kpi-engine/src/parser.ts |
| Evaluator | packages/kpi-engine/src/evaluator.ts |
| Profile runner | apps/api/src/routes/dataAnalysisProfiles.ts |