How to Build a Privacy-Friendly Motion Detection System with WiFi Signals in 15 Minutes
Step-by-step guide to building a camera-free, privacy-focused motion detector using an ESP32 and WiFi CSI data. Integrates seamlessly with ESPHome and Home Assistant for automations like "lights on when you enter." Complete setup in under 15 minutes with zero coding.

How to Build a Privacy-Friendly Motion Detection System with WiFi Signals in 15 Minutes
After tinkering with Home Assistant for nearly two years, I kept hitting a common wall: PIR sensors have blind spots, cameras feel invasive, and mmWave radars are too expensive. Then I found an open-source project called ESPectre. It uses WiFi Channel State Information (CSI) to detect motion without any cameras, microphones, or wearable devices. The hardware cost? Just around €10.
In this tutorial, I’ll walk you through building a complete WiFi motion sensor from scratch. By the end, you’ll have a working sensor running in your space, fully integrated with Home Assistant for automations like "lights on when you enter" or "security alert when you're away."
Prerequisites
Hardware:
- An ESP32 development board that supports CSI (ESP32-S3 or ESP32-C6 recommended, easily available online for ~$10-15)
- A standard 2.4GHz wireless router (your existing home router works fine, no special config needed)
Software:
- Home Assistant (running on Raspberry Pi, NAS, old PC, or Docker)
- ESPHome integration already installed in Home Assistant
Knowledge Requirements:
- Basic YAML familiarity (just get the indentation right)
- Familiarity with basic Home Assistant navigation
- No programming experience required. You do not need to modify your router settings.
Quick Start: Step-by-Step Firmware Flashing
Step 1: Prepare the ESPHome Configuration
ESPectre operates as a custom ESPHome component. The underlying principle is straightforward: 2.4GHz WiFi signals between your router and the ESP32 create a multipath propagation pattern in your space. When someone walks through, their body "disturbs" these electromagnetic waves. The ESP32 analyzes amplitude changes in the Channel State Information (CSI) to detect movement. Think of it like casting a shadow in front of a flashlight—the system detects the disturbance, not an image.
Open Home Assistant → ESPHome → Create Device, and paste the following YAML configuration:
yaml
esphome:
name: espectre-sensor
platformio_options:
lib_deps:
- https://github.com/francescopace/espectre
esp32:
board: esp32-s3-devkitc-1
framework:
type: esp-idf
wifi:
ssid: "Your_WiFi_SSID"
password: "Your_WiFi_Password"
## ESPectre sensor component
espectre:
detection_algorithm: mvs # MVS (classic algorithm) or ml (experimental neural network)
segmentation_threshold: auto # Set to 'auto' for adaptive tuning, or a fixed number (e.g., 3500)
auto_calibration_time: 10s # Calibration period at startup. Keep the room still during this time.
## Binary sensor for motion status
binary_sensor:
- platform: espectre
name: "Room Motion"
device_class: motion
## Optional: Expose motion score and threshold for debugging
sensor:
- platform: espectre
type: movement_score
name: "Movement Score"
Key configuration notes:
detection_algorithm: Usemvsfor the stable, classic algorithm.mlis an experimental neural network detector that skips calibration but is still in development. Stick with MVS for now.segmentation_threshold: Determines how "strong" a disturbance must be to count as motion.autoadapts to your environment. If you find it too sensitive or too sluggish, switch to a manual value.auto_calibration_time: The device needs a short period of stillness at startup to establish a baseline. Avoid moving around the room during this window to ensure accuracy.
Step 2: Flash the Firmware
Click the INSTALL button in ESPHome and select your connection method (USB or OTA). For a fresh device, connect it via USB to your computer. Once flashed, it will automatically connect to your WiFi and appear in Home Assistant.
Step 3: Home Assistant Auto-Discovery
This is where ESPHome shines: the device will be discovered automatically. You’ll see:
- A Binary Sensor (for instant motion state updates)
- A Sensor (periodically reports the raw movement score)
- A Number Entity (adjustable threshold for live tuning without editing YAML)
Hardware setup is now complete. Check your Home Assistant entity list for binary_sensor.room_motion and walk around the room to verify state changes.
Hands-On: Complete Automation Example (Lights On/Off)
Now let’s make the sensor useful. We’ll set up a classic "lights on when motion is detected, off after inactivity" automation.
In Home Assistant, go to Settings → Devices & Services → Automations → Create Automation. Switch to YAML mode and paste the following:
yaml
alias: "Study Room Auto Lights"
description: "Turn on lights on motion, turn off after 30s of inactivity"
trigger:
- platform: state
entity_id: binary_sensor.room_motion
to: "on"
id: motion_on
- platform: state
entity_id: binary_sensor.room_motion
to: "off"
for:
seconds: 30
id: motion_off
action:
- choose:
- conditions:
- condition: trigger
id: motion_on
sequence:
- service: light.turn_on
target:
entity_id: light.study_desk
- conditions:
- condition: trigger
id: motion_off
sequence:
- service: light.turn_off
target:
entity_id: light.study_desk
mode: single
Save and enable. Walk into the room, and the lights will turn on. Leave for 30 seconds, and they’ll turn off automatically. Simple as that.
Sensor Placement: Getting It Right
Many beginners experience inaccurate detection simply due to poor placement. Based on the project documentation, here are the core principles:
Optimal Distance from Router: 3 ~ 8 meters (10 ~ 26 ft)
- Too close (< 2m): Signal is too strong, multipath effects are minimal, leading to low sensitivity.
- Too far (> 10m): Signal attenuation is high, noise increases false positives.
Placement Tips:
- Place the sensor inside the area you want to monitor (line-of-sight to the router is not required).
- Mount at 1 ~ 1.5 meters high (desk/table height is ideal).
- Avoid metal obstacles (refrigerators, metal cabinets), as they severely reflect WiFi signals and distort CSI data.
- Avoid corners or fully enclosed spaces, which reduce multipath diversity.
If your board comes with an IPEX external antenna connector, adding an external antenna significantly improves performance.
FAQ & Troubleshooting
1. Detection is inaccurate right after startup?
The auto-calibration might still be in progress, or there was movement during the calibration window. Keep the room still for the default 10 seconds. If using the ML detector (detection_algorithm: ml), calibration is skipped and it works immediately.
2. Too sensitive (triggers when curtains blow)?
Locate the number entity in Home Assistant and increase the threshold value. Alternatively, set a fixed segmentation_threshold in your YAML config.
3. Not sensitive enough (doesn't trigger when walking by)?
Verify the ESP32-to-router distance is within 3–8 meters. If distance is fine, lower the threshold or check for metal obstructions in the signal path.
4. What's the coverage area?
A single sensor covers approximately 50 square meters (~530 sq ft). For larger homes, deploy multiple ESP32 units; Home Assistant will auto-discover each one.
5. Can it distinguish between humans and pets?
Currently, it performs binary classification: IDLE vs. MOTION. It doesn't differentiate between humans and pets. The project author is working on advanced ML features like gait analysis and people counting, so stay tuned.
6. Does it work during internet outages?
Yes. All detection logic runs locally on the ESP32. Offline status only means Home Assistant won't receive state updates until the network recovers, at which point it will sync automatically.
Summary & Next Steps
Here’s what we accomplished in under 15 minutes:
- Acquired an ESP32 board (~€10)
- Flashed firmware using ESPHome + the ESPectre component (zero code, YAML-only)
- Let Home Assistant auto-discover the motion sensor
- Built a working "motion-on, motion-off" automation
- Optimized sensor placement and tuned parameters
You now have a fully functional, privacy-friendly motion detection system—no cameras watching you, no microphones listening, and zero router configuration required.
Where to go from here:
- Multi-Zone Monitoring: Deploy multiple ESP32s across different rooms for full-home coverage.
- Energy Saving: Automatically turn off AC or monitors when rooms are empty.
- Elderly Care: Trigger alerts if no motion is detected for an extended period.
- Security Mode: Push phone notifications when motion is detected while your system is armed.
Check the repository for detailed tuning guides and algorithm documentation. If you build an interesting automation, feel free to share it in the comments!
Project Repository: github.com/francescopace/espectre