---
title: 'Formula reference'
description: Every metric, score and threshold used across the AI Analytics reports, on a single page.
section: AI Analytics
weight: 3
related:
  - ai-analytics/methodology
---

Every formula used across the reports, gathered in one place. Each formula is annotated with the report it belongs to and the context in which it applies. Math is rendered with KaTeX.

## Composite scoring — multiplier logic

Combines independent signals as if they were independent probabilities. Used by **Metering Bypass** (node and fleet).

$$
S_\text{composite} = 100 \cdot \left(1 - \prod_{i=1}^{N}(1 - p_i)\right)
$$

where $p_i \in [0, 1]$ is the severity-derived probability of the $i$-th pattern that fired:

$$
p_i = \begin{cases}
0.00 & \text{severity}=\text{info} \\
0.10 & \text{severity}=\text{low} \\
0.30 & \text{severity}=\text{medium} \\
0.50 & \text{severity}=\text{high} \\
0.65 & \text{severity}=\text{high\_plus}
\end{cases}
$$

**Example.** Two high+ patterns give $S = 100 \cdot (1 - 0.35^2) = 87.75$. The score deliberately **cannot** reach 100 from pattern detection alone — saturating to 100 requires confirmed device events (confidence ceiling = medium without them).

## Weighted-sum scoring

**Top Problem Nodes** (five measurements):

$$
S_\text{composite} = \sum_{k \in K} w_k \cdot s_k, \quad K = \{\text{battery}, \text{telem}, \text{quality}, \text{risk}, \text{events}\}
$$

Equal weighting, $w_k = 20\%$ each.

**Top Gas Leaks** (four sub-scores, unequal weights):

$$
S_\text{leak} = 0.4 \cdot s_\text{quiet} + 0.3 \cdot s_\text{baseline} + 0.2 \cdot s_\text{drip} + 0.1 \cdot s_\text{drift}
$$

## Pattern detectors — Metering Bypass

**Pattern 1 — zero flow at a default pressure** (severity = high+, p = 0.65):

$$
\text{trigger} = (\bar Q \leq 0.5\,\text{m³/h over a window} \geq 6\,\text{h}) \land (\sigma_P < 0.1\,\text{kPa}) \land (P \in \mathcal{D})
$$

$\mathcal{D} = \{100.0, 101.325, 103.0, 105.0\}_{\pm 0.5} \cup \{0.0\}_{\pm 0.3}$ (kPa). These are the canonical default values a flow computer falls back to when the pressure transducer is disconnected or substituted.

**Pattern 2 — zero flow with a stuck pressure** (severity = medium, p = 0.30). Violation of the Gay-Lussac law for a sealed gas volume.

$$
\text{trigger} = (\bar Q \leq 0.5\,\text{m³/h}) \land (\Delta T \geq 1\text{°C}) \land (\sigma_P < 0.1\,\text{kPa})
$$

Expected ΔP per Gay-Lussac (isochoric process):

$$
\frac{P_1}{T_1} = \frac{P_2}{T_2} \;\Longrightarrow\; \Delta P_\text{expected} = P_\text{abs}^{(1)} \cdot \frac{\Delta T_K}{T_1^{(K)}}
$$

where:
- $P_\text{abs}^{(1)} = P_\text{gauge} + 101.325$ kPa if $P_\text{gauge} < 50$ kPa (gauge sensor); otherwise $P_\text{abs} = P_\text{kPa}$
- $T^{(K)} = T_{°C} + 273.15$
- $\Delta T_K = |T_2^{(K)} - T_1^{(K)}| = |T_2^{°C} - T_1^{°C}|$ (Kelvin diff ≡ Celsius diff)

"P is frozen" fires when:

$$
\frac{\Delta P_\text{expected}}{\sigma_P} \geq 3
$$

**False-positive guard — network node.** Gay-Lussac only applies to a **closed volume**. In a node connected to the gas main, gauge pressure is held by the network regulator, not by gas physics. Before the detector fires:

$$
\text{is\_network} = (\text{median}(P_\text{gauge}) < 10\,\text{kPa}) \land (\sigma_P^\text{(window)} < 2\,\text{kPa}) \land \neg \text{is\_p\_sensor\_broken}
$$

If the node is a network node, all stuck-pressure events are excluded from the score and an informational card is added.

**Pattern 3 — recovery after a zero-flow run** (severity = high, p = 0.50). Synchronous Q + P jump immediately after a long zero-flow run:

$$
\text{trigger} = \exists\, t \in [\text{end}_\text{run}, +2\text{h}] : Q(t) \geq 10 \land |\Delta P| \geq 20\,\text{kPa}
$$

**Pattern 4 — gap with clean sessions** (severity = medium, p = 0.30). Hours of missing archive while the device was demonstrably reachable:

$$
\text{trigger} = (\text{missing\_hours} \geq 24) \land (\text{successful\_sessions\_in\_gap} \geq 1)
$$

### Pre-filters (false-positive guards)

| Signal | Threshold | Effect |
|---|---|---|
| P sensor broken | P frozen ≥ 168 h at any time in the window | all P-based detectors disabled |
| Network-connected | median(P_gauge) < 10 kPa AND σ_P < 2 kPa AND not broken | stuck-pressure pattern excluded from the score |
| Telemetry spike | $P > 500$ kPa OR ($Q > 20 \times \text{median}(Q)$ while Q > 1000 m³/h) | row replaced with NULL before tampering logic |

Severity cap, applied after all detectors and before the suspicion score:

| Composition of events | Max allowed level |
|---|---|
| has high+ | very high |
| has high | high |
| two or more medium | high |
| exactly one medium | medium |
| only low or nothing | medium |

## Coverage and data quality — Consumption Analytics

$$
\text{cov} = \frac{H_\text{OK} + H_\text{NULL}}{H_\text{expected}}, \quad
\text{unobs}_\% = (1 - \text{cov}) \cdot 100\%
$$

| Condition | Severity |
|---|---|
| `tail_h > 168` h | critical |
| `unobs_pct > 30%` | high |
| `unobs_pct > 10%` | medium |
| otherwise | low |

**Estimated unobserved volume (two methods).** Mean-flow extrapolation:

$$
V^{(\text{mean})}_\text{unobs} = \bar Q_\text{OK} \cdot H_\text{unobs}
$$

Diurnal-profile reconstruction:

$$
V^{(\text{profile})}_\text{unobs} = \sum_{h \in \text{unobs}} \bar Q_h
$$

**Operational idle threshold:**

$$
\frac{|\{h : Q(h) < 0.05\}|}{H_\text{OK}} > 0.95 \Rightarrow \text{idle mode (zero consumption is not penalised)}
$$

**Q/V reconciliation:**

$$
\Delta V_\text{integral} = \sum_h Q(h) \cdot 1\text{h}, \quad \Delta V_\text{counter} = V(t_\text{end}) - V(t_\text{start})
$$

$$
\text{raise Q/V mismatch if } \frac{|\Delta V_\text{counter} - \Delta V_\text{integral}|}{\Delta V_\text{counter}} > 5\%
$$

The 5% tolerance follows OIML R 137 class 1.0 plus an integration round-off allowance.

## Sub-scores — Top Problem Nodes

**Fast pre-rank (metadata only):**

$$
S_\text{fast} = d_\text{pts}(\text{days\_since\_last\_session}) + s_\text{pts}(\text{status})
$$

$$
d_\text{pts}(d) = \begin{cases}
100 & d \geq 60 \\
60 + (d-30) \cdot 1.33 & 30 \leq d < 60 \\
20 + (d-7) \cdot 1.74 & 7 \leq d < 30 \\
d \cdot 2.85 & d < 7
\end{cases}
$$

$s_\text{pts} = 30$ if the device status is not "operational", otherwise 0.

**Battery sub-score (mV):**

$$
v_\text{pts} = \begin{cases}
100 & V_\text{last} < 3000 \\
80 & V_\text{last} < 3200 \\
50 & V_\text{last} < 3400 \\
25 & V_\text{last} < 3600 \\
0 & \text{otherwise}
\end{cases}
$$

$$
S_\text{battery} = \min(100, v_\text{pts} + d_\text{pts}(\text{drop\_pct}))
$$

where $d_\text{pts} = 30$ if drop > 10%, 15 if drop > 5%, otherwise 0.

**Risk sub-score:**

$$
S_\text{risk} = \frac{1}{1.85} \sum_i \min(\text{cap}_i, \alpha_i \cdot n_i)
$$

| Signal $n_i$ | $\alpha_i$ | cap |
|---|---|---|
| `quiet_n_pct` | 0.8 | 40 |
| `n_plateau` | 4 | 20 |
| `n_neg` (binary) | 25 | 25 |
| `n_live_p` | 8 | 40 |
| `n_pt_resets` | 6 | 30 |
| `n_drop_rec` | 5 | 30 |

**Events sub-score:**

| Condition | $S_\text{events}$ |
|---|---|
| physical AND substitution | 100 |
| physical only | 80 |
| substitution only | 60 |
| metrology / system error only | 30 |
| no events | 0 |

## Battery threshold — Battery Forecast and Fleet Battery Forecast

**Per-source score (% or mV):**

$$
S_\text{metro} = \text{clip}_{[0,100]}\left(\frac{V - V_\text{crit}}{V_\text{fresh} - V_\text{crit}} \cdot 100\right)
$$

| Scale | $V_\text{crit}$ | $V_\text{fresh}$ |
|---|---|---|
| % (metering Li-SOCl₂) | 20 | 90 |
| mV (telemetry Li-pol) | 3300 | 3600 |

**Composite (weakest link):**

$$
S_\text{battery} = \min(S_\text{metro}, S_\text{telem})
$$

**Forecast $T_\text{crit}$ (three scenarios):**

$$
T_\text{crit}^{(\text{opt})} = t_\text{now} + \frac{V_\text{now} - V_\text{crit}}{|\text{drop\_rate}|}
$$

$$
T_\text{crit}^{(\text{real})} = T_\text{crit}^{(\text{opt})} \cdot (1 - \alpha_\text{accel})
$$

$$
T_\text{crit}^{(\text{pess})} = T_\text{crit}^{(\text{real})} \cdot 0.5
$$

When a replacement event is found in the report window, all linear regressions are restricted to the period after the replacement. Otherwise the voltage jump at replacement (for example, 3225 → 4197 mV) gives a spurious positive slope — physically impossible for a non-rechargeable Li-pol.

$$
\text{slope}_\text{real} = \text{linreg}\big(\{(t_i, v_i) : t_i \geq t_\text{replacement}\}\big)
$$

**Telemetry-block replacement.** For devices whose battery is a non-cycling telemetry pack, the "day-to-critical from discharge" forecast does not apply. The replacement decision is taken as the **worst of three** independent criteria.

Calendar age:

$$
\text{age\_status} = \begin{cases}
\text{ok}   & y_\text{age} < 0.75 \cdot y_\text{expected} \\
\text{plan} & 0.75 \cdot y_\text{expected} \leq y_\text{age} < y_\text{expected} \\
\text{due}  & y_\text{age} \geq y_\text{expected}
\end{cases}
$$

where $y_\text{expected} = 3$ years (Li-pol passport life).

Sessions used against the pack budget:

$$
\text{sessions\_status} = \begin{cases}
\text{ok}   & \text{ratio} < 0.75 \\
\text{plan} & 0.75 \leq \text{ratio} < 1.0 \\
\text{due}  & \text{ratio} \geq 1.0
\end{cases}, \quad \text{ratio} = \frac{\text{sessions\_used}}{2000}
$$

The 2000-session budget matches a 2000 mAh pack (≈ 1 mAh per session under TX load).

Degradation under load (last 30 d vs 180–150 d ago):

$$
\text{deg\_pct} = 100 \cdot \frac{\min(V_\text{old}) - \min(V_\text{recent})}{\min(V_\text{old})}
$$

$$
\text{deg\_status} = \begin{cases}
\text{ok}       & \text{deg\_pct} < 3\% \\
\text{watch}    & 3\% \leq \text{deg\_pct} < 8\% \\
\text{degraded} & \text{deg\_pct} \geq 8\%
\end{cases}
$$

Final verdict (worst of three):

$$
\text{overall} = \begin{cases}
\text{due}  & \text{any of } \{\text{age, sessions, deg}\} \in \{\text{due, degraded}\} \\
\text{plan} & \text{else if any} \in \{\text{plan, watch}\} \\
\text{ok}   & \text{otherwise}
\end{cases}
$$

**Battery capacity for signal / consumption models:**

$$
\Delta V_\text{period} = V_\text{first} - V_\text{last}, \quad
\Delta C_\text{used} = \Delta V \cdot \frac{C_\text{mAh}}{1200\text{ mV}}
$$

where 1200 mV is the Li-pol voltage swing from nominal to fully discharged (3.0 → 4.2 V). Anomalous-drop detection fires when the drop rate over the last 30 days exceeds twice the 90-day baseline.

## Leak detection — Top Gas Leaks

**Adaptive per-station threshold:**

$$
\theta_\text{leak} = \max(0.05, P_{95}(Q) \cdot 0.05)
$$

5% of each station's own p95 — adaptive, so commercial sites are not flagged at the same threshold as residential ones.

**Sub-scores:**

$$
s_\text{quiet} = 100 \cdot \frac{\min_{h \in [2,5]} Q(h)}{\theta_\text{leak}} \text{ (capped at 100)}
$$

$$
s_\text{baseline} = 100 \cdot \frac{P_5(Q)}{\theta_\text{leak}} \text{ (capped at 100)}
$$

$$
s_\text{drip} = 100 \cdot \frac{|\{h : 0.5\theta \leq Q(h) \leq 2\theta\}|}{|H|}
$$

$$
s_\text{drift} = 100 \cdot \tanh\left(\frac{\text{slope}(P_5)}{\theta_\text{leak} / \text{month}}\right)
$$

## CO₂e calculations — Decarbonization and Emissions and Energy

**Methane → CO₂e:**

$$
m_\text{CH4} = V_\text{leak} \cdot \phi_\text{CH4} \cdot \rho_\text{CH4}, \quad \rho_\text{CH4} = 0.68 \text{ kg/m³}
$$

$$
m_\text{CO2e}^{(\text{GWP100})} = m_\text{CH4} \cdot 28, \quad m_\text{CO2e}^{(\text{GWP20})} = m_\text{CH4} \cdot 84
$$

GWP factors per IPCC AR6 (the 20-year factor reflects the short-term warming impact relevant for near-term mitigation targets).

**Direct CO₂ (from burnt gas):**

$$
m_\text{CO2,direct} = V_\text{consumed} \cdot \text{EF}_\text{CO2}, \quad \text{EF}_\text{CO2} = 1.96 \text{ kg/m³}
$$

**Energy:**

$$
E_\text{GJ} = V \cdot \text{HHV}, \quad \text{HHV} = 37.0 \text{ MJ/m³}
$$

$$
E_\text{kWh} = E_\text{GJ} \cdot \frac{1000}{3.6}
$$

## Investment scenarios — Decarbonization and Automation ROI

**CAPEX / OPEX (per node):**

$$
\text{CAPEX}_\text{total} = N \cdot \text{capex\_per\_node}, \quad \text{OPEX}/\text{year} = N \cdot \text{opex\_per\_node\_per\_year}
$$

**Value / Payback:**

$$
\text{Value}/\text{year} = \sum_\text{hot spots}(\text{gas} + \text{carbon}_\text{GWP100})
$$

$$
\text{Payback}_\text{months} = \begin{cases}
\dfrac{\text{CAPEX}}{\text{Value} - \text{OPEX}} \cdot 12 & \text{Value} > \text{OPEX} \\
\text{none} & \text{otherwise}
\end{cases}
$$

**ROI / TCO:**

$$
\text{ROI} = \frac{\text{Value/year} - \text{OPEX/year}}{\text{CAPEX}_\text{total}} \cdot 100\%
$$

$$
\text{TCO}_5 = \text{CAPEX}_\text{total} + 5 \cdot \text{OPEX/year}
$$

## Demand forecasting — Gas Demand Forecast

**Linear model (OLS):**

$$
Q(t) = \beta_0 + \beta_1 t + \sum_{k=1}^{2}[\alpha_k \sin(2\pi k t/365) + \gamma_k \cos(2\pi k t/365)] + \sum_{j=1}^{6} w_j \mathbb{1}_{\text{dow}=j} + \delta \cdot \text{HDD}(t) + \varepsilon
$$

Trend + two-harmonic annual seasonality + day-of-week dummies + a heating-degree-day term.

**HDD:**

$$
\text{HDD}(t) = \max(0, 18°C - \bar T(t))
$$

**95% CI:**

$$
\hat Q(t) \pm 1.96 \cdot \hat\sigma_\varepsilon \cdot \sqrt{1 + h(t)}
$$

**Backtest:**

$$
\text{MAE} = \frac{1}{N} \sum_t |Q(t) - \hat Q(t)|, \quad \text{MAPE} = \frac{1}{N} \sum_t \frac{|Q(t) - \hat Q(t)|}{Q(t)} \cdot 100\%
$$

$$
\text{Coverage}_{95\%} = \frac{1}{N} \sum_t \mathbb{1}_{Q(t) \in [\hat Q_t \pm 1.96\hat\sigma]}
$$

Healthy fit: coverage ≈ 95%, MAPE < 15%.

## Pressure anomalies — Pressure Anomalies

**Outage:**

$$
\text{outage}(t) = \mathbb{1}_{P(t) = \text{null} \lor P(t) = 0}
$$

**Sharp drop:**

$$
\text{drop}(t) = \mathbb{1}_{P(t-1) - P(t) > 5 \text{ kPa/h}}
$$

**Baseline drift:**

$$
\text{drift}_{30d} = \frac{P_5^{(\text{last 30d})} - P_5^{(\text{first 30d})}}{P_5^{(\text{first 30d})}} \cdot 100\%
$$

Raise a baseline-drift incident if |drift| > 20% over the analyzed period.

**Instability (rolling):**

$$
\text{instability}(t) = \frac{\sigma_P^{(24h)}}{\bar P^{(24h)}}
$$

Raise an instability incident if the ratio exceeds 0.3 over a window ≥ 6 hours.

## Long sessions — IQR detection

**Per-station threshold:**

$$
\theta_\text{long} = Q_3 + 1.5 \cdot \text{IQR}, \quad \text{IQR} = Q_3 - Q_1
$$

A robust outlier detector — better than z-score for the skewed distribution of polling-session durations.

**Severity score:**

$$
S = 40 \cdot \text{long\_frac} + 30 \cdot \frac{\bar t_\text{anomaly}}{\theta_\text{long}} + 30 \cdot \text{n\_incidents\_critical}
$$

## Home energy — Household Report

**Breakdown template (single-family house):**

| Segment | Share |
|---|---|
| Space heating | 60% |
| Domestic hot water | 20% |
| Cooking | 10% |
| Other | 10% |

**Savings from insulation:**

$$
\Delta V_\text{insulation} = V_\text{heating} \cdot 0.15 \text{ (typical retrofit)}
$$

**Compound interest (savings deposited at rate r):**

$$
\text{Reinvest}_T = \text{Savings} \cdot \frac{(1 + r)^T - 1}{r}
$$

## Severity classification — unified scale

| Range | Severity | Color | Context |
|---|---|---|---|
| 0–9 | OK | green | composite, top problem nodes |
| 10–29 | Low | blue | composite |
| 30–49 | Medium | yellow | composite |
| 50–69 | High | orange | composite, top problem nodes warning |
| 70–100 | Critical | red | composite, top problem nodes critical |

Top Problem Nodes uses thresholds 30 / 60 — more of the green band is treated as the "normal" state.

## Confidence framework — Decarbonization and Metering Bypass

| Confidence | Condition |
|---|---|
| **High** | deep score ≥ 80 with ≥ 6 months of data |
| **Medium** | deep score ≥ 50 or limited data history |
| **Low** | low score / fallback estimation |

## Field-investigation priority — Metering Bypass

| Condition | Priority |
|---|---|
| Recent physical event (≤ 7 d) | **P0** (override) |
| Older physical event (> 7 d) | **P1** |
| score ≥ 70 with confidence medium or high | **P0** |
| score ≥ 70 with confidence low | **P1** |
| score ≥ 50 | **P1** |
| score ≥ 30 | **P2** |
| score < 30 | **P3** |

## Constants reference

| Symbol | Value | Source | Used in |
|---|---|---|---|
| $\text{EF}_\text{CO2}$ | 1.96 kg/m³ | IPCC AR6 | Decarbonization, Emissions and Energy |
| $\text{HHV}$ | 37.0 MJ/m³ | natural-gas typical (IEA) | Emissions and Energy |
| $\rho_\text{CH4}$ | 0.68 kg/m³ | standard conditions | Decarbonization |
| $\text{GWP}_{100}$ | 28 | IPCC AR6, 100-year | Decarbonization, Emissions and Energy |
| $\text{GWP}_{20}$ | 84 | IPCC AR6, 20-year | Decarbonization, Emissions and Energy |
| Near-zero flow | 0.5 m³/h | empirical | Metering Bypass |
| Min zero-flow run | 6 h | empirical | Metering Bypass |
| Stuck-pressure σ | 0.1 kPa | empirical | Metering Bypass |
| Min ΔT for Gay-Lussac | 1.0 °C | empirical | Metering Bypass |
| Recovery Q min | 10 m³/h | empirical | Metering Bypass |
| Recovery ΔP min | 20 kPa | empirical | Metering Bypass |
| Physical P max | 500 kPa | physical limit | Metering Bypass pre-filter |
| Q spike multiplier | 20× | empirical | Metering Bypass pre-filter |
| P-sensor-broken stuck time | 168 h | empirical | Metering Bypass sensor health |
| HDD base temperature | 18 °C | IPCC | Gas Demand Forecast |
| Default leak fraction | 0.5% | IEA fleet average | Decarbonization fallback |

Methodological references: IPCC AR6 (WG I, Ch. 7) for GWP and emission factors; OIML R 137-1 for flow-meter accuracy classes; ISO 5167 and AGA Report No. 3 for differential-pressure flow calculation; EN 1776 for metering-station design conventions; GHG Protocol Scope 1 for direct-combustion CO₂ accounting.
