ESPresense
DIY Bluetooth presence detection with ESP32 nodes
ESPresense is firmware for ESP32 devices that creates a network of Bluetooth presence-detection nodes. It reports the location of phones, watches, and beacons to home automation systems over MQTT.
Key features
- Room-level presence detection
- ESP32 sensor network
- MQTT reporting
- Beacon and device tracking
Pros & cons
Strengths
- Accurate indoor presence
- Cheap hardware
Trade-offs
- Needs multiple ESP32 nodes
- Tuning required
ESPresense replaces
Last reviewed Sep 13, 2026 · 861 words
One ESP32 per room at about 6 dollars each, plus an MQTT broker you probably already have, is what it costs to know which room a person is in rather than whether their phone is on the Wi-Fi. That is the deal ESPresense offers. It is firmware, not a server: you flash it to cheap boards, they listen for Bluetooth Low Energy advertisements, and they publish distance estimates for each device they hear to MQTT. Everything clever happens downstream in Home Assistant or in the companion app.
The firmware flashes from a browser and needs no toolchain
The espresense.com installer uses Web Serial, so Chrome or Edge, a USB cable and a supported board are the whole requirement. The M5Atom Lite and the plain ESP32 dev kits are the boards the community has done the most tuning on; ESP32-C3 and S3 variants work with different antenna behaviour. After flashing, the node hosts a captive portal for Wi-Fi and MQTT settings, then reboots and starts publishing under espresense/devices/<device-id>/<room> with a JSON payload carrying RSSI, estimated distance and a fingerprint.
Where it sits in a stack: a broker such as Mosquitto, the nodes as MQTT publishers, and a consumer that turns "distance 1.8 m from kitchen node" into "person is in the kitchen". The consumer is the part people underestimate.
Tracking a phone is the hard part, and iPhones are hardest
Beacons, Tiles and most watches advertise a stable identifier, so they just work. Phones randomise their Bluetooth address every 15 minutes or so, which is the entire point of the privacy feature and the entire reason ESPresense has an identity resolution step. Two working routes:
- Android: the Home Assistant companion app can broadcast a BLE transmitter beacon with a fixed UUID. Enable it, set the interval, and the node sees a stable ID.
- iPhone and Apple Watch: extract the identity resolving key (IRK) for the device and give it to ESPresense so it can de-randomise the address. The project documents the extraction; it involves a paired Mac or a Windows registry read and is a one-time chore per device.
Skip identity work and you get a node that reports 40 anonymous devices, which is useless. Do it for the 2 to 4 devices that matter and you get room-level presence that beats any Wi-Fi or GPS method for the indoor case, which is the case that matters for lights and heating.
The companion app does the trilateration you do not want to write
ESPresense Companion is a separate Docker container with a floor plan editor. You draw rooms, place nodes at their real coordinates, and it fuses the distance reports from several nodes into an x/y position and a room name, then pushes device_tracker entities into Home Assistant via MQTT discovery. Without it you fall back to the older pattern of a per-room sensor and an automation that picks the nearest, which works in a flat with 3 nodes and gets flaky in a house with 8.
Run the companion on the same box as the broker. It is light, and it also gives you a live map that makes the next step tolerable.
Tuning is real work, and 3 numbers do most of it
The catalogue lists tuning as a con and it is right. The distance estimate comes from RSSI through a path-loss model, and walls, bodies and fridge doors all lie to it. The values that move results:
ref_rssiper device, the signal strength at 1 metre. Calibrate by standing 1 metre from a node and reading the raw value.absorptionper node, how quickly signal decays with distance. Between 3 and 4 for most rooms; higher for thick walls.max_distance, the cut-off past which a node ignores a device. Set it just beyond the room's far corner or two rooms will fight.
Plan an evening of walking around with the companion map open. The result stabilises; it never becomes perfect, and the correct expectation is "which room, updated within 10 seconds", not "which chair".
It is not a security system and not a substitute for ESPHome
ESPresense answers one question. For sensors, relays and displays on the same class of hardware, ESPHome is the tool, and the two coexist happily on separate boards. Do not try to run both on one ESP32; BLE scanning wants the radio and the CPU to itself. And because presence is inferred from a phone people sometimes leave on a shelf, use it for comfort automations, not for locking doors.
What I'd do
Buy 4 M5Atom Lites, flash from the browser, run Mosquitto and the ESPresense Companion in Docker next to Home Assistant, and set up identity for two phones before touching any tuning. Give it a week to settle, then write the two automations that justify it: lights off when a room empties and heating down when the house does. If your first month with Home Assistant is still underway, put this on the list for month three.
Compare ESPresense
1 head-to-head comparisons.
Similar home automation apps
Home Assistant
Home AutomationOpen-source home automation that puts privacy first
Replaces SmartThings, Google Home
Frigate
Home AutomationLocal NVR with real-time AI object detection
Replaces Google Home
ntfy
Home AutomationSend push notifications to your phone via simple HTTP
Replaces Pushover, Pushbullet
Homebridge
Home AutomationBring non-HomeKit smart devices into Apple Home
Replaces Apple HomeKit hubs
Tasmota
Home AutomationOpen-source firmware for ESP-based smart devices
Replaces Tuya Cloud
ThingsBoard
Home AutomationOpen-source IoT platform for device management and data
Replaces AWS IoT, Azure IoT