The addressing model was built to name places. The outages screen asks whether the same grid can carry a live social signal: people reporting that their power is out, from where they stand, in a form the electricity board could act on. It is the application layer on top of the model, and this page is its method — what is real, what is simulated, and what the grid contributes that a pin on a map would not.
The problem
Chennai’s power cuts are frequent, uneven and badly instrumented from the consumer’s side. The board’s complaint channels take one address at a time, so the person on the phone cannot tell whether they are the only dark house on the street or one of four hundred — and that distinction decides who should be dealing with it: a fuse-off call handled by the section office, or a feeder trip that the substation already knows about. There is no public feed of outages at street resolution, which is why this screen has to simulate one.
Citizens as sensors
Goodchild’s phrase for volunteered geographic information fits exactly: every resident is a sensor for the one variable the board cannot observe from the substation, whether the lights are on in a particular house. The design question is the reporting unit. A raw GPS fix is too precise to publish and too noisy to trust; a ward is too coarse to be useful. The 12.5 m cell is the compromise the model already makes: finer than a phone’s GNSS error, coarser than a front door, and — because the report is a three-word address rather than a coordinate — readable aloud over a phone call.
What the grid computes
Two properties of the addressing model do analytical work here, and neither would exist on a flat, scrambled scheme.
Containment → roll-ups
The 250 m locality containing a 12.5 m cell is its column and row divided by twenty; the 5 km region, divided by four hundred. Counting dark cells per locality and per region is therefore integer arithmetic on the cell key, recomputed on every tick, and it is what the map draws as a choropleth when zoomed out: how many cells are dark in each part of the city, read off the hierarchy rather than off a spatial join.
Adjacency → outages
Three rules turn dark cells into outages. Touching cells are one patch, with the eight-neighbour adjacency the Around tab already exposes. A patch never crosses a substation zone boundary — the zones are the Thiessen polygons of the real substations — so a fault that would straddle two feeders is two outages and two calls. And patches that do not touch but sit within 100 m of each other in one zone are one outage once they hold 3 dark cells between them: not every house in a dark street reports, and three that did are the street. An outage read that way is marked inferred, drawn with a halo over the hull of its patches, and sized by that hull rather than by the few cells that spoke.
Every outage has an age (the oldest still-active cell in it: how long it has gone unfixed), an estimated headcount from the population pack, and the localities and regions it spans. Each patch’s boundary is traced along cell edges and drawn as the outline you see, and the footprint maps to a severity tier that in turn names whom to call.
| Tier | Footprint | Likely fault | Whom to contact |
|---|---|---|---|
| Individual | 1 cell | Service line or cut-out fuse at one premises | Section fuse-off call via 1912 |
| Street | 2–40 cells | Distribution transformer or low-tension line | Section office (Assistant Engineer) |
| Neighbourhood | 41–199 cells, or ≥ 4 localities | 11 kV feeder trip | Sub-division via the nearest substation |
| Area | ≥ 200 cells, or ≥ 8 localities | 33 / 110 kV substation fault or scheduled maintenance | Division or circle; check maintenance notices |
The simulated day
With no public feed, the day is generated: a seeded, population-weighted, spatially coherent point process over the lattice. The seed is the Indian Standard Time calendar date, so every visitor sees the same day and tomorrow is a new one, and the generator is integer-only with a fixed iteration order, so it is bit-identical across devices. Twenty-four hours replay in 2:30. Replay is the only place the simulated day appears: Live shows the real reports alone, so nothing on the live map is invented.
| Kind | Per day | Footprint | Duration | Shape | Stands in for |
|---|---|---|---|---|---|
| individual | 160 | 1 cell | 20–90 min, ×2 with p = 0.1 | one cell | service-line fault; blown cut-out fuse; meter or main-switch trip |
| scattered | 6 | 3–6 cells | 30–150 min, ×1.8 with p = 0.15 | single houses scattered within 100 m | distribution-transformer fuse; LT phase failure; LT line fault |
| street | 45 | 4–40 cells | 30–180 min, ×1.8 with p = 0.15 | a two-cell-wide lane | distribution-transformer fuse; LT line fault; tree on the LT line |
| area | 8 | 120–800 cells | 60–360 min, ×1.6 with p = 0.25 | a flood-filled blob | 11 kV feeder trip; 33 kV feeder fault; substation breaker trip |
| Scheduled | 2 | 200–600 cells | 120–240 min, 09:00–13:00 start | a flood-filled blob | scheduled maintenance |
Where
A locality is drawn with probability proportional to its population, taken from WorldPop’s 2020 India raster (ind_ppp_2020_1km_UNadj.tif, about 903 m pixels) resampled onto the 250 m lattice (1,11,26,260 people across the extent, 37,067 populated cells). Faults land where people live and never in the sea, the marsh or the national park. The same pack is what turns a component into “about 1,400 people”.
A second pack says where the ground is water, because a kilometre pixel spills a few people over the edge of every lake and creek it touches — the count alone puts 0.14 people on a cell in the middle of Chembarambakkam. OpenStreetMap’s water bodies, reservoirs, river beds, wetlands and coastline are sampled sixteen times per 250 m cell, and a cell three quarters or more under water is water: 6,440 cells. Neither a simulated fault nor a live report lands on one — the screen offers no report there, and the API refuses one — while a shoreline cell with houses on its dry part stays reportable.
Shape
Streets are lanes: a two-cell-wide run along one axis with the occasional kink, because a low-tension line follows a road. Areas are blobs grown by random-priority flood fill — and confined to the Thiessen zone of one real substation. The 126 substations OpenStreetMap knows about become 126 nearest-facility polygons over the 250 m lattice, and an area fault never crosses out of the one it started in. That is a crude stand-in for feeder service areas, and it is labelled as such below, but it makes the simulated map follow real infrastructure rather than spilling across a river into a neighbourhood on a different feeder.
When
Start hours follow a diurnal weight table with two humps: the afternoon, when air-conditioning load peaks with the heat, and the evening, when the whole city is home. The heaviest hour is 20:00 and the quietest 02:00. Scheduled maintenance starts mid-morning.
Live reports
- A report is a three-word address, a client token and three timestamps. It stays on the map for 10 minutes after the reporter last touched it; “Still out” refreshes it, “Power is back” ends it. Only the reporter sees their countdown.
- One network is a claim, not an outage. A device holds at most 3 reports and a network 12, however many client tokens it mints, and one network’s reports are never joined into a street or a neighbourhood, however they sit, because one network cannot corroborate itself. Once 3 different networks have reported within reach of each other (touching, or within 100 m with three cells between them, in one substation zone) the reports confirm one another and share one collective cool-off: 15 minutes from that moment, plus 10 for the next network and 75% of the last addition for each network after it, never less than 3. A network’s second house adds nothing. A witness is an address counted per ISP and per family: a machine with both an IPv4 and an IPv6 address is one witness, a whole IPv6 home delegation (a /56) is one witness, and three phones behind one carrier IPv4 address are three when their IPv6 sides differ — which, on India’s IPv6-first carriers, they do. Three witnesses rather than two, for margin against a person with two connections. If the group falls under the threshold, its reports return to their own windows. “Still out” is offered — and accepted — only in the last 5 minutes of a report’s countdown: a real outage is kept alive by coming back, not by holding a button.
- Abuse resistance without an account. Every write is throttled, a dozen a minute per network and per browser; every new report or contact must carry a Cloudflare Turnstile token, the invisible proof that a real browser asked; a device holds three reports, a network twelve; and one machine is never more than one witness. What remains possible is expensive rather than scripted: a person with three separate internet connections, or a paid pool of residential addresses, each behind a real browser. That is the bar a citizen map can set without asking anyone to sign in.
- A report can never name the cell a substation or a board office stands on. Tapping that cell frames the place instead of picking it, no house is ever drawn there, the simulated day never darkens it, and the endpoint refuses the address.
- Live cells draw in pink with a pulsing ring, so a real report can never be mistaken for the simulation. A live cell inside a simulated blob keeps the blob’s age and gains the label “live” — the person in it has corroborated the simulation.
- A contact is “and I have told someone”: tapping the 1912 or WhatsApp button on a dark cell records that its resident reached the board, and draws a link from the house to the place the outage’s tier names — the section office for a fuse-off or a dark street, the substation for a feeder or an area fault. A link lies on the ground and follows the 12.5 m lattice lines, the streets of the model: out of the house to the grid line facing the place, along it to a column of the link’s own, down that column and in. Every person is one link and nothing is merged at any zoom; where links share a grid line the translucent stroke darkens, so a dark area shows exactly as many links as people who reached out, never as many as houses dark: not every house in a dark area rings. Real contacts are stored beside the reports, one per device, cell and channel; the replayed day makes its own, a seeded minority of each fault’s houses calling in a few minutes after the lights go out.
- A device may hold 3 active reports at once. Open maps poll every 10 seconds and pause while the tab is hidden.
- Storage is two small Cloudflare D1 tables that hold only what is on the map: a withdrawn report is deleted at once, an expired report or contact on the next request, and a contact whose cell has no live report left goes with it. Nothing is archived, so the database is the same size on the thousandth day as on the first. The rest of the site remains keyless and stateless.
The board’s places
Substations and board offices come from OpenStreetMap: 126 substations (well mapped, often with voltage) and 23 offices (mapped patchily under half a dozen naming conventions, deduplicated by name within 150 m). Every marker links to its source element. The offices are what volunteers have recorded, not a directory, and the screen says so. The universal channels shown with every outage are the board’s published consumer lines — Minnagam helpline 1912 and Complaints on WhatsApp 94987 94987 — checked against Citizen consumer and civic Action Group’s listing and a second independent listing.
What this does not claim
- Thiessen zones of substations are not feeder service areas. Real feeders interleave and cross; the zones are the best keyless approximation available and only shape the simulation.
- WorldPop is a 2020 model of population, not a census. A pixel is split into equal sub-samples and each lands in the cell containing its centre, so a pixel coarser than a cell is spread evenly over the cells it covers — the committed pack was built from the 903 m product, and finer input sharpens it without changing the method. Headcounts are estimates for scale, not for compensation.
- Severity by footprint is a heuristic. A 200-cell component could be two coincident faults; a one-cell report could be a substation trip nobody else has reported yet. Corroboration — several reporters in one component — is the signal that firms it up, and the map shows it.
- OpenStreetMap completeness varies across the city. Where offices are missing, the nearest substation still gives a resident somewhere real to point at.
- Live reports are unverified and trivially spoofable by anyone with a browser. Rate limits, cool-off and corroboration mitigate; they do not prove. A deployment for real use would add the board’s own confirmation channel.
GIS concepts this exercises
| Concept | Where it is load-bearing |
|---|---|
| Volunteered geographic information | Reports as citizen sensor readings; quantisation to a cell as the privacy and precision floor; cool-off and corroboration as VGI data-quality controls. |
| Spatio-temporal data | Events with start and end, a clock that replays a day, ages rather than timestamps so simulated and live cells share one time base. |
| Topology — connected components | Eight-neighbour adjacency on the lattice turns a set of cells into outages with size, age and boundary. The neighbour function is the addressing model's own. |
| Hierarchical aggregation | Roll-ups to 250 m and 5 km by integer division on the cell key — the containment property doing analysis. The modifiable areal unit problem appears deliberately: the same outage reads differently at each level. |
| Nearest-facility / Thiessen polygons | Every 250 m cell allocated to its nearest substation by planar UTM distance; the zones confine simulated feeder faults and answer “which substation serves me”. |
| Raster to lattice | A population raster resampled onto the 250 m tessellation by sub-sampling each pixel, with the edge misallocation acknowledged and the source resolution recorded in the manifest. |
| Stochastic simulation | A seeded, population-weighted spatial point process with spatially coherent footprints (flood fill, lanes) and a diurnal intensity function; reproducible by construction. |
| Data sources and licensing | WorldPop (CC BY 4.0), OpenStreetMap via Overpass (ODbL), both fetched keylessly at build time and committed with a provenance manifest. |
The build script that assembles the packs is scripts/build-outages-data.ts; the model constants are in src/lib/outages/model.ts; the analysis is unit-tested for determinism, connectivity and roll-up correctness in src/lib/outages/outages.test.ts.