- Email[email protected]
- Phone+962 797 166 177
- Birthday1982-09-25
- LocationAmman, Jordan
Building the Ultimate Smart Room Node with ESP32 & ESPHome
G'day, makers and home automation fans! Today I'm sharing a little project I've been working on: a fully loaded multisensor built around the legendary ESP32 and powered by ESPHome. If you want to make your smart home truly "smart," local sensors are the way to go, and this little board packs a massive punch!
For this build, I wanted to create a single node that could monitor the climate, detect motion, track light levels, and even act as a Bluetooth proxy for my home network. Here is the hardware lineup I used:
The Brains: An ESP32 dev board running the ESP-IDF framework. It's powerful, reliable, and handles Wi-Fi/Bluetooth like an absolute champ.
Climate Control (BME280): Hooked up via I2C, this gives me ultra-precise Temperature, Humidity, and Pressure readings.
Motion Detection (HC-SR501): A classic PIR sensor to trigger automations the second someone walks into the room.
Custom Light Sensing (LDR): An analog light-dependent resistor to measure ambient light in volts, complete with a sliding window moving average filter to smooth out the readings.
One of my absolute favorite parts of this configuration is the custom logic for the light sensor. Instead of just relying on raw voltage drops, I created a custom template number component. This lets me adjust the "Light Threshold" dynamically from my dashboard! The board then uses a template binary sensor to calculate if the light is "on" or "off" based on that live threshold, with a 2-second delay to prevent annoying flickering.
Oh, and because the ESP32 has the extra horsepower, I enabled the bluetooth_proxy feature. This means the node is actively extending my Bluetooth range, picking up BLE devices from across the house without breaking a sweat!
Here is the full ESPHome YAML configuration so you can build your own. Check out the clean YAML structure, especially how the Wi-Fi secrets and static IPs are organized:
YAML
esphome:
name: br-esp32
friendly_name: BR ESP32
esp32:
board: esp32dev
framework:
type: esp-idf
# Enable logging
logger:
level: WARN
# Enable Home Assistant API
api:
encryption:
key: "mj2jSrdGC25OoEt6VNcMgfTU+Be0eVuG6Kc9i2eLFPU="
ota:
- platform: esphome
password: "17236dc7a7dd96ab92822407cb142c4e"
wifi:
# This 'networks:' key is the fix.
# It holds the list of networks to connect to.
networks:
- ssid: !secret wifi_ssid
password: !secret wifi_password
hidden: true
manual_ip:
static_ip: 192.168.3.162
gateway: 192.168.3.1
subnet: 255.255.255.0
# 'ap:' is now at the same level as 'networks:',
# which is valid YAML.
ap:
ssid: "BR ESP32"
password: "2vsPcQNqWFt9"
mqtt:
broker: !secret mqtt
username: !secret mqtt_user
password: !secret mqtt_password
# Enable Bluetooth
esp32_ble_tracker:
scan_parameters:
active: true
bluetooth_proxy:
active: true
captive_portal:
# ---------------- I2C BUS ----------------
i2c:
sda: GPIO21
scl: GPIO22
scan: true
id: bus_a
sensor:
# ---------- BME280 ----------
- platform: bme280_i2c
i2c_id: bus_a
address: 0x76
update_interval: 10s
temperature:
name: "BR Temperature H"
id: bme280_temp
oversampling: 16x
pressure:
name: "BR Pressure H"
id: bme280_pressure
humidity:
name: "BR Humidity H"
id: bme280_humidity
# ---------- LDR on ADC ----------
- platform: adc
pin: GPIO36
id: light_level_v
name: "BR Light Level H"
unit_of_measurement: "V"
icon: "mdi:sun-wireless"
accuracy_decimals: 3
update_interval: 1s
filters:
- sliding_window_moving_average:
window_size: 6
send_every: 1
# ---------------- NUMBER (Single Threshold) ----------------
number:
- platform: template
id: light_threshold_v
name: "BR Light Threshold H"
optimistic: true
restore_value: true
initial_value: 0.60
step: 0.01
min_value: 0.05
max_value: 2.50
# ---------------- BINARY SENSORS ----------------
binary_sensor:
# Motion Sensor (HC-SR501)
- platform: gpio
pin:
number: GPIO19
mode: INPUT_PULLDOWN # This line is the fix
name: "BR Motion H"
device_class: motion
# Simple light detection
- platform: template
name: "BR Light Detected H"
device_class: light
lambda: |-
// If the current voltage is greater than the threshold, light is detected (return true).
return id(light_level_v).state < id(light_threshold_v).state;
filters:
# These prevent the light from flickering rapidly if the voltage is hovering
# right at the threshold.
- delayed_on: 2s
- delayed_off: 2s
Have you guys tried combining analog LDRs with template thresholds in ESPHome before? It saves hardcoding values and makes tweaking a breeze! Let me know what you'd add to this board in the comments. Cheers! 🍻