BLE beacons and RFID readers in a hospital do not tell you "the pump is in room 304". They tell you that tag A1F3 was heard by receiver R-3-07 at -71 dBm. Turning that stream into a reliable room-level location is the core software problem in any hospital RTLS.

The raw data

from dataclasses import dataclass from datetime import datetime @dataclass class Sighting: tag_id: str # tag on the device  receiver_id: str # fixed receiver, mapped to a room or zone  rssi: int # signal strength in dBm  ts: datetime 

Step 1: smooth the noise

RSSI jumps around as people walk past and doors open. Never decide location from a single reading. Keep a short window per tag and receiver and use the median:

from statistics import median from collections import defaultdict, deque WINDOW = 5 buf = defaultdict(lambda: deque(maxlen=WINDOW)) def add(s: Sighting): buf[(s.tag_id, s.receiver_id)].append(s.rssi) def strength(tag, receiver): vals = buf[(tag, receiver)] return median(vals) if vals else None 

Step 2: pick a room, with hysteresis

Choose the receiver with the strongest smoothed signal, but only move the device to a new room if the new room wins by a margin for a few cycles. Without this, a pump near a wall will "flicker" between two rooms all day.

MARGIN = 6 # dB the new room must win by CONFIRM = 3 # consecutive cycles  def decide(current_room, candidates, streak): best_room, best = max(candidates.items(), key=lambda kv: kv[1]) if best_room == current_room: return current_room, 0 if best - candidates.get(current_room, -200) >= MARGIN: streak += 1 if streak >= CONFIRM: return best_room, 0 return current_room, streak 

Step 3: handle silence

Tags go quiet when batteries die, when a device is in a shielded room, or when it has left the building. Store a last_seen time and show "last seen in ICU, 2 hours ago" instead of pretending the location is current. Alert when a high-value device goes silent near an exit.

Lessons from the field

  • Map every receiver to a room in a config table, not in code. Rooms get renumbered.
  • Log raw sightings for a week before tuning MARGIN and CONFIRM.
  • Room-level accuracy needs enough receivers; software cannot fix a receiver that hears three rooms equally.

For the business side (which equipment to tag first, maintenance and audit benefits), see this guide to the hospital asset tracking system.