Skip to content

BLE & RTLS Settings

This page documents every knob on Admin → Devices → BLE Configuration. It explains what each setting controls, when to change it, what "too high" and "too low" each look like in practice, and which scenarios to use as a starting point.

The panel is organised into sections that mirror the real-time location pipeline:

Gateway Scanning

RSSI Filtering      ← drop noise, throttle per-tag

Envelope Aggregation ← reject multipath fades (peak-hold)

Positioning Algorithm ← trilateration / centroid / proximity

Math Tuning         ← IRLS outlier rejection, centroid weighting

Dominant Receiver Bias ← snap when obvious

Position Smoothing  ← Kalman (optional velocity model)

Presence Thresholds ← Active → Last Seen → Stale

Everything between RSSI Filtering and Position Smoothing was substantially rebuilt in the RTLS Accuracy Overhaul (migration 066). Details on what changed and why are at the bottom of this page.

Before you tune — change one setting at a time, wait at least 2–3 minutes for the pipeline to stabilise, then compare live vs. historical playback on the floor plan page. If the two still disagree, open Admin → Devices → Signal Monitor to inspect per-AP RSSI per device.


Gateway Scanning

Controls how often BLE radios actually listen.

FieldDefaultRangeWhat it does
BLE Tracking EnabledOnMaster toggle. When off, no raddecs reach the database — the floor plan will freeze on its last-known state.
Scan Interval (seconds)101–60Seconds between scan cycles. Lower values detect new tags faster but raise AP CPU.
Scan Window (seconds)51–30Length of each listen. Higher values catch more beacons per cycle.

Setting Scan Window greater than Scan Interval has no effect — the AP is always listening.


RSSI Filtering

Drops noise-level samples and throttles per-tag pipeline passes so the DB stays healthy.

FieldDefaultRangeWhat it does
Minimum RSSI Threshold (dBm)−90−100 to −50Drop readings weaker than this. At −90 dBm indoor range is roughly 10 m — that's usually the sweet spot for capturing 2nd and 3rd APs for trilateration.
Transmitter Dedup Window (seconds)50–3600Minimum gap between pipeline passes for the same transmitter. Setting this too low (<1 s) can overload the DB; too high (>30 s) makes live tracking laggy.
Max Reading Age (ms)45 0001 000–120 000Readings older than this (relative to the freshest sample in the batch) are discarded before trilateration.

Too strict (threshold −80): trilateration often falls back to single-receiver proximity — visible as live markers snapping to the strongest gateway.

Too permissive (threshold −100): very weak signals contribute to the fit and add jitter. You'll see tags "breathing" a few metres around their true position.


Envelope Aggregation RTLS overhaul

Indoor BLE RSSI is dominated by multipath fading — quick ±5 to 10 dB fluctuations that have nothing to do with the tag's true distance. Historical playback has always taken the max RSSI per (tag, AP) over a 30-second window, which approximates the free-path envelope and rejects those dips. That is precisely why historical playback has historically looked more accurate than live. This section brings the same trick server-side for the live pipeline.

FieldDefaultRangeWhat it does
Aggregation MethodMaxMax / Mean / LatestHow samples per (tag, AP) are collapsed into one value for trilateration. Max is the new default and the behaviour you want.
Aggregation Window (seconds)155–120Window over which samples are aggregated. Shorter = lower latency. Longer = better multipath rejection.
Positioning Lookback (seconds)9010–600Upper bound on how far back raddecs can feed the fit. Effective window = min(aggregation, lookback).

When to use which method:

  • Max (recommended): rejects multipath fade dips. Live positions match historical playback. Use this.
  • Mean: averages every sample in the window. Slightly smoother than max but biased downward by the same fades we want to ignore.
  • Latest: legacy behaviour — pipe the last raw sample straight through. Useful for A/B diagnosis against the old pipeline.

Walking personnel tradeoff — a longer aggregation window is more multipath-tolerant but lags behind a moving tag. 15 s is a good balance for offices. Warehouses with mostly stationary tags can push this to 30 s.


Positioning Algorithm

Which algorithm converts RSSI readings into an (x, y) position, and how many APs feed the fit.

FieldDefaultRangeWhat it does
Position Calculation MethodTrilaterationTrilateration / Weighted Centroid / Nearest ReceiverTrilateration (3+ APs, linearised least-squares) is the default and the most accurate. Weighted Centroid is the 2-AP fallback. Nearest Receiver is proximity-only — use for diagnostics.
Max Positioning Receivers41–10Top-N APs (by filtered RSSI) used in the fit. 3–5 is the typical sweet spot.
Max Trilateration Devices per Batch10010–500How many tags to position per Event Hub batch. Higher = wider coverage per cycle, heavier DB load.

Which method should I pick?

  • Trilateration — the default. The pipeline automatically falls back to Weighted Centroid when only 2 APs have a valid reading and to proximity when only 1 AP does.
  • Weighted Centroid — force the centroid path even with 3+ APs. Only useful if you have degenerate geometry (collinear gateways).
  • Nearest Receiver — disables trilateration entirely. Marks positions with the strongest gateway's coordinates. Useful for sanity checks or for very sparse deployments where trilateration has nothing to work with.

Math Tuning RTLS overhaul

Fine-tunes the actual math inside the fit. You usually won't touch these, but knowing what they do helps when diagnosing outlier-driven snaps.

FieldDefaultRangeWhat it does
Weighted Centroid Exponent2.00.5–4Distance-weighting exponent for the 2-AP centroid: weight = 1/d^exponent. 2.0 is variance-weighted under the log-distance path-loss model. Lower values (0.5–1.0) are less eager to collapse onto the strongest AP.
Residual Rejection σ3.00–10Tukey bisquare tuning constant for IRLS outlier rejection. A circle whose geometric residual exceeds σ × robust-scale gets zero weight in the next iteration. Set to 0 to disable IRLS.
Max IRLS Iterations51–20Upper bound on reweighting passes. IRLS usually converges in 2–3; raise if per-device diagnostics show slow convergence.

What IRLS does

Iteratively Reweighted Least Squares solves plain LSQ, then computes the per-circle residual (|estimated distance − actual distance from the solution|), then re-weights circles using a Tukey bisquare function of their residual. Big outliers go to zero weight and drop out of the next iteration. The process repeats up to Max IRLS Iterations.

The residual scale is estimated robustly with 1.4826 × MAD (Median Absolute Deviation), so IRLS still works even when half the measurements are bad — which is usually the case in a multipath-heavy reflection scenario.

When to change the centroid exponent

The 2-AP weighted centroid always lies inside the convex hull of the two APs. With the default exponent of 2, it falls close to the closer AP because the closer AP has 4× the weight. In sparse-coverage offices where only 2 APs ever see a tag, dropping the exponent to 1.0 or even 0.5 produces visibly less "snap to nearest AP" behaviour.


Dominant Receiver Bias

When a tag really is right under one AP — strong signal, much closer than everything else — "snap" to that AP. The result is blended 35% toward the multi-AP solution so it isn't perfectly pinned.

FieldDefaultRangeWhat it does
Prefer Dominant GatewayOnMaster toggle for the bias.
Dominant RSSI Gap (dBm)121–30Minimum gap between strongest and 2nd-strongest AP before bias kicks in.
Dominant Max Distance (m)1.50.5–20Only bias when the tag is within this radius of the strongest AP (by the log-distance model).
Dominant Distance Ratio0.40.1–1Alternative trigger: bias when strongest_distance / second_distance ≤ ratio.

The dominant bias is intentionally conservative. You generally want it on: in offices tags genuinely spend a lot of time directly under an AP, and the bias produces a more intuitive display than a pure centroid solution in that case.

If live markers still snap to gateways after the RTLS overhaul, your first instinct is probably to turn this off. Don't — the overhaul already made the bias much less trigger-happy (gap went 8 → 12 dBm, max-distance 2.0 → 1.5 m). Try dropping the centroid exponent first.


Position Smoothing

A Kalman filter that removes position jitter between trilateration passes. Optionally tracks velocity for moving tags.

FieldDefaultRangeWhat it does
Position FilterKalmanKalman / NoneOff = show raw trilateration output. Useful for calibration debugging.
Process Noise (Q)0.50.1–10Higher = more responsive to movement, lower = smoother.
Measurement Noise (R)20.5–100Higher = trust new measurements less. Raise this if live positions jitter even with envelope aggregation on.
Initial Variance251–10 000Starting position uncertainty (percentage-coordinate² units). 25 gives sensible smoothing from the second sample. 1000 (the legacy value) gave essentially no smoothing for the first 5–10 samples.
Velocity Variance00–10 000> 0 enables the constant-velocity Kalman model (better tracking of moving tags). 0 = position-only.

The legacy initial-variance problem

Before the RTLS overhaul, Initial Variance was 1 000. That's a very wide prior. With measurement noise R = 2, the Kalman gain on the second sample was 1000 / (1000 + 2) ≈ 0.998 — the filter accepted the new measurement at nearly 100% trust. That meant newly-detected tags took 5–10 position updates before the filter actually started smoothing, and during those updates the marker would bounce around.

25 is a much more principled default (≈5 m stddev in percentage-coordinate space). Combined with the envelope aggregation, first-measurement tracking should feel much calmer now.

When to enable the velocity model

Default — leave velocity variance at 0. The position-only Kalman is simpler and perfectly adequate for mostly-stationary personnel.

Turn it on (typical value: 4) if you're tracking fast-moving assets where the filter visibly lags behind the tag. The velocity model predicts where the tag will be on the next sample based on its recent motion, which means it doesn't have to "catch up" on each measurement.


Presence Thresholds

How fast a tag transitions through the three status tiers shown on the floor plan.

FieldDefaultRangeWhat it does
Active Threshold (minutes)51–30Minutes of silence before a tag transitions from Active (green) to Last Seen (yellow).
Last Seen Threshold (minutes)155–60Minutes of silence before Last Seen (yellow) transitions to Stale (red).

These are display-only thresholds — they don't affect the algorithm. They do affect what users see, so align them with your deployment's expectations. An emergency-response deployment wants shorter thresholds (tags should "drop off" quickly). A warehouse asset-tracking deployment wants longer thresholds (tags get seen every few minutes).


Battery Monitoring

Applies to tags that report a battery level in their BLE advertisements.

FieldDefaultRangeWhat it does
Enable MonitoringOnCollect battery telemetry and surface low / critical alerts.
Check Interval (minutes)6010–1440How often to re-evaluate tag battery levels for alerts.
Low Battery Threshold (%)300–100Battery level at which a tag flips to Low Battery.
Critical Battery Threshold (%)100–100Battery level at which a tag flips to Critical and raises an alert.

Ambient Device Tracking

Ambient mode captures all surrounding BLE devices, not just known personnel. It's useful for coverage audits, heatmaps, and asset discovery.

FieldDefaultRangeWhat it does
Enable Ambient TrackingOffCapture raddecs for non-personnel BLE devices.
Retention (days)301–365How long to keep ambient device events before rollup / deletion.

Ambient device-type, manufacturer, and MAC-exclusion filters are managed in a separate page: Beacons → BLE Tracking.


Troubleshooting scenarios

Live markers "snap" to gateways; historical playback looks better

Classic symptom of the problem the RTLS Accuracy Overhaul was designed to solve. Make sure:

  1. Aggregation Method = Max (Envelope Aggregation section)
  2. Aggregation Window ≥ 10 s (15 is default)
  3. Residual Rejection σ ≥ 3 (Math Tuning section)
  4. Initial Variance ≤ 50 (Position Smoothing section)

If symptoms persist, drop the Weighted Centroid Exponent to 1.0 or 0.5 — helpful in sparse-coverage deployments where only 2 APs see a tag and the centroid is the dominant code path.

New tags bounce for the first few samples

Initial Variance is still too high. Drop it from 25 to 10 or 15.

Tags lag behind fast-moving personnel

Enable the constant-velocity model: set Velocity Variance to 4 (try 1 or 2 if you want more smoothing, 10 for very fast movement).

Live positions look good but historical playback looks different

Historical playback does its max-hold on the frontend over a 30-second window with a different weighted-centroid formulation. With envelope aggregation now server-side, the two should mostly agree — but historical will always be slightly better because it uses a longer window.

DB CPU pegged during heavy ingest

Max Trilateration Devices per Batch is the primary knob — drop from 100 to 50. If that's not enough, raise Transmitter Dedup Window (seconds) from 5 to 10 to halve the per-device pipeline pass rate.

Dominant bias is still triggering when I don't want it to

Raise Dominant RSSI Gap from 12 to 16–20 dBm. Or disable the bias entirely with Prefer Dominant Gateway.


Dense office (APs ≈ every 10–15 m)

Use the defaults. The RTLS overhaul was tuned specifically for this topology.

Sparse warehouse (APs ≈ every 30–60 m)

  • Minimum RSSI Threshold: −95 dBm (catch weaker reflections)
  • Aggregation Window: 25–30 s (tags are mostly stationary, more window rejects more fading)
  • Weighted Centroid Exponent: 1.0 (less collapse onto strongest AP when only 2 APs see a tag)
  • Dominant RSSI Gap: 16 dBm (harder to trigger bias in open space)

Healthcare / high-density personnel

  • Active / Last Seen thresholds: 3 min / 8 min (faster status transitions)
  • Velocity Variance: 2 (people walk, filter should track)
  • Max Trilateration Devices per Batch: 200 (lots of simultaneous tags)

What changed in the RTLS Accuracy Overhaul (migration 066)

This is the summary of what shipped in PR 296, which introduced all the settings marked RTLS overhaul above.

Diagnosis

Live floor plan positions routinely collapsed onto the strongest gateway — especially in the NISC Lake St. Louis deployment — while historical playback of the same time range looked noticeably more accurate. Three contributing issues:

  1. The trilateration SQL pulled latest RSSI per (tag, AP) in a 90 s window, so multipath fade dips passed straight through to the distance model.
  2. Least-squares trilateration had no outlier rejection, so one spurious reflection reading could drag the solution well off-centre.
  3. The 2D Kalman position smoother used an initial variance of 1 000. With measurement noise 2, that gave a 0.998 Kalman gain on the second sample — essentially zero smoothing for the first 5–10 samples of a new tag.

Fix

  1. Envelope aggregation at the SQL layer: MAX(rssi) per (tag, AP) over a configurable 15 s window. Rejects multipath dips exactly the way historical playback has always done.
  2. IRLS outlier rejection inside least-squares: Tukey bisquare reweighting driven by the 1.4826 × MAD robust residual scale.
  3. Calibrated initial covariance (25 instead of 1 000) so the second sample is actually smoothed, plus an optional 2D constant-velocity Kalman model for moving tags.

All three are on by default and backward-compatible with existing deployments that haven't tuned anything. Per-site tuning is exposed here.

Where to read more

  • Design & tradeoffs: RTLS Accuracy Overhaul spec
  • Backend services: static-web-app/api/src/services/trilaterationService.js, positionSmoother.js, rssiEnvelope.js
  • Migration: database/migrations/066_rtls_accuracy_settings.sql

NISC Muster Tracking Documentation