Smart-Meter Tampering Detection
Tested against SynapCores CE v1.7.0.1-ce (the currently-shipped release on Docker Hub:
synapcores/community:v1.7.0.1-ce).
Objective
Surface meters whose hourly consumption suddenly drops to near-zero while the household is presumably still drawing power — the canonical signature of meter bypassing, magnet attacks, or CT-shorting.
Why this matters: the World Bank puts non-technical (theft + tampering) losses at $96B/year globally; >40% in some emerging-market grids. Field crews can only follow a lead; this is the lead.
Step 1 — Schema + hourly readings
100 hourly kWh readings on a single meter. 3 planted tampering events at hours 35, 62, 84 (consumption drops to ~0 mid-day).
DROP TABLE IF EXISTS smart_meter;
CREATE TABLE smart_meter (
id INTEGER PRIMARY KEY,
hour INTEGER,
kwh DOUBLE
);
INSERT INTO smart_meter VALUES
(1,0,1.19),
(2,1,0.8),
(3,2,1.14),
(4,3,1.75),
(5,4,1.4),
(6,5,1.36),
(7,6,0.65),
(8,7,0.93),
(9,8,2.7),
(10,9,2.79),
(11,10,1.72),
(12,11,2.4),
(13,12,3.26),
(14,13,2.56),
(15,14,2.7),
(16,15,2.97),
(17,16,1.74),
(18,17,2.37),
(19,18,2.53),
(20,19,2.68),
(21,20,2.92),
(22,21,1.42),
(23,22,0.87),
(24,23,1.05),
(25,24,1.15),
(26,25,1.23),
(27,26,1.24),
(28,27,1.53),
(29,28,0.6),
(30,29,1.31),
(31,30,1.69),
(32,31,1.41),
(33,32,2.97),
(34,33,2.34),
(35,34,2.37),
(36,35,0.04),
(37,36,1.72),
(38,37,2.26),
(39,38,2.43),
(40,39,2.49),
(41,40,1.97),
(42,41,2.7),
(43,42,2.64),
(44,43,2.47),
(45,44,1.96),
(46,45,1.69),
(47,46,1.67),
(48,47,1.73),
(49,48,1.33),
(50,49,1.68),
(51,50,1.01),
(52,51,1.51),
(53,52,0.96),
(54,53,1.18),
(55,54,1.49),
(56,55,1.06),
(57,56,1.8),
(58,57,1.77),
(59,58,2.96),
(60,59,2.8),
(61,60,2.49),
(62,61,2.72),
(63,62,0.4),
(64,63,2.48),
(65,64,3.15),
(66,65,3.09),
(67,66,2.84),
(68,67,2.1),
(69,68,2.77),
(70,69,1.24),
(71,70,1.04),
(72,71,0.95),
(73,72,1.05),
(74,73,1.25),
(75,74,1.53),
(76,75,0.45),
(77,76,1.62),
(78,77,0.83),
(79,78,0.99),
(80,79,1.04),
(81,80,1.81),
(82,81,2.47),
(83,82,2.4),
(84,83,2.32),
(85,84,0.0),
(86,85,3.08),
(87,86,2.82),
(88,87,2.66),
(89,88,2.63),
(90,89,1.68),
(91,90,2.51),
(92,91,2.58),
(93,92,2.61),
(94,93,1.12),
(95,94,0.95),
(96,95,1.14),
(97,96,1.17),
(98,97,1.35),
(99,98,1.03),
(100,99,0.76)
;
Step 2 — Baseline
SELECT AVG(kwh) AS mu, STDDEV(kwh) AS sigma, MIN(kwh), MAX(kwh) FROM smart_meter;
-- → μ ≈ 1.80, σ ≈ 0.79, min = 0.00, max = 3.26
Step 3 — Sudden-drop detector
-- Any hour where consumption is less than 30% of the meter's own average
SELECT id, hour, kwh,
(SELECT AVG(kwh) FROM smart_meter) AS baseline_mu,
kwh / (SELECT AVG(kwh) FROM smart_meter) AS ratio
FROM smart_meter
WHERE kwh < 0.3 * (SELECT AVG(kwh) FROM smart_meter)
ORDER BY hour;
-- → 3 rows (the planted tampering events).
Step 4 — Make it operational
-- Stricter alert: any hour < 25% baseline AND below the night-floor
SELECT hour, kwh
FROM smart_meter
WHERE kwh < 0.25 * (SELECT AVG(kwh) FROM smart_meter)
AND kwh < (SELECT MIN(kwh) + 0.2 FROM smart_meter WHERE hour >= 2 AND hour <= 5)
ORDER BY hour;
Productionizing
For a real utility: partition by meter_id, compute baseline on a
30-day rolling window per-meter, escalate the 95th-percentile-worst
meters to a field-crew route-optimizer. Pair with Recipe 6
(per-equipment baseline) for two-signal detection.