Files
zorruno-homeassistant/esphome/esp-occupancystair.yaml
T
2026-02-25 21:05:21 +13:00

482 lines
16 KiB
YAML

#:########################################################################################:#
# TITLE: STAIR OCCUPANCY AND UNDERHOUSE ENVIRONMENT
# zorruno.com layout v1.1 2026
#:########################################################################################:#
# REPO:
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-occupancystair.yaml
#:########################################################################################:#
# VERSIONS:
# V2.2 2026-02-25 Updated yaml to zorruno layout V1.1
# V2.1 2025-08-25 Added some MQTT to send commands to turn on remote lights
# V2.0 2025-06-05 YAML Tidyups
#:########################################################################################:#
# HARDWARE:
# D1 Mini ESP32 with:
# - HiLink LD2410 mmWave presence sensor (UART)
# - BME280 Temp/Humidity/Pressure sensor (I2C)
# - Generic PIR sensor (GPIO)
#
# References:
# - https://esphome.io/components/sensor/ld2410.html
# - https://www.simplysmart.house/blog/presence-detection-ld2410-home-assistant
# - https://github.com/patrick3399/Hi-Link_mmWave_Radar_ESPHome/tree/main
#:########################################################################################:#
# OPERATION NOTES:
# - Provides mmWave presence (moving/still) plus PIR motion.
# - Provides environment sensors (BME280).
# - When mmWave presence/moving target or PIR triggers, a script publishes MQTT commands to a remote
# light controller (e.g. stair footer lights) for a configurable auto-on duration.
# - Auto control can be enabled/disabled with "Stair Footer Lights Auto".
# - Auto duration is controlled by "Stair Footer Lights Auto Time" (seconds).
# - LD2410 exposes configuration entities (numbers/selects/switches/buttons/text sensors).
#:########################################################################################:#
# MQTT COMMANDS:
# This device publishes MQTT commands to a remote device:
# - Topic: ${mqtt_remote_device1_command_topic}
# - Payloads: ${mqtt_remote_device_command_ON}, ${mqtt_remote_device_command_OFF}
#
# Example (as configured by substitutions):
# - ${mqtt_command_main_topic}/stair-footerlights -> ON, OFF
#:########################################################################################:#
# OFFLINE NOTES:
# a) Home Assistant OFFLINE, but Network and MQTT ONLINE
# - mmWave/PIR and BME280 sensing continues locally.
# - Remote light control via MQTT publish continues (auto script still publishes).
# - HA entities are unavailable until HA returns.
# b) MQTT OFFLINE (but WiFi/Network and HA API ONLINE)
# - Sensing continues and HA API entities remain available.
# - Remote light control will NOT work (MQTT publishes fail while MQTT is down).
# c) Entire WiFi/Network OFFLINE
# - Sensing continues locally, but no HA API and no MQTT remote control.
# - SNTP is not needed (no timeclocks used).
#:########################################################################################:#
#:########################################################################################:#
# SUBSTITUTIONS: Specific device variable substitutions
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
#:########################################################################################:#
substitutions:
# Device Naming
device_name: "esp-occupancystair"
friendly_name: "Stair Occupancy and Underhouse Environment"
description_comment: "D1 Mini ESP32 with LD2410 mmWave for internal stairwell and environment sensors for under house (Layout V1.1)"
device_area: "Underhouse" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
# Project Naming
project_name: "Generic.ESP32"
project_version: "v2.2" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
# Passwords & Secrets (unfortunately you can't use substitutions inside secrets names)
api_key: !secret esp-api_key
ota_pass: !secret esp-ota_pass
static_ip_address: !secret esp-occupancystair_ip
mqtt_command_main_topic: !secret mqtt_command_main_topic
mqtt_status_main_topic: !secret mqtt_status_main_topic
# If we are changing IP addresses, you must update the current IP address here, otherwise it remains
# Don't forget to switch it back when changed.
current_ip_address: ${static_ip_address}
# Device Settings
log_level: "INFO" # NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
update_interval: "60s" # update time for general sensors etc
# MQTT REMOTE Controls
mqtt_remote_device1_name: "stair-footerlights"
mqtt_remote_device1_command_topic: "${mqtt_command_main_topic}/${mqtt_remote_device1_name}"
mqtt_remote_device_command_ON: "ON"
mqtt_remote_device_command_OFF: "OFF"
#:########################################################################################:#
# PACKAGES: Included Common Packages
# https://esphome.io/components/packages.html
#:########################################################################################:#
packages:
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
common_wifi: !include
file: common/network_common.yaml
vars:
local_device_name: "${device_name}"
local_static_ip_address: "${static_ip_address}"
local_ota_pass: "${ota_pass}"
local_current_ip_address: "${current_ip_address}"
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
common_api: !include
file: common/api_common.yaml
#file: common/api_common_noencryption.yaml
vars:
local_api_key: "${api_key}"
#### MQTT ####
common_mqtt: !include
file: common/mqtt_common.yaml
vars:
local_device_name: "${device_name}"
#### WEB PORTAL ####
#common_webportal: !include common/webportal_common.yaml
#### SNTP (Only use if you want/need accurate timeclocks) ####
#common_sntp: !include common/sntp_common.yaml
#### DIAGNOSTICS Sensors ####
diag_basic: !include common/include_basic_diag_sensors.yaml
diag_more: !include common/include_more_diag_sensors.yaml
#diag_debug: !include common/include_debug_diag_sensors.yaml
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
#:########################################################################################:#
# ESPHOME:
# https://esphome.io/components/esphome.html
#:########################################################################################:#
esphome:
name: "${device_name}"
friendly_name: "${friendly_name}"
comment: "${description_comment}" # appears on the esphome page in HA
area: "${device_area}"
min_version: 2024.6.0
#:########################################################################################:#
# ESP PLATFORM AND FRAMEWORK:
# https://esphome.io/components/esp32.html
#:########################################################################################:#
esp32:
board: esp32dev
framework:
type: esp-idf # "esp-idf" OR "arduino"
version: recommended
#:########################################################################################:#
# GLOBAL VARIABLES:
# https://esphome.io/components/globals.html
#:########################################################################################:#
globals:
- id: stair_footer_auto_default_s
type: int
restore_value: true
initial_value: "20"
#:########################################################################################:#
# I2C BUS:
# https://esphome.io/components/i2c.html
#:########################################################################################:#
i2c:
sda: GPIO19
scl: GPIO21
scan: true
frequency: 100kHz
#:########################################################################################:#
# LOGGING:
# https://esphome.io/components/logger.html
#:########################################################################################:#
logger:
level: "${log_level}"
baud_rate: 0
#:########################################################################################:#
# UART:
# https://esphome.io/components/uart.html
#:########################################################################################:#
uart:
id: ld2410_uart
rx_pin: GPIO16
tx_pin: GPIO17
baud_rate: 256000
data_bits: 8
stop_bits: 1
parity: NONE
#:########################################################################################:#
# STATUS LED:
# https://esphome.io/components/status_led.html
#:########################################################################################:#
status_led:
pin:
number: GPIO2
ignore_strapping_warning: true
inverted: false
#:########################################################################################:#
# LD2410:
# https://esphome.io/components/sensor/ld2410.html
#:########################################################################################:#
ld2410:
uart_id: ld2410_uart
#:########################################################################################:#
# NUMBER COMPONENT:
# https://esphome.io/components/number/
#:########################################################################################:#
number:
- platform: ld2410
timeout:
name: "Timeout"
light_threshold:
name: "Light Threshold"
max_move_distance_gate:
name: "Max Move Distance Gate"
max_still_distance_gate:
name: "Max Still Distance Gate"
g0:
move_threshold:
name: "g0 move threshold"
still_threshold:
name: "g0 still threshold"
g1:
move_threshold:
name: "g1 move threshold"
still_threshold:
name: "g1 still threshold"
g2:
move_threshold:
name: "g2 move threshold"
still_threshold:
name: "g2 still threshold"
g3:
move_threshold:
name: "g3 move threshold"
still_threshold:
name: "g3 still threshold"
g4:
move_threshold:
name: "g4 move threshold"
still_threshold:
name: "g4 still threshold"
g5:
move_threshold:
name: "g5 move threshold"
still_threshold:
name: "g5 still threshold"
g6:
move_threshold:
name: "g6 move threshold"
still_threshold:
name: "g6 still threshold"
g7:
move_threshold:
name: "g7 move threshold"
still_threshold:
name: "g7 still threshold"
g8:
move_threshold:
name: "g8 move threshold"
still_threshold:
name: "g8 still threshold"
- platform: template
id: stair_footer_auto_time_s
name: "Stair Footer Lights Auto Time"
unit_of_measurement: "s"
min_value: 10
max_value: 300
step: 1
optimistic: true
restore_value: true
initial_value: 20
#:########################################################################################:#
# SELECT COMPONENT:
# https://esphome.io/components/select/index.html
#:########################################################################################:#
select:
- platform: ld2410
distance_resolution:
name: "${friendly_name} LD2140 Distance Resolution"
baud_rate:
name: "${friendly_name} LD2140 Baud Rate"
light_function:
name: "${friendly_name} LD2140 Light Function"
out_pin_level:
name: "${friendly_name} LD2140 Out Pin Level"
#:########################################################################################:#
# SENSOR COMPONENT:
# https://esphome.io/components/sensor/
#:########################################################################################:#
sensor:
- platform: bme280_i2c
temperature:
name: "Temperature"
accuracy_decimals: 1
oversampling: 2x
pressure:
name: "Pressure"
oversampling: 2x
humidity:
name: "Humidity"
accuracy_decimals: 1
oversampling: 2x
address: 0x76
update_interval: "${update_interval}"
- platform: ld2410
light:
name: "Light"
moving_distance:
name: "Moving Distance"
still_distance:
name: "Still Distance"
moving_energy:
name: "Move Energy"
still_energy:
name: "Still Energy"
detection_distance:
name: "Detection Distance"
g0:
move_energy:
name: "g0 move energy"
still_energy:
name: "g0 still energy"
g1:
move_energy:
name: "g1 move energy"
still_energy:
name: "g1 still energy"
g2:
move_energy:
name: "g2 move energy"
still_energy:
name: "g2 still energy"
g3:
move_energy:
name: "g3 move energy"
still_energy:
name: "g3 still energy"
g4:
move_energy:
name: "g4 move energy"
still_energy:
name: "g4 still energy"
g5:
move_energy:
name: "g5 move energy"
still_energy:
name: "g5 still energy"
g6:
move_energy:
name: "g6 move energy"
still_energy:
name: "g6 still energy"
g7:
move_energy:
name: "g7 move energy"
still_energy:
name: "g7 still energy"
g8:
move_energy:
name: "g8 move energy"
still_energy:
name: "g8 still energy"
#:########################################################################################:#
# SWITCH COMPONENT:
# https://esphome.io/components/switch/
#:########################################################################################:#
switch:
- platform: ld2410
engineering_mode:
name: "${friendly_name} LD2140 Engineering Mode"
#bluetooth:
# name: "${friendly_name} LD2140 Control Bluetooth"
- platform: template
id: stair_footer_auto_enabled
name: "Stair Footer Lights Auto"
optimistic: true
restore_mode: RESTORE_DEFAULT_ON
#:########################################################################################:#
# BINARY SENSORS:
# https://esphome.io/components/binary_sensor/
#:########################################################################################:#
binary_sensor:
- platform: ld2410
has_target:
name: "mmWave Presence"
on_press:
- if:
condition:
switch.is_on: stair_footer_auto_enabled
then:
- script.execute: stair_footer_auto_script
has_moving_target:
name: "mmWave Moving Target"
on_press:
- if:
condition:
switch.is_on: stair_footer_auto_enabled
then:
- script.execute: stair_footer_auto_script
has_still_target:
name: "mmWave Still Target"
out_pin_presence_status:
name: "LD2140 Out Pin Presence Status"
entity_category: diagnostic
# Generic PIR Sensor (GPIO13)
- platform: gpio
pin:
number: GPIO13
mode:
input: true
pullup: true
inverted: true
name: "PIR Sensor"
device_class: motion
filters:
- delayed_on: 50ms
on_press:
- if:
condition:
switch.is_on: stair_footer_auto_enabled
then:
- script.execute: stair_footer_auto_script
#:########################################################################################:#
# BUTTON COMPONENT:
# https://esphome.io/components/button/index.html
#:########################################################################################:#
button:
- platform: ld2410
factory_reset:
name: "${friendly_name} LD2140 Factory reset"
restart:
name: "${friendly_name} LD2140 Restart"
query_params:
name: "Query Parameters"
#:########################################################################################:#
# TEXT SENSOR COMPONENT:
# https://esphome.io/components/text_sensor/
#:########################################################################################:#
text_sensor:
- platform: ld2410
version:
name: "${friendly_name} LD2140 Firmware Version"
#mac_address:
# name: "${friendly_name} LD2140 BT MAC Address"
#:########################################################################################:#
# SCRIPT COMPONENT:
# https://esphome.io/components/script.html
#:########################################################################################:#
script:
- id: stair_footer_auto_script
mode: restart
then:
# Turn lights on (command the Top switch's footer relay)
- mqtt.publish:
topic: "${mqtt_remote_device1_command_topic}"
payload: "${mqtt_remote_device_command_ON}"
retain: false
# Wait for the HA-adjustable timeout
- delay: !lambda "return (uint32_t)(id(stair_footer_auto_time_s).state) * 1000;"
# Turn lights back off
- mqtt.publish:
topic: "${mqtt_remote_device1_command_topic}"
payload: "${mqtt_remote_device_command_OFF}"
retain: false