Floor map layers
A layer is one question asked of a floor. floorplan_map accepts 13
layers; you name the ones you want in layers, and each adds its own
findings, and usually something drawn, on top of the
floor map. With no layers argument you get
["aps"].
Every layer is judged by what it can state, not what it draws. Some layers report measured facts, some run a model, and some need data that only exists once something else is set up. The table below says which is which.
The layer catalogue
Section titled “The layer catalogue”| Layer | What it shows | Kind | Needs | Extra R1 call |
|---|---|---|---|---|
aps | Every AP and switch on the plan, and the plan’s own defects | Measured | Nothing — always on | No |
clients | Per-AP client counts, a per-AP table and a per-client roster | Measured | The R1 client query; webhook events refine it | Yes |
bands | Which radio each AP’s clients chose, per AP and floor-wide | Measured | The client query (turned on automatically) | Yes |
roams | The AP-to-AP roam matrix as arrows, with the distance between each pair | Measured | Stored webhook roam events | No |
roamTrail | One client’s hops across the floor, newest brightest | Measured | Stored webhook roam events, plus roamClient | No |
entry | Where clients first appear on the floor, ranked | Measured | Stored webhook roam events | No |
cochannel | Channel-overlap pairs confirmed or dismissed by distance | Measured | A metric scale to judge distance | No |
coverage | A predicted signal heat field and weak areas in m² | Predicted | A metric scale; the plan image for walls | No |
blastRadius | What each single AP failing would cost | Predicted | Same as coverage | No |
demand | Live per-AP load against the area each AP is predicted to serve | Predicted + measured | Same as coverage, plus the client query | Yes |
airtime | Each radio’s measured channel occupancy | Measured | An LBS source | No |
footfall | Distinct devices each AP heard, including passers-by | Measured | An LBS source | No |
heardBy | One device’s measured position and every AP that heard it | Measured | An LBS source, plus lbsClient | No |
The client query is the only extra R1 call any layer makes. Roam and entry layers read the matrix the webhooks feature has already stored.
What each layer can and cannot state
Section titled “What each layer can and cannot state”aps — the plan’s own defects
Section titled “aps — the plan’s own defects”aps is always in the stack, even if you only ask for clients, because
its findings invalidate everything drawn over them.
- States: APs assigned to the floor but never placed; APs left at (0,0), R1’s default for an AP nobody dragged onto the plan; pairs closer than 6 m; APs more than 40 m from any neighbour; APs on other floorplans; a missing or low-confidence scale.
- Cannot state: any distance, when the plan has no metric scale.
clients and bands — who is connected
Section titled “clients and bands — who is connected”- States: how many clients each AP has, where weak signal concentrates,
and a lopsided split between two APs that are metres apart.
bandsbreaks the counts down by radio and separates an AP whose 5 GHz radio is on air but going unused from one with no 5 GHz radio reporting a channel. - Cannot state: where a client is. Connected clients are not drawn as
dots — they’re on the AP badges, the per-AP table and the roster. And
bandsis an association count, not a capability census: it says which band a client chose, not which bands it supports.
The client data is the R1 snapshot, with webhook joins, leaves and roams since then applied on top. The roster is capped at 1,500 rows, ranked weakest signal first, so read a missing MAC as “not in the roster”, not “not on this floor”.
roams, roamTrail and entry — movement
Section titled “roams, roamTrail and entry — movement”These three draw the roam data your webhook receiver has already stored, joined to the distances R1 never puts beside it: “clients cross between these two APs 300 times” becomes “…and they are 44.7 m apart”.
- States: busy pairs that are far apart, pairs trading clients back and forth without either gaining signal, pairs that fully re-authenticate on most roams, roams leaking to other floors, and one client’s path.
- Cannot state: anything, until the webhook receiver is set up — the layer
reports
no_roam_datarather than a quiet floor. Counts are approximate, because webhook deliveries are stored as received and never de-duplicated. entryshows where clients appear, not where the doors are. A phone waking at a desk or a laptop coming off a dock counts as an arrival too.
Roam signal changes are RUCKUS relative units, not dB — never compare them with a client’s dBm reading. Up to 80 roam arrows are drawn, busiest first; the rest are counted and reported.
cochannel — confirm or dismiss overlap
Section titled “cochannel — confirm or dismiss overlap”analyze_rf can say two APs share a channel; this layer adds the distance.
| Distance between the two APs | Verdict |
|---|---|
| 12 m or less | Confirmed |
| Up to 30 m | Marginal |
| More than 30 m | Dismissed |
- States: which candidates are real and, just as usefully, which to stop chasing — “both on channel 36 but 48 m apart” is channel reuse working.
- Cannot state: a verdict without a metric scale; candidates are then listed as unconfirmable. Offline APs are excluded and named, because their channel is a last-known value, not what is on the air.
coverage, blastRadius and demand — the predicted layers
Section titled “coverage, blastRadius and demand — the predicted layers”These three share one prediction, so they always describe the same floor. It radiates each online AP’s reported transmit power through a log-distance path-loss model and charges a few dB for each wall it can see in the plan image.
- No metric scale, no prediction — the layer refuses with
coverage_unpredictablerather than guess. - Without the plan image there are no walls to count, so the prediction is optimistic, and it says so.
- Offline APs, and APs whose transmit power R1 reports only as a setting
such as
"max", are excluded and named. A weak area near one of them may be the model missing an AP, not a hole. coverageBandpicks the band, 5 GHz by default. If no placed AP has a usable radio on that band, another is predicted instead and a finding says so.
blastRadius removes each AP in turn and reports the floor area that would drop
below the cell edge, and how much of it nothing else reaches. It models no
recovery — R1 raises neighbours’ power and re-picks channels afterwards — and
removes one AP at a time, so it says nothing about a switch or PoE budget
taking several down. A client count beside it means clients that must
reassociate, never clients that lose service.
demand crosses the prediction with the live client count per AP. Every
finding is about an AP, never a place. Its sharpest one is clients on an AP
the model never picks as strongest anywhere — a sign that an input is wrong,
such as a stale AP position or a wall the image doesn’t show.
airtime, footfall and heardBy — the LBS layers
Section titled “airtime, footfall and heardBy — the LBS layers”These three, and the measured client dots in clients, need an LBS source:
the venue’s APs sending location-based-services reports to a probe on the venue
LAN.
airtimewould state each radio’s measured channel occupancy. It is a different quantity from theanalyze_rfairtime estimate, which covers beacon overhead only.footfallwould state the distinct devices each AP heard in the last 60 seconds — a wider net than connected clients. The per-AP counts don’t add up to the floor total, and none of it is a headcount.heardBywould trace one named device: its measured position and a line to every AP that heard it. A stronger reading from another AP is a roam candidate, never a verdict.
Which layer wins when two compete?
Section titled “Which layer wins when two compete?”A map has one heat field and each AP marker has one badge, so some layers compete. The loser’s findings are always complete — only the drawing is affected — and it says so in a finding of its own.
| Slot | Priority, winner first | The loser reports |
|---|---|---|
| Heat field | footfall → coverage → blastRadius | <layer>_field_not_drawn, naming the field that was drawn and how to see its own |
| AP badge | clients → airtime → footfall → bands → entry | <layer>_badges_not_drawn, pointing to its per-AP table in the same response |
So coverage and blastRadius together draw the coverage field. To see the
failure field, ask for blastRadius without coverage. With clients on, the
AP badges show client counts; drop clients to see the band mix or arrival
counts on the markers instead.
What no layer does
Section titled “What no layer does”No layer infers a distance or a position from a signal, places APs automatically, or tracks channel changes over time or how long clients stay on an AP. Nothing stores a history of channel changes, and the roam data keeps counts, not durations.