For the SCON course (Sistemas de Comunicación) in the UPM master’s programme, I built a complete analysis of my own home WiFi network: a beacon scanner that captured real over-the-air traffic, a per-room signal study of all 26 rooms of the flat, band occupancy statistics for 2.4/5 GHz, and two simulations — optimal router placement and WiFi repeater placement — built on a path-loss model fitted from my own measurements.
📡 The pipeline
wifi_scanner.py — a scapy-based monitor-mode scanner: it hops channels (1 → 14 →
36 → 60) and records every beacon — BSSID, SSID, zone, dBm, channel, crypto — into a CSV.
DomesticNetworkAnalysis.ipynb — the full analysis: a choropleth of the measured
5 GHz signal per room, 2.4/5 GHz band occupancy and channel statistics, and the placement
simulations. analysis_model.py — the signal model extracted from the notebook into a
reusable, unit-tested module (and later ported 1:1 to JavaScript for the web edition).
📈 What the scan showed
The measured 5 GHz heatmap tells a very familiar story: the router lives in Habitación 1 (strongest mean signal, around −39 dBm), and the signal degrades steadily through the hallway into the living room, terrace, bathrooms and — the weakest corner of the flat — the kitchen (−86 dBm). The band-occupancy analysis completes the picture with channel usage across the whole building:
Measured mode — the real 5 GHz scan of the house’s own network, per room.
📡️ The model and the simulations
The core of the project is a simple, interpretable path-loss model fitted from the real measurements. The predicted received power at distance \(d\) metres from the router, through \(W\) walls:
\[ P(d) = P_{\max} - 3\,d - 7\,W \]i.e. 3 dB/m free-space-ish attenuation plus 7 dB per interior wall, with \(P_{\max} = -39.2\) dBm calibrated from the measurements — the notebook’s exact model, with a hand-built 10×10 wall matrix between the house zones and a zone-weighted score (living areas matter more). The web edition refines that matrix: every heatmap cell walks the straight line from the router and counts the actual walls crossed by ray-casting — including the exterior walls when the line leaves the house through a concave corner or notch — so neighbouring rooms never lose to more distant ones and corner rooms don’t over-score. That refinement is why the web edition’s optimal spot can differ from the notebook’s result:
Simulate mode — drag the router anywhere; every cell’s predicted dBm, the score ranking and the heatmap recompute live (subdivision 32, 3 dB/m, 7 dB/wall).
Running an exhaustive search over every room as the candidate router location:
- the notebook’s zone-matrix model picks Pasillo-2 — the central hallway — as the spot that maximises the zone-weighted signal across the whole flat;
- the web edition’s ray-cast model refines the walls cell by cell — counting exterior walls at concave corners too — and its search lands on a lavabo sub-zone (zone 8, mean −78 dBm) instead — a direct illustration of how the model’s granularity changes the answer.
“Find optimal room” — the web edition’s ray-cast search highlights its best placement (zone 8, mean −78 dBm).
The same model supports a repeater simulation with a second source.
🎮 Try it in the browser
The whole lab is playable at alejp1998.github.io/domestic_net_analysis:
- 4 flat plans — the real scanned home (rebuilt as a perfectly tiled, gap-free plan) plus three designed flats: Estudio, Piso 2 hab, Loft;
- discrete subdivision model — a slider chooses the cell size; every cell predicts its own signal, so heatmaps are smooth and walls are grid-aligned;
- measured — the real scan heatmap per room; simulate — drag the router (and a repeater) with live recomputation and dB/metre + dB/wall sliders; find optimal room — the exhaustive search;
- cold→hot scale — −37 dBm (best) deep red to blue (worst), with dBm ticks on the legend.
The JavaScript model port is cross-checked against the Python — the unit-tested analysis_model.py
suite (6/6 tests) keeps both honest.