more esphome devices and fixes
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 8.8 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 6.1 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 9.0 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 6.1 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
After Width: | Height: | Size: 7.9 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 9.4 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 9.2 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 7.3 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 612 B |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 11 KiB |
@@ -1 +1 @@
|
|||||||
{"pid": 67, "version": 1, "ha_version": "2026.3.1", "start_ts": 1772875766.7594833}
|
{"pid": 67, "version": 1, "ha_version": "2026.4.0", "start_ts": 1775105928.9191253}
|
||||||
@@ -6,9 +6,10 @@
|
|||||||
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-entrancebathrmlights.yaml
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-entrancebathrmlights.yaml
|
||||||
#:########################################################################################:#
|
#:########################################################################################:#
|
||||||
# VERSIONS:
|
# VERSIONS:
|
||||||
# v3.8 2026-02-25 Updated yaml to zorruno layout V1.1
|
# V3.9 2026-03-11 Updated yaml to zorruno layout V1.1
|
||||||
# v3.7 2025-09-34 Upload to this bathroom (as noted in original header)
|
# V3.8 2026-02-25 Updated yaml to zorruno layout V1.1
|
||||||
# v3.5 2025-07-24 YAML tidyups
|
# V3.7 2025-09-34 Upload to this bathroom (as noted in original header)
|
||||||
|
# V3.5 2025-07-24 YAML tidyups
|
||||||
#:########################################################################################:#
|
#:########################################################################################:#
|
||||||
# HARDWARE:
|
# HARDWARE:
|
||||||
# - Zemismart KS-811 Double push button (ESP8266)
|
# - Zemismart KS-811 Double push button (ESP8266)
|
||||||
@@ -33,7 +34,6 @@
|
|||||||
# - Accurate time is NOT needed (SNTP not needed).
|
# - Accurate time is NOT needed (SNTP not needed).
|
||||||
#:########################################################################################:#
|
#:########################################################################################:#
|
||||||
|
|
||||||
|
|
||||||
#:########################################################################################:#
|
#:########################################################################################:#
|
||||||
# SUBSTITUTIONS: Specific device variable substitutions
|
# SUBSTITUTIONS: Specific device variable substitutions
|
||||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||||
@@ -47,7 +47,7 @@ substitutions:
|
|||||||
|
|
||||||
# Project Naming
|
# Project Naming
|
||||||
project_name: "Zemismart Technologies.KS-811 Double"
|
project_name: "Zemismart Technologies.KS-811 Double"
|
||||||
project_version: "v3.8"
|
project_version: "v3.9"
|
||||||
|
|
||||||
# Passwords & Secrets
|
# Passwords & Secrets
|
||||||
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
||||||
@@ -144,7 +144,7 @@ logger:
|
|||||||
status_led:
|
status_led:
|
||||||
pin:
|
pin:
|
||||||
number: GPIO2
|
number: GPIO2
|
||||||
inverted: yes
|
inverted: true
|
||||||
|
|
||||||
#:########################################################################################:#
|
#:########################################################################################:#
|
||||||
# BINARY SENSORS
|
# BINARY SENSORS
|
||||||
@@ -155,7 +155,7 @@ binary_sensor:
|
|||||||
pin:
|
pin:
|
||||||
number: GPIO16
|
number: GPIO16
|
||||||
mode: INPUT
|
mode: INPUT
|
||||||
inverted: True
|
inverted: true
|
||||||
use_interrupt: false # GPIO16 pin doesn't support interrupts so use polling. Only suppresses a warning.
|
use_interrupt: false # GPIO16 pin doesn't support interrupts so use polling. Only suppresses a warning.
|
||||||
name: "Button 1: ${switch_1_name}"
|
name: "Button 1: ${switch_1_name}"
|
||||||
on_press:
|
on_press:
|
||||||
@@ -163,9 +163,9 @@ binary_sensor:
|
|||||||
|
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
pin:
|
pin:
|
||||||
number: GPIO05
|
number: GPIO5
|
||||||
mode: INPUT
|
mode: INPUT
|
||||||
inverted: True
|
inverted: true
|
||||||
name: "Button 2: ${switch_2_name}"
|
name: "Button 2: ${switch_2_name}"
|
||||||
on_press:
|
on_press:
|
||||||
- switch.toggle: Relay_2
|
- switch.toggle: Relay_2
|
||||||
|
|||||||
@@ -1,14 +1,19 @@
|
|||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# TITLE: FRONT ENTRANCEWAY LED LIGHT CONTROLS
|
||||||
# FRONT ENTRANCEWAY LED LIGHT CONTROLS
|
# zorruno.com layout v1.1 2026
|
||||||
# File: esp-entranceoutsideledlights.yaml
|
#:########################################################################################:#
|
||||||
#
|
# REPO:
|
||||||
# v1.0 - 2026-02-23 Initial version (converted from Tasmota)
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-entranceoutsideledlights.yaml
|
||||||
#
|
#:########################################################################################:#
|
||||||
# Hardware: H801 (ESP8266EX) 5-channel PWM MOSFET LED controller
|
# VERSIONS:
|
||||||
#
|
# V1.2 2026-03-10 Added per-channel maximum ON timers with auto-dim-to-off, restart-on-ON, and moved defaults into substitutions
|
||||||
###########################################################################################
|
# V1.1 2026-03-10 Updated yaml to zorruno layout V1.1
|
||||||
# NOTES
|
# V1.0 2026-02-23 Initial version (converted from Tasmota)
|
||||||
|
#:########################################################################################:#
|
||||||
|
# HARDWARE:
|
||||||
|
# - H801 (ESP8266EX) 5-channel PWM MOSFET LED controller
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OPERATION NOTES:
|
||||||
# - H801 PWM outputs (typical / ESPHome Devices):
|
# - H801 PWM outputs (typical / ESPHome Devices):
|
||||||
# PWM1 / R -> GPIO15
|
# PWM1 / R -> GPIO15
|
||||||
# PWM2 / G -> GPIO13
|
# PWM2 / G -> GPIO13
|
||||||
@@ -23,43 +28,56 @@
|
|||||||
# * Brightness slider 0-100% normalized to the per-channel hard limit
|
# * Brightness slider 0-100% normalized to the per-channel hard limit
|
||||||
# * Ramp time (seconds) for a full 0 -> hard limit transition
|
# * Ramp time (seconds) for a full 0 -> hard limit transition
|
||||||
# * Hard limit (percent) absolute cap for that channel
|
# * Hard limit (percent) absolute cap for that channel
|
||||||
|
# * Maximum ON time (minutes) after which the channel dims to OFF
|
||||||
|
#
|
||||||
|
# - A fresh ON command restarts the countdown timer for that channel.
|
||||||
|
# - Setting channel brightness above 0 also restarts that channel timer.
|
||||||
#
|
#
|
||||||
# - Underlying PWM light entities are INTERNAL so HA cannot bypass the hard limit.
|
# - Underlying PWM light entities are INTERNAL so HA cannot bypass the hard limit.
|
||||||
#
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# MQTT COMMANDS:
|
||||||
##########################################################################################
|
# - None (no device-specific MQTT commands in this YAML; common_mqtt is included for standardisation)
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OFFLINE NOTES:
|
||||||
|
# a) Home Assistant OFFLINE, but Network and MQTT ONLINE
|
||||||
|
# - Local PWM control continues via HA entities if HA is offline (entities unavailable until HA returns)
|
||||||
|
# - Device continues running with last commanded PWM states
|
||||||
|
# - Any already-running max ON timer continues locally on the device
|
||||||
|
# b) MQTT OFFLINE (but WiFi/Network and HA API ONLINE)
|
||||||
|
# - No impact unless you rely on MQTT for diagnostics; local control via HA/API continues
|
||||||
|
# - Any already-running max ON timer continues locally on the device
|
||||||
|
# c) Entire WiFi/Network OFFLINE
|
||||||
|
# - No HA API and no MQTT connectivity
|
||||||
|
# - Outputs remain in their last driven state (until power loss/reboot)
|
||||||
|
# - Any already-running max ON timer continues locally on the device
|
||||||
|
# - Accurate time is NOT needed (SNTP not required for operation)
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
##########################################################################################
|
|
||||||
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
|
#:########################################################################################:#
|
||||||
|
# SUBSTITUTIONS: Specific device variable substitutions
|
||||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
substitutions:
|
substitutions:
|
||||||
# Device Naming
|
# Device Naming
|
||||||
device_name: "esp-entranceoutsideledlights"
|
device_name: "esp-entranceoutsideledlights"
|
||||||
friendly_name: "Front Entranceway LED Light controls"
|
friendly_name: "Front Entranceway LED Light controls"
|
||||||
description_comment: "H801 ESP8266 5-channel PWM LED controller (Entranceway)"
|
description_comment: "H801 ESP8266 5-channel PWM LED controller (Entranceway) (Layout V1.1)"
|
||||||
device_area: "Entranceway" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
device_area: "Entranceway" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
||||||
|
|
||||||
# Project Naming
|
# Project Naming
|
||||||
project_name: "H801.5CH PWM LED Controller"
|
project_name: "H801.5CH PWM LED Controller"
|
||||||
project_version: "v1.0"
|
project_version: "v1.2"
|
||||||
|
|
||||||
# Passwords & Secrets
|
# Passwords & Secrets
|
||||||
api_key: !secret esp-api_key
|
api_key: !secret esp-api_key
|
||||||
ota_pass: !secret esp-ota_pass
|
ota_pass: !secret esp-ota_pass
|
||||||
static_ip_address: !secret esp-entranceoutsideledlights_ip # unfortunately you can't use substitutions inside secrets names
|
static_ip_address: !secret esp-entranceoutsideledlights_ip # unfortunately you can't use substitutions inside secrets names
|
||||||
#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
|
# 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.
|
# Don't forget to switch it back when changed.
|
||||||
current_ip_address: ${static_ip_address}
|
current_ip_address: ${static_ip_address}
|
||||||
|
|
||||||
# MQTT LOCAL Controls (optional, kept for consistency with your templates)
|
|
||||||
#mqtt_local_device_name: "entranceoutsideledlights"
|
|
||||||
#mqtt_local_command_topic: "${mqtt_command_main_topic}/${mqtt_local_device_name}"
|
|
||||||
#mqtt_local_status_topic: "${mqtt_status_main_topic}/${mqtt_local_device_name}"
|
|
||||||
|
|
||||||
# Device Settings
|
# Device Settings
|
||||||
log_level: "INFO" # NONE, ERROR, WARN, INFO, DEBUG, VERBOSE, VERY_VERBOSE
|
log_level: "INFO" # NONE, ERROR, WARN, INFO, DEBUG, VERBOSE, VERY_VERBOSE
|
||||||
update_interval: "60s"
|
update_interval: "60s"
|
||||||
@@ -68,9 +86,28 @@ substitutions:
|
|||||||
out1_name: "Main Entrance Outside LED Lights"
|
out1_name: "Main Entrance Outside LED Lights"
|
||||||
out2_name: "Number 16 LED Light"
|
out2_name: "Number 16 LED Light"
|
||||||
out3_name: "Spare 3"
|
out3_name: "Spare 3"
|
||||||
out4_name: "Spare 4"
|
out4_name: "Doorbell Illumination"
|
||||||
out5_name: "Spare 5"
|
out5_name: "Spare 5"
|
||||||
|
|
||||||
|
# OUTPUT DEFAULT SETTINGS
|
||||||
|
out1_ramp_default_s: "2.0"
|
||||||
|
out2_ramp_default_s: "2.0"
|
||||||
|
out3_ramp_default_s: "2.0"
|
||||||
|
out4_ramp_default_s: "2.0"
|
||||||
|
out5_ramp_default_s: "2.0"
|
||||||
|
|
||||||
|
out1_max_limit_default_pct: "100"
|
||||||
|
out2_max_limit_default_pct: "100"
|
||||||
|
out3_max_limit_default_pct: "100"
|
||||||
|
out4_max_limit_default_pct: "100"
|
||||||
|
out5_max_limit_default_pct: "100"
|
||||||
|
|
||||||
|
out1_max_on_time_default_mins: "240"
|
||||||
|
out2_max_on_time_default_mins: "240"
|
||||||
|
out3_max_on_time_default_mins: "10"
|
||||||
|
out4_max_on_time_default_mins: "4"
|
||||||
|
out5_max_on_time_default_mins: "10"
|
||||||
|
|
||||||
# H801 PWM PINS (easy swap here if needed)
|
# H801 PWM PINS (easy swap here if needed)
|
||||||
out1_pwm_pin: "GPIO15"
|
out1_pwm_pin: "GPIO15"
|
||||||
out2_pwm_pin: "GPIO13"
|
out2_pwm_pin: "GPIO13"
|
||||||
@@ -79,10 +116,11 @@ substitutions:
|
|||||||
out5_pwm_pin: "GPIO4"
|
out5_pwm_pin: "GPIO4"
|
||||||
pwm_frequency: "1000 Hz"
|
pwm_frequency: "1000 Hz"
|
||||||
|
|
||||||
##########################################################################################
|
|
||||||
|
#:########################################################################################:#
|
||||||
# PACKAGES: Included Common Packages
|
# PACKAGES: Included Common Packages
|
||||||
# https://esphome.io/components/packages.html
|
# https://esphome.io/components/packages.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
packages:
|
packages:
|
||||||
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
||||||
common_wifi: !include
|
common_wifi: !include
|
||||||
@@ -115,38 +153,43 @@ packages:
|
|||||||
diag_debug: !include common/include_debug_diag_sensors.yaml
|
diag_debug: !include common/include_debug_diag_sensors.yaml
|
||||||
#diag_resetcount: !include common/include_resetcount_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
|
|
||||||
min_version: 2025.11.0
|
|
||||||
area: ${device_area}
|
|
||||||
project:
|
|
||||||
name: ${project_name}
|
|
||||||
version: ${project_version}
|
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# ESP Platform and Framework
|
# 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
|
||||||
|
min_version: 2025.11.0
|
||||||
|
area: "${device_area}"
|
||||||
|
project:
|
||||||
|
name: "${project_name}"
|
||||||
|
version: "${project_version}"
|
||||||
|
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# ESP PLATFORM AND FRAMEWORK:
|
||||||
# https://esphome.io/components/esp8266.html
|
# https://esphome.io/components/esp8266.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
esp8266:
|
esp8266:
|
||||||
board: esp01_1m
|
board: esp01_1m
|
||||||
|
|
||||||
#############################################
|
|
||||||
# ESPHome Logging Enable
|
#:########################################################################################:#
|
||||||
|
# LOGGING:
|
||||||
# https://esphome.io/components/logger.html
|
# https://esphome.io/components/logger.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
logger:
|
logger:
|
||||||
level: ${log_level}
|
level: "${log_level}"
|
||||||
baud_rate: 0 # set to 0 for no logging via UART
|
baud_rate: 0 # set to 0 for no logging via UART
|
||||||
|
|
||||||
##########################################################################################
|
|
||||||
# OUTPUTS (H801 PWM MOSFET CHANNELS)
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# OUTPUTS: H801 PWM MOSFET CHANNELS
|
||||||
|
# https://esphome.io/components/output/esp8266_pwm.html
|
||||||
|
#:########################################################################################:#
|
||||||
output:
|
output:
|
||||||
- platform: esp8266_pwm
|
- platform: esp8266_pwm
|
||||||
id: out1_pwm
|
id: out1_pwm
|
||||||
@@ -173,9 +216,11 @@ output:
|
|||||||
pin: ${out5_pwm_pin}
|
pin: ${out5_pwm_pin}
|
||||||
frequency: ${pwm_frequency}
|
frequency: ${pwm_frequency}
|
||||||
|
|
||||||
##########################################################################################
|
|
||||||
# INTERNAL LIGHTS (do not expose to HA; use helper entities below)
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# LIGHTS: Internal raw PWM lights (not exposed to HA)
|
||||||
|
# https://esphome.io/components/light/monochromatic.html
|
||||||
|
#:########################################################################################:#
|
||||||
light:
|
light:
|
||||||
- platform: monochromatic
|
- platform: monochromatic
|
||||||
id: out1_light_raw
|
id: out1_light_raw
|
||||||
@@ -212,9 +257,11 @@ light:
|
|||||||
internal: true
|
internal: true
|
||||||
restore_mode: RESTORE_DEFAULT_OFF
|
restore_mode: RESTORE_DEFAULT_OFF
|
||||||
|
|
||||||
##########################################################################################
|
|
||||||
# GLOBALS (store "last non-zero" brightness per channel)
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# GLOBALS: Store "last non-zero" brightness per channel
|
||||||
|
# https://esphome.io/components/globals.html
|
||||||
|
#:########################################################################################:#
|
||||||
globals:
|
globals:
|
||||||
- id: out1_last_nonzero_pct
|
- id: out1_last_nonzero_pct
|
||||||
type: float
|
type: float
|
||||||
@@ -241,9 +288,11 @@ globals:
|
|||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: "100.0"
|
initial_value: "100.0"
|
||||||
|
|
||||||
##########################################################################################
|
|
||||||
# SCRIPTS (apply normalized brightness + proportional ramping)
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# SCRIPTS: Apply normalized brightness + proportional ramping + per-channel auto-off timers
|
||||||
|
# https://esphome.io/components/script.html
|
||||||
|
#:########################################################################################:#
|
||||||
script:
|
script:
|
||||||
#############################################
|
#############################################
|
||||||
# OUT1
|
# OUT1
|
||||||
@@ -319,6 +368,14 @@ script:
|
|||||||
call.set_transition_length(trans_ms);
|
call.set_transition_length(trans_ms);
|
||||||
call.perform();
|
call.perform();
|
||||||
|
|
||||||
|
- id: out1_auto_off_timer
|
||||||
|
mode: restart
|
||||||
|
parameters:
|
||||||
|
delay_ms: int
|
||||||
|
then:
|
||||||
|
- delay: !lambda "return delay_ms;"
|
||||||
|
- script.execute: out1_turn_off
|
||||||
|
|
||||||
#############################################
|
#############################################
|
||||||
# OUT2
|
# OUT2
|
||||||
#############################################
|
#############################################
|
||||||
@@ -393,6 +450,14 @@ script:
|
|||||||
call.set_transition_length(trans_ms);
|
call.set_transition_length(trans_ms);
|
||||||
call.perform();
|
call.perform();
|
||||||
|
|
||||||
|
- id: out2_auto_off_timer
|
||||||
|
mode: restart
|
||||||
|
parameters:
|
||||||
|
delay_ms: int
|
||||||
|
then:
|
||||||
|
- delay: !lambda "return delay_ms;"
|
||||||
|
- script.execute: out2_turn_off
|
||||||
|
|
||||||
#############################################
|
#############################################
|
||||||
# OUT3
|
# OUT3
|
||||||
#############################################
|
#############################################
|
||||||
@@ -467,6 +532,14 @@ script:
|
|||||||
call.set_transition_length(trans_ms);
|
call.set_transition_length(trans_ms);
|
||||||
call.perform();
|
call.perform();
|
||||||
|
|
||||||
|
- id: out3_auto_off_timer
|
||||||
|
mode: restart
|
||||||
|
parameters:
|
||||||
|
delay_ms: int
|
||||||
|
then:
|
||||||
|
- delay: !lambda "return delay_ms;"
|
||||||
|
- script.execute: out3_turn_off
|
||||||
|
|
||||||
#############################################
|
#############################################
|
||||||
# OUT4
|
# OUT4
|
||||||
#############################################
|
#############################################
|
||||||
@@ -541,6 +614,14 @@ script:
|
|||||||
call.set_transition_length(trans_ms);
|
call.set_transition_length(trans_ms);
|
||||||
call.perform();
|
call.perform();
|
||||||
|
|
||||||
|
- id: out4_auto_off_timer
|
||||||
|
mode: restart
|
||||||
|
parameters:
|
||||||
|
delay_ms: int
|
||||||
|
then:
|
||||||
|
- delay: !lambda "return delay_ms;"
|
||||||
|
- script.execute: out4_turn_off
|
||||||
|
|
||||||
#############################################
|
#############################################
|
||||||
# OUT5
|
# OUT5
|
||||||
#############################################
|
#############################################
|
||||||
@@ -615,9 +696,19 @@ script:
|
|||||||
call.set_transition_length(trans_ms);
|
call.set_transition_length(trans_ms);
|
||||||
call.perform();
|
call.perform();
|
||||||
|
|
||||||
##########################################################################################
|
- id: out5_auto_off_timer
|
||||||
# NUMBERS (brightness normalized to limit, plus per-channel ramp and hard limit)
|
mode: restart
|
||||||
##########################################################################################
|
parameters:
|
||||||
|
delay_ms: int
|
||||||
|
then:
|
||||||
|
- delay: !lambda "return delay_ms;"
|
||||||
|
- script.execute: out5_turn_off
|
||||||
|
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# NUMBER: Brightness normalized to limit, plus per-channel ramp, hard limit, and max ON time
|
||||||
|
# https://esphome.io/components/number/template.html
|
||||||
|
#:########################################################################################:#
|
||||||
number:
|
number:
|
||||||
#############################################
|
#############################################
|
||||||
# OUT1
|
# OUT1
|
||||||
@@ -632,7 +723,7 @@ number:
|
|||||||
max_value: 30.0
|
max_value: 30.0
|
||||||
step: 0.1
|
step: 0.1
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: 2.0
|
initial_value: ${out1_ramp_default_s}
|
||||||
optimistic: true
|
optimistic: true
|
||||||
set_action:
|
set_action:
|
||||||
- script.execute: out1_apply_target
|
- script.execute: out1_apply_target
|
||||||
@@ -647,11 +738,24 @@ number:
|
|||||||
max_value: 100
|
max_value: 100
|
||||||
step: 1
|
step: 1
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: 100
|
initial_value: ${out1_max_limit_default_pct}
|
||||||
optimistic: true
|
optimistic: true
|
||||||
set_action:
|
set_action:
|
||||||
- script.execute: out1_apply_target
|
- script.execute: out1_apply_target
|
||||||
|
|
||||||
|
- platform: template
|
||||||
|
id: out1_auto_off_mins
|
||||||
|
name: "${out1_name} Max ON Time"
|
||||||
|
icon: mdi:timer-lock-outline
|
||||||
|
entity_category: config
|
||||||
|
unit_of_measurement: "min"
|
||||||
|
min_value: 1
|
||||||
|
max_value: 720
|
||||||
|
step: 1
|
||||||
|
restore_value: true
|
||||||
|
initial_value: ${out1_max_on_time_default_mins}
|
||||||
|
optimistic: true
|
||||||
|
|
||||||
- platform: template
|
- platform: template
|
||||||
id: out1_brightness_pct
|
id: out1_brightness_pct
|
||||||
name: "${out1_name} Brightness"
|
name: "${out1_name} Brightness"
|
||||||
@@ -667,6 +771,16 @@ number:
|
|||||||
- lambda: |-
|
- lambda: |-
|
||||||
if (x > 0.0f) id(out1_last_nonzero_pct) = x;
|
if (x > 0.0f) id(out1_last_nonzero_pct) = x;
|
||||||
- script.execute: out1_apply_target
|
- script.execute: out1_apply_target
|
||||||
|
- if:
|
||||||
|
condition:
|
||||||
|
lambda: |-
|
||||||
|
return x > 0.0f;
|
||||||
|
then:
|
||||||
|
- script.execute:
|
||||||
|
id: out1_auto_off_timer
|
||||||
|
delay_ms: !lambda "return (int) (id(out1_auto_off_mins).state * 60000.0f);"
|
||||||
|
else:
|
||||||
|
- script.stop: out1_auto_off_timer
|
||||||
|
|
||||||
#############################################
|
#############################################
|
||||||
# OUT2
|
# OUT2
|
||||||
@@ -681,7 +795,7 @@ number:
|
|||||||
max_value: 30.0
|
max_value: 30.0
|
||||||
step: 0.1
|
step: 0.1
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: 2.0
|
initial_value: ${out2_ramp_default_s}
|
||||||
optimistic: true
|
optimistic: true
|
||||||
set_action:
|
set_action:
|
||||||
- script.execute: out2_apply_target
|
- script.execute: out2_apply_target
|
||||||
@@ -696,11 +810,24 @@ number:
|
|||||||
max_value: 100
|
max_value: 100
|
||||||
step: 1
|
step: 1
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: 100
|
initial_value: ${out2_max_limit_default_pct}
|
||||||
optimistic: true
|
optimistic: true
|
||||||
set_action:
|
set_action:
|
||||||
- script.execute: out2_apply_target
|
- script.execute: out2_apply_target
|
||||||
|
|
||||||
|
- platform: template
|
||||||
|
id: out2_auto_off_mins
|
||||||
|
name: "${out2_name} Max ON Time"
|
||||||
|
icon: mdi:timer-lock-outline
|
||||||
|
entity_category: config
|
||||||
|
unit_of_measurement: "min"
|
||||||
|
min_value: 1
|
||||||
|
max_value: 720
|
||||||
|
step: 1
|
||||||
|
restore_value: true
|
||||||
|
initial_value: ${out2_max_on_time_default_mins}
|
||||||
|
optimistic: true
|
||||||
|
|
||||||
- platform: template
|
- platform: template
|
||||||
id: out2_brightness_pct
|
id: out2_brightness_pct
|
||||||
name: "${out2_name} Brightness"
|
name: "${out2_name} Brightness"
|
||||||
@@ -716,6 +843,16 @@ number:
|
|||||||
- lambda: |-
|
- lambda: |-
|
||||||
if (x > 0.0f) id(out2_last_nonzero_pct) = x;
|
if (x > 0.0f) id(out2_last_nonzero_pct) = x;
|
||||||
- script.execute: out2_apply_target
|
- script.execute: out2_apply_target
|
||||||
|
- if:
|
||||||
|
condition:
|
||||||
|
lambda: |-
|
||||||
|
return x > 0.0f;
|
||||||
|
then:
|
||||||
|
- script.execute:
|
||||||
|
id: out2_auto_off_timer
|
||||||
|
delay_ms: !lambda "return (int) (id(out2_auto_off_mins).state * 60000.0f);"
|
||||||
|
else:
|
||||||
|
- script.stop: out2_auto_off_timer
|
||||||
|
|
||||||
#############################################
|
#############################################
|
||||||
# OUT3
|
# OUT3
|
||||||
@@ -730,7 +867,7 @@ number:
|
|||||||
max_value: 30.0
|
max_value: 30.0
|
||||||
step: 0.1
|
step: 0.1
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: 2.0
|
initial_value: ${out3_ramp_default_s}
|
||||||
optimistic: true
|
optimistic: true
|
||||||
set_action:
|
set_action:
|
||||||
- script.execute: out3_apply_target
|
- script.execute: out3_apply_target
|
||||||
@@ -745,11 +882,24 @@ number:
|
|||||||
max_value: 100
|
max_value: 100
|
||||||
step: 1
|
step: 1
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: 100
|
initial_value: ${out3_max_limit_default_pct}
|
||||||
optimistic: true
|
optimistic: true
|
||||||
set_action:
|
set_action:
|
||||||
- script.execute: out3_apply_target
|
- script.execute: out3_apply_target
|
||||||
|
|
||||||
|
- platform: template
|
||||||
|
id: out3_auto_off_mins
|
||||||
|
name: "${out3_name} Max ON Time"
|
||||||
|
icon: mdi:timer-lock-outline
|
||||||
|
entity_category: config
|
||||||
|
unit_of_measurement: "min"
|
||||||
|
min_value: 1
|
||||||
|
max_value: 720
|
||||||
|
step: 1
|
||||||
|
restore_value: true
|
||||||
|
initial_value: ${out3_max_on_time_default_mins}
|
||||||
|
optimistic: true
|
||||||
|
|
||||||
- platform: template
|
- platform: template
|
||||||
id: out3_brightness_pct
|
id: out3_brightness_pct
|
||||||
name: "${out3_name} Brightness"
|
name: "${out3_name} Brightness"
|
||||||
@@ -765,6 +915,16 @@ number:
|
|||||||
- lambda: |-
|
- lambda: |-
|
||||||
if (x > 0.0f) id(out3_last_nonzero_pct) = x;
|
if (x > 0.0f) id(out3_last_nonzero_pct) = x;
|
||||||
- script.execute: out3_apply_target
|
- script.execute: out3_apply_target
|
||||||
|
- if:
|
||||||
|
condition:
|
||||||
|
lambda: |-
|
||||||
|
return x > 0.0f;
|
||||||
|
then:
|
||||||
|
- script.execute:
|
||||||
|
id: out3_auto_off_timer
|
||||||
|
delay_ms: !lambda "return (int) (id(out3_auto_off_mins).state * 60000.0f);"
|
||||||
|
else:
|
||||||
|
- script.stop: out3_auto_off_timer
|
||||||
|
|
||||||
#############################################
|
#############################################
|
||||||
# OUT4
|
# OUT4
|
||||||
@@ -779,7 +939,7 @@ number:
|
|||||||
max_value: 30.0
|
max_value: 30.0
|
||||||
step: 0.1
|
step: 0.1
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: 2.0
|
initial_value: ${out4_ramp_default_s}
|
||||||
optimistic: true
|
optimistic: true
|
||||||
set_action:
|
set_action:
|
||||||
- script.execute: out4_apply_target
|
- script.execute: out4_apply_target
|
||||||
@@ -794,11 +954,24 @@ number:
|
|||||||
max_value: 100
|
max_value: 100
|
||||||
step: 1
|
step: 1
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: 100
|
initial_value: ${out4_max_limit_default_pct}
|
||||||
optimistic: true
|
optimistic: true
|
||||||
set_action:
|
set_action:
|
||||||
- script.execute: out4_apply_target
|
- script.execute: out4_apply_target
|
||||||
|
|
||||||
|
- platform: template
|
||||||
|
id: out4_auto_off_mins
|
||||||
|
name: "${out4_name} Max ON Time"
|
||||||
|
icon: mdi:timer-lock-outline
|
||||||
|
entity_category: config
|
||||||
|
unit_of_measurement: "min"
|
||||||
|
min_value: 1
|
||||||
|
max_value: 720
|
||||||
|
step: 1
|
||||||
|
restore_value: true
|
||||||
|
initial_value: ${out4_max_on_time_default_mins}
|
||||||
|
optimistic: true
|
||||||
|
|
||||||
- platform: template
|
- platform: template
|
||||||
id: out4_brightness_pct
|
id: out4_brightness_pct
|
||||||
name: "${out4_name} Brightness"
|
name: "${out4_name} Brightness"
|
||||||
@@ -814,6 +987,16 @@ number:
|
|||||||
- lambda: |-
|
- lambda: |-
|
||||||
if (x > 0.0f) id(out4_last_nonzero_pct) = x;
|
if (x > 0.0f) id(out4_last_nonzero_pct) = x;
|
||||||
- script.execute: out4_apply_target
|
- script.execute: out4_apply_target
|
||||||
|
- if:
|
||||||
|
condition:
|
||||||
|
lambda: |-
|
||||||
|
return x > 0.0f;
|
||||||
|
then:
|
||||||
|
- script.execute:
|
||||||
|
id: out4_auto_off_timer
|
||||||
|
delay_ms: !lambda "return (int) (id(out4_auto_off_mins).state * 60000.0f);"
|
||||||
|
else:
|
||||||
|
- script.stop: out4_auto_off_timer
|
||||||
|
|
||||||
#############################################
|
#############################################
|
||||||
# OUT5
|
# OUT5
|
||||||
@@ -828,7 +1011,7 @@ number:
|
|||||||
max_value: 30.0
|
max_value: 30.0
|
||||||
step: 0.1
|
step: 0.1
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: 2.0
|
initial_value: ${out5_ramp_default_s}
|
||||||
optimistic: true
|
optimistic: true
|
||||||
set_action:
|
set_action:
|
||||||
- script.execute: out5_apply_target
|
- script.execute: out5_apply_target
|
||||||
@@ -843,11 +1026,24 @@ number:
|
|||||||
max_value: 100
|
max_value: 100
|
||||||
step: 1
|
step: 1
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: 100
|
initial_value: ${out5_max_limit_default_pct}
|
||||||
optimistic: true
|
optimistic: true
|
||||||
set_action:
|
set_action:
|
||||||
- script.execute: out5_apply_target
|
- script.execute: out5_apply_target
|
||||||
|
|
||||||
|
- platform: template
|
||||||
|
id: out5_auto_off_mins
|
||||||
|
name: "${out5_name} Max ON Time"
|
||||||
|
icon: mdi:timer-lock-outline
|
||||||
|
entity_category: config
|
||||||
|
unit_of_measurement: "min"
|
||||||
|
min_value: 1
|
||||||
|
max_value: 720
|
||||||
|
step: 1
|
||||||
|
restore_value: true
|
||||||
|
initial_value: ${out5_max_on_time_default_mins}
|
||||||
|
optimistic: true
|
||||||
|
|
||||||
- platform: template
|
- platform: template
|
||||||
id: out5_brightness_pct
|
id: out5_brightness_pct
|
||||||
name: "${out5_name} Brightness"
|
name: "${out5_name} Brightness"
|
||||||
@@ -863,14 +1059,26 @@ number:
|
|||||||
- lambda: |-
|
- lambda: |-
|
||||||
if (x > 0.0f) id(out5_last_nonzero_pct) = x;
|
if (x > 0.0f) id(out5_last_nonzero_pct) = x;
|
||||||
- script.execute: out5_apply_target
|
- script.execute: out5_apply_target
|
||||||
|
- if:
|
||||||
|
condition:
|
||||||
|
lambda: |-
|
||||||
|
return x > 0.0f;
|
||||||
|
then:
|
||||||
|
- script.execute:
|
||||||
|
id: out5_auto_off_timer
|
||||||
|
delay_ms: !lambda "return (int) (id(out5_auto_off_mins).state * 60000.0f);"
|
||||||
|
else:
|
||||||
|
- script.stop: out5_auto_off_timer
|
||||||
|
|
||||||
##########################################################################################
|
|
||||||
# SWITCHES (On/Off that respects ramping; brightness slider remains unchanged when off)
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# SWITCH: On/Off that respects ramping; brightness slider remains unchanged when off
|
||||||
|
# https://esphome.io/components/switch/template.html
|
||||||
|
#:########################################################################################:#
|
||||||
switch:
|
switch:
|
||||||
- platform: template
|
- platform: template
|
||||||
id: out1_switch
|
id: out1_switch
|
||||||
name: ${out1_name}
|
name: "${out1_name}"
|
||||||
icon: mdi:lightbulb
|
icon: mdi:lightbulb
|
||||||
lambda: |-
|
lambda: |-
|
||||||
return id(out1_light_raw).current_values.is_on();
|
return id(out1_light_raw).current_values.is_on();
|
||||||
@@ -885,12 +1093,16 @@ switch:
|
|||||||
value: !lambda "return id(out1_last_nonzero_pct);"
|
value: !lambda "return id(out1_last_nonzero_pct);"
|
||||||
else:
|
else:
|
||||||
- script.execute: out1_apply_target
|
- script.execute: out1_apply_target
|
||||||
|
- script.execute:
|
||||||
|
id: out1_auto_off_timer
|
||||||
|
delay_ms: !lambda "return (int) (id(out1_auto_off_mins).state * 60000.0f);"
|
||||||
turn_off_action:
|
turn_off_action:
|
||||||
|
- script.stop: out1_auto_off_timer
|
||||||
- script.execute: out1_turn_off
|
- script.execute: out1_turn_off
|
||||||
|
|
||||||
- platform: template
|
- platform: template
|
||||||
id: out2_switch
|
id: out2_switch
|
||||||
name: ${out2_name}
|
name: "${out2_name}"
|
||||||
icon: mdi:lightbulb
|
icon: mdi:lightbulb
|
||||||
lambda: |-
|
lambda: |-
|
||||||
return id(out2_light_raw).current_values.is_on();
|
return id(out2_light_raw).current_values.is_on();
|
||||||
@@ -905,12 +1117,16 @@ switch:
|
|||||||
value: !lambda "return id(out2_last_nonzero_pct);"
|
value: !lambda "return id(out2_last_nonzero_pct);"
|
||||||
else:
|
else:
|
||||||
- script.execute: out2_apply_target
|
- script.execute: out2_apply_target
|
||||||
|
- script.execute:
|
||||||
|
id: out2_auto_off_timer
|
||||||
|
delay_ms: !lambda "return (int) (id(out2_auto_off_mins).state * 60000.0f);"
|
||||||
turn_off_action:
|
turn_off_action:
|
||||||
|
- script.stop: out2_auto_off_timer
|
||||||
- script.execute: out2_turn_off
|
- script.execute: out2_turn_off
|
||||||
|
|
||||||
- platform: template
|
- platform: template
|
||||||
id: out3_switch
|
id: out3_switch
|
||||||
name: ${out3_name}
|
name: "${out3_name}"
|
||||||
icon: mdi:lightbulb
|
icon: mdi:lightbulb
|
||||||
lambda: |-
|
lambda: |-
|
||||||
return id(out3_light_raw).current_values.is_on();
|
return id(out3_light_raw).current_values.is_on();
|
||||||
@@ -925,12 +1141,16 @@ switch:
|
|||||||
value: !lambda "return id(out3_last_nonzero_pct);"
|
value: !lambda "return id(out3_last_nonzero_pct);"
|
||||||
else:
|
else:
|
||||||
- script.execute: out3_apply_target
|
- script.execute: out3_apply_target
|
||||||
|
- script.execute:
|
||||||
|
id: out3_auto_off_timer
|
||||||
|
delay_ms: !lambda "return (int) (id(out3_auto_off_mins).state * 60000.0f);"
|
||||||
turn_off_action:
|
turn_off_action:
|
||||||
|
- script.stop: out3_auto_off_timer
|
||||||
- script.execute: out3_turn_off
|
- script.execute: out3_turn_off
|
||||||
|
|
||||||
- platform: template
|
- platform: template
|
||||||
id: out4_switch
|
id: out4_switch
|
||||||
name: ${out4_name}
|
name: "${out4_name}"
|
||||||
icon: mdi:lightbulb
|
icon: mdi:lightbulb
|
||||||
lambda: |-
|
lambda: |-
|
||||||
return id(out4_light_raw).current_values.is_on();
|
return id(out4_light_raw).current_values.is_on();
|
||||||
@@ -945,12 +1165,16 @@ switch:
|
|||||||
value: !lambda "return id(out4_last_nonzero_pct);"
|
value: !lambda "return id(out4_last_nonzero_pct);"
|
||||||
else:
|
else:
|
||||||
- script.execute: out4_apply_target
|
- script.execute: out4_apply_target
|
||||||
|
- script.execute:
|
||||||
|
id: out4_auto_off_timer
|
||||||
|
delay_ms: !lambda "return (int) (id(out4_auto_off_mins).state * 60000.0f);"
|
||||||
turn_off_action:
|
turn_off_action:
|
||||||
|
- script.stop: out4_auto_off_timer
|
||||||
- script.execute: out4_turn_off
|
- script.execute: out4_turn_off
|
||||||
|
|
||||||
- platform: template
|
- platform: template
|
||||||
id: out5_switch
|
id: out5_switch
|
||||||
name: ${out5_name}
|
name: "${out5_name}"
|
||||||
icon: mdi:lightbulb
|
icon: mdi:lightbulb
|
||||||
lambda: |-
|
lambda: |-
|
||||||
return id(out5_light_raw).current_values.is_on();
|
return id(out5_light_raw).current_values.is_on();
|
||||||
@@ -965,5 +1189,9 @@ switch:
|
|||||||
value: !lambda "return id(out5_last_nonzero_pct);"
|
value: !lambda "return id(out5_last_nonzero_pct);"
|
||||||
else:
|
else:
|
||||||
- script.execute: out5_apply_target
|
- script.execute: out5_apply_target
|
||||||
|
- script.execute:
|
||||||
|
id: out5_auto_off_timer
|
||||||
|
delay_ms: !lambda "return (int) (id(out5_auto_off_mins).state * 60000.0f);"
|
||||||
turn_off_action:
|
turn_off_action:
|
||||||
|
- script.stop: out5_auto_off_timer
|
||||||
- script.execute: out5_turn_off
|
- script.execute: out5_turn_off
|
||||||
@@ -1,49 +1,66 @@
|
|||||||
#############################################
|
#:########################################################################################:#
|
||||||
#############################################
|
# TITLE: GARAGE ENTRANCE BLUETOOTH PROXY
|
||||||
# ESP32 - Garage
|
# zorruno.com layout v1.1 2026
|
||||||
# Bluetooth Proxy
|
#:########################################################################################:#
|
||||||
#############################################
|
# REPO:
|
||||||
#############################################
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-garagebtproxy.yaml
|
||||||
|
#:########################################################################################:#
|
||||||
|
# VERSIONS:
|
||||||
|
# V1.1 2026-03-11 Updated yaml to zorruno layout V1.1
|
||||||
|
# V1.0 2025-06-14 Initial Version
|
||||||
|
#:########################################################################################:#
|
||||||
|
# HARDWARE:
|
||||||
|
# - ESP32-WROOM (esp32dev)
|
||||||
|
# - Bluetooth Proxy (ESPHome bluetooth_proxy + esp32_ble_tracker)
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OPERATION NOTES:
|
||||||
|
# - Provides Bluetooth Proxy coverage at the garage entrance for Home Assistant
|
||||||
|
# - Uses ESP-IDF framework for BLE stability/performance
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OFFLINE NOTES:
|
||||||
|
# a) Home Assistant OFFLINE, but Network and MQTT ONLINE
|
||||||
|
# - BLE proxy is unavailable to Home Assistant until HA returns
|
||||||
|
# b) MQTT OFFLINE (but WiFi/Network and HA API ONLINE)
|
||||||
|
# - BLE proxy still works via Home Assistant API
|
||||||
|
# c) Entire WiFi/Network OFFLINE
|
||||||
|
# - BLE proxy unavailable until network returns
|
||||||
|
# - Accurate time is not needed (SNTP not required)
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
#############################################
|
|
||||||
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
|
#:########################################################################################:#
|
||||||
|
# SUBSTITUTIONS: Specific device variable substitutions
|
||||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
substitutions:
|
substitutions:
|
||||||
# Device Naming
|
# Device Naming
|
||||||
device_name: "esp-garagebtproxy"
|
device_name: "esp-garagebtproxy"
|
||||||
friendly_name: "Garage Entrance Bluetooth Proxy"
|
friendly_name: "Garage Entrance Bluetooth Proxy"
|
||||||
description_comment: "ESP32-WROOM garage entrance with BT Proxy"
|
description_comment: "ESP32-WROOM garage entrance with BT Proxy (Layout V1.1)"
|
||||||
device_area: "Garage" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
device_area: "Garage" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
||||||
|
|
||||||
# Project Naming
|
# Project Naming
|
||||||
project_name: "Zemismart Technologies.KS-811-3 (Triple)" # Project Details
|
project_name: "ESPHome.Bluetooth Proxy"
|
||||||
project_version: "v1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
project_version: "v1.1"
|
||||||
|
|
||||||
#entity_prefix: "Main Bathroom" # Simple device name where we want to prefix a sensor or switch, eg "Load" Current.
|
# Passwords & Secrets
|
||||||
|
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
||||||
|
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
|
||||||
|
static_ip_address: !secret esp-garagebtproxy_ip # unfortunately you can't use substitutions inside secrets names
|
||||||
|
|
||||||
|
# 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}
|
||||||
|
|
||||||
# Passwords
|
|
||||||
api_key: !secret esp-api_key #unfortunately you can't use substitutions in secrets names
|
|
||||||
ota_pass: !secret esp-ota_pass #unfortunately you can't use substitutions in secrets names
|
|
||||||
static_ip_address: !secret esp-garagebtproxy_ip
|
|
||||||
#mqtt_local_command_main_topic: !secret mqtt_local_command_main_topic
|
|
||||||
#mqtt_local_status_main_topic: !secret mqtt_local_status_main_topic
|
|
||||||
|
|
||||||
# Device Settings
|
# Device Settings
|
||||||
#relay_icon: "mdi:heating-coil"
|
log_level: "INFO" # NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
||||||
log_level: "INFO" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
update_interval: "60s" # update time for general sensors etc
|
||||||
update_interval: "60s" # update time for for general sensors etc
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# SPECIFIC PROJECT VARIABLE SUBSTITUTIONS
|
|
||||||
#############################################
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# PACKAGES: Included Common Packages
|
# PACKAGES: Included Common Packages
|
||||||
# https://esphome.io/components/packages.html
|
# https://esphome.io/components/packages.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
packages:
|
packages:
|
||||||
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
||||||
common_wifi: !include
|
common_wifi: !include
|
||||||
@@ -52,6 +69,7 @@ packages:
|
|||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
local_static_ip_address: "${static_ip_address}"
|
local_static_ip_address: "${static_ip_address}"
|
||||||
local_ota_pass: "${ota_pass}"
|
local_ota_pass: "${ota_pass}"
|
||||||
|
local_current_ip_address: "${current_ip_address}"
|
||||||
|
|
||||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||||
common_api: !include
|
common_api: !include
|
||||||
@@ -65,69 +83,62 @@ packages:
|
|||||||
file: common/mqtt_common.yaml
|
file: common/mqtt_common.yaml
|
||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
|
|
||||||
#### WEB PORTAL ####
|
|
||||||
#common_webportal: !include common/webportal_common.yaml
|
|
||||||
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
||||||
common_sntp: !include common/sntp_common.yaml
|
common_sntp: !include common/sntp_common.yaml
|
||||||
|
|
||||||
#### DIAGNOSTICS Sensors ####
|
#### DIAGNOSTICS Sensors ####
|
||||||
diag_basic: !include common/include_basic_diag_sensors.yaml
|
diag_basic: !include common/include_basic_diag_sensors.yaml
|
||||||
diag_more: !include common/include_more_diag_sensors.yaml
|
diag_more: !include common/include_more_diag_sensors.yaml
|
||||||
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
||||||
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
||||||
|
|
||||||
#############################################
|
|
||||||
# ESPHome
|
#:########################################################################################:#
|
||||||
|
# ESPHOME:
|
||||||
# https://esphome.io/components/esphome.html
|
# https://esphome.io/components/esphome.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
esphome:
|
esphome:
|
||||||
name: ${device_name}
|
name: ${device_name}
|
||||||
friendly_name: ${friendly_name}
|
friendly_name: ${friendly_name}
|
||||||
comment: ${description_comment} #appears on the esphome page in HA
|
comment: ${description_comment} # appears on the esphome page in HA
|
||||||
min_version: 2024.6.0 #
|
|
||||||
area: ${device_area}
|
area: ${device_area}
|
||||||
|
min_version: 2024.6.0
|
||||||
|
project:
|
||||||
|
name: ${project_name}
|
||||||
|
version: ${project_version}
|
||||||
|
|
||||||
#############################################
|
|
||||||
# ESP Platform and Framework
|
#:########################################################################################:#
|
||||||
|
# ESP PLATFORM AND FRAMEWORK:
|
||||||
# https://esphome.io/components/esp32.html
|
# https://esphome.io/components/esp32.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
esp32:
|
esp32:
|
||||||
board: esp32dev
|
board: esp32dev
|
||||||
framework:
|
framework:
|
||||||
#type: arduino
|
#type: arduino
|
||||||
type: esp-idf #Suggested Use ESP-IDF Framework, or Plug Out the UART Cable Might Cause ESP32 Hang.
|
type: esp-idf
|
||||||
version: recommended #recommended, latest or dev
|
version: recommended
|
||||||
advanced:
|
advanced:
|
||||||
minimum_chip_revision: "3.1" # This makes the binary slightly smaller
|
minimum_chip_revision: "3.1"
|
||||||
|
|
||||||
#############################################
|
|
||||||
# ESPHome Logging Enable
|
#:########################################################################################:#
|
||||||
|
# LOGGING:
|
||||||
# https://esphome.io/components/logger.html
|
# https://esphome.io/components/logger.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
logger:
|
logger:
|
||||||
level: ${log_level} #INFO Level suggested, or DEBUG for testing
|
level: ${log_level}
|
||||||
#baud_rate: 0 #set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
|
||||||
#esp8266_store_log_strings_in_flash: false
|
|
||||||
#tx_buffer_size: 64
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Bluetooth
|
#:########################################################################################:#
|
||||||
|
# BLUETOOTH:
|
||||||
# https://esphome.io/components/bluetooth_proxy.html
|
# https://esphome.io/components/bluetooth_proxy.html
|
||||||
# https://esphome.io/components/esp32_ble_tracker.html
|
# https://esphome.io/components/esp32_ble_tracker.html
|
||||||
# Remember that this takes a LOT of processing. On the
|
#:########################################################################################:#
|
||||||
# ESP32, enable the IDF framework, and disable the
|
|
||||||
# Web server component. Changing to the IDF framework
|
|
||||||
# needs to be via cable not OTA to change the
|
|
||||||
# partition setup.
|
|
||||||
#############################################
|
|
||||||
bluetooth_proxy:
|
bluetooth_proxy:
|
||||||
active: true
|
active: true
|
||||||
|
|
||||||
esp32_ble_tracker:
|
esp32_ble_tracker:
|
||||||
scan_parameters:
|
scan_parameters:
|
||||||
# We currently use the defaults to ensure Bluetooth
|
active: true
|
||||||
# can co-exist with WiFi In the future we may be able to
|
|
||||||
# enable the built-in coexistence logic in ESP-IDF
|
|
||||||
active: true
|
|
||||||
|
|
||||||
@@ -1,54 +1,91 @@
|
|||||||
#############################################
|
#:########################################################################################:#
|
||||||
#############################################
|
# TITLE: GARAGE ENTRY LIGHTSWITCH (OBK CONVERTED, BK7231N)
|
||||||
# GARAGE ENTRY LIGHTSWITCH (OBK Converted, BK7231N)
|
# zorruno.com layout v1.1 2026
|
||||||
|
#:########################################################################################:#
|
||||||
|
# REPO:
|
||||||
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-garageentrylights.yaml
|
||||||
|
#:########################################################################################:#
|
||||||
|
# VERSIONS:
|
||||||
|
# V1.1 2026-03-11 Updated yaml to zorruno layout V1.1
|
||||||
# V1.0 2025-11-23 Initial
|
# V1.0 2025-11-23 Initial
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# Zemismart KS-811 Triple push button
|
# HARDWARE:
|
||||||
# pinout/schematic https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
|
# - Zemismart KS-811 Triple push button (OBK converted, BK7231N)
|
||||||
#
|
# - ESPHome bk72xx: generic-bk7231n-qfn32-tuya
|
||||||
# NOTES
|
# - Status LED: P22
|
||||||
# -
|
# - Buttons: P17 (Btn1), P26 (Btn2), P24 (Btn3)
|
||||||
#
|
# - Relays: P14 (Relay1), P16 (Relay2), P15 (Relay3)
|
||||||
#############################################
|
# - Pinout/schematic: https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
|
# OPERATION NOTES:
|
||||||
|
# - 3 button / 3 relay wall switch
|
||||||
|
# - Button 1 toggles Relay 1 (Corridor Lights)
|
||||||
|
# - Button 2 toggles Relay 2 (Patio Lights)
|
||||||
|
# - Button 3 toggles Relay 3 (Garage Lights)
|
||||||
|
# - Default relay restore mode is controlled via substitution: relay_restore_mode
|
||||||
|
# - WiFi package overrides:
|
||||||
|
# - min_auth_mode removed (WPA2-only not supported on bk72xx)
|
||||||
|
# - reboot_timeout overridden to 15min
|
||||||
|
# - fast_connect forced false
|
||||||
|
# - MQTT keepalive overridden to 15s
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OFFLINE NOTES:
|
||||||
|
# a) Home Assistant OFFLINE, but Network and MQTT ONLINE
|
||||||
|
# - Physical buttons still toggle relays locally
|
||||||
|
# - MQTT (from common package) continues if broker is reachable
|
||||||
|
# b) MQTT OFFLINE (but WiFi/Network and HA API ONLINE)
|
||||||
|
# - Physical buttons still toggle relays locally
|
||||||
|
# - HA/API control remains available (switch entities)
|
||||||
|
# - MQTT diagnostics/publishes (common_mqtt) will fail while MQTT is down
|
||||||
|
# c) Entire WiFi/Network OFFLINE
|
||||||
|
# - Physical buttons still toggle relays locally (standalone operation)
|
||||||
|
# - No HA API and no MQTT connectivity until network returns
|
||||||
|
# - Accurate time is not needed (SNTP not required)
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
#############################################
|
|
||||||
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
|
#:########################################################################################:#
|
||||||
|
# SUBSTITUTIONS: Specific device variable substitutions
|
||||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
substitutions:
|
substitutions:
|
||||||
# Device Naming
|
# Device Naming
|
||||||
device_name: "esp-garageentrylights"
|
device_name: "esp-garageentrylights"
|
||||||
friendly_name: "Garage Entry Lightswitch (3)"
|
friendly_name: "Garage Entry Lightswitch (3)"
|
||||||
description_comment: "BK7231N - Garage Entry Lightswitch using a Zemismart KS-811 Triple Push Button. Corridor Light (1), Patio Lights (2), Garage Lights (3)"
|
description_comment: "BK7231N - Garage Entry Lightswitch using a Zemismart KS-811 Triple Push Button. Corridor Light (1), Patio Lights (2), Garage Lights (3) (Layout V1.1)"
|
||||||
device_area: "Garage" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
device_area: "Garage" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
||||||
|
|
||||||
# Project Naming
|
|
||||||
project_name: "Zemismart Technologies.KS-811 Triple BK7231N" # Project Details
|
|
||||||
project_version: "v1.0" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
|
||||||
|
|
||||||
# Passwords
|
# Project Naming
|
||||||
|
project_name: "Zemismart Technologies.KS-811 Triple BK7231N"
|
||||||
|
project_version: "v1.1"
|
||||||
|
|
||||||
|
# Passwords & Secrets
|
||||||
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
||||||
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
|
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
|
||||||
static_ip_address: !secret esp-garageentrylights_ip
|
static_ip_address: !secret esp-garageentrylights_ip
|
||||||
|
|
||||||
|
# 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
|
# Device Settings
|
||||||
log_level: "NONE" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
log_level: "NONE" # NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
||||||
update_interval: "60s" # update time for for general sensors etc
|
update_interval: "60s" # update time for general sensors etc
|
||||||
|
|
||||||
# Default relay restore mode
|
# Default relay restore mode
|
||||||
# Options: RESTORE_DEFAULT_OFF, RESTORE_DEFAULT_ON, ALWAYS_ON, ALWAYS_OFF
|
# Options: RESTORE_DEFAULT_OFF, RESTORE_DEFAULT_ON, ALWAYS_ON, ALWAYS_OFF
|
||||||
relay_restore_mode: "RESTORE_DEFAULT_OFF"
|
relay_restore_mode: "RESTORE_DEFAULT_OFF"
|
||||||
|
|
||||||
# Switch Naming
|
|
||||||
switch_1_name: "Corridor Lights" # Only one light (Garage Side) actually connected to this relay
|
|
||||||
switch_2_name: "Patio Lights" # Output for pario string hanging lights
|
|
||||||
switch_3_name: "Garage Lights" # This is virtual only, no power connected to 3rd relay
|
|
||||||
|
|
||||||
##########################################################################################
|
# Switch Naming
|
||||||
|
switch_1_name: "Corridor Lights" # Only one light (Garage Side) actually connected to this relay
|
||||||
|
switch_2_name: "Patio Lights" # Output for patio string hanging lights
|
||||||
|
switch_3_name: "Garage Lights" # This is virtual only, no power connected to 3rd relay
|
||||||
|
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
# PACKAGES: Included Common Packages
|
# PACKAGES: Included Common Packages
|
||||||
# https://esphome.io/components/packages.html
|
# https://esphome.io/components/packages.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
packages:
|
packages:
|
||||||
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
||||||
common_wifi: !include
|
common_wifi: !include
|
||||||
@@ -57,6 +94,7 @@ packages:
|
|||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
local_static_ip_address: "${static_ip_address}"
|
local_static_ip_address: "${static_ip_address}"
|
||||||
local_ota_pass: "${ota_pass}"
|
local_ota_pass: "${ota_pass}"
|
||||||
|
local_current_ip_address: "${current_ip_address}"
|
||||||
|
|
||||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||||
common_api: !include
|
common_api: !include
|
||||||
@@ -70,86 +108,75 @@ packages:
|
|||||||
file: common/mqtt_common.yaml
|
file: common/mqtt_common.yaml
|
||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
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 ####
|
#### DIAGNOSTICS Sensors ####
|
||||||
diag_basic: !include common/include_basic_diag_sensors.yaml
|
diag_basic: !include common/include_basic_diag_sensors.yaml
|
||||||
#diag_more: !include common/include_more_diag_sensors.yaml
|
#diag_more: !include common/include_more_diag_sensors.yaml
|
||||||
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
||||||
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
||||||
|
|
||||||
# Package item removals
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# PACKAGE OVERRIDES:
|
||||||
|
# These override or remove items from included packages above
|
||||||
|
#:########################################################################################:#
|
||||||
wifi:
|
wifi:
|
||||||
min_auth_mode: !remove # The WPA2 only works on esp32/8266
|
min_auth_mode: !remove # The WPA2-only mode works on esp32/esp8266, not bk72xx
|
||||||
reboot_timeout: 15min # override the selection from from the common package
|
reboot_timeout: 15min # override selection from common package
|
||||||
fast_connect: false # (optional) force off, in case package vars change
|
fast_connect: false # force off, in case package vars change
|
||||||
|
|
||||||
mqtt:
|
mqtt:
|
||||||
keepalive: 15s # overriding the value from the common package
|
keepalive: 15s # override value from common package
|
||||||
|
|
||||||
#############################################
|
|
||||||
# ESPHome
|
#:########################################################################################:#
|
||||||
|
# ESPHOME:
|
||||||
# https://esphome.io/components/esphome.html
|
# https://esphome.io/components/esphome.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
esphome:
|
esphome:
|
||||||
name: "${device_name}"
|
name: "${device_name}"
|
||||||
friendly_name: "${friendly_name}"
|
friendly_name: "${friendly_name}"
|
||||||
comment: "${description_comment}" # Appears on the esphome page in HA
|
comment: "${description_comment}" # Appears on the ESPHome page in HA
|
||||||
area: "${device_area}"
|
area: "${device_area}"
|
||||||
project:
|
project:
|
||||||
name: "${project_name}"
|
name: "${project_name}"
|
||||||
version: "${project_version}"
|
version: "${project_version}"
|
||||||
# on_boot:
|
|
||||||
# priority: 200
|
|
||||||
# then:
|
|
||||||
# - switch.turn_on: Relay_3
|
|
||||||
|
|
||||||
mdns:
|
mdns:
|
||||||
disabled: true
|
disabled: true
|
||||||
|
|
||||||
#############################################
|
|
||||||
# BUILD FOR BK CHIPSET
|
#:########################################################################################:#
|
||||||
# bk72xx
|
# BK72XX:
|
||||||
# https://devices.esphome.io/board/bk72xx/
|
# https://devices.esphome.io/board/bk72xx/
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
bk72xx:
|
bk72xx:
|
||||||
board: generic-bk7231n-qfn32-tuya
|
board: generic-bk7231n-qfn32-tuya
|
||||||
|
|
||||||
#############################################
|
|
||||||
# ESP Platform and Framework
|
|
||||||
# https://esphome.io/components/esp32.html
|
|
||||||
#############################################
|
|
||||||
#esp8266:
|
|
||||||
# board: esp01_1m
|
|
||||||
# early_pin_init: False # Initialise pins early to known values. Recommended false where switches are involved. Defaults to True.
|
|
||||||
# board_flash_mode: dout # Default is dout
|
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# ESPHome Logging Enable
|
# LOGGING:
|
||||||
# https://esphome.io/components/logger.html
|
# https://esphome.io/components/logger.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
logger:
|
logger:
|
||||||
level: "${log_level}" #INFO Level suggested, or DEBUG for testing
|
level: "${log_level}"
|
||||||
#baud_rate: 0 #set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
|
||||||
id: logger_id
|
id: logger_id
|
||||||
|
|
||||||
#############################################
|
|
||||||
# STATUS LED
|
#:########################################################################################:#
|
||||||
|
# STATUS LED:
|
||||||
# https://esphome.io/components/status_led.html
|
# https://esphome.io/components/status_led.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
status_led:
|
status_led:
|
||||||
pin:
|
pin:
|
||||||
number: P22 #GPIO22
|
number: P22
|
||||||
inverted: true
|
inverted: true
|
||||||
|
|
||||||
#############################################
|
|
||||||
# BINARY SENSORS
|
#:########################################################################################:#
|
||||||
|
# BINARY SENSORS:
|
||||||
# https://esphome.io/components/binary_sensor/
|
# https://esphome.io/components/binary_sensor/
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
pin:
|
pin:
|
||||||
@@ -172,8 +199,8 @@ binary_sensor:
|
|||||||
inverted: true
|
inverted: true
|
||||||
name: "Button 2: ${switch_2_name}"
|
name: "Button 2: ${switch_2_name}"
|
||||||
on_press:
|
on_press:
|
||||||
- delay: 50ms
|
- delay: 50ms
|
||||||
- switch.toggle: Relay_2
|
- switch.toggle: Relay_2
|
||||||
|
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
pin:
|
pin:
|
||||||
@@ -184,26 +211,29 @@ binary_sensor:
|
|||||||
inverted: true
|
inverted: true
|
||||||
name: "Button 3: ${switch_3_name}"
|
name: "Button 3: ${switch_3_name}"
|
||||||
on_press:
|
on_press:
|
||||||
- delay: 50ms
|
- delay: 50ms
|
||||||
- switch.toggle: Relay_3
|
- switch.toggle: Relay_3
|
||||||
|
|
||||||
#############################################
|
|
||||||
# SWITCH COMPONENT
|
#:########################################################################################:#
|
||||||
|
# SWITCH COMPONENT:
|
||||||
# https://esphome.io/components/switch/
|
# https://esphome.io/components/switch/
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
switch:
|
switch:
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
name: "Relay 1: ${switch_1_name}"
|
name: "Relay 1: ${switch_1_name}"
|
||||||
pin: P14 #GPIO14
|
pin: P14
|
||||||
id: Relay_1
|
id: Relay_1
|
||||||
restore_mode: ${relay_restore_mode}
|
restore_mode: ${relay_restore_mode}
|
||||||
|
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
name: "Relay 2: ${switch_2_name}"
|
name: "Relay 2: ${switch_2_name}"
|
||||||
pin: P16 #GPIO16
|
pin: P16
|
||||||
id: Relay_2
|
id: Relay_2
|
||||||
restore_mode: ${relay_restore_mode}
|
restore_mode: ${relay_restore_mode}
|
||||||
|
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
name: "Relay 3: ${switch_3_name}"
|
name: "Relay 3: ${switch_3_name}"
|
||||||
pin: P15 #GPIO15
|
pin: P15
|
||||||
id: Relay_3
|
id: Relay_3
|
||||||
restore_mode: ${relay_restore_mode}
|
restore_mode: ${relay_restore_mode}
|
||||||
@@ -1,54 +1,90 @@
|
|||||||
#############################################
|
#:########################################################################################:#
|
||||||
#############################################
|
# TITLE: GARAGE EXTERNAL CORNER LIGHT
|
||||||
# GARAGE LIGHTS
|
# zorruno.com layout v1.1 2026
|
||||||
# Controlled by a Sonoff Basic R1
|
#:########################################################################################:#
|
||||||
#
|
# REPO:
|
||||||
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-garageextcornerlight.yaml
|
||||||
|
#:########################################################################################:#
|
||||||
|
# VERSIONS:
|
||||||
|
# V2.1 2026-03-11 Updated yaml to zorruno layout V1.1
|
||||||
# V2.0 2025-10-22 Latest layout with home MQTT code
|
# V2.0 2025-10-22 Latest layout with home MQTT code
|
||||||
# V1.0 2025-10-22 Initial Version
|
# V1.0 2025-10-22 Initial Version
|
||||||
#
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# HARDWARE:
|
||||||
##########################################################################################
|
# - Sonoff Basic R1 (ESP8266)
|
||||||
|
# - Relay: GPIO12
|
||||||
|
# - Button: GPIO03
|
||||||
|
# - Status LED: GPIO13 (inverted)
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OPERATION NOTES:
|
||||||
|
# - Local button toggles the relay output
|
||||||
|
# - MQTT control:
|
||||||
|
# - Command topic: ${mqtt_command_topic}
|
||||||
|
# Payload: "ON" / "OFF"
|
||||||
|
# - Status topic: ${mqtt_status_topic}
|
||||||
|
# Payload: "ON" / "OFF"
|
||||||
|
# - On MQTT connect, publishes current relay state to the status topic
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OFFLINE NOTES:
|
||||||
|
# a) Home Assistant OFFLINE, but Network and MQTT ONLINE
|
||||||
|
# - Local button still works
|
||||||
|
# - MQTT commands still work
|
||||||
|
# b) MQTT OFFLINE (but WiFi/Network and HA API ONLINE)
|
||||||
|
# - Local button still works
|
||||||
|
# - HA/API control still works
|
||||||
|
# - MQTT commands will not work while broker is down
|
||||||
|
# c) Entire WiFi/Network OFFLINE
|
||||||
|
# - Local button still works
|
||||||
|
# - No HA/API and no MQTT control until network returns
|
||||||
|
# - Accurate time is not needed (SNTP not required)
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
##########################################################################################
|
|
||||||
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
|
#:########################################################################################:#
|
||||||
|
# SUBSTITUTIONS: Specific device variable substitutions
|
||||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
substitutions:
|
substitutions:
|
||||||
# Device Custom Naming
|
# Device Custom Naming
|
||||||
device_name: "esp-garageextcornerlight"
|
device_name: "esp-garageextcornerlight"
|
||||||
friendly_name: "Garage External Corner Light"
|
friendly_name: "Garage External Corner Light"
|
||||||
description_comment: "Garage External Corner Light :: Sonoff Basic"
|
description_comment: "Garage External Corner Light :: Sonoff Basic (Layout V1.1)"
|
||||||
device_area: "Garage" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
device_area: "Garage" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
||||||
static_ip_address: !secret esp-garageextcornerlight_ip
|
static_ip_address: !secret esp-garageextcornerlight_ip
|
||||||
mqtt_device_name: "garage-externalcorner-light"
|
mqtt_device_name: "garage-externalcorner-light"
|
||||||
|
|
||||||
# Project Naming
|
# Project Naming
|
||||||
project_name: "Sonoff Technologies.Sonoff Basic V1" # Project Details
|
project_name: "Sonoff Technologies.Sonoff Basic V1" # Project Details
|
||||||
project_version: "v2.0" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
project_version: "v2.1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
||||||
|
|
||||||
# Passwords
|
# Passwords & Secrets
|
||||||
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
||||||
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
|
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
|
||||||
mqtt_command_main_topic: !secret mqtt_command_main_topic
|
mqtt_command_main_topic: !secret mqtt_command_main_topic
|
||||||
mqtt_status_main_topic: !secret mqtt_status_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
|
# Device Settings
|
||||||
relay_icon: "mdi:lightbulb"
|
relay_icon: "mdi:lightbulb"
|
||||||
log_level: "ERROR" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
log_level: "ERROR" # NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
||||||
update_interval: "60s" # update time for for general sensors etc
|
update_interval: "60s" # update time for for general sensors etc
|
||||||
|
|
||||||
# Device Naming
|
# I/O Naming
|
||||||
relay_1_name: "Garage External Light"
|
relay_1_name: "Garage External Light"
|
||||||
button_1_name: "Power Button"
|
button_1_name: "Power Button"
|
||||||
|
|
||||||
# MQTT Controls
|
# MQTT Controls
|
||||||
mqtt_command_topic: "${mqtt_command_main_topic}/${mqtt_device_name}"
|
mqtt_command_topic: "${mqtt_command_main_topic}/${mqtt_device_name}"
|
||||||
mqtt_status_topic: "${mqtt_status_main_topic}/${mqtt_device_name}"
|
mqtt_status_topic: "${mqtt_status_main_topic}/${mqtt_device_name}"
|
||||||
|
|
||||||
##########################################################################################
|
|
||||||
|
#:########################################################################################:#
|
||||||
# PACKAGES: Included Common Packages
|
# PACKAGES: Included Common Packages
|
||||||
# https://esphome.io/components/packages.html
|
# https://esphome.io/components/packages.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
packages:
|
packages:
|
||||||
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
||||||
common_wifi: !include
|
common_wifi: !include
|
||||||
@@ -57,6 +93,7 @@ packages:
|
|||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
local_static_ip_address: "${static_ip_address}"
|
local_static_ip_address: "${static_ip_address}"
|
||||||
local_ota_pass: "${ota_pass}"
|
local_ota_pass: "${ota_pass}"
|
||||||
|
local_current_ip_address: "${current_ip_address}"
|
||||||
|
|
||||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||||
common_api: !include
|
common_api: !include
|
||||||
@@ -70,80 +107,85 @@ packages:
|
|||||||
file: common/mqtt_common.yaml
|
file: common/mqtt_common.yaml
|
||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
|
|
||||||
#### WEB PORTAL ####
|
#### WEB PORTAL ####
|
||||||
#common_webportal: !include common/webportal_common.yaml
|
#common_webportal: !include common/webportal_common.yaml
|
||||||
|
|
||||||
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
||||||
#common_sntp: !include common/sntp_common.yaml
|
#common_sntp: !include common/sntp_common.yaml
|
||||||
|
|
||||||
#### DIAGNOSTICS Sensors ####
|
#### DIAGNOSTICS Sensors ####
|
||||||
diag_basic: !include common/include_basic_diag_sensors.yaml
|
diag_basic: !include common/include_basic_diag_sensors.yaml
|
||||||
diag_more: !include common/include_more_diag_sensors.yaml
|
diag_more: !include common/include_more_diag_sensors.yaml
|
||||||
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
||||||
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
||||||
|
|
||||||
##########################################################################################
|
|
||||||
# ESPHome
|
#:########################################################################################:#
|
||||||
|
# ESPHOME:
|
||||||
# https://esphome.io/components/esphome.html
|
# https://esphome.io/components/esphome.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
esphome:
|
esphome:
|
||||||
name: "${device_name}"
|
name: "${device_name}"
|
||||||
friendly_name: "${friendly_name}"
|
friendly_name: "${friendly_name}"
|
||||||
comment: "${description_comment}" # Appears on the esphome page in HA
|
comment: "${description_comment}" # Appears on the ESPHome page in HA
|
||||||
area: "${device_area}"
|
area: "${device_area}"
|
||||||
# platformio_options:
|
|
||||||
# build_flags:
|
|
||||||
# - "-Os" # optimize for size
|
|
||||||
# - "-Wl,--gc-sections" # drop unused code/data
|
|
||||||
# - "-fno-exceptions" # strip C++ exceptions
|
|
||||||
# - "-fno-rtti" # strip C++ RTTI
|
|
||||||
|
|
||||||
##########################################################################################
|
|
||||||
# ESP Platform and Framework
|
#:########################################################################################:#
|
||||||
# https://esphome.io/components/esp32.html
|
# ESP PLATFORM AND FRAMEWORK:
|
||||||
##########################################################################################
|
# https://esphome.io/components/esp8266.html
|
||||||
|
#:########################################################################################:#
|
||||||
esp8266:
|
esp8266:
|
||||||
board: esp01_1m # The original sonoff basic
|
board: esp01_1m # The original Sonoff Basic
|
||||||
restore_from_flash: True # restore some values on reboot
|
restore_from_flash: true # restore some values on reboot
|
||||||
|
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# PREFERENCES:
|
||||||
|
# https://esphome.io/components/preferences.html
|
||||||
|
#:########################################################################################:#
|
||||||
preferences:
|
preferences:
|
||||||
flash_write_interval: 5min
|
flash_write_interval: 5min
|
||||||
|
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# MDNS:
|
||||||
|
# https://esphome.io/components/mdns.html
|
||||||
|
#:########################################################################################:#
|
||||||
mdns:
|
mdns:
|
||||||
disabled: False
|
disabled: false
|
||||||
|
|
||||||
##########################################################################################
|
|
||||||
# ESPHome Logging Enable
|
#:########################################################################################:#
|
||||||
|
# LOGGING:
|
||||||
# https://esphome.io/components/logger.html
|
# https://esphome.io/components/logger.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
logger:
|
logger:
|
||||||
level: "${log_level}" #INFO Level suggested, or DEBUG for testing
|
level: "${log_level}"
|
||||||
baud_rate: 0 # set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
baud_rate: 0 # set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
||||||
#esp8266_store_log_strings_in_flash: false
|
|
||||||
#tx_buffer_size: 64
|
|
||||||
|
|
||||||
##########################################################################################
|
|
||||||
# SWITCH COMPONENT
|
#:########################################################################################:#
|
||||||
|
# SWITCH COMPONENT:
|
||||||
# https://esphome.io/components/switch/
|
# https://esphome.io/components/switch/
|
||||||
##########################################################################################
|
# Sonoff Basic R1 relay is GPIO12
|
||||||
# Sonoff Basic R1 Relay Switch is GPIO12
|
#:########################################################################################:#
|
||||||
#############################################
|
|
||||||
switch:
|
switch:
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
name: "${relay_1_name}"
|
name: "${relay_1_name}"
|
||||||
pin: GPIO12
|
pin: GPIO12
|
||||||
id: relay1
|
id: relay1
|
||||||
restore_mode: RESTORE_DEFAULT_OFF
|
restore_mode: RESTORE_DEFAULT_OFF
|
||||||
icon: "${relay_icon}"
|
icon: "${relay_icon}"
|
||||||
|
|
||||||
##########################################################################################
|
|
||||||
# BINARY SENSORS
|
#:########################################################################################:#
|
||||||
|
# BINARY SENSORS:
|
||||||
# https://esphome.io/components/binary_sensor/
|
# https://esphome.io/components/binary_sensor/
|
||||||
##########################################################################################
|
# Sonoff Basic R1 button is GPIO03
|
||||||
# Sonoff Basic R1 Button is GPIO03
|
#:########################################################################################:#
|
||||||
#############################################
|
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
|
|
||||||
# Actual button input
|
# Actual button input
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
pin:
|
pin:
|
||||||
@@ -166,8 +208,8 @@ binary_sensor:
|
|||||||
// Relay is OFF: turn it ON
|
// Relay is OFF: turn it ON
|
||||||
id(relay1).turn_on();
|
id(relay1).turn_on();
|
||||||
}
|
}
|
||||||
|
|
||||||
# Mimics actual relay status
|
# Mimics actual relay status (publishes MQTT state)
|
||||||
- platform: template
|
- platform: template
|
||||||
name: "${relay_1_name} Status"
|
name: "${relay_1_name} Status"
|
||||||
lambda: |-
|
lambda: |-
|
||||||
@@ -175,34 +217,30 @@ binary_sensor:
|
|||||||
on_press:
|
on_press:
|
||||||
- mqtt.publish:
|
- mqtt.publish:
|
||||||
topic: "${mqtt_status_topic}"
|
topic: "${mqtt_status_topic}"
|
||||||
payload: "ON"
|
payload: "ON"
|
||||||
on_release:
|
on_release:
|
||||||
- mqtt.publish:
|
- mqtt.publish:
|
||||||
topic: "${mqtt_status_topic}"
|
topic: "${mqtt_status_topic}"
|
||||||
payload: "OFF"
|
payload: "OFF"
|
||||||
|
|
||||||
##########################################################################################
|
|
||||||
# STATUS LED
|
#:########################################################################################:#
|
||||||
|
# STATUS LED:
|
||||||
# https://esphome.io/components/status_led.html
|
# https://esphome.io/components/status_led.html
|
||||||
##########################################################################################
|
# Sonoff Basic R1 LED is GPIO13
|
||||||
# Sonoff Basic R1 LED is GPIO13
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
|
||||||
status_led:
|
status_led:
|
||||||
pin:
|
pin:
|
||||||
number: GPIO13
|
number: GPIO13
|
||||||
inverted: yes
|
inverted: true
|
||||||
|
|
||||||
##########################################################################################
|
|
||||||
# MQTT COMMANDS
|
#:########################################################################################:#
|
||||||
# This adds device-specific MQTT command triggers to the common MQTT configuration.
|
# MQTT: Device-specific command triggers
|
||||||
# Requires you to define:
|
#:########################################################################################:#
|
||||||
# substitutions:
|
|
||||||
# mqtt_command_topic: "<your/command/topic>"
|
|
||||||
# mqtt_state_topic: "<your/state/topic>"
|
|
||||||
##########################################################################################
|
|
||||||
mqtt:
|
mqtt:
|
||||||
on_message:
|
on_message:
|
||||||
# Relay 1 control (only act and publish if a change is needed)
|
# Relay control (only act and publish if a change is needed)
|
||||||
- topic: "${mqtt_command_topic}"
|
- topic: "${mqtt_command_topic}"
|
||||||
payload: "ON"
|
payload: "ON"
|
||||||
then:
|
then:
|
||||||
@@ -215,7 +253,6 @@ mqtt:
|
|||||||
- mqtt.publish:
|
- mqtt.publish:
|
||||||
topic: "${mqtt_status_topic}"
|
topic: "${mqtt_status_topic}"
|
||||||
payload: "ON"
|
payload: "ON"
|
||||||
#retain: true
|
|
||||||
|
|
||||||
- topic: "${mqtt_command_topic}"
|
- topic: "${mqtt_command_topic}"
|
||||||
payload: "OFF"
|
payload: "OFF"
|
||||||
@@ -229,7 +266,6 @@ mqtt:
|
|||||||
- mqtt.publish:
|
- mqtt.publish:
|
||||||
topic: "${mqtt_status_topic}"
|
topic: "${mqtt_status_topic}"
|
||||||
payload: "OFF"
|
payload: "OFF"
|
||||||
#retain: true
|
|
||||||
|
|
||||||
# Announce current state whenever MQTT (re)connects
|
# Announce current state whenever MQTT (re)connects
|
||||||
on_connect:
|
on_connect:
|
||||||
@@ -237,4 +273,3 @@ mqtt:
|
|||||||
- mqtt.publish:
|
- mqtt.publish:
|
||||||
topic: "${mqtt_status_topic}"
|
topic: "${mqtt_status_topic}"
|
||||||
payload: !lambda 'return id(relay1).state ? "ON" : "OFF";'
|
payload: !lambda 'return id(relay1).state ? "ON" : "OFF";'
|
||||||
#retain: true
|
|
||||||
|
|||||||
@@ -1,39 +1,82 @@
|
|||||||
#############################################
|
#:########################################################################################:#
|
||||||
#############################################
|
# TITLE: LAUNDRY DRYER MACHINE POWER
|
||||||
# LAUNDRY DRYER MACHINE POWER
|
# zorruno.com layout v1.1 2026
|
||||||
|
#:########################################################################################:#
|
||||||
|
# REPO:
|
||||||
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-laundrydrypow.yaml
|
||||||
|
#:########################################################################################:#
|
||||||
|
# VERSIONS:
|
||||||
|
# V1.1 2026-03-11 Updated yaml to zorruno layout V1.1
|
||||||
# V1.0 2025-05-28 Initial Version
|
# V1.0 2025-05-28 Initial Version
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# Sonoff POW R1
|
# HARDWARE:
|
||||||
# https://devices.esphome.io/devices/Sonoff-POW-R1
|
# - Sonoff POW R1
|
||||||
|
# - ESP8266 based
|
||||||
|
# - HLW8012 power monitoring
|
||||||
|
# - Single relay output
|
||||||
|
# - Blue status LED on GPIO15
|
||||||
|
# - Local push button on GPIO0
|
||||||
|
# - Relay output on GPIO12
|
||||||
|
# - Reference: https://devices.esphome.io/devices/Sonoff-POW-R1
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OPERATION NOTES:
|
||||||
|
# - Monitors dryer load current, voltage, and power
|
||||||
|
# - Provides a virtual relay switch that controls the physical relay and LED together
|
||||||
|
# - Local button toggles the virtual relay switch
|
||||||
|
# - On boot, the virtual relay is turned ON
|
||||||
|
# - "Load Running" turns ON when measured power is above 4 W
|
||||||
|
# - "Load Running" uses delayed_off: 15s to avoid rapid state changes
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OFFLINE NOTES:
|
||||||
|
# a) Home Assistant offline (network and MQTT online):
|
||||||
|
# - Device continues running normally
|
||||||
|
# - Local button still works
|
||||||
|
# - MQTT remains available if your common MQTT package is enabled and broker is reachable
|
||||||
#
|
#
|
||||||
# NOTES
|
# b) MQTT offline (or HA/MQTT offline):
|
||||||
# -
|
# - Device continues running locally
|
||||||
|
# - Local button, relay control, LED control, and power monitoring still work
|
||||||
#
|
#
|
||||||
#############################################
|
# c) Entire WiFi/Network offline:
|
||||||
#############################################
|
# - Device continues running locally
|
||||||
|
# - Local button, relay control, LED control, and power monitoring still work
|
||||||
|
# - Accurate time is not needed; SNTP is not required for operation
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
|
# SUBSTITUTIONS:
|
||||||
|
# Specific device variable substitutions
|
||||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
substitutions:
|
substitutions:
|
||||||
device_name: "esp-laundrydrypow" # Reference name for the device in the system.
|
# Device Naming
|
||||||
project_name: "Sonoff Technologies.POW R1" # Project Details
|
device_name: "esp-laundrydrypow"
|
||||||
project_version: "v1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
|
||||||
entity_prefix: "Load" # Simple device name where we want to prefix a sensor or switch, eg "Load" Current.
|
|
||||||
friendly_name: "Laundry Dryer Power"
|
friendly_name: "Laundry Dryer Power"
|
||||||
description_comment: "Laundry Dryer Power using a Sonoff Pow R1."
|
description_comment: "Laundry Dryer Power using a Sonoff Pow R1. (Layout V1.1)"
|
||||||
device_area: "Laundry" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
device_area: "Laundry"
|
||||||
api_key: !secret esp-laundrydrypow_api_key # unfortunately you can't use substitutions inside secrets names
|
|
||||||
ota_pass: !secret esp-laundrydrypow_ota_pass # unfortunately you can't use substitutions inside secrets names
|
|
||||||
static_ip_address: !secret esp-laundrydrypow_ip
|
|
||||||
log_level: "INFO" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
|
||||||
update_interval: "60s" # update time for for general sensors etc
|
|
||||||
|
|
||||||
##########################################################################################
|
# Project Naming
|
||||||
# PACKAGES: Included Common Packages
|
project_name: "Sonoff Technologies.POW R1"
|
||||||
|
project_version: "v1.1"
|
||||||
|
|
||||||
|
# Entity Naming
|
||||||
|
entity_prefix: "Load"
|
||||||
|
|
||||||
|
# Passwords and Secrets
|
||||||
|
api_key: !secret esp-laundrydrypow_api_key
|
||||||
|
ota_pass: !secret esp-laundrydrypow_ota_pass
|
||||||
|
static_ip_address: !secret esp-laundrydrypow_ip
|
||||||
|
current_ip_address: ${static_ip_address}
|
||||||
|
|
||||||
|
# Device Settings
|
||||||
|
log_level: "INFO"
|
||||||
|
update_interval: "60s"
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# PACKAGES:
|
||||||
|
# Included common packages
|
||||||
# https://esphome.io/components/packages.html
|
# https://esphome.io/components/packages.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
packages:
|
packages:
|
||||||
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
||||||
common_wifi: !include
|
common_wifi: !include
|
||||||
@@ -41,12 +84,13 @@ packages:
|
|||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
local_static_ip_address: "${static_ip_address}"
|
local_static_ip_address: "${static_ip_address}"
|
||||||
|
local_current_ip_address: "${current_ip_address}"
|
||||||
local_ota_pass: "${ota_pass}"
|
local_ota_pass: "${ota_pass}"
|
||||||
|
|
||||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||||
common_api: !include
|
common_api: !include
|
||||||
file: common/api_common.yaml
|
file: common/api_common.yaml
|
||||||
#file: common/api_common_noencryption.yaml
|
# file: common/api_common_noencryption.yaml
|
||||||
vars:
|
vars:
|
||||||
local_api_key: "${api_key}"
|
local_api_key: "${api_key}"
|
||||||
|
|
||||||
@@ -55,137 +99,154 @@ packages:
|
|||||||
file: common/mqtt_common.yaml
|
file: common/mqtt_common.yaml
|
||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
|
|
||||||
#### WEB PORTAL ####
|
#### WEB PORTAL ####
|
||||||
#common_webportal: !include common/webportal_common.yaml
|
# common_webportal: !include common/webportal_common.yaml
|
||||||
|
|
||||||
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
||||||
#common_sntp: !include common/sntp_common.yaml
|
# common_sntp: !include common/sntp_common.yaml
|
||||||
|
|
||||||
#### DIAGNOSTICS Sensors ####
|
#### DIAGNOSTICS Sensors ####
|
||||||
diag_basic: !include common/include_basic_diag_sensors.yaml
|
diag_basic: !include common/include_basic_diag_sensors.yaml
|
||||||
diag_more: !include common/include_more_diag_sensors.yaml
|
diag_more: !include common/include_more_diag_sensors.yaml
|
||||||
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
# diag_debug: !include common/include_debug_diag_sensors.yaml
|
||||||
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
# diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# ESPHome
|
# ESPHOME:
|
||||||
# https://esphome.io/components/esphome.html
|
# https://esphome.io/components/esphome.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
esphome:
|
esphome:
|
||||||
name: "${device_name}"
|
name: "${device_name}"
|
||||||
friendly_name: "${friendly_name}"
|
friendly_name: "${friendly_name}"
|
||||||
comment: "${description_comment}" # Appears on the esphome page in HA
|
comment: "${description_comment}"
|
||||||
area: "${device_area}"
|
area: "${device_area}"
|
||||||
project:
|
project:
|
||||||
name: "${project_name}"
|
name: "${project_name}"
|
||||||
version: "${project_version}"
|
version: "${project_version}"
|
||||||
on_boot:
|
on_boot:
|
||||||
priority: 200
|
priority: 200
|
||||||
then:
|
then:
|
||||||
- switch.turn_on: "virtual_button"
|
- switch.turn_on: virtual_button
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# ESP Platform and Framework
|
# ESP PLATFORM AND FRAMEWORK:
|
||||||
# https://esphome.io/components/esp32.html
|
# https://esphome.io/components/esp8266.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
esp8266:
|
esp8266:
|
||||||
board: esp01_1m
|
board: esp01_1m
|
||||||
early_pin_init: False # Initialise pins early to known values. Recommended false where switches are involved. Defaults to True.
|
early_pin_init: false
|
||||||
board_flash_mode: dout # Default is dout
|
board_flash_mode: dout
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# ESPHome Logging Enable
|
# LOGGER:
|
||||||
# https://esphome.io/components/logger.html
|
# https://esphome.io/components/logger.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
logger:
|
logger:
|
||||||
level: ${log_level} #INFO Level suggested, or DEBUG for testing
|
level: "${log_level}"
|
||||||
#baud_rate: 0 #set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
# baud_rate: 0
|
||||||
#esp8266_store_log_strings_in_flash: false
|
# esp8266_store_log_strings_in_flash: false
|
||||||
#tx_buffer_size: 64
|
# tx_buffer_size: 64
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# STATUS LED
|
# STATUS LED:
|
||||||
# https://esphome.io/components/status_led.html
|
# https://esphome.io/components/status_led.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
#status_led:
|
# status_led:
|
||||||
# pin:
|
# pin:
|
||||||
# number: GPIO2
|
# number: GPIO2
|
||||||
# inverted: yes
|
# inverted: true
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# SENSORS
|
# BINARY SENSORS:
|
||||||
# https://esphome.io/components/binary_sensor/
|
# https://esphome.io/components/binary_sensor/
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
pin:
|
pin:
|
||||||
number: GPIO0
|
number: GPIO0
|
||||||
mode: INPUT_PULLUP
|
mode: INPUT_PULLUP
|
||||||
inverted: True
|
inverted: true
|
||||||
name: Button
|
name: "Button"
|
||||||
on_press:
|
on_press:
|
||||||
- switch.toggle: virtual_button
|
- switch.toggle: virtual_button
|
||||||
|
|
||||||
- platform: template
|
- platform: template
|
||||||
name: ${entity_prefix} Running
|
name: "${entity_prefix} Running"
|
||||||
filters:
|
filters:
|
||||||
- delayed_off: 15s
|
- delayed_off: 15s
|
||||||
lambda: |-
|
lambda: |-
|
||||||
if (isnan(id(power).state)) {
|
if (isnan(id(power).state)) {
|
||||||
return {};
|
return {};
|
||||||
} else if (id(power).state > 4) {
|
} else if (id(power).state > 4) {
|
||||||
// Running
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// Not running
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# SENSORS:
|
||||||
|
# https://esphome.io/components/sensor/
|
||||||
|
#:########################################################################################:#
|
||||||
sensor:
|
sensor:
|
||||||
- platform: hlw8012
|
- platform: hlw8012
|
||||||
sel_pin: 5
|
sel_pin: GPIO5
|
||||||
cf_pin: 14
|
cf_pin: GPIO14
|
||||||
cf1_pin: 13
|
cf1_pin: GPIO13
|
||||||
update_interval: 2s
|
update_interval: 2s
|
||||||
current:
|
current:
|
||||||
name: ${entity_prefix} Current
|
name: "${entity_prefix} Current"
|
||||||
voltage:
|
voltage:
|
||||||
name: ${entity_prefix} Voltage
|
name: "${entity_prefix} Voltage"
|
||||||
power:
|
power:
|
||||||
name: ${entity_prefix} Power
|
name: "${entity_prefix} Power"
|
||||||
id: power
|
id: power
|
||||||
#on_value_range:
|
# on_value_range:
|
||||||
# - above: 4.0
|
# - above: 4.0
|
||||||
# then:
|
# then:
|
||||||
# - light.turn_on: led
|
# - light.turn_on: led
|
||||||
# - below: 3.0
|
# - below: 3.0
|
||||||
# then:
|
# then:
|
||||||
# - light.turn_off: led
|
# - light.turn_off: led
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# SWITCH:
|
||||||
|
# https://esphome.io/components/switch/
|
||||||
|
#:########################################################################################:#
|
||||||
switch:
|
switch:
|
||||||
- platform: template
|
- platform: template
|
||||||
name: "Relay"
|
name: "Relay"
|
||||||
optimistic: true
|
|
||||||
id: virtual_button
|
id: virtual_button
|
||||||
|
optimistic: true
|
||||||
turn_on_action:
|
turn_on_action:
|
||||||
- switch.turn_on: relay
|
- switch.turn_on: relay
|
||||||
- light.turn_on: led
|
- light.turn_on: led
|
||||||
turn_off_action:
|
turn_off_action:
|
||||||
- switch.turn_off: relay
|
- switch.turn_off: relay
|
||||||
- light.turn_off: led
|
- light.turn_off: led
|
||||||
|
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
id: relay
|
id: relay
|
||||||
pin: GPIO12
|
pin: GPIO12
|
||||||
#restore_mode: ALWAYS_ON # Or RESTORE_DEFAULT_ON/RESTORE_DEFAULT_OFF
|
# restore_mode: ALWAYS_ON
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OUTPUT:
|
||||||
|
# https://esphome.io/components/output/
|
||||||
|
#:########################################################################################:#
|
||||||
output:
|
output:
|
||||||
- platform: esp8266_pwm
|
- platform: esp8266_pwm
|
||||||
id: pow_blue_led
|
id: pow_blue_led
|
||||||
pin:
|
pin:
|
||||||
number: GPIO15
|
number: GPIO15
|
||||||
inverted: True
|
inverted: true
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# LIGHT:
|
||||||
|
# https://esphome.io/components/light/
|
||||||
|
#:########################################################################################:#
|
||||||
light:
|
light:
|
||||||
- platform: monochromatic
|
- platform: monochromatic
|
||||||
name: Status LED
|
name: "Status LED"
|
||||||
output: pow_blue_led
|
output: pow_blue_led
|
||||||
id: led
|
id: led
|
||||||
@@ -1,39 +1,78 @@
|
|||||||
#############################################
|
#:########################################################################################:#
|
||||||
#############################################
|
# TITLE: LAUNDRY ENVIRONMENT - SONOFF DEV
|
||||||
# LAUNDRY ENVIRONMENT - SONOFF DEV
|
# zorruno.com layout v1.1 2026
|
||||||
|
#:########################################################################################:#
|
||||||
|
# REPO:
|
||||||
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-laundryenv.yaml
|
||||||
|
#:########################################################################################:#
|
||||||
|
# VERSIONS:
|
||||||
|
# V1.1 2026-03-11 Updated yaml to zorruno layout V1.1
|
||||||
# V1.0 2025-03-28 Initial Version
|
# V1.0 2025-03-28 Initial Version
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# Sonoff Dev
|
# HARDWARE:
|
||||||
# https://wiki.iteadstudio.com/Sonoff_DEV
|
# - Sonoff DEV
|
||||||
|
# - ESP8266 based
|
||||||
|
# - DHT temperature and humidity sensor on GPIO14
|
||||||
|
# - PIR input on GPIO13
|
||||||
|
# - Smoke detector input on GPIO5
|
||||||
|
# - Reference: https://wiki.iteadstudio.com/Sonoff_DEV
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OPERATION NOTES:
|
||||||
|
# - Provides laundry temperature and humidity monitoring
|
||||||
|
# - Provides a PIR motion binary sensor
|
||||||
|
# - Provides a smoke detector binary sensor
|
||||||
|
# - Designed as a simple environmental and safety monitoring node
|
||||||
|
# - No relay or timed control logic is used in this yaml
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OFFLINE NOTES:
|
||||||
|
# a) Home Assistant offline (network and MQTT online):
|
||||||
|
# - Device continues to read and publish local sensor states
|
||||||
|
# - PIR, smoke, temperature, and humidity sensing continue locally
|
||||||
#
|
#
|
||||||
# NOTES
|
# b) MQTT offline (or HA/MQTT offline):
|
||||||
# -
|
# - Device continues sampling sensors locally
|
||||||
|
# - No MQTT-based status publishing will be available
|
||||||
#
|
#
|
||||||
#############################################
|
# c) Entire WiFi/Network offline:
|
||||||
#############################################
|
# - Device continues sampling sensors locally
|
||||||
|
# - No HA or MQTT connectivity will be available
|
||||||
|
# - Accurate time is not needed; SNTP is not required for operation
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
|
# SUBSTITUTIONS:
|
||||||
|
# Specific device variable substitutions
|
||||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
substitutions:
|
substitutions:
|
||||||
device_name: "esp-laundryenv" # Reference name for the device in the system.
|
# Device Naming
|
||||||
project_name: "Sonoff Technologies.Sonoff DEV" # Project Details
|
device_name: "esp-laundryenv"
|
||||||
project_version: "v1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
|
||||||
entity_prefix: "Laundry" # Simple device name where we want to prefix a sensor or switch, eg "Load" Current.
|
|
||||||
friendly_name: "Laundry Environment"
|
friendly_name: "Laundry Environment"
|
||||||
description_comment: "Laundry Environment Sensor, PIR and Smoke Detector using Sonoff DEV"
|
description_comment: "Laundry Environment Sensor, PIR and Smoke Detector using Sonoff DEV (Layout V1.1)"
|
||||||
device_area: "Laundry" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
device_area: "Laundry"
|
||||||
api_key: !secret esp-laundryenv_api_key # unfortunately you can't use substitutions inside secrets names
|
|
||||||
ota_pass: !secret esp-laundryenv_ota_pass # unfortunately you can't use substitutions inside secrets names
|
|
||||||
static_ip_address: !secret esp-laundryenv_ip
|
|
||||||
log_level: "INFO" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
|
||||||
update_interval: "60s" # update time for for general sensors etc
|
|
||||||
|
|
||||||
##########################################################################################
|
# Project Naming
|
||||||
# PACKAGES: Included Common Packages
|
project_name: "Sonoff Technologies.Sonoff DEV"
|
||||||
|
project_version: "v1.1"
|
||||||
|
|
||||||
|
# Entity Naming
|
||||||
|
entity_prefix: "Laundry"
|
||||||
|
|
||||||
|
# Passwords and Secrets
|
||||||
|
api_key: !secret esp-laundryenv_api_key
|
||||||
|
ota_pass: !secret esp-laundryenv_ota_pass
|
||||||
|
static_ip_address: !secret esp-laundryenv_ip
|
||||||
|
current_ip_address: ${static_ip_address}
|
||||||
|
|
||||||
|
# Device Settings
|
||||||
|
log_level: "INFO"
|
||||||
|
update_interval: "60s"
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# PACKAGES:
|
||||||
|
# Included Common Packages
|
||||||
# https://esphome.io/components/packages.html
|
# https://esphome.io/components/packages.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
packages:
|
packages:
|
||||||
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
||||||
common_wifi: !include
|
common_wifi: !include
|
||||||
@@ -41,6 +80,7 @@ packages:
|
|||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
local_static_ip_address: "${static_ip_address}"
|
local_static_ip_address: "${static_ip_address}"
|
||||||
|
local_current_ip_address: "${current_ip_address}"
|
||||||
local_ota_pass: "${ota_pass}"
|
local_ota_pass: "${ota_pass}"
|
||||||
|
|
||||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||||
@@ -55,63 +95,68 @@ packages:
|
|||||||
file: common/mqtt_common.yaml
|
file: common/mqtt_common.yaml
|
||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
|
|
||||||
#### WEB PORTAL ####
|
#### WEB PORTAL ####
|
||||||
#common_webportal: !include common/webportal_common.yaml
|
#common_webportal: !include common/webportal_common.yaml
|
||||||
|
|
||||||
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
||||||
#common_sntp: !include common/sntp_common.yaml
|
#common_sntp: !include common/sntp_common.yaml
|
||||||
|
|
||||||
#### DIAGNOSTICS Sensors ####
|
#### DIAGNOSTICS Sensors ####
|
||||||
diag_basic: !include common/include_basic_diag_sensors.yaml
|
diag_basic: !include common/include_basic_diag_sensors.yaml
|
||||||
diag_more: !include common/include_more_diag_sensors.yaml
|
diag_more: !include common/include_more_diag_sensors.yaml
|
||||||
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
||||||
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# ESPHome
|
# ESPHOME:
|
||||||
# https://esphome.io/components/esphome.html
|
# https://esphome.io/components/esphome.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
esphome:
|
esphome:
|
||||||
name: "${device_name}"
|
name: "${device_name}"
|
||||||
friendly_name: "${friendly_name}"
|
friendly_name: "${friendly_name}"
|
||||||
comment: "${description_comment}" # Appears on the esphome page in HA
|
comment: "${description_comment}"
|
||||||
area: "${device_area}"
|
area: "${device_area}"
|
||||||
project:
|
project:
|
||||||
name: "${project_name}"
|
name: "${project_name}"
|
||||||
version: "${project_version}"
|
version: "${project_version}"
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# ESP Platform and Framework
|
# ESP PLATFORM AND FRAMEWORK:
|
||||||
# https://esphome.io/components/esp32.html
|
# https://esphome.io/components/esp8266.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
esp8266:
|
esp8266:
|
||||||
board: esp01_1m
|
board: esp01_1m
|
||||||
early_pin_init: False # Initialise pins early to known values. Recommended false where switches are involved. Defaults to True.
|
early_pin_init: false
|
||||||
board_flash_mode: dout # Default is dout
|
board_flash_mode: dout
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# ESPHome Logging Enable
|
# LOGGER:
|
||||||
# https://esphome.io/components/logger.html
|
# https://esphome.io/components/logger.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
logger:
|
logger:
|
||||||
level: ${log_level} #INFO Level suggested, or DEBUG for testing
|
level: "${log_level}"
|
||||||
#baud_rate: 0 #set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
#baud_rate: 0
|
||||||
#esp8266_store_log_strings_in_flash: false
|
#esp8266_store_log_strings_in_flash: false
|
||||||
#tx_buffer_size: 64
|
#tx_buffer_size: 64
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# SENSORS
|
# SENSORS:
|
||||||
# https://esphome.io/components/binary_sensor/
|
# https://esphome.io/components/sensor/
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
sensor:
|
sensor:
|
||||||
- platform: dht
|
- platform: dht
|
||||||
pin: GPIO14
|
pin: GPIO14
|
||||||
temperature:
|
temperature:
|
||||||
name: ${entity_prefix} Temperature
|
name: "${entity_prefix} Temperature"
|
||||||
humidity:
|
humidity:
|
||||||
name: ${entity_prefix} Humidity
|
name: "${entity_prefix} Humidity"
|
||||||
update_interval: ${update_interval}
|
update_interval: "${update_interval}"
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# BINARY SENSORS:
|
||||||
|
# https://esphome.io/components/binary_sensor/
|
||||||
|
#:########################################################################################:#
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
pin:
|
pin:
|
||||||
@@ -119,19 +164,16 @@ binary_sensor:
|
|||||||
mode:
|
mode:
|
||||||
input: true
|
input: true
|
||||||
pullup: false
|
pullup: false
|
||||||
name: ${entity_prefix} PIR
|
name: "${entity_prefix} PIR"
|
||||||
device_class: motion
|
device_class: motion
|
||||||
#filters:
|
#filters:
|
||||||
# - invert:
|
# - invert:
|
||||||
|
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
pin:
|
pin:
|
||||||
number: GPIO05
|
number: GPIO5
|
||||||
mode:
|
mode:
|
||||||
input: true
|
input: true
|
||||||
pullup: true
|
pullup: true
|
||||||
inverted: True
|
inverted: true
|
||||||
name: ${entity_prefix} Smoke Detector
|
name: "${entity_prefix} Smoke Detector"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,39 +1,90 @@
|
|||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# TITLE: LAUNDRY MAIN LIGHTSWITCH
|
||||||
# LAUNDRY MAIN LIGHTSWITCH
|
# zorruno.com layout v1.1 2026
|
||||||
|
#:########################################################################################:#
|
||||||
|
# REPO:
|
||||||
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-laundrylights.yaml
|
||||||
|
#:########################################################################################:#
|
||||||
|
# VERSIONS:
|
||||||
|
# V3.6 2026-03-11 Updated yaml to zorruno layout V1.1
|
||||||
# V3.5 2025-07-24 YAML tidyups
|
# V3.5 2025-07-24 YAML tidyups
|
||||||
# V3.0 2025-06-05 YAML tidyups
|
# V3.0 2025-06-05 YAML tidyups
|
||||||
# V2.0 2025-06-01 Was initially a 3 button switch, now 2
|
# V2.0 2025-06-01 Was initially a 3 button switch, now 2
|
||||||
# V1.0 2025-05-30 Initial Version
|
# V1.0 2025-05-30 Initial Version
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# Zemismart KS-811 Double push button
|
# HARDWARE:
|
||||||
# pinout/schematic https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
|
# - Zemismart KS-811 Double push button
|
||||||
|
# - ESP8266 based
|
||||||
|
# - pinout/schematic:
|
||||||
|
# https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
|
||||||
|
# - Relay 1 output on GPIO13
|
||||||
|
# - Relay 2 output on GPIO12
|
||||||
|
# - Button 1 input on GPIO16
|
||||||
|
# - Button 2 input on GPIO5
|
||||||
|
# - Status LED on GPIO2
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OPERATION NOTES:
|
||||||
|
# - Button 1 toggles Relay 1 for the laundry lights
|
||||||
|
# - Button 2 supports two actions:
|
||||||
|
# - Single click toggles Relay 2 locally
|
||||||
|
# - Hold for 2 seconds or more sends MQTT ON/OFF to the remote device
|
||||||
|
# - Relay 2 is turned ON at boot
|
||||||
|
# - Remote MQTT status is subscribed to and normalised to ON/OFF/TRUE/FALSE/1/0
|
||||||
|
# - If the remote state is unknown, a hold on Button 2 defaults to sending ON
|
||||||
|
# - This switch is used for:
|
||||||
|
# - Laundry Lights (1)
|
||||||
|
# - Laundry Power Enable (2)
|
||||||
|
#:########################################################################################:#
|
||||||
|
# MQTT COMMANDS:
|
||||||
|
# - Remote device command topic:
|
||||||
|
# - ${mqtt_remote1_command_topic}
|
||||||
|
# - Remote device status topic:
|
||||||
|
# - ${mqtt_remote1_status_topic}
|
||||||
|
# - Hold Button 2:
|
||||||
|
# - Sends OFF if remote state is known and currently ON
|
||||||
|
# - Sends ON otherwise
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OFFLINE NOTES:
|
||||||
|
# a) Home Assistant offline (network and MQTT online):
|
||||||
|
# - Local buttons and local relays continue to work
|
||||||
|
# - Remote MQTT control/status for Button 2 hold still works if the MQTT broker is online
|
||||||
#
|
#
|
||||||
# NOTES
|
# b) MQTT offline (or HA/MQTT offline):
|
||||||
# -
|
# - Local buttons and local relays continue to work
|
||||||
|
# - Button 2 single click still toggles Relay 2 locally
|
||||||
|
# - Button 2 hold cannot control the remote MQTT device
|
||||||
#
|
#
|
||||||
##########################################################################################
|
# c) Entire WiFi/Network offline:
|
||||||
##########################################################################################
|
# - Local buttons and local relays continue to work
|
||||||
|
# - Remote MQTT control/status is unavailable
|
||||||
|
# - Accurate time is not needed; SNTP is not required for operation
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
|
# SUBSTITUTIONS:
|
||||||
|
# Specific device variable substitutions
|
||||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
substitutions:
|
substitutions:
|
||||||
# Device Naming
|
# Device Naming
|
||||||
device_name: "esp-laundrylights"
|
device_name: "esp-laundrylights"
|
||||||
friendly_name: "Laundry Main Lightswitch (2)"
|
friendly_name: "Laundry Main Lightswitch (2)"
|
||||||
description_comment: "Laundry Main Lightswitch using a Zemismart KS-811 Double Push Button. Laundry Lights (1), Laundry Power Signal (2)"
|
description_comment: "Laundry Main Lightswitch using a Zemismart KS-811 Double Push Button. Laundry Lights (1), Laundry Power Signal (2) (Layout V1.1)"
|
||||||
device_area: "Laundry" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
device_area: "Laundry" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
||||||
|
|
||||||
# Project Naming
|
# Project Naming
|
||||||
project_name: "Zemismart Technologies.KS-811 Double" # Project Details
|
project_name: "Zemismart Technologies.KS-811 Double" # Project Details
|
||||||
project_version: "v3.0" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
project_version: "v3.6" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
||||||
|
|
||||||
# Passwords & Secrets
|
# Passwords & Secrets
|
||||||
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
||||||
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
|
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
|
||||||
static_ip_address: !secret esp-laundrylights_ip
|
static_ip_address: !secret esp-laundrylights_ip
|
||||||
|
|
||||||
|
# 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}
|
||||||
|
|
||||||
mqtt_command_main_topic: !secret mqtt_command_main_topic
|
mqtt_command_main_topic: !secret mqtt_command_main_topic
|
||||||
mqtt_status_main_topic: !secret mqtt_status_main_topic
|
mqtt_status_main_topic: !secret mqtt_status_main_topic
|
||||||
|
|
||||||
@@ -49,14 +100,15 @@ substitutions:
|
|||||||
|
|
||||||
# Switch Naming
|
# Switch Naming
|
||||||
switch_1_name: "Laundry Lights"
|
switch_1_name: "Laundry Lights"
|
||||||
switch_2_name: "Laundry Power Enable" # This is virtual only, no power connected to 3rd relay
|
switch_2_name: "Laundry Power Enable" # This is virtual only, no power connected to 3rd relay
|
||||||
#switch_3_name: "Fan 3 Relay"
|
#switch_3_name: "Fan 3 Relay"
|
||||||
#switch_4_name: "Fan 4 Relay"
|
#switch_4_name: "Fan 4 Relay"
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# PACKAGES: Included Common Packages
|
# PACKAGES:
|
||||||
|
# Included Common Packages
|
||||||
# https://esphome.io/components/packages.html
|
# https://esphome.io/components/packages.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
packages:
|
packages:
|
||||||
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
||||||
common_wifi: !include
|
common_wifi: !include
|
||||||
@@ -64,6 +116,7 @@ packages:
|
|||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
local_static_ip_address: "${static_ip_address}"
|
local_static_ip_address: "${static_ip_address}"
|
||||||
|
local_current_ip_address: "${current_ip_address}"
|
||||||
local_ota_pass: "${ota_pass}"
|
local_ota_pass: "${ota_pass}"
|
||||||
|
|
||||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||||
@@ -78,22 +131,23 @@ packages:
|
|||||||
file: common/mqtt_common.yaml
|
file: common/mqtt_common.yaml
|
||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
|
|
||||||
#### WEB PORTAL ####
|
#### WEB PORTAL ####
|
||||||
#common_webportal: !include common/webportal_common.yaml
|
#common_webportal: !include common/webportal_common.yaml
|
||||||
|
|
||||||
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
||||||
#common_sntp: !include common/sntp_common.yaml
|
#common_sntp: !include common/sntp_common.yaml
|
||||||
|
|
||||||
#### DIAGNOSTICS Sensors ####
|
#### DIAGNOSTICS Sensors ####
|
||||||
diag_basic: !include common/include_basic_diag_sensors.yaml
|
diag_basic: !include common/include_basic_diag_sensors.yaml
|
||||||
diag_more: !include common/include_more_diag_sensors.yaml
|
diag_more: !include common/include_more_diag_sensors.yaml
|
||||||
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
||||||
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# ESPHome
|
# ESPHOME:
|
||||||
# https://esphome.io/components/esphome.html
|
# https://esphome.io/components/esphome.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
esphome:
|
esphome:
|
||||||
name: "${device_name}"
|
name: "${device_name}"
|
||||||
friendly_name: "${friendly_name}"
|
friendly_name: "${friendly_name}"
|
||||||
@@ -102,70 +156,70 @@ esphome:
|
|||||||
project:
|
project:
|
||||||
name: "${project_name}"
|
name: "${project_name}"
|
||||||
version: "${project_version}"
|
version: "${project_version}"
|
||||||
on_boot:
|
on_boot:
|
||||||
priority: 200
|
priority: 200
|
||||||
then:
|
then:
|
||||||
- switch.turn_on: Relay_2
|
- switch.turn_on: Relay_2
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# ESP Platform and Framework
|
# ESP PLATFORM AND FRAMEWORK:
|
||||||
# https://esphome.io/components/esp32.html
|
# https://esphome.io/components/esp8266.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
esp8266:
|
esp8266:
|
||||||
board: esp01_1m
|
board: esp01_1m
|
||||||
early_pin_init: False # Initialise pins early to known values. Recommended false where switches are involved. Defaults to True.
|
early_pin_init: false # Initialise pins early to known values. Recommended false where switches are involved. Defaults to True.
|
||||||
board_flash_mode: dout # Default is dout
|
board_flash_mode: dout # Default is dout
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# ESPHome Logging Enable
|
# LOGGER:
|
||||||
# https://esphome.io/components/logger.html
|
# https://esphome.io/components/logger.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
logger:
|
logger:
|
||||||
level: "${log_level}" #INFO Level suggested, or DEBUG for testing
|
level: "${log_level}" #INFO Level suggested, or DEBUG for testing
|
||||||
#baud_rate: 0 #set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
#baud_rate: 0 #set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
||||||
#esp8266_store_log_strings_in_flash: false
|
#esp8266_store_log_strings_in_flash: false
|
||||||
#tx_buffer_size: 64
|
#tx_buffer_size: 64
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# STATUS LED
|
# STATUS LED:
|
||||||
# https://esphome.io/components/status_led.html
|
# https://esphome.io/components/status_led.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
status_led:
|
status_led:
|
||||||
pin:
|
pin:
|
||||||
number: GPIO2
|
number: GPIO2
|
||||||
inverted: yes
|
inverted: true
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# GLOBAL VARIABLES
|
# GLOBAL VARIABLES:
|
||||||
#
|
#:########################################################################################:#
|
||||||
#########################################################################################
|
|
||||||
globals:
|
globals:
|
||||||
- id: remote1_state
|
- id: remote1_state
|
||||||
type: bool
|
type: bool
|
||||||
restore_value: no
|
restore_value: false
|
||||||
initial_value: 'false'
|
initial_value: "false"
|
||||||
|
|
||||||
- id: remote1_known
|
- id: remote1_known
|
||||||
type: bool
|
type: bool
|
||||||
restore_value: no
|
restore_value: false
|
||||||
initial_value: 'false'
|
initial_value: "false"
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# BINARY SENSORS
|
# BINARY SENSORS:
|
||||||
# https://esphome.io/components/binary_sensor/
|
# https://esphome.io/components/binary_sensor/
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
pin:
|
pin:
|
||||||
number: GPIO16
|
number: GPIO16
|
||||||
mode: INPUT
|
mode: INPUT
|
||||||
inverted: True
|
inverted: true
|
||||||
name: "Button 1: ${switch_1_name}"
|
name: "Button 1: ${switch_1_name}"
|
||||||
on_press:
|
on_press:
|
||||||
- switch.toggle: Relay_1
|
- switch.toggle: Relay_1
|
||||||
|
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
pin:
|
pin:
|
||||||
number: GPIO05
|
number: GPIO5
|
||||||
mode: INPUT
|
mode: INPUT
|
||||||
inverted: true
|
inverted: true
|
||||||
name: "Button 2: ${switch_2_name}"
|
name: "Button 2: ${switch_2_name}"
|
||||||
@@ -177,18 +231,21 @@ binary_sensor:
|
|||||||
then:
|
then:
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
lambda: 'return id(Relay_2).state;'
|
lambda: |-
|
||||||
|
return id(Relay_2).state;
|
||||||
then:
|
then:
|
||||||
- switch.turn_off: Relay_2
|
- switch.turn_off: Relay_2
|
||||||
else:
|
else:
|
||||||
- switch.turn_on: Relay_2
|
- switch.turn_on: Relay_2
|
||||||
|
|
||||||
# HOLD: pressed for 2s or more -> toggle remote; default to ON if unknown
|
# HOLD: pressed for 2s or more -> toggle remote; default to ON if unknown
|
||||||
- timing:
|
- timing:
|
||||||
- ON for at least 2s
|
- ON for at least 2s
|
||||||
then:
|
then:
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
lambda: 'return id(remote1_known) && id(remote1_state);' # known AND currently ON
|
lambda: |-
|
||||||
|
return id(remote1_known) && id(remote1_state); // known AND currently ON
|
||||||
then:
|
then:
|
||||||
- mqtt.publish:
|
- mqtt.publish:
|
||||||
topic: "${mqtt_remote1_command_topic}"
|
topic: "${mqtt_remote1_command_topic}"
|
||||||
@@ -200,10 +257,9 @@ binary_sensor:
|
|||||||
payload: "ON"
|
payload: "ON"
|
||||||
retain: false
|
retain: false
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# TEXT SENSORS
|
# TEXT SENSORS:
|
||||||
#
|
#:########################################################################################:#
|
||||||
#########################################################################################
|
|
||||||
text_sensor:
|
text_sensor:
|
||||||
- platform: mqtt_subscribe
|
- platform: mqtt_subscribe
|
||||||
id: remote1_status
|
id: remote1_status
|
||||||
@@ -214,11 +270,13 @@ text_sensor:
|
|||||||
- lambda: |-
|
- lambda: |-
|
||||||
// copy, trim whitespace, uppercase
|
// copy, trim whitespace, uppercase
|
||||||
std::string s = x;
|
std::string s = x;
|
||||||
|
|
||||||
// trim leading/trailing whitespace
|
// trim leading/trailing whitespace
|
||||||
auto notspace = [](int ch){ return !std::isspace(ch); };
|
auto notspace = [](int ch) { return !std::isspace(ch); };
|
||||||
s.erase(s.begin(), std::find_if(s.begin(), s.end(), notspace));
|
s.erase(s.begin(), std::find_if(s.begin(), s.end(), notspace));
|
||||||
s.erase(std::find_if(s.rbegin(), s.rend(), notspace).base(), s.end());
|
s.erase(std::find_if(s.rbegin(), s.rend(), notspace).base(), s.end());
|
||||||
for (auto &c : s) c = (char)toupper(c);
|
|
||||||
|
for (auto &c : s) c = (char) toupper(c);
|
||||||
|
|
||||||
bool recognized = false;
|
bool recognized = false;
|
||||||
if (s == "ON" || s == "1" || s == "TRUE") {
|
if (s == "ON" || s == "1" || s == "TRUE") {
|
||||||
@@ -233,15 +291,16 @@ text_sensor:
|
|||||||
// unknown payload (e.g. "ONLINE", "OFFLINE", JSON, etc.)
|
// unknown payload (e.g. "ONLINE", "OFFLINE", JSON, etc.)
|
||||||
id(remote1_known) = false;
|
id(remote1_known) = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGI("remote1_status", "Parsed status='%s' -> known=%s state=%s",
|
ESP_LOGI("remote1_status", "Parsed status='%s' -> known=%s state=%s",
|
||||||
s.c_str(),
|
s.c_str(),
|
||||||
id(remote1_known) ? "true" : "false",
|
id(remote1_known) ? "true" : "false",
|
||||||
id(remote1_state) ? "ON" : "OFF");
|
id(remote1_state) ? "ON" : "OFF");
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# SWITCH COMPONENT
|
# SWITCH COMPONENT:
|
||||||
# https://esphome.io/components/switch/
|
# https://esphome.io/components/switch/
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
switch:
|
switch:
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
name: "Relay 1: ${switch_1_name}"
|
name: "Relay 1: ${switch_1_name}"
|
||||||
@@ -251,7 +310,4 @@ switch:
|
|||||||
- platform: gpio
|
- platform: gpio
|
||||||
name: "Relay 2: ${switch_2_name}"
|
name: "Relay 2: ${switch_2_name}"
|
||||||
pin: GPIO12
|
pin: GPIO12
|
||||||
id: Relay_2
|
id: Relay_2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,39 +1,82 @@
|
|||||||
#############################################
|
#:########################################################################################:#
|
||||||
#############################################
|
# TITLE: LAUNDRY BENCH PLUGS POWER AND SWITCH
|
||||||
# LAUNDRY BENCH PLUGS POWER AND SWITCH
|
# zorruno.com layout v1.1 2026
|
||||||
|
#:########################################################################################:#
|
||||||
|
# REPO:
|
||||||
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-laundryplugpow.yaml
|
||||||
|
#:########################################################################################:#
|
||||||
|
# VERSIONS:
|
||||||
|
# V1.1 2026-03-11 Updated yaml to zorruno layout V1.1
|
||||||
# V1.0 2025-03-28 Initial Version
|
# V1.0 2025-03-28 Initial Version
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# Sonoff POW R1
|
# HARDWARE:
|
||||||
# https://devices.esphome.io/devices/Sonoff-POW-R1
|
# - Sonoff POW R1
|
||||||
|
# - ESP8266 based
|
||||||
|
# - HLW8012 power monitoring
|
||||||
|
# - Single relay output
|
||||||
|
# - Blue status LED on GPIO15
|
||||||
|
# - Local push button on GPIO0
|
||||||
|
# - Relay output on GPIO12
|
||||||
|
# - Reference: https://devices.esphome.io/devices/Sonoff-POW-R1
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OPERATION NOTES:
|
||||||
|
# - Monitors plug load current, voltage, and power
|
||||||
|
# - Provides a virtual relay switch that controls the physical relay and LED together
|
||||||
|
# - Local button toggles the virtual relay switch
|
||||||
|
# - On boot, the virtual relay is turned ON
|
||||||
|
# - "Load Running" turns ON when measured power is above 4 W
|
||||||
|
# - "Load Running" uses delayed_off: 15s to avoid rapid state changes
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OFFLINE NOTES:
|
||||||
|
# a) Home Assistant offline (network and MQTT online):
|
||||||
|
# - Device continues running normally
|
||||||
|
# - Local button still works
|
||||||
|
# - MQTT remains available if your common MQTT package is enabled and broker is reachable
|
||||||
#
|
#
|
||||||
# NOTES
|
# b) MQTT offline (or HA/MQTT offline):
|
||||||
# -
|
# - Device continues running locally
|
||||||
|
# - Local button, relay control, LED control, and power monitoring still work
|
||||||
#
|
#
|
||||||
#############################################
|
# c) Entire WiFi/Network offline:
|
||||||
#############################################
|
# - Device continues running locally
|
||||||
|
# - Local button, relay control, LED control, and power monitoring still work
|
||||||
|
# - Accurate time is not needed; SNTP is not required for operation
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
|
# SUBSTITUTIONS:
|
||||||
|
# Specific device variable substitutions
|
||||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
substitutions:
|
substitutions:
|
||||||
device_name: "esp-laundryplugpow" # Reference name for the device in the system.
|
# Device Naming
|
||||||
project_name: "Sonoff Technologies.POW R1" # Project Details
|
device_name: "esp-laundryplugpow"
|
||||||
project_version: "v1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
|
||||||
entity_prefix: "Load" # Simple device name where we want to prefix a sensor or switch, eg "Load" Current.
|
|
||||||
friendly_name: "Laundry Bench Plug Power"
|
friendly_name: "Laundry Bench Plug Power"
|
||||||
description_comment: "Laundry Bench Plug Power and switch override using a Sonoff Pow R1."
|
description_comment: "Laundry Bench Plug Power and switch override using a Sonoff Pow R1. (Layout V1.1)"
|
||||||
device_area: "Laundry" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
device_area: "Laundry"
|
||||||
api_key: !secret esp-laundryplugpow_api_key # unfortunately you can't use substitutions inside secrets names
|
|
||||||
ota_pass: !secret esp-laundryplugpow_ota_pass # unfortunately you can't use substitutions inside secrets names
|
|
||||||
static_ip_address: !secret esp-laundryplugpow_ip
|
|
||||||
log_level: "INFO" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
|
||||||
update_interval: "60s" # update time for for general sensors etc
|
|
||||||
|
|
||||||
##########################################################################################
|
# Project Naming
|
||||||
# PACKAGES: Included Common Packages
|
project_name: "Sonoff Technologies.POW R1"
|
||||||
|
project_version: "v1.1"
|
||||||
|
|
||||||
|
# Entity Naming
|
||||||
|
entity_prefix: "Load"
|
||||||
|
|
||||||
|
# Passwords and Secrets
|
||||||
|
api_key: !secret esp-laundryplugpow_api_key
|
||||||
|
ota_pass: !secret esp-laundryplugpow_ota_pass
|
||||||
|
static_ip_address: !secret esp-laundryplugpow_ip
|
||||||
|
current_ip_address: ${static_ip_address}
|
||||||
|
|
||||||
|
# Device Settings
|
||||||
|
log_level: "INFO"
|
||||||
|
update_interval: "60s"
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# PACKAGES:
|
||||||
|
# Included common packages
|
||||||
# https://esphome.io/components/packages.html
|
# https://esphome.io/components/packages.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
packages:
|
packages:
|
||||||
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
||||||
common_wifi: !include
|
common_wifi: !include
|
||||||
@@ -41,12 +84,13 @@ packages:
|
|||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
local_static_ip_address: "${static_ip_address}"
|
local_static_ip_address: "${static_ip_address}"
|
||||||
|
local_current_ip_address: "${current_ip_address}"
|
||||||
local_ota_pass: "${ota_pass}"
|
local_ota_pass: "${ota_pass}"
|
||||||
|
|
||||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||||
common_api: !include
|
common_api: !include
|
||||||
file: common/api_common.yaml
|
file: common/api_common.yaml
|
||||||
#file: common/api_common_noencryption.yaml
|
# file: common/api_common_noencryption.yaml
|
||||||
vars:
|
vars:
|
||||||
local_api_key: "${api_key}"
|
local_api_key: "${api_key}"
|
||||||
|
|
||||||
@@ -55,137 +99,154 @@ packages:
|
|||||||
file: common/mqtt_common.yaml
|
file: common/mqtt_common.yaml
|
||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
|
|
||||||
#### WEB PORTAL ####
|
#### WEB PORTAL ####
|
||||||
#common_webportal: !include common/webportal_common.yaml
|
# common_webportal: !include common/webportal_common.yaml
|
||||||
|
|
||||||
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
||||||
#common_sntp: !include common/sntp_common.yaml
|
# common_sntp: !include common/sntp_common.yaml
|
||||||
|
|
||||||
#### DIAGNOSTICS Sensors ####
|
#### DIAGNOSTICS Sensors ####
|
||||||
diag_basic: !include common/include_basic_diag_sensors.yaml
|
diag_basic: !include common/include_basic_diag_sensors.yaml
|
||||||
diag_more: !include common/include_more_diag_sensors.yaml
|
diag_more: !include common/include_more_diag_sensors.yaml
|
||||||
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
# diag_debug: !include common/include_debug_diag_sensors.yaml
|
||||||
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
# diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# ESPHome
|
# ESPHOME:
|
||||||
# https://esphome.io/components/esphome.html
|
# https://esphome.io/components/esphome.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
esphome:
|
esphome:
|
||||||
name: "${device_name}"
|
name: "${device_name}"
|
||||||
friendly_name: "${friendly_name}"
|
friendly_name: "${friendly_name}"
|
||||||
comment: "${description_comment}" # Appears on the esphome page in HA
|
comment: "${description_comment}"
|
||||||
area: "${device_area}"
|
area: "${device_area}"
|
||||||
project:
|
project:
|
||||||
name: "${project_name}"
|
name: "${project_name}"
|
||||||
version: "${project_version}"
|
version: "${project_version}"
|
||||||
on_boot:
|
on_boot:
|
||||||
priority: 200
|
priority: 200
|
||||||
then:
|
then:
|
||||||
- switch.turn_on: "virtual_button"
|
- switch.turn_on: virtual_button
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# ESP Platform and Framework
|
# ESP PLATFORM AND FRAMEWORK:
|
||||||
# https://esphome.io/components/esp32.html
|
# https://esphome.io/components/esp8266.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
esp8266:
|
esp8266:
|
||||||
board: esp01_1m
|
board: esp01_1m
|
||||||
early_pin_init: False # Initialise pins early to known values. Recommended false where switches are involved. Defaults to True.
|
early_pin_init: false
|
||||||
board_flash_mode: dout # Default is dout
|
board_flash_mode: dout
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# ESPHome Logging Enable
|
# LOGGER:
|
||||||
# https://esphome.io/components/logger.html
|
# https://esphome.io/components/logger.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
logger:
|
logger:
|
||||||
level: ${log_level} #INFO Level suggested, or DEBUG for testing
|
level: "${log_level}"
|
||||||
#baud_rate: 0 #set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
# baud_rate: 0
|
||||||
#esp8266_store_log_strings_in_flash: false
|
# esp8266_store_log_strings_in_flash: false
|
||||||
#tx_buffer_size: 64
|
# tx_buffer_size: 64
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# STATUS LED
|
# STATUS LED:
|
||||||
# https://esphome.io/components/status_led.html
|
# https://esphome.io/components/status_led.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
#status_led:
|
# status_led:
|
||||||
# pin:
|
# pin:
|
||||||
# number: GPIO2
|
# number: GPIO2
|
||||||
# inverted: yes
|
# inverted: true
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# SENSORS
|
# BINARY SENSORS:
|
||||||
# https://esphome.io/components/binary_sensor/
|
# https://esphome.io/components/binary_sensor/
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
pin:
|
pin:
|
||||||
number: GPIO0
|
number: GPIO0
|
||||||
mode: INPUT_PULLUP
|
mode: INPUT_PULLUP
|
||||||
inverted: True
|
inverted: true
|
||||||
name: Button
|
name: "Button"
|
||||||
on_press:
|
on_press:
|
||||||
- switch.toggle: virtual_button
|
- switch.toggle: virtual_button
|
||||||
|
|
||||||
- platform: template
|
- platform: template
|
||||||
name: ${entity_prefix} Running
|
name: "${entity_prefix} Running"
|
||||||
filters:
|
filters:
|
||||||
- delayed_off: 15s
|
- delayed_off: 15s
|
||||||
lambda: |-
|
lambda: |-
|
||||||
if (isnan(id(power).state)) {
|
if (isnan(id(power).state)) {
|
||||||
return {};
|
return {};
|
||||||
} else if (id(power).state > 4) {
|
} else if (id(power).state > 4) {
|
||||||
// Running
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// Not running
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# SENSORS:
|
||||||
|
# https://esphome.io/components/sensor/
|
||||||
|
#:########################################################################################:#
|
||||||
sensor:
|
sensor:
|
||||||
- platform: hlw8012
|
- platform: hlw8012
|
||||||
sel_pin: 5
|
sel_pin: GPIO5
|
||||||
cf_pin: 14
|
cf_pin: GPIO14
|
||||||
cf1_pin: 13
|
cf1_pin: GPIO13
|
||||||
update_interval: 2s
|
update_interval: 2s
|
||||||
current:
|
current:
|
||||||
name: ${entity_prefix} Current
|
name: "${entity_prefix} Current"
|
||||||
voltage:
|
voltage:
|
||||||
name: ${entity_prefix} Voltage
|
name: "${entity_prefix} Voltage"
|
||||||
power:
|
power:
|
||||||
name: ${entity_prefix} Power
|
name: "${entity_prefix} Power"
|
||||||
id: power
|
id: power
|
||||||
#on_value_range:
|
# on_value_range:
|
||||||
# - above: 4.0
|
# - above: 4.0
|
||||||
# then:
|
# then:
|
||||||
# - light.turn_on: led
|
# - light.turn_on: led
|
||||||
# - below: 3.0
|
# - below: 3.0
|
||||||
# then:
|
# then:
|
||||||
# - light.turn_off: led
|
# - light.turn_off: led
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# SWITCH:
|
||||||
|
# https://esphome.io/components/switch/
|
||||||
|
#:########################################################################################:#
|
||||||
switch:
|
switch:
|
||||||
- platform: template
|
- platform: template
|
||||||
name: "Relay"
|
name: "Relay"
|
||||||
optimistic: true
|
|
||||||
id: virtual_button
|
id: virtual_button
|
||||||
|
optimistic: true
|
||||||
turn_on_action:
|
turn_on_action:
|
||||||
- switch.turn_on: relay
|
- switch.turn_on: relay
|
||||||
- light.turn_on: led
|
- light.turn_on: led
|
||||||
turn_off_action:
|
turn_off_action:
|
||||||
- switch.turn_off: relay
|
- switch.turn_off: relay
|
||||||
- light.turn_off: led
|
- light.turn_off: led
|
||||||
|
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
id: relay
|
id: relay
|
||||||
pin: GPIO12
|
pin: GPIO12
|
||||||
#restore_mode: ALWAYS_ON # Or RESTORE_DEFAULT_ON/RESTORE_DEFAULT_OFF
|
# restore_mode: ALWAYS_ON
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OUTPUT:
|
||||||
|
# https://esphome.io/components/output/
|
||||||
|
#:########################################################################################:#
|
||||||
output:
|
output:
|
||||||
- platform: esp8266_pwm
|
- platform: esp8266_pwm
|
||||||
id: pow_blue_led
|
id: pow_blue_led
|
||||||
pin:
|
pin:
|
||||||
number: GPIO15
|
number: GPIO15
|
||||||
inverted: True
|
inverted: true
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# LIGHT:
|
||||||
|
# https://esphome.io/components/light/
|
||||||
|
#:########################################################################################:#
|
||||||
light:
|
light:
|
||||||
- platform: monochromatic
|
- platform: monochromatic
|
||||||
name: Status LED
|
name: "Status LED"
|
||||||
output: pow_blue_led
|
output: pow_blue_led
|
||||||
id: led
|
id: led
|
||||||
@@ -1,39 +1,82 @@
|
|||||||
#############################################
|
#:########################################################################################:#
|
||||||
#############################################
|
# TITLE: LAUNDRY WASHING MACHINE POWER
|
||||||
# LAUNDRY WASHING MACHINE POWER
|
# zorruno.com layout v1.1 2026
|
||||||
|
#:########################################################################################:#
|
||||||
|
# REPO:
|
||||||
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-laundrywashpow.yaml
|
||||||
|
#:########################################################################################:#
|
||||||
|
# VERSIONS:
|
||||||
|
# V1.1 2026-03-11 Updated yaml to zorruno layout V1.1
|
||||||
# V1.0 2025-03-28 Initial Version
|
# V1.0 2025-03-28 Initial Version
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# Sonoff POW R1
|
# HARDWARE:
|
||||||
# https://devices.esphome.io/devices/Sonoff-POW-R1
|
# - Sonoff POW R1
|
||||||
|
# - ESP8266 based
|
||||||
|
# - HLW8012 power monitoring
|
||||||
|
# - Single relay output
|
||||||
|
# - Blue status LED on GPIO15
|
||||||
|
# - Local push button on GPIO0
|
||||||
|
# - Relay output on GPIO12
|
||||||
|
# - Reference: https://devices.esphome.io/devices/Sonoff-POW-R1
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OPERATION NOTES:
|
||||||
|
# - Monitors washing machine load current, voltage, and power
|
||||||
|
# - Provides a virtual relay switch that controls the physical relay and LED together
|
||||||
|
# - Local button toggles the virtual relay switch
|
||||||
|
# - On boot, the virtual relay is turned ON
|
||||||
|
# - "Load Running" turns ON when measured power is above 4 W
|
||||||
|
# - "Load Running" uses delayed_off: 15s to avoid rapid state changes
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OFFLINE NOTES:
|
||||||
|
# a) Home Assistant offline (network and MQTT online):
|
||||||
|
# - Device continues running normally
|
||||||
|
# - Local button still works
|
||||||
|
# - MQTT remains available if your common MQTT package is enabled and broker is reachable
|
||||||
#
|
#
|
||||||
# NOTES
|
# b) MQTT offline (or HA/MQTT offline):
|
||||||
# -
|
# - Device continues running locally
|
||||||
|
# - Local button, relay control, LED control, and power monitoring still work
|
||||||
#
|
#
|
||||||
#############################################
|
# c) Entire WiFi/Network offline:
|
||||||
#############################################
|
# - Device continues running locally
|
||||||
|
# - Local button, relay control, LED control, and power monitoring still work
|
||||||
|
# - Accurate time is not needed; SNTP is not required for operation
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
|
# SUBSTITUTIONS:
|
||||||
|
# Specific device variable substitutions
|
||||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
substitutions:
|
substitutions:
|
||||||
device_name: "esp-laundrywashpow" # Reference name for the device in the system.
|
# Device Naming
|
||||||
project_name: "Sonoff Technologies.POW R1" # Project Details
|
device_name: "esp-laundrywashpow"
|
||||||
project_version: "v1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
friendly_name: "Laundry Washing Machine Power"
|
||||||
entity_prefix: "Load" # Simple device name where we want to prefix a sensor or switch, eg "Load" Current.
|
description_comment: "Laundry Washing Machine Power using a Sonoff Pow R1. (Layout V1.1)"
|
||||||
friendly_name: "Laundry Washing Machine Power" # Friendly name to show in Home Assistant.
|
device_area: "Laundry"
|
||||||
description_comment: "Laundry Washing Machine Power using a Sonoff Pow R1."
|
|
||||||
device_area: "Laundry" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
|
||||||
api_key: !secret esp-laundrywashpow_api_key # unfortunately you can't use substitutions inside secrets names
|
|
||||||
ota_pass: !secret esp-laundrywashpow_ota_pass # unfortunately you can't use substitutions inside secrets names
|
|
||||||
static_ip_address: !secret esp-laundrywashpow_ip
|
|
||||||
log_level: "INFO" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
|
||||||
update_interval: "60s" # update time for for general sensors etc
|
|
||||||
|
|
||||||
##########################################################################################
|
# Project Naming
|
||||||
# PACKAGES: Included Common Packages
|
project_name: "Sonoff Technologies.POW R1"
|
||||||
|
project_version: "v1.1"
|
||||||
|
|
||||||
|
# Entity Naming
|
||||||
|
entity_prefix: "Load"
|
||||||
|
|
||||||
|
# Passwords and Secrets
|
||||||
|
api_key: !secret esp-laundrywashpow_api_key
|
||||||
|
ota_pass: !secret esp-laundrywashpow_ota_pass
|
||||||
|
static_ip_address: !secret esp-laundrywashpow_ip
|
||||||
|
current_ip_address: ${static_ip_address}
|
||||||
|
|
||||||
|
# Device Settings
|
||||||
|
log_level: "INFO"
|
||||||
|
update_interval: "60s"
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# PACKAGES:
|
||||||
|
# Included common packages
|
||||||
# https://esphome.io/components/packages.html
|
# https://esphome.io/components/packages.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
packages:
|
packages:
|
||||||
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
||||||
common_wifi: !include
|
common_wifi: !include
|
||||||
@@ -41,12 +84,13 @@ packages:
|
|||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
local_static_ip_address: "${static_ip_address}"
|
local_static_ip_address: "${static_ip_address}"
|
||||||
|
local_current_ip_address: "${current_ip_address}"
|
||||||
local_ota_pass: "${ota_pass}"
|
local_ota_pass: "${ota_pass}"
|
||||||
|
|
||||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||||
common_api: !include
|
common_api: !include
|
||||||
file: common/api_common.yaml
|
file: common/api_common.yaml
|
||||||
#file: common/api_common_noencryption.yaml
|
# file: common/api_common_noencryption.yaml
|
||||||
vars:
|
vars:
|
||||||
local_api_key: "${api_key}"
|
local_api_key: "${api_key}"
|
||||||
|
|
||||||
@@ -55,137 +99,154 @@ packages:
|
|||||||
file: common/mqtt_common.yaml
|
file: common/mqtt_common.yaml
|
||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
|
|
||||||
#### WEB PORTAL ####
|
#### WEB PORTAL ####
|
||||||
#common_webportal: !include common/webportal_common.yaml
|
# common_webportal: !include common/webportal_common.yaml
|
||||||
|
|
||||||
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
||||||
#common_sntp: !include common/sntp_common.yaml
|
# common_sntp: !include common/sntp_common.yaml
|
||||||
|
|
||||||
#### DIAGNOSTICS Sensors ####
|
#### DIAGNOSTICS Sensors ####
|
||||||
diag_basic: !include common/include_basic_diag_sensors.yaml
|
diag_basic: !include common/include_basic_diag_sensors.yaml
|
||||||
diag_more: !include common/include_more_diag_sensors.yaml
|
diag_more: !include common/include_more_diag_sensors.yaml
|
||||||
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
# diag_debug: !include common/include_debug_diag_sensors.yaml
|
||||||
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
# diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# ESPHome
|
# ESPHOME:
|
||||||
# https://esphome.io/components/esphome.html
|
# https://esphome.io/components/esphome.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
esphome:
|
esphome:
|
||||||
name: "${device_name}"
|
name: "${device_name}"
|
||||||
friendly_name: "${friendly_name}"
|
friendly_name: "${friendly_name}"
|
||||||
comment: "${description_comment}" # Appears on the esphome page in HA
|
comment: "${description_comment}"
|
||||||
area: "${device_area}"
|
area: "${device_area}"
|
||||||
project:
|
project:
|
||||||
name: "${project_name}"
|
name: "${project_name}"
|
||||||
version: "${project_version}"
|
version: "${project_version}"
|
||||||
on_boot:
|
on_boot:
|
||||||
priority: 200
|
priority: 200
|
||||||
then:
|
then:
|
||||||
- switch.turn_on: "virtual_button"
|
- switch.turn_on: virtual_button
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# ESP Platform and Framework
|
# ESP PLATFORM AND FRAMEWORK:
|
||||||
# https://esphome.io/components/esp32.html
|
# https://esphome.io/components/esp8266.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
esp8266:
|
esp8266:
|
||||||
board: esp01_1m
|
board: esp01_1m
|
||||||
early_pin_init: False # Initialise pins early to known values. Recommended false where switches are involved. Defaults to True.
|
early_pin_init: false
|
||||||
board_flash_mode: dout # Default is dout
|
board_flash_mode: dout
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# ESPHome Logging Enable
|
# LOGGER:
|
||||||
# https://esphome.io/components/logger.html
|
# https://esphome.io/components/logger.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
logger:
|
logger:
|
||||||
level: ${log_level} #INFO Level suggested, or DEBUG for testing
|
level: "${log_level}"
|
||||||
#baud_rate: 0 #set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
# baud_rate: 0
|
||||||
#esp8266_store_log_strings_in_flash: false
|
# esp8266_store_log_strings_in_flash: false
|
||||||
#tx_buffer_size: 64
|
# tx_buffer_size: 64
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# STATUS LED
|
# STATUS LED:
|
||||||
# https://esphome.io/components/status_led.html
|
# https://esphome.io/components/status_led.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
#status_led:
|
# status_led:
|
||||||
# pin:
|
# pin:
|
||||||
# number: GPIO2
|
# number: GPIO2
|
||||||
# inverted: yes
|
# inverted: true
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# SENSORS
|
# BINARY SENSORS:
|
||||||
# https://esphome.io/components/binary_sensor/
|
# https://esphome.io/components/binary_sensor/
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
pin:
|
pin:
|
||||||
number: GPIO0
|
number: GPIO0
|
||||||
mode: INPUT_PULLUP
|
mode: INPUT_PULLUP
|
||||||
inverted: True
|
inverted: true
|
||||||
name: Button
|
name: "Button"
|
||||||
on_press:
|
on_press:
|
||||||
- switch.toggle: virtual_button
|
- switch.toggle: virtual_button
|
||||||
|
|
||||||
- platform: template
|
- platform: template
|
||||||
name: ${entity_prefix} Running
|
name: "${entity_prefix} Running"
|
||||||
filters:
|
filters:
|
||||||
- delayed_off: 15s
|
- delayed_off: 15s
|
||||||
lambda: |-
|
lambda: |-
|
||||||
if (isnan(id(power).state)) {
|
if (isnan(id(power).state)) {
|
||||||
return {};
|
return {};
|
||||||
} else if (id(power).state > 4) {
|
} else if (id(power).state > 4) {
|
||||||
// Running
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// Not running
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# SENSORS:
|
||||||
|
# https://esphome.io/components/sensor/
|
||||||
|
#:########################################################################################:#
|
||||||
sensor:
|
sensor:
|
||||||
- platform: hlw8012
|
- platform: hlw8012
|
||||||
sel_pin: 5
|
sel_pin: GPIO5
|
||||||
cf_pin: 14
|
cf_pin: GPIO14
|
||||||
cf1_pin: 13
|
cf1_pin: GPIO13
|
||||||
update_interval: 2s
|
update_interval: 2s
|
||||||
current:
|
current:
|
||||||
name: ${entity_prefix} Current
|
name: "${entity_prefix} Current"
|
||||||
voltage:
|
voltage:
|
||||||
name: ${entity_prefix} Voltage
|
name: "${entity_prefix} Voltage"
|
||||||
power:
|
power:
|
||||||
name: ${entity_prefix} Power
|
name: "${entity_prefix} Power"
|
||||||
id: power
|
id: power
|
||||||
#on_value_range:
|
# on_value_range:
|
||||||
# - above: 4.0
|
# - above: 4.0
|
||||||
# then:
|
# then:
|
||||||
# - light.turn_on: led
|
# - light.turn_on: led
|
||||||
# - below: 3.0
|
# - below: 3.0
|
||||||
# then:
|
# then:
|
||||||
# - light.turn_off: led
|
# - light.turn_off: led
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# SWITCH:
|
||||||
|
# https://esphome.io/components/switch/
|
||||||
|
#:########################################################################################:#
|
||||||
switch:
|
switch:
|
||||||
- platform: template
|
- platform: template
|
||||||
name: "Relay"
|
name: "Relay"
|
||||||
optimistic: true
|
|
||||||
id: virtual_button
|
id: virtual_button
|
||||||
|
optimistic: true
|
||||||
turn_on_action:
|
turn_on_action:
|
||||||
- switch.turn_on: relay
|
- switch.turn_on: relay
|
||||||
- light.turn_on: led
|
- light.turn_on: led
|
||||||
turn_off_action:
|
turn_off_action:
|
||||||
- switch.turn_off: relay
|
- switch.turn_off: relay
|
||||||
- light.turn_off: led
|
- light.turn_off: led
|
||||||
|
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
id: relay
|
id: relay
|
||||||
pin: GPIO12
|
pin: GPIO12
|
||||||
#restore_mode: ALWAYS_ON # Or RESTORE_DEFAULT_ON/RESTORE_DEFAULT_OFF
|
# restore_mode: ALWAYS_ON
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OUTPUT:
|
||||||
|
# https://esphome.io/components/output/
|
||||||
|
#:########################################################################################:#
|
||||||
output:
|
output:
|
||||||
- platform: esp8266_pwm
|
- platform: esp8266_pwm
|
||||||
id: pow_blue_led
|
id: pow_blue_led
|
||||||
pin:
|
pin:
|
||||||
number: GPIO15
|
number: GPIO15
|
||||||
inverted: True
|
inverted: true
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# LIGHT:
|
||||||
|
# https://esphome.io/components/light/
|
||||||
|
#:########################################################################################:#
|
||||||
light:
|
light:
|
||||||
- platform: monochromatic
|
- platform: monochromatic
|
||||||
name: Status LED
|
name: "Status LED"
|
||||||
output: pow_blue_led
|
output: pow_blue_led
|
||||||
id: led
|
id: led
|
||||||
@@ -1,29 +1,59 @@
|
|||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# TITLE: NISSAN LEAF 12V BATTERY MONITOR
|
||||||
# Nissan Leaf 12V Battery Monitor
|
# zorruno.com layout v1.1 2026
|
||||||
# Monitoring the status of a vehicle 12V battery with
|
#:########################################################################################:#
|
||||||
# an esp8266 (D1 Mini). It will obviously only
|
# REPO:
|
||||||
# transmit when the vehicle is within wifi range.
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-leafbattery.yaml
|
||||||
# Voltage is measured with a resistor voltage divider
|
#:########################################################################################:#
|
||||||
# into the analogue GPIO on the esp8266.
|
# VERSIONS:
|
||||||
# https://zorruno.com/2022/vehicle-12v-battery-monitoring/
|
# V1.1 2026-03-22 Updated yaml to zorruno layout V1.1
|
||||||
##########################################################################################
|
# V1.0 2025-??-?? Initial Version
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
|
# HARDWARE:
|
||||||
|
# - Generic ESP8266 D1 Mini
|
||||||
|
# - Nissan Leaf 12V battery monitor
|
||||||
|
# - Voltage measured with a resistor divider into the ESP8266 analogue pin
|
||||||
|
# - Device only transmits when the vehicle is within WiFi range
|
||||||
|
# - Reference:
|
||||||
|
# https://zorruno.com/2022/vehicle-12v-battery-monitoring/
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OPERATION NOTES:
|
||||||
|
# - Monitors the Nissan Leaf 12V battery voltage.
|
||||||
|
# - Device wakes for a short period, publishes voltage, then deep sleeps.
|
||||||
|
# - Deep sleep is PREVENTED on boot by default.
|
||||||
|
# - Device waits up to 30 seconds for MQTT to connect.
|
||||||
|
# - If MQTT does not connect within 30 seconds, it enters a longer fallback sleep period.
|
||||||
|
# - If MQTT connects, deep sleep can be controlled by MQTT command topic.
|
||||||
|
# - Battery voltage is read from A0 and calibrated using a linear table.
|
||||||
|
# - Voltage is published immediately when it changes by 0.05 V or more.
|
||||||
|
# - Voltage is also republished every 60 seconds while awake.
|
||||||
|
#
|
||||||
|
# MQTT COMMANDS:
|
||||||
|
# - ${mqtt_command_topic}/deepsleep = ON
|
||||||
|
# - Allow deep sleep when run_duration expires
|
||||||
|
# - ${mqtt_command_topic}/deepsleep = OFF
|
||||||
|
# - Prevent deep sleep
|
||||||
|
#
|
||||||
|
# MQTT STATUS:
|
||||||
|
# - ${mqtt_status_topic}/availability = online/offline
|
||||||
|
# - ${mqtt_status_topic}/batteryvoltage = voltage value
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
|
# SUBSTITUTIONS:
|
||||||
|
# Specific device variable substitutions
|
||||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
substitutions:
|
substitutions:
|
||||||
# Device Naming
|
# Device Naming
|
||||||
device_name: "esp-leafbattery"
|
device_name: "esp-leafbattery"
|
||||||
friendly_name: "Nissan Leaf 12V Battery Monitor"
|
friendly_name: "Nissan Leaf 12V Battery Monitor"
|
||||||
description_comment: "Nissan Leaf 12V Battery Monitor (when home)"
|
description_comment: "Nissan Leaf 12V Battery Monitor (when home) (Layout V1.1)"
|
||||||
device_area: "Garage" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
device_area: "Garage" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
||||||
|
|
||||||
# Project Naming
|
# Project Naming
|
||||||
project_name: "Generic ESP8266.D1 Mini" # Project Details
|
project_name: "Generic ESP8266.D1 Mini" # Project Details
|
||||||
project_version: "v1.0" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
project_version: "v1.1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
||||||
|
|
||||||
# Passwords & Secrets
|
# Passwords & Secrets
|
||||||
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
||||||
@@ -32,26 +62,28 @@ substitutions:
|
|||||||
mqtt_command_main_topic: !secret mqtt_command_main_topic
|
mqtt_command_main_topic: !secret mqtt_command_main_topic
|
||||||
mqtt_status_main_topic: !secret mqtt_status_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}
|
||||||
|
|
||||||
# MQTT LOCAL Controls
|
# MQTT LOCAL Controls
|
||||||
mqtt_device_name: "leaf-battery"
|
mqtt_device_name: "leaf-battery"
|
||||||
mqtt_command_topic: "${mqtt_command_main_topic}/${mqtt_device_name}" # Topic we will use to command this locally without HA
|
mqtt_command_topic: "${mqtt_command_main_topic}/${mqtt_device_name}" # Topic we will use to command this locally without HA
|
||||||
mqtt_status_topic: "${mqtt_status_main_topic}/${mqtt_device_name}" # Topic we will use to view status locally without HA
|
mqtt_status_topic: "${mqtt_status_main_topic}/${mqtt_device_name}" # Topic we will use to view status locally without HA
|
||||||
|
|
||||||
# Device Settings
|
# Device Settings
|
||||||
#relay_icon: "mdi:lightbulb-group"
|
|
||||||
log_level: "INFO" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
log_level: "INFO" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
||||||
update_interval: "60s" # update time for for general sensors etc
|
update_interval: "60s" # update time for for general sensors etc
|
||||||
|
|
||||||
wake_interval: "20s"
|
wake_interval: "20s"
|
||||||
sleep_interval: "300s"
|
sleep_interval: "300s"
|
||||||
mqtt_fail_sleep: "1h" # If MQTT is unavailable after boot wait, sleep this long
|
mqtt_fail_sleep: "1h" # If MQTT is unavailable after boot wait, sleep this long
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# PACKAGES: Included Common Packages
|
# PACKAGES:
|
||||||
|
# Included Common Packages
|
||||||
# https://esphome.io/components/packages.html
|
# https://esphome.io/components/packages.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# Comment some of these out where not needed, eg MQTT, Web portal, SNTP, General Sensors
|
|
||||||
##########################################################################################
|
|
||||||
packages:
|
packages:
|
||||||
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
||||||
common_wifi: !include
|
common_wifi: !include
|
||||||
@@ -60,6 +92,7 @@ packages:
|
|||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
local_static_ip_address: "${static_ip_address}"
|
local_static_ip_address: "${static_ip_address}"
|
||||||
local_ota_pass: "${ota_pass}"
|
local_ota_pass: "${ota_pass}"
|
||||||
|
local_current_ip_address: "${current_ip_address}"
|
||||||
|
|
||||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||||
common_api: !include
|
common_api: !include
|
||||||
@@ -73,28 +106,32 @@ packages:
|
|||||||
file: common/mqtt_common.yaml
|
file: common/mqtt_common.yaml
|
||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
|
|
||||||
#### WEB PORTAL ####
|
#### WEB PORTAL ####
|
||||||
common_webportal: !include common/webportal_common.yaml
|
common_webportal: !include common/webportal_common.yaml
|
||||||
|
|
||||||
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
||||||
#common_sntp: !include common/sntp_common.yaml
|
#common_sntp: !include common/sntp_common.yaml
|
||||||
|
|
||||||
#### DIAGNOSTICS Sensors ####
|
#### DIAGNOSTICS Sensors ####
|
||||||
diag_basic: !include common/include_basic_diag_sensors.yaml
|
diag_basic: !include common/include_basic_diag_sensors.yaml
|
||||||
diag_more: !include common/include_more_diag_sensors.yaml
|
diag_more: !include common/include_more_diag_sensors.yaml
|
||||||
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
||||||
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# ESPHome
|
# ESPHOME:
|
||||||
# https://esphome.io/components/esphome.html
|
# https://esphome.io/components/esphome.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
esphome:
|
esphome:
|
||||||
name: ${device_name}
|
name: "${device_name}"
|
||||||
friendly_name: ${friendly_name}
|
friendly_name: "${friendly_name}"
|
||||||
comment: ${description_comment} #appears on the esphome page in HA
|
comment: "${description_comment}" # appears on the esphome page in HA
|
||||||
|
area: "${device_area}"
|
||||||
min_version: 2024.6.0
|
min_version: 2024.6.0
|
||||||
|
project:
|
||||||
|
name: "${project_name}"
|
||||||
|
version: "${project_version}"
|
||||||
on_boot:
|
on_boot:
|
||||||
priority: 600
|
priority: 600
|
||||||
then:
|
then:
|
||||||
@@ -115,41 +152,41 @@ esphome:
|
|||||||
- logger.log: "MQTT unreachable after 30s -> entering FALLBACK sleep for ${mqtt_fail_sleep}."
|
- logger.log: "MQTT unreachable after 30s -> entering FALLBACK sleep for ${mqtt_fail_sleep}."
|
||||||
- deep_sleep.enter:
|
- deep_sleep.enter:
|
||||||
id: deep_sleep_1
|
id: deep_sleep_1
|
||||||
sleep_duration: ${mqtt_fail_sleep} # override only this cycle
|
sleep_duration: ${mqtt_fail_sleep} # override only this cycle
|
||||||
else:
|
else:
|
||||||
- logger.log: "MQTT connected; awaiting '${mqtt_command_topic}/deepsleep' command."
|
- logger.log: "MQTT connected; awaiting '${mqtt_command_topic}/deepsleep' command."
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# ESP Platform and Framework
|
# ESP PLATFORM AND FRAMEWORK:
|
||||||
# https://esphome.io/components/esp8266.html
|
# https://esphome.io/components/esp8266.html
|
||||||
# https://esphome.io/components/esp32.html
|
# https://esphome.io/components/esp32.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
esp8266:
|
esp8266:
|
||||||
board: d1_mini
|
board: d1_mini
|
||||||
framework:
|
framework:
|
||||||
version: latest #recommended, latest or dev
|
version: latest # recommended, latest or dev
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# ESPHome Logging Enable
|
# LOGGER:
|
||||||
# https://esphome.io/components/logger.html
|
# https://esphome.io/components/logger.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
logger:
|
logger:
|
||||||
level: "${log_level}" #INFO Level suggested, or DEBUG for testing
|
level: "${log_level}" # INFO Level suggested, or DEBUG for testing
|
||||||
#baud_rate: 0 #set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
#baud_rate: 0 # set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
||||||
#esp8266_store_log_strings_in_flash: false
|
#esp8266_store_log_strings_in_flash: false
|
||||||
#tx_buffer_size: 64
|
#tx_buffer_size: 64
|
||||||
|
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
# Enable Over the Air Update Capability
|
# OTA:
|
||||||
# https://esphome.io/components/ota.html?highlight=ota
|
# https://esphome.io/components/ota.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
ota:
|
ota:
|
||||||
- platform: web_server # Uncomment if you want to be able to do OTA with the web interface
|
- platform: web_server # Uncomment if you want to be able to do OTA with the web interface
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# MQTT COMMANDS
|
# MQTT COMMANDS:
|
||||||
# This adds device-specific MQTT command triggers to the common MQTT configuration.
|
# This adds device-specific MQTT command triggers to the common MQTT configuration.
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
mqtt:
|
mqtt:
|
||||||
# Availability Topic
|
# Availability Topic
|
||||||
birth_message:
|
birth_message:
|
||||||
@@ -173,19 +210,19 @@ mqtt:
|
|||||||
- deep_sleep.prevent: deep_sleep_1
|
- deep_sleep.prevent: deep_sleep_1
|
||||||
- logger.log: "Deep sleep PREVENTED via MQTT."
|
- logger.log: "Deep sleep PREVENTED via MQTT."
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# Deep Sleep
|
# DEEP SLEEP:
|
||||||
# https://esphome.io/components/deep_sleep.html
|
# https://esphome.io/components/deep_sleep.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
deep_sleep:
|
deep_sleep:
|
||||||
id: deep_sleep_1
|
id: deep_sleep_1
|
||||||
run_duration: ${wake_interval}
|
run_duration: ${wake_interval}
|
||||||
sleep_duration: ${sleep_interval}
|
sleep_duration: ${sleep_interval}
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SENSOR COMPONENT
|
# SENSOR COMPONENT:
|
||||||
# https://esphome.io/components/sensor/
|
# https://esphome.io/components/sensor/
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
sensor:
|
sensor:
|
||||||
- platform: adc
|
- platform: adc
|
||||||
pin: A0
|
pin: A0
|
||||||
@@ -208,8 +245,8 @@ sensor:
|
|||||||
- 0.32 -> 07.00
|
- 0.32 -> 07.00
|
||||||
- 0.28 -> 06.00
|
- 0.28 -> 06.00
|
||||||
- 0.23 -> 05.00
|
- 0.23 -> 05.00
|
||||||
- delta: 0.05 # publish immediately if change >= 0.05 V
|
- delta: 0.05 # publish immediately if change >= 0.05 V
|
||||||
- throttle: 2s # avoid bursts if noisy
|
- throttle: 2s # avoid bursts if noisy
|
||||||
on_value:
|
on_value:
|
||||||
then:
|
then:
|
||||||
- mqtt.publish:
|
- mqtt.publish:
|
||||||
@@ -221,9 +258,10 @@ sensor:
|
|||||||
snprintf(buf, sizeof(buf), "%.2f", x);
|
snprintf(buf, sizeof(buf), "%.2f", x);
|
||||||
return std::string(buf);
|
return std::string(buf);
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# INTERVAL COMPONENT
|
# INTERVAL COMPONENT:
|
||||||
##########################################################################################
|
# https://esphome.io/components/interval.html
|
||||||
|
#:########################################################################################:#
|
||||||
interval:
|
interval:
|
||||||
- interval: 60s
|
- interval: 60s
|
||||||
then:
|
then:
|
||||||
@@ -237,6 +275,3 @@ interval:
|
|||||||
snprintf(buf, sizeof(buf), "%.2f", v);
|
snprintf(buf, sizeof(buf), "%.2f", v);
|
||||||
return std::string(buf);
|
return std::string(buf);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,72 +1,97 @@
|
|||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# TITLE: LOUNGE BOOKSHELF LEDS
|
||||||
# Title: LOUNGE BOOKSHELF LEDS
|
# zorruno.com layout v1.1 2026
|
||||||
# Repo: https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-loungebookshelfleds.yaml
|
#:########################################################################################:#
|
||||||
#
|
# REPO:
|
||||||
# v2.0 - 2025-09-15 A bunch of fixes and made it more standard across my devices
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-loungebookshelfleds.yaml
|
||||||
# v1.0 - 2025-08-17 First setup (and replacement of Tasmota)
|
#:########################################################################################:#
|
||||||
|
# VERSIONS:
|
||||||
|
# V2.1 2026-03-11 Updated yaml to zorruno layout V1.1
|
||||||
|
# V2.0 2025-09-15 A bunch of fixes and made it more standard across my devices
|
||||||
|
# V1.0 2025-08-17 First setup (and replacement of Tasmota)
|
||||||
|
#:########################################################################################:#
|
||||||
|
# HARDWARE:
|
||||||
|
# - Magichome LED controller single channel (ESP8266, NOT the later ones with BL602)
|
||||||
|
# - Reference:
|
||||||
|
# https://devices.esphome.io/devices/MagicHome-ZJ-WFMN-C-Single-Color
|
||||||
|
# - Device GPIO (Magichome ESP8266):
|
||||||
|
# - GPIO2 Blue LED (used for ESPHome status)
|
||||||
|
# - GPIO12 MOSFET output (0 V when switched)
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OPERATION NOTES:
|
||||||
|
# - General-purpose LED controller.
|
||||||
|
# - Designed for the Sinilink XY-WFMS board with a MOSFET output (claimed 5A, 5-36 V DC),
|
||||||
|
# but will suit similar MOSFET boards.
|
||||||
|
# - In SUBSTITUTIONS there is a maximum output setting to extend LED life.
|
||||||
|
# - In SUBSTITUTIONS there is a minimum output setting; switches fully OFF at/below the minimum
|
||||||
|
# to avoid low-PWM flicker.
|
||||||
|
# - PWM frequency is set to 1 kHz by default. You can increase it, but higher values caused
|
||||||
|
# resets on the Sinilink device. On ESP32 you can run much higher.
|
||||||
|
# - Min/max output settings are not exposed in Home Assistant/MQTT by default, but could be.
|
||||||
|
# - Packages include common items: network settings, diagnostic entities, MQTT, and optional SNTP.
|
||||||
|
# - Default restart behaviours:
|
||||||
|
# - Fade up to full
|
||||||
|
# - Restore Brightness
|
||||||
|
# - Remain Off
|
||||||
|
# - The green LED flashes while fading (different patterns for up/down). The red LED follows the
|
||||||
|
# output (it shares the MOSFET GPIO). This depends on hardware.
|
||||||
|
# - Fade timing scales with configured values proportionally when starting mid-brightness.
|
||||||
|
# - Exposed in Home Assistant/MQTT:
|
||||||
|
# - Startup action (On, Off, Restore)
|
||||||
|
# - Fade Up / Fade Down / Fade Stop buttons
|
||||||
|
# - Fade Up/Down toggle switch
|
||||||
|
# - Normal On/Off switch using quick ramp up/down
|
||||||
|
# - Fade up/down times (0-60 s)
|
||||||
|
# - Output % (pre-gamma) and PWM % (post-gamma)
|
||||||
|
# - Output Set (1-100, respects min/max)
|
||||||
|
# - Many device diagnostics from the included diagnostics package
|
||||||
|
# - Maximum ON time before automatic fade-down (1-48 h, 0 = no limit)
|
||||||
#
|
#
|
||||||
# ------------------------------------------
|
# MQTT COMMANDS:
|
||||||
# OPERATION (as of v2.0)
|
# - ${mqtt_local_command_topic}/light/set = ON
|
||||||
# ------------------------------------------
|
# - ${mqtt_local_command_topic}/light/set = OFF
|
||||||
# 1. General-purpose LED controller.
|
# - State publishes to:
|
||||||
# 2. Designed for the Sinilink XY-WFMS board with a MOSFET output (claimed 5A, 5-36 V DC), but will suit similar mosfet boards.
|
# - ${mqtt_local_status_topic}/light/state
|
||||||
# 3. (In SUBSTITUTIONS) setting for MAX % output to extend LED life (ie can ensure it is only ever 95%)
|
#:########################################################################################:#
|
||||||
# 4. (In SUBSTITUTIONS) Minimum output setting; switches fully OFF at/below the minimum to avoid low-PWM flicker.
|
# OFFLINE NOTES:
|
||||||
# 5. (In SUBSTITUTIONS) PWM frequency is set to 1kHz by default. You can increase it, but higher values caused
|
# a) Home Assistant offline (network and MQTT online):
|
||||||
# resets on Sinilink device. On ESP32 you can run much higher (~40 kHz).
|
# - LED control continues locally on the device
|
||||||
# 6. Min/Max output settings are not exposed in Home Assistant/MQTT by default, but could be.
|
# - Direct local MQTT commands still work if the broker is available
|
||||||
# With a 1 MB flash, space is tight and only minimal optimisation has been done so far.
|
# - Stored brightness/ramp settings and restart behaviour continue to work
|
||||||
# 7. (PACKAGES) include common items: network settings, diagnostic entities, MQTT, and SNTP (optional).
|
#
|
||||||
# 8. Default behaviours, for recovery from lost power or reset:
|
# b) MQTT offline (or HA/MQTT offline):
|
||||||
# - "Fade up to full": fade from floor to max on boot.
|
# - LED control continues locally on the device
|
||||||
# - "Restore Brightness": fade from floor to the last non-zero brightness on boot (should be no on/off blip/flash).
|
# - Physical button control and local ramp logic continue to work
|
||||||
# - "Remain Off": stays off on boot.
|
# - No MQTT control/state publishing available
|
||||||
# 9. The green LED flashes while fading (different patterns for up/down). The red LED follows the
|
#
|
||||||
# output (it shares the MOSFET GPIO). (Obviously this depends on hardware)
|
# c) Entire WiFi/Network offline:
|
||||||
# 10. Fade timing scales with the configured values (proportionally when starting mid-brightness).
|
# - LED control continues locally on the device
|
||||||
# 11. Exposed in Home Assistant/MQTT:
|
# - Physical button control and local ramp logic continue to work
|
||||||
# - Startup action (On,Off,Restore)
|
# - Accurate time is not needed; SNTP is not required for operation
|
||||||
# - Fade Up / Fade Down / Fade Stop buttons
|
#:########################################################################################:#
|
||||||
# - Fade Up/Down toggle switch (keeps fading up to full, or down to off unless stopped)
|
|
||||||
# - Normal On/Off switch (quick ramp up/down, up to the level of previous brightness)
|
|
||||||
# - Fade up/down times (0-60s)
|
|
||||||
# - Output % (pre-gamma) and PWM % (post-gamma)
|
|
||||||
# - Output Set (1-100, respects min/max). This also changes with other output so reflects value.
|
|
||||||
# - Many device diagnostics (from the included 'diagnostics' package)
|
|
||||||
# - Maximum 'on' time before automatic fade-down (1-48 h, 0 = no limit)
|
|
||||||
##########################################################################################
|
|
||||||
##########################################################################################
|
|
||||||
# Hardware: Magishome LED controller single channel (ESP8266, NOT the later ones with BL602)
|
|
||||||
# https://devices.esphome.io/devices/MagicHome-ZJ-WFMN-C-Single-Color
|
|
||||||
# ------------------------------------------
|
|
||||||
# DEVICE GPIO (Magichome ESP8266)
|
|
||||||
# ------------------------------------------
|
|
||||||
# GPIO02 Blue LED (used for ESPHome status) - I think... can't see the board
|
|
||||||
# GPIO12 MOSFET output (0 V when switched)
|
|
||||||
##########################################################################################
|
|
||||||
##########################################################################################
|
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
|
# SUBSTITUTIONS:
|
||||||
|
# Specific device variable substitutions
|
||||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
substitutions:
|
substitutions:
|
||||||
# Device Naming
|
# Device Naming
|
||||||
device_name: "esp-loungebookshelfleds" # yaml file should be device_name.yaml
|
device_name: "esp-loungebookshelfleds" # yaml file should be device_name.yaml
|
||||||
friendly_name: "Lounge Bookshelf LEDs"
|
friendly_name: "Lounge Bookshelf LEDs"
|
||||||
description_comment: "LED Strip around the bookshelf in the upstairs lounge :: Magichome ESP8266"
|
description_comment: "LED Strip around the bookshelf in the upstairs lounge :: Magichome ESP8266 (Layout V1.1)"
|
||||||
device_area: "Lounge" # Allows the ESP device to be automatically linked to an 'Area' in Home Assistant.
|
device_area: "Lounge" # Allows the ESP device to be automatically linked to an 'Area' in Home Assistant.
|
||||||
|
|
||||||
# Project Naming
|
# Project Naming
|
||||||
project_name: "Magichome Single Colour V1.1 LED Controller.Generic ESP8266" # Project details. Manufacturer before the dot, device after the dot.
|
project_name: "Magichome Single Colour V1.1 LED Controller.Generic ESP8266" # Project details. Manufacturer before the dot, device after the dot.
|
||||||
project_version: "v2.0" # Project version denotes release of the YAML file, allowing checking of deployed vs latest version
|
project_version: "v2.1" # Project version denotes release of the YAML file, allowing checking of deployed vs latest version
|
||||||
|
|
||||||
# Passwords & Secrets (Unfortunately, you can't use substitutions inside secret names)
|
# Passwords & Secrets (Unfortunately, you can't use substitutions inside secret names)
|
||||||
api_key: !secret esp-api_key # If using HA API
|
api_key: !secret esp-api_key # If using HA API
|
||||||
ota_pass: !secret esp-ota_pass # If passwording OTA updates
|
ota_pass: !secret esp-ota_pass # If passwording OTA updates
|
||||||
static_ip_address: !secret esp-loungebookshelfleds_ip # CHANGE THIS
|
static_ip_address: !secret esp-loungebookshelfleds_ip # CHANGE THIS
|
||||||
|
current_ip_address: ${static_ip_address}
|
||||||
|
|
||||||
# MQTT LOCAL Controls (This is just my local method of controlling via MQTT, I also use the built in method)
|
# MQTT LOCAL Controls (This is just my local method of controlling via MQTT, I also use the built in method)
|
||||||
mqtt_local_device_name: "lounge-bookshelfleds"
|
mqtt_local_device_name: "lounge-bookshelfleds"
|
||||||
mqtt_local_command_main_topic: !secret mqtt_command_main_topic
|
mqtt_local_command_main_topic: !secret mqtt_command_main_topic
|
||||||
@@ -77,24 +102,25 @@ substitutions:
|
|||||||
mqtt_local_device_command_OFF: "OFF"
|
mqtt_local_device_command_OFF: "OFF"
|
||||||
|
|
||||||
# Device Specific Settings
|
# Device Specific Settings
|
||||||
log_level: "NONE" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (default), VERBOSE, VERY_VERBOSE
|
log_level: "NONE" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (default), VERBOSE, VERY_VERBOSE
|
||||||
update_interval: "20s" # Update time for general sensors, etc.
|
update_interval: "20s" # Update time for general sensors, etc.
|
||||||
led_gamma: "1.2" # Gamma from 1.2-3 is sensible to normalise the LED fading vs PWM
|
led_gamma: "1.2" # Gamma from 1.2-3 is sensible to normalise the LED fading vs PWM
|
||||||
minimum_led_output: "1" # % If at this value or below, we'll switch it completely off
|
minimum_led_output: "1" # % If at this value or below, we will switch it completely off
|
||||||
maximum_led_output: "90" # % Maximum output; it is sometimes nice to limit the output for longevity or aesthetics
|
maximum_led_output: "90" # % Maximum output; it is sometimes nice to limit the output for longevity or aesthetics
|
||||||
max_on_default_hours: "24" # The maximum time the LEDs will be on, in case they get left on. 0 = no automatic turn-off
|
max_on_default_hours: "24" # The maximum time the LEDs will be on, in case they get left on. 0 = no automatic turn-off
|
||||||
pwm_frequency: "1000" # PWM output Frequency in Hz. High enough to avoid audible/visible artifacts
|
pwm_frequency: "1000" # PWM output Frequency in Hz. High enough to avoid audible/visible artifacts
|
||||||
|
|
||||||
# Device Specific GPIO (so we can easily update for other devices)
|
# Device Specific GPIO (so we can easily update for other devices)
|
||||||
device_status_led: GPIO02
|
device_status_led: GPIO2
|
||||||
device_mosfet_out: GPIO12
|
device_mosfet_out: GPIO12
|
||||||
device_usr_button: GPIO04 # if no button, this is just a fake/safeish choice so it compiles with the generic yaml
|
device_usr_button: GPIO4 # if no button, this is just a fake/safeish choice so it compiles with the generic yaml
|
||||||
device_fading_led: GPIO13 # if no LED, this is just a fake/safeish choice so it compiles with the generic yaml
|
device_fading_led: GPIO13 # if no LED, this is just a fake/safeish choice so it compiles with the generic yaml
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# PACKAGES: Included Common Packages
|
# PACKAGES:
|
||||||
|
# Included Common Packages
|
||||||
# https://esphome.io/components/packages.html
|
# https://esphome.io/components/packages.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
packages:
|
packages:
|
||||||
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
||||||
common_wifi: !include
|
common_wifi: !include
|
||||||
@@ -102,6 +128,7 @@ packages:
|
|||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
local_static_ip_address: "${static_ip_address}"
|
local_static_ip_address: "${static_ip_address}"
|
||||||
|
local_current_ip_address: "${current_ip_address}"
|
||||||
local_ota_pass: "${ota_pass}"
|
local_ota_pass: "${ota_pass}"
|
||||||
|
|
||||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||||
@@ -116,22 +143,23 @@ packages:
|
|||||||
file: common/mqtt_common.yaml
|
file: common/mqtt_common.yaml
|
||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
|
|
||||||
#### WEB PORTAL ####
|
#### WEB PORTAL ####
|
||||||
#common_webportal: !include common/webportal_common.yaml
|
#common_webportal: !include common/webportal_common.yaml
|
||||||
|
|
||||||
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
||||||
#common_sntp: !include common/sntp_common.yaml
|
#common_sntp: !include common/sntp_common.yaml
|
||||||
|
|
||||||
#### DIAGNOSTICS Sensors ####
|
#### DIAGNOSTICS Sensors ####
|
||||||
diag_basic: !include common/include_basic_diag_sensors.yaml
|
diag_basic: !include common/include_basic_diag_sensors.yaml
|
||||||
diag_more: !include common/include_more_diag_sensors.yaml
|
diag_more: !include common/include_more_diag_sensors.yaml
|
||||||
diag_debug: !include common/include_debug_diag_sensors.yaml
|
diag_debug: !include common/include_debug_diag_sensors.yaml
|
||||||
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# ESPHome CORE CONFIGURATION
|
# ESPHOME CORE CONFIGURATION
|
||||||
# https://esphome.io/components/esphome.html
|
# https://esphome.io/components/esphome.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
esphome:
|
esphome:
|
||||||
name: "${device_name}"
|
name: "${device_name}"
|
||||||
friendly_name: "${friendly_name}"
|
friendly_name: "${friendly_name}"
|
||||||
@@ -152,32 +180,32 @@ esphome:
|
|||||||
# Mode 0: Fade up to full (obeys fade settings; no on/off flicker)
|
# Mode 0: Fade up to full (obeys fade settings; no on/off flicker)
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
lambda: 'return id(restart_mode) == 0;'
|
lambda: "return id(restart_mode) == 0;"
|
||||||
then:
|
then:
|
||||||
- lambda: 'id(ramp_switch_target_on) = true;'
|
- lambda: "id(ramp_switch_target_on) = true;"
|
||||||
- script.execute: ramp_on_script
|
- script.execute: ramp_on_script
|
||||||
|
|
||||||
# Mode 1: Restore Brightness (deferred to avoid races)
|
# Mode 1: Restore Brightness (deferred to avoid races)
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
lambda: 'return id(restart_mode) == 1;'
|
lambda: "return id(restart_mode) == 1;"
|
||||||
then:
|
then:
|
||||||
- script.execute: deferred_restore_brightness
|
- script.execute: deferred_restore_brightness
|
||||||
|
|
||||||
# Mode 2: Remain Off (no blip; stays off)
|
# Mode 2: Remain Off (no blip; stays off)
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
lambda: 'return id(restart_mode) == 2;'
|
lambda: "return id(restart_mode) == 2;"
|
||||||
then:
|
then:
|
||||||
- script.stop: ramp_on_script
|
- script.stop: ramp_on_script
|
||||||
- script.stop: ramp_off_script
|
- script.stop: ramp_off_script
|
||||||
- lambda: 'id(ramp_switch_target_on) = false;'
|
- lambda: "id(ramp_switch_target_on) = false;"
|
||||||
- light.turn_off:
|
- light.turn_off:
|
||||||
id: mosfet_leds
|
id: mosfet_leds
|
||||||
transition_length: 0s
|
transition_length: 0s
|
||||||
|
|
||||||
# Boot complete: allow OFF handlers again
|
# Boot complete: allow OFF handlers again
|
||||||
- lambda: 'id(booting) = false;'
|
- lambda: "id(booting) = false;"
|
||||||
|
|
||||||
# NEW: force indicator OFF after boot logic
|
# NEW: force indicator OFF after boot logic
|
||||||
# (Removed: output.turn_off: green_led_out)
|
# (Removed: output.turn_off: green_led_out)
|
||||||
@@ -193,11 +221,11 @@ esphome:
|
|||||||
# - -fdata-sections
|
# - -fdata-sections
|
||||||
# - -DNDEBUG
|
# - -DNDEBUG
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# ESP PLATFORM AND FRAMEWORK
|
# ESP PLATFORM AND FRAMEWORK
|
||||||
# https://esphome.io/components/esp8266.html
|
# https://esphome.io/components/esp8266.html
|
||||||
# https://esphome.io/components/esp32.html
|
# https://esphome.io/components/esp32.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
esp8266:
|
esp8266:
|
||||||
board: esp01_1m
|
board: esp01_1m
|
||||||
restore_from_flash: true # restore some values on reboot
|
restore_from_flash: true # restore some values on reboot
|
||||||
@@ -208,10 +236,10 @@ mdns:
|
|||||||
preferences:
|
preferences:
|
||||||
flash_write_interval: 2min # enough time to update values for reboots, but not enough to wear flash
|
flash_write_interval: 2min # enough time to update values for reboots, but not enough to wear flash
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# GLOBAL VARIABLES
|
# GLOBAL VARIABLES
|
||||||
# https://esphome.io/components/globals.html
|
# https://esphome.io/components/globals.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
globals:
|
globals:
|
||||||
# Minimum Brightness % for LEDs (will switch off if <=)
|
# Minimum Brightness % for LEDs (will switch off if <=)
|
||||||
- id: min_brightness_pct
|
- id: min_brightness_pct
|
||||||
@@ -223,7 +251,7 @@ globals:
|
|||||||
type: int
|
type: int
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: "${maximum_led_output}" # hard cap; never exceed this
|
initial_value: "${maximum_led_output}" # hard cap; never exceed this
|
||||||
# The maximum time the lights will stay on, in hours. Just in case they are left on. 0 = forever
|
# The maximum time the lights will stay on, in hours. Just in case they are left on. 0 = forever
|
||||||
- id: max_on_hours
|
- id: max_on_hours
|
||||||
type: int
|
type: int
|
||||||
restore_value: true
|
restore_value: true
|
||||||
@@ -232,23 +260,23 @@ globals:
|
|||||||
- id: led_gamma_f
|
- id: led_gamma_f
|
||||||
type: float
|
type: float
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: ${led_gamma} # <-- numeric at compile time
|
initial_value: ${led_gamma} # numeric at compile time
|
||||||
|
|
||||||
# Default Fading Up Time (Selectable and will be retained)
|
# Default Fading Up Time (Selectable and will be retained)
|
||||||
- id: ramp_up_ms # fade-in when turned ON
|
- id: ramp_up_ms # fade-in when turned ON
|
||||||
type: int
|
type: int
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: '5000' # 5 s
|
initial_value: "5000" # 5 s
|
||||||
# Default Fading Down Time (Selectable and will be retained)
|
# Default Fading Down Time (Selectable and will be retained)
|
||||||
- id: ramp_down_ms # fade-out when turned OFF
|
- id: ramp_down_ms # fade-out when turned OFF
|
||||||
type: int
|
type: int
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: '10000' # 10 s
|
initial_value: "10000" # 10 s
|
||||||
# Action on Restart. (0=Fade full, 1=Restore brightness, 2=Remain off)
|
# Action on Restart. (0=Fade full, 1=Restore brightness, 2=Remain off)
|
||||||
- id: restart_mode
|
- id: restart_mode
|
||||||
type: int
|
type: int
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: '0' # default = Fade Up to Full (so can be deployed with no other setup)
|
initial_value: "0" # default = Fade Up to Full (so can be deployed with no other setup)
|
||||||
|
|
||||||
# Determine last fade direction.
|
# Determine last fade direction.
|
||||||
# true when you asked the light to end up ON (Ramp Up)
|
# true when you asked the light to end up ON (Ramp Up)
|
||||||
@@ -256,70 +284,70 @@ globals:
|
|||||||
- id: ramp_switch_target_on
|
- id: ramp_switch_target_on
|
||||||
type: bool
|
type: bool
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: 'false'
|
initial_value: "false"
|
||||||
# Prevent jitter when adjusting the slider
|
# Prevent jitter when adjusting the slider
|
||||||
- id: suppress_slider_sync
|
- id: suppress_slider_sync
|
||||||
type: bool
|
type: bool
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: 'false'
|
initial_value: "false"
|
||||||
# actual 0..100 seen last time, for restart
|
# actual 0..100 seen last time, for restart
|
||||||
- id: last_brightness_pct
|
- id: last_brightness_pct
|
||||||
type: float
|
type: float
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: '0.0'
|
initial_value: "0.0"
|
||||||
# last published "Output Set (0-100)" integer
|
# last published "Output Set (0-100)" integer
|
||||||
- id: last_set_pos
|
- id: last_set_pos
|
||||||
type: int
|
type: int
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: '-1'
|
initial_value: "-1"
|
||||||
# helper to keep blink time == transition time
|
# helper to keep blink time == transition time
|
||||||
- id: last_ramp_ms
|
- id: last_ramp_ms
|
||||||
type: int
|
type: int
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: '0'
|
initial_value: "0"
|
||||||
# target for "Restore Brightness" scripted ramp
|
# target for "Restore Brightness" scripted ramp
|
||||||
- id: restore_target_pct
|
- id: restore_target_pct
|
||||||
type: float
|
type: float
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: '0.0'
|
initial_value: "0.0"
|
||||||
# true while a scripted ramp is in progress (to limit flash writes)
|
# true while a scripted ramp is in progress (to limit flash writes)
|
||||||
- id: is_ramping
|
- id: is_ramping
|
||||||
type: bool
|
type: bool
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: 'false'
|
initial_value: "false"
|
||||||
# guards OFF persistence during startup caused by restore_mode: ALWAYS_OFF
|
# guards OFF persistence during startup caused by restore_mode: ALWAYS_OFF
|
||||||
- id: booting
|
- id: booting
|
||||||
type: bool
|
type: bool
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: 'true'
|
initial_value: "true"
|
||||||
# true only while we are performing a ramp-down that briefly turns the light ON to hit the floor
|
# true only while we are performing a ramp-down that briefly turns the light ON to hit the floor
|
||||||
- id: ramping_for_off
|
- id: ramping_for_off
|
||||||
type: bool
|
type: bool
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: 'false'
|
initial_value: "false"
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# LOGGER COMPONENT
|
# LOGGER COMPONENT
|
||||||
# https://esphome.io/components/logger.html
|
# https://esphome.io/components/logger.html
|
||||||
# Logs all log messages through the serial port and through MQTT topics.
|
# Logs all log messages through the serial port and through MQTT topics.
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
logger:
|
logger:
|
||||||
level: "${log_level}" # INFO Level suggested, or DEBUG for testing
|
level: "${log_level}" # INFO Level suggested, or DEBUG for testing
|
||||||
baud_rate: 0 # set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM, Serial control)
|
baud_rate: 0 # set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM, Serial control)
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# STATUS LED
|
# STATUS LED
|
||||||
# https://esphome.io/components/status_led.html
|
# https://esphome.io/components/status_led.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
status_led:
|
status_led:
|
||||||
pin:
|
pin:
|
||||||
number: ${device_status_led}
|
number: ${device_status_led}
|
||||||
inverted: true
|
inverted: true
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# MQTT COMMANDS
|
# MQTT COMMANDS
|
||||||
# This adds device-specific MQTT command triggers to the common MQTT configuration.
|
# This adds device-specific MQTT command triggers to the common MQTT configuration.
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
mqtt:
|
mqtt:
|
||||||
on_message:
|
on_message:
|
||||||
# Light control to ramp up
|
# Light control to ramp up
|
||||||
@@ -333,10 +361,10 @@ mqtt:
|
|||||||
then:
|
then:
|
||||||
- switch.turn_off: mosfet_ramp_switch
|
- switch.turn_off: mosfet_ramp_switch
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SWITCH COMPONENT
|
# SWITCH COMPONENT
|
||||||
# https://esphome.io/components/switch/
|
# https://esphome.io/components/switch/
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
switch:
|
switch:
|
||||||
# Ramp-aware ON/OFF for HA (asymmetric, eased; no bounce)
|
# Ramp-aware ON/OFF for HA (asymmetric, eased; no bounce)
|
||||||
- platform: template
|
- platform: template
|
||||||
@@ -356,10 +384,10 @@ switch:
|
|||||||
- script.stop: ramp_on_script
|
- script.stop: ramp_on_script
|
||||||
- script.execute: ramp_off_script
|
- script.execute: ramp_off_script
|
||||||
|
|
||||||
#################################################################################################
|
#:########################################################################################:#
|
||||||
# BUTTON COMPONENT
|
# BUTTON COMPONENT
|
||||||
# https://esphome.io/components/button/index.html
|
# https://esphome.io/components/button/index.html
|
||||||
#################################################################################################
|
#:########################################################################################:#
|
||||||
button:
|
button:
|
||||||
# Start ramping UP (from current level)
|
# Start ramping UP (from current level)
|
||||||
- platform: template
|
- platform: template
|
||||||
@@ -399,7 +427,7 @@ button:
|
|||||||
id(ramping_for_off) = false;
|
id(ramping_for_off) = false;
|
||||||
id(is_ramping) = false;
|
id(is_ramping) = false;
|
||||||
|
|
||||||
// Freeze the light at its *current* level by overwriting the transition
|
// Freeze the light at its current level by overwriting the transition
|
||||||
const auto &cv = id(mosfet_leds).current_values;
|
const auto &cv = id(mosfet_leds).current_values;
|
||||||
if (cv.is_on()) {
|
if (cv.is_on()) {
|
||||||
auto call = id(mosfet_leds).make_call();
|
auto call = id(mosfet_leds).make_call();
|
||||||
@@ -415,12 +443,10 @@ button:
|
|||||||
id(last_brightness_pct) = pct;
|
id(last_brightness_pct) = pct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
#########################################################################################
|
|
||||||
# SELECT COMPONENT
|
# SELECT COMPONENT
|
||||||
# https://esphome.io/components/select/index.html
|
# https://esphome.io/components/select/index.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
select:
|
select:
|
||||||
- platform: template
|
- platform: template
|
||||||
id: restart_action
|
id: restart_action
|
||||||
@@ -442,10 +468,10 @@ select:
|
|||||||
id(restart_mode) = 2;
|
id(restart_mode) = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# BINARY SENSORS
|
# BINARY SENSORS
|
||||||
# https://esphome.io/components/binary_sensor/
|
# https://esphome.io/components/binary_sensor/
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
id: btn_gpio12
|
id: btn_gpio12
|
||||||
@@ -462,7 +488,7 @@ binary_sensor:
|
|||||||
on_press:
|
on_press:
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
lambda: 'return id(ramp_switch_target_on);'
|
lambda: "return id(ramp_switch_target_on);"
|
||||||
then:
|
then:
|
||||||
# Target is currently ON -> press should go OFF (start ramp-down)
|
# Target is currently ON -> press should go OFF (start ramp-down)
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
@@ -478,10 +504,10 @@ binary_sensor:
|
|||||||
- script.stop: ramp_off_script
|
- script.stop: ramp_off_script
|
||||||
- script.execute: ramp_on_script
|
- script.execute: ramp_on_script
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SENSOR COMPONENT
|
# SENSOR COMPONENT
|
||||||
# https://esphome.io/components/sensor/
|
# https://esphome.io/components/sensor/
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
sensor:
|
sensor:
|
||||||
- platform: template
|
- platform: template
|
||||||
id: mosfet_output_pct
|
id: mosfet_output_pct
|
||||||
@@ -489,7 +515,7 @@ sensor:
|
|||||||
unit_of_measurement: "%"
|
unit_of_measurement: "%"
|
||||||
icon: mdi:percent
|
icon: mdi:percent
|
||||||
accuracy_decimals: 0
|
accuracy_decimals: 0
|
||||||
update_interval: 2s # consider 200ms if you want fewer updates
|
update_interval: 2s
|
||||||
lambda: |-
|
lambda: |-
|
||||||
const auto &cv = id(mosfet_leds).current_values;
|
const auto &cv = id(mosfet_leds).current_values;
|
||||||
return cv.is_on() ? (float) (int)(cv.get_brightness() * 100.0f + 0.5f) : 0.0f;
|
return cv.is_on() ? (float) (int)(cv.get_brightness() * 100.0f + 0.5f) : 0.0f;
|
||||||
@@ -530,28 +556,29 @@ sensor:
|
|||||||
if (pwm > 1.0f) pwm = 1.0f;
|
if (pwm > 1.0f) pwm = 1.0f;
|
||||||
return pwm * 100.0f;
|
return pwm * 100.0f;
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# OUTPUT COMPONENT
|
# OUTPUT COMPONENT
|
||||||
# https://esphome.io/components/light/index.html
|
# https://esphome.io/components/light/index.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# An OUTPUT can be binary (0,1) or float, which is any value between 0 and 1.
|
# An OUTPUT can be binary (0,1) or float, which is any value between 0 and 1.
|
||||||
# PWM Outputs such as "ledc" are float. https://esphome.io/components/output/ledc.html
|
# PWM Outputs such as "ledc" are float. https://esphome.io/components/output/ledc.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
output:
|
output:
|
||||||
- platform: esp8266_pwm
|
- platform: esp8266_pwm
|
||||||
id: mosfet_pwm
|
id: mosfet_pwm
|
||||||
pin: ${device_mosfet_out}
|
pin: ${device_mosfet_out}
|
||||||
frequency: ${pwm_frequency}
|
frequency: ${pwm_frequency}
|
||||||
|
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
id: green_led_out # Green LED
|
id: green_led_out # Green LED
|
||||||
pin:
|
pin:
|
||||||
number: ${device_fading_led}
|
number: ${device_fading_led}
|
||||||
inverted: false
|
inverted: false
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# LIGHT COMPONENT
|
# LIGHT COMPONENT
|
||||||
# https://esphome.io/components/light/
|
# https://esphome.io/components/light/
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
light:
|
light:
|
||||||
- platform: monochromatic
|
- platform: monochromatic
|
||||||
id: mosfet_leds
|
id: mosfet_leds
|
||||||
@@ -570,14 +597,14 @@ light:
|
|||||||
payload: "${mqtt_local_device_command_ON}"
|
payload: "${mqtt_local_device_command_ON}"
|
||||||
retain: true
|
retain: true
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
// Do not flip "intent to ON" when we're inside an OFF ramp's floor-kick
|
// Do not flip "intent to ON" when we are inside an OFF ramp's floor-kick
|
||||||
if (!id(ramping_for_off)) {
|
if (!id(ramping_for_off)) {
|
||||||
id(ramp_switch_target_on) = true;
|
id(ramp_switch_target_on) = true;
|
||||||
}
|
}
|
||||||
- script.stop: max_on_watchdog
|
- script.stop: max_on_watchdog
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
lambda: 'return id(max_on_hours) > 0;'
|
lambda: "return id(max_on_hours) > 0;"
|
||||||
then:
|
then:
|
||||||
- script.execute: max_on_watchdog
|
- script.execute: max_on_watchdog
|
||||||
|
|
||||||
@@ -587,13 +614,13 @@ light:
|
|||||||
- output.turn_off: green_led_out
|
- output.turn_off: green_led_out
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
lambda: 'return !id(booting);'
|
lambda: "return !id(booting);"
|
||||||
then:
|
then:
|
||||||
- mqtt.publish:
|
- mqtt.publish:
|
||||||
topic: "${mqtt_local_status_topic}/light/state"
|
topic: "${mqtt_local_status_topic}/light/state"
|
||||||
payload: "${mqtt_local_device_command_OFF}"
|
payload: "${mqtt_local_device_command_OFF}"
|
||||||
retain: true
|
retain: true
|
||||||
- lambda: 'id(ramp_switch_target_on) = false;'
|
- lambda: "id(ramp_switch_target_on) = false;"
|
||||||
- script.stop: max_on_watchdog
|
- script.stop: max_on_watchdog
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
id(last_brightness_pct) = 0.0f;
|
id(last_brightness_pct) = 0.0f;
|
||||||
@@ -614,11 +641,10 @@ light:
|
|||||||
call.set_transition_length(0);
|
call.set_transition_length(0);
|
||||||
call.perform();
|
call.perform();
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
|
||||||
# NUMBER COMPONENT
|
# NUMBER COMPONENT
|
||||||
# https://esphome.io/components/number/
|
# https://esphome.io/components/number/
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
number:
|
number:
|
||||||
- platform: template
|
- platform: template
|
||||||
id: cfg_ramp_up_s
|
id: cfg_ramp_up_s
|
||||||
@@ -683,10 +709,10 @@ number:
|
|||||||
set_action:
|
set_action:
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
lambda: 'return x <= 0.0f;'
|
lambda: "return x <= 0.0f;"
|
||||||
then:
|
then:
|
||||||
# 0 means OFF
|
# 0 means OFF
|
||||||
- lambda: 'id(suppress_slider_sync) = true;'
|
- lambda: "id(suppress_slider_sync) = true;"
|
||||||
- script.stop: ramp_on_script
|
- script.stop: ramp_on_script
|
||||||
- script.stop: ramp_off_script
|
- script.stop: ramp_off_script
|
||||||
- light.turn_off:
|
- light.turn_off:
|
||||||
@@ -698,7 +724,7 @@ number:
|
|||||||
id(last_brightness_pct) = 0.0f; // persist OFF immediately
|
id(last_brightness_pct) = 0.0f; // persist OFF immediately
|
||||||
id(last_set_pos) = 0;
|
id(last_set_pos) = 0;
|
||||||
- delay: 400ms
|
- delay: 400ms
|
||||||
- lambda: 'id(suppress_slider_sync) = false;'
|
- lambda: "id(suppress_slider_sync) = false;"
|
||||||
else:
|
else:
|
||||||
# Map 1..100 - [min..max] and set ON
|
# Map 1..100 - [min..max] and set ON
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
@@ -730,7 +756,7 @@ number:
|
|||||||
if (out_pct > maxp) out_pct = maxp;
|
if (out_pct > maxp) out_pct = maxp;
|
||||||
id(last_brightness_pct) = out_pct; // persist exact target now
|
id(last_brightness_pct) = out_pct; // persist exact target now
|
||||||
- delay: 400ms
|
- delay: 400ms
|
||||||
- lambda: 'id(suppress_slider_sync) = false;'
|
- lambda: "id(suppress_slider_sync) = false;"
|
||||||
|
|
||||||
- platform: template
|
- platform: template
|
||||||
id: cfg_max_on_hours
|
id: cfg_max_on_hours
|
||||||
@@ -753,27 +779,26 @@ number:
|
|||||||
id(cfg_max_on_hours).publish_state((float) hrs);
|
id(cfg_max_on_hours).publish_state((float) hrs);
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
lambda: 'return id(mosfet_leds).current_values.is_on();'
|
lambda: "return id(mosfet_leds).current_values.is_on();"
|
||||||
then:
|
then:
|
||||||
- script.stop: max_on_watchdog
|
- script.stop: max_on_watchdog
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
lambda: 'return id(max_on_hours) > 0;'
|
lambda: "return id(max_on_hours) > 0;"
|
||||||
then:
|
then:
|
||||||
- script.execute: max_on_watchdog
|
- script.execute: max_on_watchdog
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SCRIPT COMPONENT
|
# SCRIPT COMPONENT
|
||||||
# https://esphome.io/components/script.html
|
# https://esphome.io/components/script.html
|
||||||
# Scripts can be executed nearly anywhere in your device configuration with a single call.
|
# Scripts can be executed nearly anywhere in your device configuration with a single call.
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
script:
|
script:
|
||||||
|
# Script: ramp up from current level. Obey global max. (LED ON while ramping)
|
||||||
# Script: ramp up from current level. Obey global max. (LED ON while ramping)
|
|
||||||
- id: ramp_on_script
|
- id: ramp_on_script
|
||||||
mode: restart
|
mode: restart
|
||||||
then:
|
then:
|
||||||
- lambda: 'id(is_ramping) = true;'
|
- lambda: "id(is_ramping) = true;"
|
||||||
- script.stop: ramp_off_script
|
- script.stop: ramp_off_script
|
||||||
# Ensure we start at at least the floor without a visible "pop".
|
# Ensure we start at at least the floor without a visible "pop".
|
||||||
- if:
|
- if:
|
||||||
@@ -785,12 +810,12 @@ script:
|
|||||||
then:
|
then:
|
||||||
- light.turn_on:
|
- light.turn_on:
|
||||||
id: mosfet_leds
|
id: mosfet_leds
|
||||||
brightness: !lambda 'return id(min_brightness_pct) / 100.0f;'
|
brightness: !lambda "return id(min_brightness_pct) / 100.0f;"
|
||||||
transition_length: 80ms
|
transition_length: 80ms
|
||||||
# Ramp from current (>= floor) to cap over a fraction of ramp_up_ms.
|
# Ramp from current (>= floor) to cap over a fraction of ramp_up_ms.
|
||||||
- light.turn_on:
|
- light.turn_on:
|
||||||
id: mosfet_leds
|
id: mosfet_leds
|
||||||
brightness: !lambda 'return id(max_brightness_pct) / 100.0f;'
|
brightness: !lambda "return id(max_brightness_pct) / 100.0f;"
|
||||||
transition_length: !lambda |-
|
transition_length: !lambda |-
|
||||||
const auto &cv = id(mosfet_leds).current_values;
|
const auto &cv = id(mosfet_leds).current_values;
|
||||||
const float floor = id(min_brightness_pct) / 100.0f;
|
const float floor = id(min_brightness_pct) / 100.0f;
|
||||||
@@ -810,7 +835,7 @@ script:
|
|||||||
if (frac > 1.0f) frac = 1.0f;
|
if (frac > 1.0f) frac = 1.0f;
|
||||||
id(last_ramp_ms) = (int) (id(ramp_up_ms) * frac);
|
id(last_ramp_ms) = (int) (id(ramp_up_ms) * frac);
|
||||||
return (uint32_t) id(last_ramp_ms);
|
return (uint32_t) id(last_ramp_ms);
|
||||||
- delay: !lambda 'return (uint32_t) id(last_ramp_ms);'
|
- delay: !lambda "return (uint32_t) id(last_ramp_ms);"
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
id(is_ramping) = false;
|
id(is_ramping) = false;
|
||||||
const auto &cv = id(mosfet_leds).current_values;
|
const auto &cv = id(mosfet_leds).current_values;
|
||||||
@@ -823,7 +848,7 @@ script:
|
|||||||
- id: ramp_to_target_script
|
- id: ramp_to_target_script
|
||||||
mode: restart
|
mode: restart
|
||||||
then:
|
then:
|
||||||
- lambda: 'id(is_ramping) = true;'
|
- lambda: "id(is_ramping) = true;"
|
||||||
- script.stop: ramp_off_script
|
- script.stop: ramp_off_script
|
||||||
# Ensure we start at the floor cleanly.
|
# Ensure we start at the floor cleanly.
|
||||||
- if:
|
- if:
|
||||||
@@ -835,7 +860,7 @@ script:
|
|||||||
then:
|
then:
|
||||||
- light.turn_on:
|
- light.turn_on:
|
||||||
id: mosfet_leds
|
id: mosfet_leds
|
||||||
brightness: !lambda 'return id(min_brightness_pct) / 100.0f;'
|
brightness: !lambda "return id(min_brightness_pct) / 100.0f;"
|
||||||
transition_length: 80ms
|
transition_length: 80ms
|
||||||
# Ramp from current (>= floor) to restore_target_pct over a fraction of ramp_up_ms.
|
# Ramp from current (>= floor) to restore_target_pct over a fraction of ramp_up_ms.
|
||||||
- light.turn_on:
|
- light.turn_on:
|
||||||
@@ -866,7 +891,7 @@ script:
|
|||||||
if (frac > 1.0f) frac = 1.0f;
|
if (frac > 1.0f) frac = 1.0f;
|
||||||
id(last_ramp_ms) = (int) (id(ramp_up_ms) * frac);
|
id(last_ramp_ms) = (int) (id(ramp_up_ms) * frac);
|
||||||
return (uint32_t) id(last_ramp_ms);
|
return (uint32_t) id(last_ramp_ms);
|
||||||
- delay: !lambda 'return (uint32_t) id(last_ramp_ms);'
|
- delay: !lambda "return (uint32_t) id(last_ramp_ms);"
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
id(is_ramping) = false;
|
id(is_ramping) = false;
|
||||||
const auto &cv = id(mosfet_leds).current_values;
|
const auto &cv = id(mosfet_leds).current_values;
|
||||||
@@ -875,7 +900,6 @@ script:
|
|||||||
id(last_brightness_pct) = pct; // persist final level
|
id(last_brightness_pct) = pct; // persist final level
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Script: ramp down from current level to floor, then cleanly cut to OFF. (LED ON while ramping)
|
# Script: ramp down from current level to floor, then cleanly cut to OFF. (LED ON while ramping)
|
||||||
- id: ramp_off_script
|
- id: ramp_off_script
|
||||||
mode: restart
|
mode: restart
|
||||||
@@ -886,7 +910,7 @@ script:
|
|||||||
- script.stop: ramp_on_script
|
- script.stop: ramp_on_script
|
||||||
- light.turn_on:
|
- light.turn_on:
|
||||||
id: mosfet_leds
|
id: mosfet_leds
|
||||||
brightness: !lambda 'return id(min_brightness_pct) / 100.0f;'
|
brightness: !lambda "return id(min_brightness_pct) / 100.0f;"
|
||||||
transition_length: !lambda |-
|
transition_length: !lambda |-
|
||||||
const auto &cv = id(mosfet_leds).current_values;
|
const auto &cv = id(mosfet_leds).current_values;
|
||||||
const float floor = id(min_brightness_pct) / 100.0f;
|
const float floor = id(min_brightness_pct) / 100.0f;
|
||||||
@@ -899,7 +923,7 @@ script:
|
|||||||
if (frac > 1.0f) frac = 1.0f;
|
if (frac > 1.0f) frac = 1.0f;
|
||||||
id(last_ramp_ms) = (int) (id(ramp_down_ms) * frac);
|
id(last_ramp_ms) = (int) (id(ramp_down_ms) * frac);
|
||||||
return (uint32_t) id(last_ramp_ms);
|
return (uint32_t) id(last_ramp_ms);
|
||||||
- delay: !lambda 'return (uint32_t) id(last_ramp_ms);'
|
- delay: !lambda "return (uint32_t) id(last_ramp_ms);"
|
||||||
- light.turn_off:
|
- light.turn_off:
|
||||||
id: mosfet_leds
|
id: mosfet_leds
|
||||||
transition_length: 150ms
|
transition_length: 150ms
|
||||||
@@ -916,12 +940,12 @@ script:
|
|||||||
then:
|
then:
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
lambda: 'return id(max_on_hours) > 0;'
|
lambda: "return id(max_on_hours) > 0;"
|
||||||
then:
|
then:
|
||||||
- delay: !lambda 'return (uint32_t) (id(max_on_hours) * 3600000UL);'
|
- delay: !lambda "return (uint32_t) (id(max_on_hours) * 3600000UL);"
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
lambda: 'return id(mosfet_leds).current_values.is_on();'
|
lambda: "return id(mosfet_leds).current_values.is_on();"
|
||||||
then:
|
then:
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
id(ramp_switch_target_on) = false;
|
id(ramp_switch_target_on) = false;
|
||||||
@@ -948,18 +972,18 @@ script:
|
|||||||
|
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
lambda: 'return id(restore_target_pct) > 0.5f;'
|
lambda: "return id(restore_target_pct) > 0.5f;"
|
||||||
then:
|
then:
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
id(ramp_switch_target_on) = true; // reflect our intent
|
id(ramp_switch_target_on) = true; // reflect our intent
|
||||||
id(suppress_slider_sync) = true;
|
id(suppress_slider_sync) = true;
|
||||||
- script.stop: ramp_off_script
|
- script.stop: ramp_off_script
|
||||||
- script.execute: ramp_to_target_script
|
- script.execute: ramp_to_target_script
|
||||||
- delay: !lambda 'return (uint32_t) id(last_ramp_ms);'
|
- delay: !lambda "return (uint32_t) id(last_ramp_ms);"
|
||||||
- lambda: 'id(suppress_slider_sync) = false;'
|
- lambda: "id(suppress_slider_sync) = false;"
|
||||||
else:
|
else:
|
||||||
# Exact last was 0 -> remain OFF
|
# Exact last was 0 -> remain OFF
|
||||||
- lambda: 'id(ramp_switch_target_on) = false;'
|
- lambda: "id(ramp_switch_target_on) = false;"
|
||||||
- light.turn_off:
|
- light.turn_off:
|
||||||
id: mosfet_leds
|
id: mosfet_leds
|
||||||
transition_length: 0s
|
transition_length: 0s
|
||||||
|
|||||||
@@ -1,76 +1,95 @@
|
|||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# TITLE: LOUNGE CABINET LEDS
|
||||||
# Title: LOUNGE CABINET LEDS
|
# zorruno.com layout v1.1 2026
|
||||||
# Repo: https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-loungecabinetleds.yaml
|
#:########################################################################################:#
|
||||||
|
# REPO:
|
||||||
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-loungecabinetleds.yaml
|
||||||
|
#:########################################################################################:#
|
||||||
|
# VERSIONS:
|
||||||
|
# V2.1 2026-03-11 Updated yaml to zorruno layout V1.1
|
||||||
|
# V2.0 2025-09-15 A bunch of fixes, this is now the master for other similar mosfet controllers of mine
|
||||||
|
# V1.5 2025-09-11 First setup (copied from another template)
|
||||||
|
#:########################################################################################:#
|
||||||
|
# HARDWARE:
|
||||||
|
# - Sinilink MOSFET Board XY-WFMS (ESP8266) - sometimes listed as "XY-VFMS"
|
||||||
|
# - Reference:
|
||||||
|
# https://devices.esphome.io/devices/Sinilink-XY-WFMS
|
||||||
|
# - DEVICE GPIO (Sinilink XY-WFMS)
|
||||||
|
# - GPIO2 Blue LED, active-low (used for ESPHome status)
|
||||||
|
# - GPIO4 MOSFET output (0V when switched) and Red LED
|
||||||
|
# - GPIO12 Toggle button
|
||||||
|
# - GPIO13 Green LED (used to display fading status)
|
||||||
|
# - 3D-printed case for Sinilink XY-WFMS:
|
||||||
|
# https://cults3d.com/en/3d-model/tool/snapfit-enclosure-for-esp8266-sinilink-xy-wfms-5v-36v-mosfet-switch-module
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OPERATION NOTES:
|
||||||
|
# - General-purpose LED controller.
|
||||||
|
# - Designed for the Sinilink XY-WFMS board with a MOSFET output (claimed 5A, 5-36 V DC), but will suit similar MOSFET boards.
|
||||||
|
# - In SUBSTITUTIONS there is a MAX % output setting to extend LED life.
|
||||||
|
# - In SUBSTITUTIONS there is a minimum output setting; switches fully OFF at/below the minimum to avoid low-PWM flicker.
|
||||||
|
# - In SUBSTITUTIONS PWM frequency is set to 1kHz by default. You can increase it, but higher values caused resets on Sinilink device.
|
||||||
|
# - On ESP32 you can run much higher PWM frequencies (about 40 kHz).
|
||||||
|
# - Min/Max output settings are not exposed in Home Assistant/MQTT by default, but could be.
|
||||||
|
# - With a 1 MB flash, space is tight and only minimal optimisation has been done so far.
|
||||||
|
# - Included packages provide network settings, diagnostic entities, MQTT, and optional SNTP.
|
||||||
|
# - Default restart behaviours:
|
||||||
|
# - Fade up to full
|
||||||
|
# - Restore Brightness
|
||||||
|
# - Remain Off
|
||||||
|
# - The green LED flashes while fading. The red LED follows the output because it shares the MOSFET GPIO.
|
||||||
|
# - Fade timing scales with the configured values proportionally when starting mid-brightness.
|
||||||
|
# - Exposed in Home Assistant/MQTT:
|
||||||
|
# - Startup action (On, Off, Restore)
|
||||||
|
# - Fade Up / Fade Down / Fade Stop buttons
|
||||||
|
# - Fade Up/Down toggle switch
|
||||||
|
# - Normal On/Off switch
|
||||||
|
# - Fade up/down times (0-60s)
|
||||||
|
# - Output % (pre-gamma) and PWM % (post-gamma)
|
||||||
|
# - Output Set (1-100, respects min/max)
|
||||||
|
# - Many device diagnostics from the included diagnostics package
|
||||||
|
# - Maximum ON time before automatic fade-down (1-48 h, 0 = no limit)
|
||||||
#
|
#
|
||||||
# v2.0 - 2025-09-15 A bunch of fixes, this is now the master for other similar mosfet controllers of mine
|
# MQTT COMMANDS:
|
||||||
# v1.5 - 2025-09-11 First setup (copied from another template)
|
# - ${mqtt_local_command_topic}/light/set = ON
|
||||||
#
|
# - ${mqtt_local_command_topic}/light/set = OFF
|
||||||
# ------------------------------------------
|
# - State publishes to:
|
||||||
# OPERATION (as of v2.0)
|
# - ${mqtt_local_status_topic}/light/state
|
||||||
# ------------------------------------------
|
#:########################################################################################:#
|
||||||
# 1. General-purpose LED controller.
|
# OFFLINE NOTES:
|
||||||
# 2. Designed for the Sinilink XY-WFMS board with a MOSFET output (claimed 5A, 5-36 V DC), but will suit similar mosfet boards.
|
# a) Home Assistant offline (network and MQTT online)
|
||||||
# 3. (In SUBSTITUTIONS) setting for MAX % output to extend LED life (ie can ensure it is only ever 95%)
|
# - Local light logic, fades, restart behaviour, and watchdog timing continue to operate.
|
||||||
# 4. (In SUBSTITUTIONS) Minimum output setting; switches fully OFF at/below the minimum to avoid low-PWM flicker.
|
# - Local MQTT control and status publishing continue if the MQTT broker is online.
|
||||||
# 5. (In SUBSTITUTIONS) PWM frequency is set to 1kHz by default. You can increase it, but higher values caused
|
# b) MQTT offline (or HA/MQTT offline)
|
||||||
# resets on Sinilink device. On ESP32 you can run much higher (~40 kHz).
|
# - Local light logic, fades, restart behaviour, and watchdog timing continue to operate.
|
||||||
# 6. Min/Max output settings are not exposed in Home Assistant/MQTT by default, but could be.
|
# - MQTT control and MQTT state publishing are unavailable.
|
||||||
# With a 1 MB flash, space is tight and only minimal optimisation has been done so far.
|
# c) Entire WiFi/Network offline
|
||||||
# 7. (PACKAGES) include common items: network settings, diagnostic entities, MQTT, and SNTP (optional).
|
# - Local light logic, fades, restart behaviour, and watchdog timing continue to operate.
|
||||||
# 8. Default behaviours, for recovery from lost power or reset:
|
# - Accurate time is not needed (SNTP not needed).
|
||||||
# - "Fade up to full": fade from floor to max on boot.
|
#:########################################################################################:#
|
||||||
# - "Restore Brightness": fade from floor to the last non-zero brightness on boot (should be no on/off blip/flash).
|
|
||||||
# - "Remain Off": stays off on boot.
|
|
||||||
# 9. The green LED flashes while fading (different patterns for up/down). The red LED follows the
|
|
||||||
# output (it shares the MOSFET GPIO). (Obviously this depends on hardware)
|
|
||||||
# 10. Fade timing scales with the configured values (proportionally when starting mid-brightness).
|
|
||||||
# 11. Exposed in Home Assistant/MQTT:
|
|
||||||
# - Startup action (On,Off,Restore)
|
|
||||||
# - Fade Up / Fade Down / Fade Stop buttons
|
|
||||||
# - Fade Up/Down toggle switch (keeps fading up to full, or down to off unless stopped)
|
|
||||||
# - Normal On/Off switch (quick ramp up/down, up to the level of previous brightness)
|
|
||||||
# - Fade up/down times (0-60s)
|
|
||||||
# - Output % (pre-gamma) and PWM % (post-gamma)
|
|
||||||
# - Output Set (1-100, respects min/max). This also changes with other output so reflects value.
|
|
||||||
# - Many device diagnostics (from the included 'diagnostics' package)
|
|
||||||
# - Maximum 'on' time before automatic fade-down (1-48 h, 0 = no limit)
|
|
||||||
###########################################################################################
|
|
||||||
# Hardware: Sinilink MOSFET Board XY-WFMS (ESP8266) - sometimes listed as "XY-VFMS"
|
|
||||||
# https://devices.esphome.io/devices/Sinilink-XY-WFMS
|
|
||||||
# ------------------------------------------
|
|
||||||
# DEVICE GPIO (Sinilink XY-WFMS)
|
|
||||||
# ------------------------------------------
|
|
||||||
# GPIO02 Blue LED, active-low (used for ESPHome status)
|
|
||||||
# GPIO04 MOSFET output (0V when switched) and Red LED
|
|
||||||
# GPIO12 Toggle button
|
|
||||||
# GPIO13 Green LED (used to display fading status)
|
|
||||||
#
|
|
||||||
# 3D-printed case for Sinilink XY-WFMS
|
|
||||||
# https://cults3d.com/en/3d-model/tool/snapfit-enclosure-for-esp8266-sinilink-xy-wfms-5v-36v-mosfet-switch-module
|
|
||||||
#
|
|
||||||
##########################################################################################
|
|
||||||
##########################################################################################
|
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
|
# SUBSTITUTIONS: Specific device variable substitutions
|
||||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
substitutions:
|
substitutions:
|
||||||
# Device Naming
|
# Device Naming
|
||||||
device_name: "esp-loungecabinetleds2" # yaml file should be device_name.yaml
|
device_name: "esp-loungecabinetleds" # yaml file should be device_name.yaml
|
||||||
friendly_name: "Lounge Cabinet LEDs"
|
friendly_name: "Lounge Cabinet LEDs"
|
||||||
description_comment: "LED Strip inside the display cabinet upstairs lounge :: Sinilink XY-WFMS"
|
description_comment: "LED Strip inside the display cabinet upstairs lounge :: Sinilink XY-WFMS (Layout V1.1)"
|
||||||
device_area: "Lounge" # Allows the ESP device to be automatically linked to an 'Area' in Home Assistant.
|
device_area: "Lounge" # Allows the ESP device to be automatically linked to an 'Area' in Home Assistant.
|
||||||
|
|
||||||
# Project Naming
|
# Project Naming
|
||||||
project_name: "Sinilink.XY-WFMS" # Project details. Manufacturer before the dot, device after the dot.
|
project_name: "Sinilink.XY-WFMS" # Project details. Manufacturer before the dot, device after the dot.
|
||||||
project_version: "v2.0" # Project version denotes release of the YAML file, allowing checking of deployed vs latest version
|
project_version: "v2.1" # Project version denotes release of the YAML file, allowing checking of deployed vs latest version
|
||||||
|
|
||||||
# Passwords & Secrets (Unfortunately, you can't use substitutions inside secret names)
|
# Passwords & Secrets (Unfortunately, you can't use substitutions inside secret names)
|
||||||
api_key: !secret esp-api_key # If using HA API
|
api_key: !secret esp-api_key # If using HA API
|
||||||
ota_pass: !secret esp-ota_pass # If passwording OTA updates
|
ota_pass: !secret esp-ota_pass # If passwording OTA updates
|
||||||
static_ip_address: !secret esp-loungecabinetleds2_ip # CHANGE THIS
|
static_ip_address: !secret esp-loungecabinetleds_ip # CHANGE THIS
|
||||||
|
|
||||||
|
# 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}
|
||||||
|
|
||||||
# MQTT LOCAL Controls (This is just my local method of controlling via MQTT, I also use the built in method)
|
# MQTT LOCAL Controls (This is just my local method of controlling via MQTT, I also use the built in method)
|
||||||
mqtt_local_device_name: "lounge-cabinetleds"
|
mqtt_local_device_name: "lounge-cabinetleds"
|
||||||
@@ -82,24 +101,24 @@ substitutions:
|
|||||||
mqtt_local_device_command_OFF: "OFF"
|
mqtt_local_device_command_OFF: "OFF"
|
||||||
|
|
||||||
# Device Specific Settings
|
# Device Specific Settings
|
||||||
log_level: "NONE" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (default), VERBOSE, VERY_VERBOSE
|
log_level: "NONE" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (default), VERBOSE, VERY_VERBOSE
|
||||||
update_interval: "30s" # Update time for general sensors, etc.
|
update_interval: "30s" # Update time for general sensors, etc.
|
||||||
led_gamma: "1.2" # Gamma from 1.2-3 is sensible to normalise the LED fading vs PWM
|
led_gamma: "1.2" # Gamma from 1.2-3 is sensible to normalise the LED fading vs PWM
|
||||||
minimum_led_output: "1" # % If at this value or below, we'll switch it completely off
|
minimum_led_output: "1" # % If at this value or below, we'll switch it completely off
|
||||||
maximum_led_output: "90" # % Maximum output; it is sometimes nice to limit the output for longevity or aesthetics
|
maximum_led_output: "90" # % Maximum output; it is sometimes nice to limit the output for longevity or aesthetics
|
||||||
max_on_default_hours: "24" # The maximum time the LEDs will be on, in case they get left on. 0 = no automatic turn-off
|
max_on_default_hours: "24" # The maximum time the LEDs will be on, in case they get left on. 0 = no automatic turn-off
|
||||||
pwm_frequency: "1000" # PWM output Frequency in Hz. High enough to avoid audible/visible artifacts
|
pwm_frequency: "1000" # PWM output Frequency in Hz. High enough to avoid audible/visible artifacts
|
||||||
|
|
||||||
# Device Specific GPIO (so we can easily update for other devices)
|
# Device Specific GPIO (so we can easily update for other devices)
|
||||||
device_status_led: GPIO02
|
device_status_led: GPIO2
|
||||||
device_mosfet_out: GPIO04
|
device_mosfet_out: GPIO4
|
||||||
device_usr_button: GPIO12 # if no button, this is just a fake/safeish choice so it compiles with the generic yaml
|
device_usr_button: GPIO12 # if no button, this is just a fake/safeish choice so it compiles with the generic yaml
|
||||||
device_fading_led: GPIO13 # if no LED, this is just a fake/safeish choice so it compiles with the generic yaml
|
device_fading_led: GPIO13 # if no LED, this is just a fake/safeish choice so it compiles with the generic yaml
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# PACKAGES: Included Common Packages
|
# PACKAGES: Included Common Packages
|
||||||
# https://esphome.io/components/packages.html
|
# https://esphome.io/components/packages.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
packages:
|
packages:
|
||||||
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
||||||
common_wifi: !include
|
common_wifi: !include
|
||||||
@@ -108,6 +127,7 @@ packages:
|
|||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
local_static_ip_address: "${static_ip_address}"
|
local_static_ip_address: "${static_ip_address}"
|
||||||
local_ota_pass: "${ota_pass}"
|
local_ota_pass: "${ota_pass}"
|
||||||
|
local_current_ip_address: "${current_ip_address}"
|
||||||
|
|
||||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||||
common_api: !include
|
common_api: !include
|
||||||
@@ -121,27 +141,31 @@ packages:
|
|||||||
file: common/mqtt_common.yaml
|
file: common/mqtt_common.yaml
|
||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
|
|
||||||
#### WEB PORTAL ####
|
#### WEB PORTAL ####
|
||||||
#common_webportal: !include common/webportal_common.yaml
|
#common_webportal: !include common/webportal_common.yaml
|
||||||
|
|
||||||
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
||||||
#common_sntp: !include common/sntp_common.yaml
|
#common_sntp: !include common/sntp_common.yaml
|
||||||
|
|
||||||
#### DIAGNOSTICS Sensors ####
|
#### DIAGNOSTICS Sensors ####
|
||||||
diag_basic: !include common/include_basic_diag_sensors.yaml
|
diag_basic: !include common/include_basic_diag_sensors.yaml
|
||||||
#diag_more: !include common/include_more_diag_sensors.yaml
|
#diag_more: !include common/include_more_diag_sensors.yaml
|
||||||
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
||||||
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# ESPHome CORE CONFIGURATION
|
# ESPHOME CORE CONFIGURATION
|
||||||
# https://esphome.io/components/esphome.html
|
# https://esphome.io/components/esphome.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
esphome:
|
esphome:
|
||||||
name: "${device_name}"
|
name: "${device_name}"
|
||||||
friendly_name: "${friendly_name}"
|
friendly_name: "${friendly_name}"
|
||||||
comment: "${description_comment}"
|
comment: "${description_comment}"
|
||||||
area: "${device_area}"
|
area: "${device_area}"
|
||||||
|
project:
|
||||||
|
name: "${project_name}"
|
||||||
|
version: "${project_version}"
|
||||||
on_boot:
|
on_boot:
|
||||||
# Run later so everything is initialised before we touch states.
|
# Run later so everything is initialised before we touch states.
|
||||||
priority: 200
|
priority: 200
|
||||||
@@ -198,11 +222,11 @@ esphome:
|
|||||||
# - -fdata-sections
|
# - -fdata-sections
|
||||||
# - -DNDEBUG
|
# - -DNDEBUG
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# ESP PLATFORM AND FRAMEWORK
|
# ESP PLATFORM AND FRAMEWORK
|
||||||
# https://esphome.io/components/esp8266.html
|
# https://esphome.io/components/esp8266.html
|
||||||
# https://esphome.io/components/esp32.html
|
# https://esphome.io/components/esp32.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
esp8266:
|
esp8266:
|
||||||
board: esp01_1m
|
board: esp01_1m
|
||||||
restore_from_flash: true # restore some values on reboot
|
restore_from_flash: true # restore some values on reboot
|
||||||
@@ -213,47 +237,52 @@ mdns:
|
|||||||
preferences:
|
preferences:
|
||||||
flash_write_interval: 2min # enough time to update values for reboots, but not enough to wear flash
|
flash_write_interval: 2min # enough time to update values for reboots, but not enough to wear flash
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# GLOBAL VARIABLES
|
# GLOBAL VARIABLES
|
||||||
# https://esphome.io/components/globals.html
|
# https://esphome.io/components/globals.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
globals:
|
globals:
|
||||||
# Minimum Brightness % for LEDs (will switch off if <=)
|
# Minimum Brightness % for LEDs (will switch off if <=)
|
||||||
- id: min_brightness_pct
|
- id: min_brightness_pct
|
||||||
type: int
|
type: int
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: "${minimum_led_output}" # start/finish at X%
|
initial_value: "${minimum_led_output}" # start/finish at X%
|
||||||
|
|
||||||
# Maximum Brightness % for LEDs (should never go beyond this)
|
# Maximum Brightness % for LEDs (should never go beyond this)
|
||||||
- id: max_brightness_pct
|
- id: max_brightness_pct
|
||||||
type: int
|
type: int
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: "${maximum_led_output}" # hard cap; never exceed this
|
initial_value: "${maximum_led_output}" # hard cap; never exceed this
|
||||||
# The maximum time the lights will stay on, in hours. Just in case they are left on. 0 = forever
|
|
||||||
|
# The maximum time the lights will stay on, in hours. Just in case they are left on. 0 = forever
|
||||||
- id: max_on_hours
|
- id: max_on_hours
|
||||||
type: int
|
type: int
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: "${max_on_default_hours}"
|
initial_value: "${max_on_default_hours}"
|
||||||
|
|
||||||
# Compile time Gamma
|
# Compile time Gamma
|
||||||
- id: led_gamma_f
|
- id: led_gamma_f
|
||||||
type: float
|
type: float
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: ${led_gamma} # <-- numeric at compile time
|
initial_value: ${led_gamma} # numeric at compile time
|
||||||
|
|
||||||
# Default Fading Up Time (Selectable and will be retained)
|
# Default Fading Up Time (Selectable and will be retained)
|
||||||
- id: ramp_up_ms # fade-in when turned ON
|
- id: ramp_up_ms # fade-in when turned ON
|
||||||
type: int
|
type: int
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: '5000' # 5 s
|
initial_value: "5000" # 5 s
|
||||||
|
|
||||||
# Default Fading Down Time (Selectable and will be retained)
|
# Default Fading Down Time (Selectable and will be retained)
|
||||||
- id: ramp_down_ms # fade-out when turned OFF
|
- id: ramp_down_ms # fade-out when turned OFF
|
||||||
type: int
|
type: int
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: '10000' # 10 s
|
initial_value: "10000" # 10 s
|
||||||
|
|
||||||
# Action on Restart. (0=Fade full, 1=Restore brightness, 2=Remain off)
|
# Action on Restart. (0=Fade full, 1=Restore brightness, 2=Remain off)
|
||||||
- id: restart_mode
|
- id: restart_mode
|
||||||
type: int
|
type: int
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: '0' # default = Fade Up to Full (so can be deployed with no other setup)
|
initial_value: "0" # default = Fade Up to Full (so can be deployed with no other setup)
|
||||||
|
|
||||||
# Determine last fade direction.
|
# Determine last fade direction.
|
||||||
# true when you asked the light to end up ON (Ramp Up)
|
# true when you asked the light to end up ON (Ramp Up)
|
||||||
@@ -261,70 +290,78 @@ globals:
|
|||||||
- id: ramp_switch_target_on
|
- id: ramp_switch_target_on
|
||||||
type: bool
|
type: bool
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: 'false'
|
initial_value: "false"
|
||||||
|
|
||||||
# Prevent jitter when adjusting the slider
|
# Prevent jitter when adjusting the slider
|
||||||
- id: suppress_slider_sync
|
- id: suppress_slider_sync
|
||||||
type: bool
|
type: bool
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: 'false'
|
initial_value: "false"
|
||||||
# actual 0..100 seen last time, for restart
|
|
||||||
- id: last_brightness_pct
|
# actual 0..100 seen last time, for restart
|
||||||
|
- id: last_brightness_pct
|
||||||
type: float
|
type: float
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: '0.0'
|
initial_value: "0.0"
|
||||||
|
|
||||||
# last published "Output Set (0-100)" integer
|
# last published "Output Set (0-100)" integer
|
||||||
- id: last_set_pos
|
- id: last_set_pos
|
||||||
type: int
|
type: int
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: '-1'
|
initial_value: "-1"
|
||||||
# helper to keep blink time == transition time
|
|
||||||
|
# helper to keep blink time == transition time
|
||||||
- id: last_ramp_ms
|
- id: last_ramp_ms
|
||||||
type: int
|
type: int
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: '0'
|
initial_value: "0"
|
||||||
|
|
||||||
# target for "Restore Brightness" scripted ramp
|
# target for "Restore Brightness" scripted ramp
|
||||||
- id: restore_target_pct
|
- id: restore_target_pct
|
||||||
type: float
|
type: float
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: '0.0'
|
initial_value: "0.0"
|
||||||
|
|
||||||
# true while a scripted ramp is in progress (to limit flash writes)
|
# true while a scripted ramp is in progress (to limit flash writes)
|
||||||
- id: is_ramping
|
- id: is_ramping
|
||||||
type: bool
|
type: bool
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: 'false'
|
initial_value: "false"
|
||||||
|
|
||||||
# guards OFF persistence during startup caused by restore_mode: ALWAYS_OFF
|
# guards OFF persistence during startup caused by restore_mode: ALWAYS_OFF
|
||||||
- id: booting
|
- id: booting
|
||||||
type: bool
|
type: bool
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: 'true'
|
initial_value: "true"
|
||||||
|
|
||||||
# true only while we are performing a ramp-down that briefly turns the light ON to hit the floor
|
# true only while we are performing a ramp-down that briefly turns the light ON to hit the floor
|
||||||
- id: ramping_for_off
|
- id: ramping_for_off
|
||||||
type: bool
|
type: bool
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: 'false'
|
initial_value: "false"
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# LOGGER COMPONENT
|
# LOGGER COMPONENT
|
||||||
# https://esphome.io/components/logger.html
|
# https://esphome.io/components/logger.html
|
||||||
# Logs all log messages through the serial port and through MQTT topics.
|
# Logs all log messages through the serial port and through MQTT topics.
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
logger:
|
logger:
|
||||||
level: "${log_level}" # INFO Level suggested, or DEBUG for testing
|
level: "${log_level}" # INFO Level suggested, or DEBUG for testing
|
||||||
baud_rate: 0 # set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM, Serial control)
|
baud_rate: 0 # set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM, Serial control)
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# STATUS LED
|
# STATUS LED
|
||||||
# https://esphome.io/components/status_led.html
|
# https://esphome.io/components/status_led.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
status_led:
|
status_led:
|
||||||
pin:
|
pin:
|
||||||
number: ${device_status_led}
|
number: ${device_status_led}
|
||||||
inverted: true
|
inverted: true
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# MQTT COMMANDS
|
# MQTT COMMANDS
|
||||||
# This adds device-specific MQTT command triggers to the common MQTT configuration.
|
# This adds device-specific MQTT command triggers to the common MQTT configuration.
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
mqtt:
|
mqtt:
|
||||||
on_message:
|
on_message:
|
||||||
# Light control to ramp up
|
# Light control to ramp up
|
||||||
@@ -332,16 +369,17 @@ mqtt:
|
|||||||
payload: "${mqtt_local_device_command_ON}"
|
payload: "${mqtt_local_device_command_ON}"
|
||||||
then:
|
then:
|
||||||
- switch.turn_on: mosfet_ramp_switch
|
- switch.turn_on: mosfet_ramp_switch
|
||||||
|
|
||||||
# Light control to ramp down
|
# Light control to ramp down
|
||||||
- topic: "${mqtt_local_command_topic}/light/set"
|
- topic: "${mqtt_local_command_topic}/light/set"
|
||||||
payload: "${mqtt_local_device_command_OFF}"
|
payload: "${mqtt_local_device_command_OFF}"
|
||||||
then:
|
then:
|
||||||
- switch.turn_off: mosfet_ramp_switch
|
- switch.turn_off: mosfet_ramp_switch
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SWITCH COMPONENT
|
# SWITCH COMPONENT
|
||||||
# https://esphome.io/components/switch/
|
# https://esphome.io/components/switch/
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
switch:
|
switch:
|
||||||
# Ramp-aware ON/OFF for HA (asymmetric, eased; no bounce)
|
# Ramp-aware ON/OFF for HA (asymmetric, eased; no bounce)
|
||||||
- platform: template
|
- platform: template
|
||||||
@@ -361,10 +399,10 @@ switch:
|
|||||||
- script.stop: ramp_on_script
|
- script.stop: ramp_on_script
|
||||||
- script.execute: ramp_off_script
|
- script.execute: ramp_off_script
|
||||||
|
|
||||||
#################################################################################################
|
#:########################################################################################:#
|
||||||
# BUTTON COMPONENT
|
# BUTTON COMPONENT
|
||||||
# https://esphome.io/components/button/index.html
|
# https://esphome.io/components/button/index.html
|
||||||
#################################################################################################
|
#:########################################################################################:#
|
||||||
button:
|
button:
|
||||||
# Start ramping UP (from current level)
|
# Start ramping UP (from current level)
|
||||||
- platform: template
|
- platform: template
|
||||||
@@ -404,7 +442,7 @@ button:
|
|||||||
id(ramping_for_off) = false;
|
id(ramping_for_off) = false;
|
||||||
id(is_ramping) = false;
|
id(is_ramping) = false;
|
||||||
|
|
||||||
// Freeze the light at its *current* level by overwriting the transition
|
// Freeze the light at its current level by overwriting the transition
|
||||||
const auto &cv = id(mosfet_leds).current_values;
|
const auto &cv = id(mosfet_leds).current_values;
|
||||||
if (cv.is_on()) {
|
if (cv.is_on()) {
|
||||||
auto call = id(mosfet_leds).make_call();
|
auto call = id(mosfet_leds).make_call();
|
||||||
@@ -420,12 +458,10 @@ button:
|
|||||||
id(last_brightness_pct) = pct;
|
id(last_brightness_pct) = pct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
#########################################################################################
|
|
||||||
# SELECT COMPONENT
|
# SELECT COMPONENT
|
||||||
# https://esphome.io/components/select/index.html
|
# https://esphome.io/components/select/index.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
select:
|
select:
|
||||||
- platform: template
|
- platform: template
|
||||||
id: restart_action
|
id: restart_action
|
||||||
@@ -447,10 +483,10 @@ select:
|
|||||||
id(restart_mode) = 2;
|
id(restart_mode) = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# BINARY SENSORS
|
# BINARY SENSORS
|
||||||
# https://esphome.io/components/binary_sensor/
|
# https://esphome.io/components/binary_sensor/
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
id: btn_gpio12
|
id: btn_gpio12
|
||||||
@@ -483,10 +519,10 @@ binary_sensor:
|
|||||||
- script.stop: ramp_off_script
|
- script.stop: ramp_off_script
|
||||||
- script.execute: ramp_on_script
|
- script.execute: ramp_on_script
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SENSOR COMPONENT
|
# SENSOR COMPONENT
|
||||||
# https://esphome.io/components/sensor/
|
# https://esphome.io/components/sensor/
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
sensor:
|
sensor:
|
||||||
- platform: template
|
- platform: template
|
||||||
id: mosfet_output_pct
|
id: mosfet_output_pct
|
||||||
@@ -494,7 +530,7 @@ sensor:
|
|||||||
unit_of_measurement: "%"
|
unit_of_measurement: "%"
|
||||||
icon: mdi:percent
|
icon: mdi:percent
|
||||||
accuracy_decimals: 0
|
accuracy_decimals: 0
|
||||||
update_interval: 2s # consider 200ms if you want fewer updates
|
update_interval: 2s # consider 200ms if you want fewer updates
|
||||||
lambda: |-
|
lambda: |-
|
||||||
const auto &cv = id(mosfet_leds).current_values;
|
const auto &cv = id(mosfet_leds).current_values;
|
||||||
return cv.is_on() ? (float) (int)(cv.get_brightness() * 100.0f + 0.5f) : 0.0f;
|
return cv.is_on() ? (float) (int)(cv.get_brightness() * 100.0f + 0.5f) : 0.0f;
|
||||||
@@ -535,28 +571,29 @@ sensor:
|
|||||||
if (pwm > 1.0f) pwm = 1.0f;
|
if (pwm > 1.0f) pwm = 1.0f;
|
||||||
return pwm * 100.0f;
|
return pwm * 100.0f;
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# OUTPUT COMPONENT
|
# OUTPUT COMPONENT
|
||||||
# https://esphome.io/components/light/index.html
|
# https://esphome.io/components/output/
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# An OUTPUT can be binary (0,1) or float, which is any value between 0 and 1.
|
# An OUTPUT can be binary (0,1) or float, which is any value between 0 and 1.
|
||||||
# PWM Outputs such as "ledc" are float. https://esphome.io/components/output/ledc.html
|
# PWM Outputs such as "ledc" are float. https://esphome.io/components/output/ledc.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
output:
|
output:
|
||||||
- platform: esp8266_pwm
|
- platform: esp8266_pwm
|
||||||
id: mosfet_pwm
|
id: mosfet_pwm
|
||||||
pin: ${device_mosfet_out}
|
pin: ${device_mosfet_out}
|
||||||
frequency: ${pwm_frequency}
|
frequency: ${pwm_frequency}
|
||||||
|
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
id: green_led_out # Green LED
|
id: green_led_out # Green LED
|
||||||
pin:
|
pin:
|
||||||
number: ${device_fading_led}
|
number: ${device_fading_led}
|
||||||
inverted: false
|
inverted: false
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# LIGHT COMPONENT
|
# LIGHT COMPONENT
|
||||||
# https://esphome.io/components/light/
|
# https://esphome.io/components/light/
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
light:
|
light:
|
||||||
- platform: monochromatic
|
- platform: monochromatic
|
||||||
id: mosfet_leds
|
id: mosfet_leds
|
||||||
@@ -619,11 +656,10 @@ light:
|
|||||||
call.set_transition_length(0);
|
call.set_transition_length(0);
|
||||||
call.perform();
|
call.perform();
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
|
||||||
# NUMBER COMPONENT
|
# NUMBER COMPONENT
|
||||||
# https://esphome.io/components/number/
|
# https://esphome.io/components/number/
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
number:
|
number:
|
||||||
- platform: template
|
- platform: template
|
||||||
id: cfg_ramp_up_s
|
id: cfg_ramp_up_s
|
||||||
@@ -767,14 +803,13 @@ number:
|
|||||||
then:
|
then:
|
||||||
- script.execute: max_on_watchdog
|
- script.execute: max_on_watchdog
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SCRIPT COMPONENT
|
# SCRIPT COMPONENT
|
||||||
# https://esphome.io/components/script.html
|
# https://esphome.io/components/script.html
|
||||||
# Scripts can be executed nearly anywhere in your device configuration with a single call.
|
# Scripts can be executed nearly anywhere in your device configuration with a single call.
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
script:
|
script:
|
||||||
|
# Script: ramp up from current level. Obey global max. (LED ON while ramping)
|
||||||
# Script: ramp up from current level. Obey global max. (LED ON while ramping)
|
|
||||||
- id: ramp_on_script
|
- id: ramp_on_script
|
||||||
mode: restart
|
mode: restart
|
||||||
then:
|
then:
|
||||||
@@ -880,7 +915,6 @@ script:
|
|||||||
id(last_brightness_pct) = pct; // persist final level
|
id(last_brightness_pct) = pct; // persist final level
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Script: ramp down from current level to floor, then cleanly cut to OFF. (LED ON while ramping)
|
# Script: ramp down from current level to floor, then cleanly cut to OFF. (LED ON while ramping)
|
||||||
- id: ramp_off_script
|
- id: ramp_off_script
|
||||||
mode: restart
|
mode: restart
|
||||||
@@ -938,7 +972,7 @@ script:
|
|||||||
- id: deferred_restore_brightness
|
- id: deferred_restore_brightness
|
||||||
mode: restart
|
mode: restart
|
||||||
then:
|
then:
|
||||||
- delay: 5s # let preferences/globals load and light settle
|
- delay: 5s # let preferences/globals load and light settle
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
// Use ONLY the exact last saved brightness.
|
// Use ONLY the exact last saved brightness.
|
||||||
float target = id(last_brightness_pct);
|
float target = id(last_brightness_pct);
|
||||||
@@ -968,4 +1002,4 @@ script:
|
|||||||
- light.turn_off:
|
- light.turn_off:
|
||||||
id: mosfet_leds
|
id: mosfet_leds
|
||||||
transition_length: 0s
|
transition_length: 0s
|
||||||
# (Removed: output.turn_off: green_led_out) # make sure LED is off if no ramp
|
# (Removed: output.turn_off: green_led_out) # make sure LED is off if no ramp
|
||||||
@@ -1,31 +1,86 @@
|
|||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# TITLE: LOUNGE ENVIRONMENT SENSOR
|
||||||
# LOUNGE ENVIRONMENT SENSOR
|
#:########################################################################################:#
|
||||||
#
|
# REPO:
|
||||||
# ESP32-C3 SuperMini + BME280 (I2C)
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-loungeenvironment.yaml
|
||||||
#
|
#:########################################################################################:#
|
||||||
|
# VERSIONS:
|
||||||
|
# V1.5 2026-03-22 Updated yaml to zorruno layout V1.1; fixed units to °C; added
|
||||||
|
# device_class/state_class; retained MQTT publishing and all existing logic
|
||||||
|
# V1.4 2026-03-22 Updated yaml to zorruno layout V1.1; added MQTT publishing for
|
||||||
|
# temperature, humidity and pressure; retained all existing sensor logic
|
||||||
|
# V1.3 2026-03-22 Added MQTT publishing for temperature, humidity and pressure readings
|
||||||
# V1.2 2026-02-16 Pressure tendency now 5-state over 3 hours + rate/hour, 1h removed
|
# V1.2 2026-02-16 Pressure tendency now 5-state over 3 hours + rate/hour, 1h removed
|
||||||
# V1.1 2026-02-16 Added derived min/max sensors and pressure trend text sensors
|
# V1.1 2026-02-16 Added derived min/max sensors and pressure trend text sensors
|
||||||
# V1.0 2026-02-16 Initial Version
|
# V1.0 2026-02-16 Initial Version
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# HARDWARE:
|
||||||
|
# - ESP32-C3 SuperMini
|
||||||
|
# - BME280 (I2C)
|
||||||
|
# - SDA = GPIO1
|
||||||
|
# - SCL = GPIO3
|
||||||
|
# - I2C address = 0x76
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OPERATION NOTES:
|
||||||
|
# - Reads temperature, humidity and pressure from the BME280 every 20 seconds
|
||||||
|
# - Publishes each fresh reading to local MQTT status topics:
|
||||||
|
# - ${mqtt_local_status_topic}/temperature
|
||||||
|
# - ${mqtt_local_status_topic}/humidity
|
||||||
|
# - ${mqtt_local_status_topic}/pressure
|
||||||
|
# - Tracks:
|
||||||
|
# - Lowest Temp Overnight
|
||||||
|
# - Highest Temp Today (Daytime)
|
||||||
|
# - Highest/Lowest Temp This Month
|
||||||
|
# - Highest/Lowest Temp Last Month
|
||||||
|
# - Highest/Lowest Temp Last 24 Hours
|
||||||
|
# - Lowest Humidity Overnight
|
||||||
|
# - Highest Humidity Today (Daytime)
|
||||||
|
# - Highest/Lowest Humidity This Month
|
||||||
|
# - Highest/Lowest Humidity Last Month
|
||||||
|
# - Highest/Lowest Humidity Last 24 Hours
|
||||||
|
# - Pressure direction uses a 3-hour tendency:
|
||||||
|
# - rising rapidly
|
||||||
|
# - rising
|
||||||
|
# - steady
|
||||||
|
# - falling
|
||||||
|
# - falling rapidly
|
||||||
|
# - Pressure rate per hour is calculated from the 3-hour pressure delta
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OFFLINE NOTES:
|
||||||
|
# a) HA offline (network + MQTT online)
|
||||||
|
# - Device continues reading sensors and publishing local MQTT status topics.
|
||||||
|
# b) MQTT offline (or HA/MQTT offline)
|
||||||
|
# - Device continues reading sensors and updating local derived values internally.
|
||||||
|
# c) Entire WiFi/Network offline
|
||||||
|
# - Accurate time is needed for daily/monthly min/max periods and pressure trend timing.
|
||||||
|
# - If SNTP is unavailable, the fallback clock can drift and can be reset by power
|
||||||
|
# cycling at 12pm (midday).
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
substitutions:
|
substitutions:
|
||||||
# Device Naming
|
# Device Naming
|
||||||
device_name: "esp-loungeenvironment"
|
device_name: "esp-loungeenvironment"
|
||||||
friendly_name: "Lounge Environment"
|
friendly_name: "Lounge Environment"
|
||||||
description_comment: "Lounge Environment :: ESP32-C3 SuperMini + BME280"
|
description_comment: "Lounge Environment :: ESP32-C3 SuperMini + BME280 (Layout V1.1)"
|
||||||
device_area: "Lounge"
|
device_area: "Lounge"
|
||||||
|
|
||||||
# Project Naming
|
# Project Naming
|
||||||
project_name: "ESP32-C3 SuperMini.BME280"
|
project_name: "ESP32-C3 SuperMini.BME280"
|
||||||
project_version: "v1.2"
|
project_version: "v1.5"
|
||||||
|
|
||||||
# Passwords
|
# Passwords
|
||||||
api_key: !secret esp-api_key
|
api_key: !secret esp-api_key
|
||||||
ota_pass: !secret esp-ota_pass
|
ota_pass: !secret esp-ota_pass
|
||||||
static_ip_address: !secret esp-loungeenvironment_ip
|
static_ip_address: !secret esp-loungeenvironment_ip
|
||||||
|
|
||||||
|
# Layout V1.1 Required
|
||||||
|
current_ip_address: ${static_ip_address}
|
||||||
|
|
||||||
|
# MQTT Local Status
|
||||||
|
mqtt_local_status_main_topic: !secret mqtt_status_main_topic
|
||||||
|
mqtt_device_name: "lounge-environment"
|
||||||
|
mqtt_local_status_topic: "${mqtt_local_status_main_topic}/${mqtt_device_name}"
|
||||||
|
|
||||||
# General Settings
|
# General Settings
|
||||||
log_level: "WARN"
|
log_level: "WARN"
|
||||||
update_interval: "60s"
|
update_interval: "60s"
|
||||||
@@ -54,6 +109,7 @@ packages:
|
|||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
local_static_ip_address: "${static_ip_address}"
|
local_static_ip_address: "${static_ip_address}"
|
||||||
|
local_current_ip_address: "${current_ip_address}"
|
||||||
local_ota_pass: "${ota_pass}"
|
local_ota_pass: "${ota_pass}"
|
||||||
|
|
||||||
common_api: !include
|
common_api: !include
|
||||||
@@ -73,10 +129,10 @@ packages:
|
|||||||
common_sntp: !include common/sntp_common.yaml
|
common_sntp: !include common/sntp_common.yaml
|
||||||
|
|
||||||
diag_basic: !include common/include_basic_diag_sensors.yaml
|
diag_basic: !include common/include_basic_diag_sensors.yaml
|
||||||
diag_more: !include common/include_more_diag_sensors.yaml
|
diag_more: !include common/include_more_diag_sensors.yaml
|
||||||
|
|
||||||
##########################################################################################
|
##########################################################################################
|
||||||
# ESPHome
|
# ESPHOME
|
||||||
##########################################################################################
|
##########################################################################################
|
||||||
esphome:
|
esphome:
|
||||||
name: "${device_name}"
|
name: "${device_name}"
|
||||||
@@ -292,17 +348,26 @@ sensor:
|
|||||||
name: "${friendly_name} Temperature"
|
name: "${friendly_name} Temperature"
|
||||||
id: lounge_temperature
|
id: lounge_temperature
|
||||||
unit_of_measurement: "°C"
|
unit_of_measurement: "°C"
|
||||||
|
device_class: temperature
|
||||||
|
state_class: measurement
|
||||||
|
accuracy_decimals: 2
|
||||||
on_value:
|
on_value:
|
||||||
then:
|
then:
|
||||||
|
# Publish current temperature to local MQTT status topic
|
||||||
|
- mqtt.publish:
|
||||||
|
topic: "${mqtt_local_status_topic}/temperature"
|
||||||
|
payload: !lambda |-
|
||||||
|
char buffer[32];
|
||||||
|
snprintf(buffer, sizeof(buffer), "%.2f", x);
|
||||||
|
return std::string(buffer);
|
||||||
|
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
auto now = id(sntp_time).now();
|
auto now = id(sntp_time).now();
|
||||||
// We only need hour buckets and month stats if we have valid SNTP.
|
|
||||||
if (!now.is_valid()) return;
|
if (!now.is_valid()) return;
|
||||||
|
|
||||||
const int hour = now.hour;
|
const int hour = now.hour;
|
||||||
const uint32_t now_ts = now.timestamp;
|
const uint32_t now_ts = now.timestamp;
|
||||||
|
|
||||||
// Update hourly bucket (rolling 24h)
|
|
||||||
{
|
{
|
||||||
int idx = hour;
|
int idx = hour;
|
||||||
if (idx < 0) idx = 0;
|
if (idx < 0) idx = 0;
|
||||||
@@ -314,9 +379,6 @@ sensor:
|
|||||||
if (isnan(id(g_temp_hour_max)[idx]) || v > id(g_temp_hour_max)[idx]) id(g_temp_hour_max)[idx] = v;
|
if (isnan(id(g_temp_hour_max)[idx]) || v > id(g_temp_hour_max)[idx]) id(g_temp_hour_max)[idx] = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Daily window tracking uses current_mins so it still works during fallback.
|
|
||||||
// Overnight: 23:00 -> 07:00
|
|
||||||
// Daytime: 07:00 -> 23:00
|
|
||||||
const int mins = id(current_mins);
|
const int mins = id(current_mins);
|
||||||
const bool in_overnight = (mins >= 1380) || (mins < 420);
|
const bool in_overnight = (mins >= 1380) || (mins < 420);
|
||||||
|
|
||||||
@@ -330,19 +392,43 @@ sensor:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Month stats
|
|
||||||
if (isnan(id(g_min_temp_this_month)) || x < id(g_min_temp_this_month)) id(g_min_temp_this_month) = x;
|
if (isnan(id(g_min_temp_this_month)) || x < id(g_min_temp_this_month)) id(g_min_temp_this_month) = x;
|
||||||
if (isnan(id(g_max_temp_this_month)) || x > id(g_max_temp_this_month)) id(g_max_temp_this_month) = x;
|
if (isnan(id(g_max_temp_this_month)) || x > id(g_max_temp_this_month)) id(g_max_temp_this_month) = x;
|
||||||
|
|
||||||
pressure:
|
pressure:
|
||||||
name: "${friendly_name} Pressure"
|
name: "${friendly_name} Pressure"
|
||||||
id: lounge_pressure
|
id: lounge_pressure
|
||||||
|
unit_of_measurement: "hPa"
|
||||||
|
device_class: pressure
|
||||||
|
state_class: measurement
|
||||||
|
accuracy_decimals: 2
|
||||||
|
on_value:
|
||||||
|
then:
|
||||||
|
# Publish current pressure to local MQTT status topic
|
||||||
|
- mqtt.publish:
|
||||||
|
topic: "${mqtt_local_status_topic}/pressure"
|
||||||
|
payload: !lambda |-
|
||||||
|
char buffer[32];
|
||||||
|
snprintf(buffer, sizeof(buffer), "%.2f", x);
|
||||||
|
return std::string(buffer);
|
||||||
|
|
||||||
humidity:
|
humidity:
|
||||||
name: "${friendly_name} Humidity"
|
name: "${friendly_name} Humidity"
|
||||||
id: lounge_humidity
|
id: lounge_humidity
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
device_class: humidity
|
||||||
|
state_class: measurement
|
||||||
|
accuracy_decimals: 1
|
||||||
on_value:
|
on_value:
|
||||||
then:
|
then:
|
||||||
|
# Publish current humidity to local MQTT status topic
|
||||||
|
- mqtt.publish:
|
||||||
|
topic: "${mqtt_local_status_topic}/humidity"
|
||||||
|
payload: !lambda |-
|
||||||
|
char buffer[32];
|
||||||
|
snprintf(buffer, sizeof(buffer), "%.1f", x);
|
||||||
|
return std::string(buffer);
|
||||||
|
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
auto now = id(sntp_time).now();
|
auto now = id(sntp_time).now();
|
||||||
if (!now.is_valid()) return;
|
if (!now.is_valid()) return;
|
||||||
@@ -350,7 +436,6 @@ sensor:
|
|||||||
const int hour = now.hour;
|
const int hour = now.hour;
|
||||||
const uint32_t now_ts = now.timestamp;
|
const uint32_t now_ts = now.timestamp;
|
||||||
|
|
||||||
// Update hourly bucket (rolling 24h)
|
|
||||||
{
|
{
|
||||||
int idx = hour;
|
int idx = hour;
|
||||||
if (idx < 0) idx = 0;
|
if (idx < 0) idx = 0;
|
||||||
@@ -362,7 +447,6 @@ sensor:
|
|||||||
if (isnan(id(g_hum_hour_max)[idx]) || v > id(g_hum_hour_max)[idx]) id(g_hum_hour_max)[idx] = v;
|
if (isnan(id(g_hum_hour_max)[idx]) || v > id(g_hum_hour_max)[idx]) id(g_hum_hour_max)[idx] = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Daily window tracking uses current_mins so it still works during fallback.
|
|
||||||
const int mins = id(current_mins);
|
const int mins = id(current_mins);
|
||||||
const bool in_overnight = (mins >= 1380) || (mins < 420);
|
const bool in_overnight = (mins >= 1380) || (mins < 420);
|
||||||
|
|
||||||
@@ -376,7 +460,6 @@ sensor:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Month stats
|
|
||||||
if (isnan(id(g_min_humidity_this_month)) || x < id(g_min_humidity_this_month)) id(g_min_humidity_this_month) = x;
|
if (isnan(id(g_min_humidity_this_month)) || x < id(g_min_humidity_this_month)) id(g_min_humidity_this_month) = x;
|
||||||
if (isnan(id(g_max_humidity_this_month)) || x > id(g_max_humidity_this_month)) id(g_max_humidity_this_month) = x;
|
if (isnan(id(g_max_humidity_this_month)) || x > id(g_max_humidity_this_month)) id(g_max_humidity_this_month) = x;
|
||||||
|
|
||||||
@@ -385,6 +468,9 @@ sensor:
|
|||||||
name: "Lowest Temp Overnight"
|
name: "Lowest Temp Overnight"
|
||||||
id: min_temp_today_overnight
|
id: min_temp_today_overnight
|
||||||
unit_of_measurement: "°C"
|
unit_of_measurement: "°C"
|
||||||
|
device_class: temperature
|
||||||
|
state_class: measurement
|
||||||
|
accuracy_decimals: 2
|
||||||
update_interval: 60s
|
update_interval: 60s
|
||||||
lambda: |-
|
lambda: |-
|
||||||
return id(g_min_temp_today_overnight);
|
return id(g_min_temp_today_overnight);
|
||||||
@@ -394,6 +480,9 @@ sensor:
|
|||||||
name: "Highest Temp Today (Daytime)"
|
name: "Highest Temp Today (Daytime)"
|
||||||
id: max_temp_today_daytime
|
id: max_temp_today_daytime
|
||||||
unit_of_measurement: "°C"
|
unit_of_measurement: "°C"
|
||||||
|
device_class: temperature
|
||||||
|
state_class: measurement
|
||||||
|
accuracy_decimals: 2
|
||||||
update_interval: 60s
|
update_interval: 60s
|
||||||
lambda: |-
|
lambda: |-
|
||||||
return id(g_max_temp_today_daytime);
|
return id(g_max_temp_today_daytime);
|
||||||
@@ -403,6 +492,9 @@ sensor:
|
|||||||
name: "Highest Temp This Month"
|
name: "Highest Temp This Month"
|
||||||
id: max_temp_this_month
|
id: max_temp_this_month
|
||||||
unit_of_measurement: "°C"
|
unit_of_measurement: "°C"
|
||||||
|
device_class: temperature
|
||||||
|
state_class: measurement
|
||||||
|
accuracy_decimals: 2
|
||||||
update_interval: 60s
|
update_interval: 60s
|
||||||
lambda: |-
|
lambda: |-
|
||||||
return id(g_max_temp_this_month);
|
return id(g_max_temp_this_month);
|
||||||
@@ -412,6 +504,9 @@ sensor:
|
|||||||
name: "Highest Temp Last Month"
|
name: "Highest Temp Last Month"
|
||||||
id: max_temp_last_month
|
id: max_temp_last_month
|
||||||
unit_of_measurement: "°C"
|
unit_of_measurement: "°C"
|
||||||
|
device_class: temperature
|
||||||
|
state_class: measurement
|
||||||
|
accuracy_decimals: 2
|
||||||
update_interval: 60s
|
update_interval: 60s
|
||||||
lambda: |-
|
lambda: |-
|
||||||
return id(g_max_temp_last_month);
|
return id(g_max_temp_last_month);
|
||||||
@@ -421,6 +516,9 @@ sensor:
|
|||||||
name: "Lowest Temp This Month"
|
name: "Lowest Temp This Month"
|
||||||
id: min_temp_this_month
|
id: min_temp_this_month
|
||||||
unit_of_measurement: "°C"
|
unit_of_measurement: "°C"
|
||||||
|
device_class: temperature
|
||||||
|
state_class: measurement
|
||||||
|
accuracy_decimals: 2
|
||||||
update_interval: 60s
|
update_interval: 60s
|
||||||
lambda: |-
|
lambda: |-
|
||||||
return id(g_min_temp_this_month);
|
return id(g_min_temp_this_month);
|
||||||
@@ -430,6 +528,9 @@ sensor:
|
|||||||
name: "Lowest Temp Last Month"
|
name: "Lowest Temp Last Month"
|
||||||
id: min_temp_last_month
|
id: min_temp_last_month
|
||||||
unit_of_measurement: "°C"
|
unit_of_measurement: "°C"
|
||||||
|
device_class: temperature
|
||||||
|
state_class: measurement
|
||||||
|
accuracy_decimals: 2
|
||||||
update_interval: 60s
|
update_interval: 60s
|
||||||
lambda: |-
|
lambda: |-
|
||||||
return id(g_min_temp_last_month);
|
return id(g_min_temp_last_month);
|
||||||
@@ -439,6 +540,9 @@ sensor:
|
|||||||
name: "Lowest Temp Last 24 Hours"
|
name: "Lowest Temp Last 24 Hours"
|
||||||
id: min_temp_today
|
id: min_temp_today
|
||||||
unit_of_measurement: "°C"
|
unit_of_measurement: "°C"
|
||||||
|
device_class: temperature
|
||||||
|
state_class: measurement
|
||||||
|
accuracy_decimals: 2
|
||||||
update_interval: 60s
|
update_interval: 60s
|
||||||
lambda: |-
|
lambda: |-
|
||||||
auto now = id(sntp_time).now();
|
auto now = id(sntp_time).now();
|
||||||
@@ -460,6 +564,9 @@ sensor:
|
|||||||
name: "Highest Temp Last 24 Hours"
|
name: "Highest Temp Last 24 Hours"
|
||||||
id: max_temp_today
|
id: max_temp_today
|
||||||
unit_of_measurement: "°C"
|
unit_of_measurement: "°C"
|
||||||
|
device_class: temperature
|
||||||
|
state_class: measurement
|
||||||
|
accuracy_decimals: 2
|
||||||
update_interval: 60s
|
update_interval: 60s
|
||||||
lambda: |-
|
lambda: |-
|
||||||
auto now = id(sntp_time).now();
|
auto now = id(sntp_time).now();
|
||||||
@@ -481,6 +588,9 @@ sensor:
|
|||||||
name: "Lowest Humidity Overnight"
|
name: "Lowest Humidity Overnight"
|
||||||
id: min_humidity_today_overnight
|
id: min_humidity_today_overnight
|
||||||
unit_of_measurement: "%"
|
unit_of_measurement: "%"
|
||||||
|
device_class: humidity
|
||||||
|
state_class: measurement
|
||||||
|
accuracy_decimals: 1
|
||||||
update_interval: 60s
|
update_interval: 60s
|
||||||
lambda: |-
|
lambda: |-
|
||||||
return id(g_min_humidity_today_overnight);
|
return id(g_min_humidity_today_overnight);
|
||||||
@@ -490,6 +600,9 @@ sensor:
|
|||||||
name: "Highest Humidity Today (Daytime)"
|
name: "Highest Humidity Today (Daytime)"
|
||||||
id: max_humidity_today_daytime
|
id: max_humidity_today_daytime
|
||||||
unit_of_measurement: "%"
|
unit_of_measurement: "%"
|
||||||
|
device_class: humidity
|
||||||
|
state_class: measurement
|
||||||
|
accuracy_decimals: 1
|
||||||
update_interval: 60s
|
update_interval: 60s
|
||||||
lambda: |-
|
lambda: |-
|
||||||
return id(g_max_humidity_today_daytime);
|
return id(g_max_humidity_today_daytime);
|
||||||
@@ -499,6 +612,9 @@ sensor:
|
|||||||
name: "Highest Humidity This Month"
|
name: "Highest Humidity This Month"
|
||||||
id: max_humidity_this_month
|
id: max_humidity_this_month
|
||||||
unit_of_measurement: "%"
|
unit_of_measurement: "%"
|
||||||
|
device_class: humidity
|
||||||
|
state_class: measurement
|
||||||
|
accuracy_decimals: 1
|
||||||
update_interval: 60s
|
update_interval: 60s
|
||||||
lambda: |-
|
lambda: |-
|
||||||
return id(g_max_humidity_this_month);
|
return id(g_max_humidity_this_month);
|
||||||
@@ -508,6 +624,9 @@ sensor:
|
|||||||
name: "Highest Humidity Last Month"
|
name: "Highest Humidity Last Month"
|
||||||
id: max_humidity_last_month
|
id: max_humidity_last_month
|
||||||
unit_of_measurement: "%"
|
unit_of_measurement: "%"
|
||||||
|
device_class: humidity
|
||||||
|
state_class: measurement
|
||||||
|
accuracy_decimals: 1
|
||||||
update_interval: 60s
|
update_interval: 60s
|
||||||
lambda: |-
|
lambda: |-
|
||||||
return id(g_max_humidity_last_month);
|
return id(g_max_humidity_last_month);
|
||||||
@@ -517,6 +636,9 @@ sensor:
|
|||||||
name: "Lowest Humidity This Month"
|
name: "Lowest Humidity This Month"
|
||||||
id: min_humidity_this_month
|
id: min_humidity_this_month
|
||||||
unit_of_measurement: "%"
|
unit_of_measurement: "%"
|
||||||
|
device_class: humidity
|
||||||
|
state_class: measurement
|
||||||
|
accuracy_decimals: 1
|
||||||
update_interval: 60s
|
update_interval: 60s
|
||||||
lambda: |-
|
lambda: |-
|
||||||
return id(g_min_humidity_this_month);
|
return id(g_min_humidity_this_month);
|
||||||
@@ -526,6 +648,9 @@ sensor:
|
|||||||
name: "Lowest Humidity Last Month"
|
name: "Lowest Humidity Last Month"
|
||||||
id: min_humidity_last_month
|
id: min_humidity_last_month
|
||||||
unit_of_measurement: "%"
|
unit_of_measurement: "%"
|
||||||
|
device_class: humidity
|
||||||
|
state_class: measurement
|
||||||
|
accuracy_decimals: 1
|
||||||
update_interval: 60s
|
update_interval: 60s
|
||||||
lambda: |-
|
lambda: |-
|
||||||
return id(g_min_humidity_last_month);
|
return id(g_min_humidity_last_month);
|
||||||
@@ -535,6 +660,9 @@ sensor:
|
|||||||
name: "Lowest Humidity Last 24 Hours"
|
name: "Lowest Humidity Last 24 Hours"
|
||||||
id: min_humidity_today
|
id: min_humidity_today
|
||||||
unit_of_measurement: "%"
|
unit_of_measurement: "%"
|
||||||
|
device_class: humidity
|
||||||
|
state_class: measurement
|
||||||
|
accuracy_decimals: 1
|
||||||
update_interval: 60s
|
update_interval: 60s
|
||||||
lambda: |-
|
lambda: |-
|
||||||
auto now = id(sntp_time).now();
|
auto now = id(sntp_time).now();
|
||||||
@@ -556,6 +684,9 @@ sensor:
|
|||||||
name: "Highest Humidity Last 24 Hours"
|
name: "Highest Humidity Last 24 Hours"
|
||||||
id: max_humidity_today
|
id: max_humidity_today
|
||||||
unit_of_measurement: "%"
|
unit_of_measurement: "%"
|
||||||
|
device_class: humidity
|
||||||
|
state_class: measurement
|
||||||
|
accuracy_decimals: 1
|
||||||
update_interval: 60s
|
update_interval: 60s
|
||||||
lambda: |-
|
lambda: |-
|
||||||
auto now = id(sntp_time).now();
|
auto now = id(sntp_time).now();
|
||||||
@@ -577,6 +708,7 @@ sensor:
|
|||||||
name: "Pressure Rate Per Hour (3h)"
|
name: "Pressure Rate Per Hour (3h)"
|
||||||
id: pressure_rate_per_hour_3h
|
id: pressure_rate_per_hour_3h
|
||||||
unit_of_measurement: "hPa/h"
|
unit_of_measurement: "hPa/h"
|
||||||
|
state_class: measurement
|
||||||
accuracy_decimals: 2
|
accuracy_decimals: 2
|
||||||
update_interval: 60s
|
update_interval: 60s
|
||||||
lambda: |-
|
lambda: |-
|
||||||
@@ -584,7 +716,7 @@ sensor:
|
|||||||
if (!now.is_valid()) return NAN;
|
if (!now.is_valid()) return NAN;
|
||||||
|
|
||||||
const uint32_t now_ts = now.timestamp;
|
const uint32_t now_ts = now.timestamp;
|
||||||
const uint32_t target_ts = now_ts - 10800; // 3h
|
const uint32_t target_ts = now_ts - 10800;
|
||||||
|
|
||||||
float past = NAN;
|
float past = NAN;
|
||||||
uint32_t best_dt = 0xFFFFFFFF;
|
uint32_t best_dt = 0xFFFFFFFF;
|
||||||
@@ -610,12 +742,6 @@ sensor:
|
|||||||
##########################################################################################
|
##########################################################################################
|
||||||
text_sensor:
|
text_sensor:
|
||||||
# Pressure Direction, Last 3 Hours (5-state tendency over the last ~3 hours)
|
# Pressure Direction, Last 3 Hours (5-state tendency over the last ~3 hours)
|
||||||
# Outputs exactly one of:
|
|
||||||
# - rising rapidly
|
|
||||||
# - rising
|
|
||||||
# - steady
|
|
||||||
# - falling
|
|
||||||
# - falling rapidly
|
|
||||||
- platform: template
|
- platform: template
|
||||||
name: "Pressure Direction, Last 3 Hours"
|
name: "Pressure Direction, Last 3 Hours"
|
||||||
id: pressure_rising_or_falling_3_hours
|
id: pressure_rising_or_falling_3_hours
|
||||||
@@ -625,7 +751,7 @@ text_sensor:
|
|||||||
if (!now.is_valid()) return std::string("unknown");
|
if (!now.is_valid()) return std::string("unknown");
|
||||||
|
|
||||||
const uint32_t now_ts = now.timestamp;
|
const uint32_t now_ts = now.timestamp;
|
||||||
const uint32_t target_ts = now_ts - 10800; // 3h
|
const uint32_t target_ts = now_ts - 10800;
|
||||||
|
|
||||||
float past = NAN;
|
float past = NAN;
|
||||||
uint32_t best_dt = 0xFFFFFFFF;
|
uint32_t best_dt = 0xFFFFFFFF;
|
||||||
@@ -689,7 +815,6 @@ interval:
|
|||||||
const bool at_0700 = (mins == 420);
|
const bool at_0700 = (mins == 420);
|
||||||
const bool at_2300 = (mins == 1380);
|
const bool at_2300 = (mins == 1380);
|
||||||
|
|
||||||
// Roll overnight window at 07:00
|
|
||||||
if (at_0700) {
|
if (at_0700) {
|
||||||
id(g_min_temp_today_overnight) = id(g_work_min_temp_overnight);
|
id(g_min_temp_today_overnight) = id(g_work_min_temp_overnight);
|
||||||
id(g_work_min_temp_overnight) = NAN;
|
id(g_work_min_temp_overnight) = NAN;
|
||||||
@@ -698,7 +823,6 @@ interval:
|
|||||||
id(g_work_min_humidity_overnight) = NAN;
|
id(g_work_min_humidity_overnight) = NAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Roll daytime window at 23:00
|
|
||||||
if (at_2300) {
|
if (at_2300) {
|
||||||
id(g_max_temp_today_daytime) = id(g_work_max_temp_daytime);
|
id(g_max_temp_today_daytime) = id(g_work_max_temp_daytime);
|
||||||
id(g_work_max_temp_daytime) = NAN;
|
id(g_work_max_temp_daytime) = NAN;
|
||||||
@@ -707,7 +831,6 @@ interval:
|
|||||||
id(g_work_max_humidity_daytime) = NAN;
|
id(g_work_max_humidity_daytime) = NAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Month rollover requires real date/time (SNTP valid)
|
|
||||||
auto now = id(sntp_time).now();
|
auto now = id(sntp_time).now();
|
||||||
if (!now.is_valid()) return;
|
if (!now.is_valid()) return;
|
||||||
|
|
||||||
@@ -720,13 +843,11 @@ interval:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mon != id(g_current_month) || yr != id(g_current_year)) {
|
if (mon != id(g_current_month) || yr != id(g_current_year)) {
|
||||||
// Copy current month stats to last month
|
|
||||||
id(g_max_temp_last_month) = id(g_max_temp_this_month);
|
id(g_max_temp_last_month) = id(g_max_temp_this_month);
|
||||||
id(g_min_temp_last_month) = id(g_min_temp_this_month);
|
id(g_min_temp_last_month) = id(g_min_temp_this_month);
|
||||||
id(g_max_humidity_last_month) = id(g_max_humidity_this_month);
|
id(g_max_humidity_last_month) = id(g_max_humidity_this_month);
|
||||||
id(g_min_humidity_last_month) = id(g_min_humidity_this_month);
|
id(g_min_humidity_last_month) = id(g_min_humidity_this_month);
|
||||||
|
|
||||||
// Reset current month stats
|
|
||||||
id(g_max_temp_this_month) = NAN;
|
id(g_max_temp_this_month) = NAN;
|
||||||
id(g_min_temp_this_month) = NAN;
|
id(g_min_temp_this_month) = NAN;
|
||||||
id(g_max_humidity_this_month) = NAN;
|
id(g_max_humidity_this_month) = NAN;
|
||||||
|
|||||||
@@ -1,38 +1,90 @@
|
|||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# TITLE: LOUNGE MIDDLE LIGHTSWITCH
|
||||||
# LOUNGE MIDDLE LIGHTSwITCH
|
# zorruno.com layout v1.1 2026
|
||||||
|
#:########################################################################################:#
|
||||||
|
# REPO:
|
||||||
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-loungemiddleswitch.yaml
|
||||||
|
#:########################################################################################:#
|
||||||
|
# VERSIONS:
|
||||||
|
# V3.6 2026-03-11 Updated yaml to zorruno layout V1.1
|
||||||
# V3.5 2025-07-28 YAML tidyups
|
# V3.5 2025-07-28 YAML tidyups
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# Zemismart KS-811 Triple push button
|
# HARDWARE:
|
||||||
# pinout/schematic https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
|
# - Zemismart KS-811 Triple push button
|
||||||
#
|
# - ESP8266 based
|
||||||
# NOTES
|
# - pinout/schematic:
|
||||||
# -
|
# https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
|
||||||
#
|
# - Relay 1 output on GPIO13
|
||||||
##########################################################################################
|
# - Relay 2 output on GPIO12
|
||||||
##########################################################################################
|
# - Relay 3 output on GPIO14
|
||||||
|
# - Button 1 input on GPIO16
|
||||||
|
# - Button 2 input on GPIO5
|
||||||
|
# - Button 3 input on GPIO4
|
||||||
|
# - Status LED on GPIO2
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OPERATION NOTES:
|
||||||
|
# - Button 1:
|
||||||
|
# - Online with HA Loss manual override ON and HA Loss Test OFF:
|
||||||
|
# - Uses Home Assistant last-scene logic
|
||||||
|
# - If last scene is not "All Off", set "All Off"
|
||||||
|
# - If last scene is "All Off", set "Bright"
|
||||||
|
# - Offline/test with HA Loss manual override ON:
|
||||||
|
# - Toggles Relay_1 locally
|
||||||
|
# - Button 2:
|
||||||
|
# - Online with HA Loss manual override ON and HA Loss Test OFF:
|
||||||
|
# - Sets Home Assistant scene "Movie"
|
||||||
|
# - Offline/test with HA Loss manual override ON:
|
||||||
|
# - Toggles Relay_2 locally
|
||||||
|
# - Button 3:
|
||||||
|
# - Online with HA Loss manual override ON and HA Loss Test OFF:
|
||||||
|
# - Sets Home Assistant scene "Reading On/Off"
|
||||||
|
# - Offline/test with HA Loss manual override ON:
|
||||||
|
# - Toggles Relay_3 locally
|
||||||
|
# - On API connect:
|
||||||
|
# - If HA Loss Test is OFF, Relay_1 and Relay_2 follow HA Loss manual override state
|
||||||
|
# - If HA Loss Test is ON, relay override is not applied
|
||||||
|
# - HA Loss manual override defaults ON and persists across restarts
|
||||||
|
# - HA Loss Test defaults OFF and can force offline/test behaviour even when HA is connected
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OFFLINE NOTES:
|
||||||
|
# a) Home Assistant offline (network online):
|
||||||
|
# - Device switches to manual/offline behaviour
|
||||||
|
# - Buttons still operate local relays if HA Loss manual override is ON
|
||||||
|
# - Home Assistant scene calls are unavailable
|
||||||
|
# b) MQTT offline (or HA/MQTT offline):
|
||||||
|
# - This yaml does not depend on MQTT for its button logic
|
||||||
|
# - If Home Assistant/API is offline, device falls back to manual/offline behaviour
|
||||||
|
# - Buttons still operate local relays if HA Loss manual override is ON
|
||||||
|
# c) Entire WiFi/Network offline:
|
||||||
|
# - Device operates in local manual/offline behaviour only
|
||||||
|
# - Buttons still operate local relays if HA Loss manual override is ON
|
||||||
|
# - Accurate time is not needed; SNTP is not required for operation
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
|
# SUBSTITUTIONS:
|
||||||
|
# Specific device variable substitutions
|
||||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
substitutions:
|
substitutions:
|
||||||
# Device Naming
|
# Device Naming
|
||||||
device_name: "esp-loungemiddleswitch"
|
device_name: "esp-loungemiddleswitch"
|
||||||
friendly_name: "Lounge Middle Lightswitch (3)"
|
friendly_name: "Lounge Middle Lightswitch (3)"
|
||||||
description_comment: "Lounge Main Lightswitch using a Zemismart KS-811 Triple Push Button. Downlights South (1), Downlights Middle (2), Downlights North (3)"
|
description_comment: "Lounge Main Lightswitch using a Zemismart KS-811 Triple Push Button. Downlights South (1), Downlights Middle (2), Downlights North (3) (Layout V1.1)"
|
||||||
device_area: "Lounge" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
device_area: "Lounge" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
||||||
|
|
||||||
# Project Naming
|
# Project Naming
|
||||||
project_name: "Zemismart Technologies.KS-811 Triple" # Project Details
|
project_name: "Zemismart Technologies.KS-811 Triple" # Project Details
|
||||||
project_version: "v3.5" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
project_version: "v3.6" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
||||||
|
|
||||||
# Passwords & Secrets
|
# Passwords & Secrets
|
||||||
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
||||||
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
|
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
|
||||||
static_ip_address: !secret esp-loungemiddleswitch_ip
|
static_ip_address: !secret esp-loungemiddleswitch_ip
|
||||||
#mqtt_command_main_topic: !secret mqtt_local_command_main_topic
|
|
||||||
#mqtt_status_main_topic: !secret mqtt_local_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
|
# Device Settings
|
||||||
log_level: "INFO" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
log_level: "INFO" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
||||||
@@ -51,10 +103,11 @@ substitutions:
|
|||||||
switch_2_name: "Downlights Middle" # Lights are connected via DMX dimmer (another esphome controller) (6 Downlights)
|
switch_2_name: "Downlights Middle" # Lights are connected via DMX dimmer (another esphome controller) (6 Downlights)
|
||||||
switch_3_name: "Downlights North" # Lights are directly connected (2 downlights)
|
switch_3_name: "Downlights North" # Lights are directly connected (2 downlights)
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# PACKAGES: Included Common Packages
|
# PACKAGES:
|
||||||
|
# Included Common Packages
|
||||||
# https://esphome.io/components/packages.html
|
# https://esphome.io/components/packages.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
packages:
|
packages:
|
||||||
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
||||||
common_wifi: !include
|
common_wifi: !include
|
||||||
@@ -62,6 +115,7 @@ packages:
|
|||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
local_static_ip_address: "${static_ip_address}"
|
local_static_ip_address: "${static_ip_address}"
|
||||||
|
local_current_ip_address: "${current_ip_address}"
|
||||||
local_ota_pass: "${ota_pass}"
|
local_ota_pass: "${ota_pass}"
|
||||||
|
|
||||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||||
@@ -79,6 +133,7 @@ packages:
|
|||||||
|
|
||||||
#### WEB PORTAL ####
|
#### WEB PORTAL ####
|
||||||
#common_webportal: !include common/webportal_common.yaml
|
#common_webportal: !include common/webportal_common.yaml
|
||||||
|
|
||||||
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
||||||
#common_sntp: !include common/sntp_common.yaml
|
#common_sntp: !include common/sntp_common.yaml
|
||||||
|
|
||||||
@@ -88,10 +143,10 @@ packages:
|
|||||||
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
||||||
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# ESPHome
|
# ESPHOME:
|
||||||
# https://esphome.io/components/esphome.html
|
# https://esphome.io/components/esphome.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
esphome:
|
esphome:
|
||||||
name: "${device_name}"
|
name: "${device_name}"
|
||||||
friendly_name: "${friendly_name}"
|
friendly_name: "${friendly_name}"
|
||||||
@@ -101,9 +156,9 @@ esphome:
|
|||||||
name: "${project_name}"
|
name: "${project_name}"
|
||||||
version: "${project_version}"
|
version: "${project_version}"
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# Home Assistant API
|
# HOME ASSISTANT API:
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
api:
|
api:
|
||||||
on_client_connected:
|
on_client_connected:
|
||||||
then:
|
then:
|
||||||
@@ -137,38 +192,38 @@ api:
|
|||||||
level: WARN
|
level: WARN
|
||||||
format: "API disconnected: switching to manual/offline behavior"
|
format: "API disconnected: switching to manual/offline behavior"
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# ESP Platform and Framework
|
# ESP PLATFORM AND FRAMEWORK:
|
||||||
# https://esphome.io/components/esp32.html
|
# https://esphome.io/components/esp8266.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
esp8266:
|
esp8266:
|
||||||
board: esp01_1m
|
board: esp01_1m
|
||||||
early_pin_init: False # Initialise pins early to known values. Recommended false where switches are involved. Defaults to True.
|
early_pin_init: false # Initialise pins early to known values. Recommended false where switches are involved. Defaults to True.
|
||||||
board_flash_mode: dout # Default is dout
|
board_flash_mode: dout # Default is dout
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# ESPHome Logging Enable
|
# LOGGER:
|
||||||
# https://esphome.io/components/logger.html
|
# https://esphome.io/components/logger.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
logger:
|
logger:
|
||||||
level: "${log_level}" # INFO Level suggested, or DEBUG for testing
|
level: "${log_level}" # INFO Level suggested, or DEBUG for testing
|
||||||
#baud_rate: 0 # set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
#baud_rate: 0 # set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
||||||
#esp8266_store_log_strings_in_flash: false
|
#esp8266_store_log_strings_in_flash: false
|
||||||
#tx_buffer_size: 64
|
#tx_buffer_size: 64
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# STATUS LED
|
# STATUS LED:
|
||||||
# https://esphome.io/components/status_led.html
|
# https://esphome.io/components/status_led.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
status_led:
|
status_led:
|
||||||
pin:
|
pin:
|
||||||
number: GPIO02
|
number: GPIO2
|
||||||
inverted: yes
|
inverted: true
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# BINARY SENSORS
|
# BINARY SENSORS:
|
||||||
# https://esphome.io/components/binary_sensor/
|
# https://esphome.io/components/binary_sensor/
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
# GPIO16 for KS-811 first button UNLESS
|
# GPIO16 for KS-811 first button UNLESS
|
||||||
# it is a single button KS-811 in which case it is GPIO00
|
# it is a single button KS-811 in which case it is GPIO00
|
||||||
@@ -176,7 +231,7 @@ binary_sensor:
|
|||||||
pin:
|
pin:
|
||||||
number: GPIO16
|
number: GPIO16
|
||||||
mode: INPUT
|
mode: INPUT
|
||||||
inverted: True
|
inverted: true
|
||||||
use_interrupt: false # This pin doesn't support interrupts so use polling. Only suppresses a warning.
|
use_interrupt: false # This pin doesn't support interrupts so use polling. Only suppresses a warning.
|
||||||
name: "Button 1: ${switch_1_name}"
|
name: "Button 1: ${switch_1_name}"
|
||||||
on_multi_click:
|
on_multi_click:
|
||||||
@@ -231,7 +286,8 @@ binary_sensor:
|
|||||||
then:
|
then:
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
lambda: 'return id(Relay_1).state;'
|
lambda: |-
|
||||||
|
return id(Relay_1).state;
|
||||||
then:
|
then:
|
||||||
- switch.turn_off: Relay_1
|
- switch.turn_off: Relay_1
|
||||||
- logger.log:
|
- logger.log:
|
||||||
@@ -250,9 +306,9 @@ binary_sensor:
|
|||||||
# GPIO05 for second button (only for KS-811-2 Double or -3 Triple)
|
# GPIO05 for second button (only for KS-811-2 Double or -3 Triple)
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
pin:
|
pin:
|
||||||
number: GPIO05
|
number: GPIO5
|
||||||
mode: INPUT
|
mode: INPUT
|
||||||
inverted: True
|
inverted: true
|
||||||
name: "Button 2: ${switch_2_name}"
|
name: "Button 2: ${switch_2_name}"
|
||||||
on_multi_click:
|
on_multi_click:
|
||||||
# --- Single short click ---
|
# --- Single short click ---
|
||||||
@@ -289,7 +345,8 @@ binary_sensor:
|
|||||||
then:
|
then:
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
lambda: 'return id(Relay_2).state;'
|
lambda: |-
|
||||||
|
return id(Relay_2).state;
|
||||||
then:
|
then:
|
||||||
- switch.turn_off: Relay_2
|
- switch.turn_off: Relay_2
|
||||||
- logger.log:
|
- logger.log:
|
||||||
@@ -310,7 +367,7 @@ binary_sensor:
|
|||||||
pin:
|
pin:
|
||||||
number: GPIO4
|
number: GPIO4
|
||||||
mode: INPUT
|
mode: INPUT
|
||||||
inverted: True
|
inverted: true
|
||||||
name: "Button 3: ${switch_3_name}"
|
name: "Button 3: ${switch_3_name}"
|
||||||
on_multi_click:
|
on_multi_click:
|
||||||
# --- Single short click ---
|
# --- Single short click ---
|
||||||
@@ -347,7 +404,8 @@ binary_sensor:
|
|||||||
then:
|
then:
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
lambda: 'return id(Relay_3).state;'
|
lambda: |-
|
||||||
|
return id(Relay_3).state;
|
||||||
then:
|
then:
|
||||||
- switch.turn_off: Relay_3
|
- switch.turn_off: Relay_3
|
||||||
- logger.log:
|
- logger.log:
|
||||||
@@ -363,9 +421,10 @@ binary_sensor:
|
|||||||
level: INFO
|
level: INFO
|
||||||
format: "BTN3: Single click ignored (override OFF)"
|
format: "BTN3: Single click ignored (override OFF)"
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# TEXT SENSOR COMPONENT
|
# TEXT SENSOR COMPONENT:
|
||||||
#########################################################################################
|
# https://esphome.io/components/text_sensor/
|
||||||
|
#:########################################################################################:#
|
||||||
text_sensor:
|
text_sensor:
|
||||||
- platform: homeassistant
|
- platform: homeassistant
|
||||||
id: ha_last_scene
|
id: ha_last_scene
|
||||||
@@ -376,10 +435,10 @@ text_sensor:
|
|||||||
format: "HA last scene now: %s"
|
format: "HA last scene now: %s"
|
||||||
args: ["x.c_str()"]
|
args: ["x.c_str()"]
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# SWITCH COMPONENT
|
# SWITCH COMPONENT:
|
||||||
# https://esphome.io/components/switch/
|
# https://esphome.io/components/switch/
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
switch:
|
switch:
|
||||||
# GPIO13 for KS-811 first button UNLESS it is KS-811-1 then it is GPIO12
|
# GPIO13 for KS-811 first button UNLESS it is KS-811-1 then it is GPIO12
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
@@ -436,7 +495,8 @@ switch:
|
|||||||
- homeassistant.service:
|
- homeassistant.service:
|
||||||
service: script.lounge_set_scene
|
service: script.lounge_set_scene
|
||||||
data:
|
data:
|
||||||
scene_name: !lambda 'return id(ha_last_scene).state;'
|
scene_name: !lambda |-
|
||||||
|
return id(ha_last_scene).state;
|
||||||
- logger.log:
|
- logger.log:
|
||||||
level: INFO
|
level: INFO
|
||||||
format: "HA Loss Test OFF: restored last scene: %s"
|
format: "HA Loss Test OFF: restored last scene: %s"
|
||||||
@@ -444,5 +504,4 @@ switch:
|
|||||||
else:
|
else:
|
||||||
- logger.log:
|
- logger.log:
|
||||||
level: WARN
|
level: WARN
|
||||||
format: "HA Loss Test OFF: cannot restore scene (API not connected or last scene unknown)"
|
format: "HA Loss Test OFF: cannot restore scene (API not connected or last scene unknown)"
|
||||||
|
|
||||||
@@ -1,41 +1,86 @@
|
|||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# TITLE: LOUNGE NORTH SWITCH (Single Switch into hallway)
|
||||||
# LOUNGE NORTH SWITCH (Single Switch into hallway)
|
# zorruno.com layout v1.1 2026
|
||||||
|
#:########################################################################################:#
|
||||||
|
# REPO:
|
||||||
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-loungenorthswitch.yaml
|
||||||
|
#:########################################################################################:#
|
||||||
|
# VERSIONS:
|
||||||
|
# V4.1 2026-03-11 Updated yaml to zorruno layout V1.1
|
||||||
# V4.0 2025-10-01 Copy from other device
|
# V4.0 2025-10-01 Copy from other device
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# Zemismart KS-811 Single push button
|
# HARDWARE:
|
||||||
# pinout/schematic https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
|
# - Zemismart KS-811 Single push button
|
||||||
|
# - ESP8266 based
|
||||||
|
# - pinout/schematic:
|
||||||
|
# https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
|
||||||
|
# - Button input on GPIO0
|
||||||
|
# - Relay output on GPIO12
|
||||||
|
# - Status LED on GPIO2
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OPERATION NOTES:
|
||||||
|
# - Single wall switch used for Lounge North / hallway control
|
||||||
|
# - This device uses Home Assistant scene calls when API is connected
|
||||||
|
# - Single click:
|
||||||
|
# - Online and HA Loss manual override ON:
|
||||||
|
# - If last scene is not "All Off", call scene "All Off"
|
||||||
|
# - If last scene is "All Off", call scene "Bright"
|
||||||
|
# - Offline and HA Loss manual override ON:
|
||||||
|
# - Toggle physical Relay_1
|
||||||
|
# - Double click:
|
||||||
|
# - Online only, calls Home Assistant script for scene "Night Light"
|
||||||
|
# - Long hold (4s+):
|
||||||
|
# - Online only, calls Home Assistant script for scene "All Off"
|
||||||
|
# - Also fires Home Assistant event esphome.lounge_switch_hold
|
||||||
|
# - On API client connect:
|
||||||
|
# - Applies override state to Relay_1
|
||||||
|
# - HA Loss manual override switch defaults ON and is restored after reboot
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OFFLINE NOTES:
|
||||||
|
# a) Home Assistant offline (network online):
|
||||||
|
# - API will disconnect and device switches to manual/offline behavior
|
||||||
|
# - Single click can still toggle Relay_1 when HA Loss manual override is ON
|
||||||
|
# - Double click and long hold actions that require Home Assistant are ignored
|
||||||
#
|
#
|
||||||
# NOTES
|
# b) MQTT offline (or HA/MQTT offline):
|
||||||
# -
|
# - This yaml does not currently depend on MQTT for its switch logic
|
||||||
|
# - If Home Assistant/API is offline, device falls back to manual/offline behavior
|
||||||
|
# - Single click can still toggle Relay_1 when HA Loss manual override is ON
|
||||||
#
|
#
|
||||||
##########################################################################################
|
# c) Entire WiFi/Network offline:
|
||||||
##########################################################################################
|
# - Device operates in local manual/offline behavior only
|
||||||
|
# - Single click can still toggle Relay_1 when HA Loss manual override is ON
|
||||||
|
# - Double click and long hold Home Assistant scene/event actions are unavailable
|
||||||
|
# - Accurate time is not needed; SNTP is not required for operation
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
|
# SUBSTITUTIONS:
|
||||||
|
# Specific device variable substitutions
|
||||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
substitutions:
|
substitutions:
|
||||||
# Device Naming
|
# Device Naming
|
||||||
device_name: "esp-loungenorthswitch"
|
device_name: "esp-loungenorthswitch"
|
||||||
friendly_name: "Lounge North Single Switch (1)"
|
friendly_name: "Lounge North Single Switch (1)"
|
||||||
description_comment: "Main Lounge from hallway Lightswitch using a Zemismart KS-811 Single Push Button. Main Lights (1)"
|
description_comment: "Main Lounge from hallway Lightswitch using a Zemismart KS-811 Single Push Button. Main Lights (1) (Layout V1.1)"
|
||||||
device_area: "Lounge" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
device_area: "Lounge" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
||||||
|
|
||||||
# Project Naming
|
# Project Naming
|
||||||
project_name: "Zemismart Technologies.KS-811 Single" # Project Details
|
project_name: "Zemismart Technologies.KS-811 Single" # Project Details
|
||||||
project_version: "v4.0" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
project_version: "v4.1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
||||||
|
|
||||||
# Passwords & Secrets
|
# Passwords & Secrets
|
||||||
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
||||||
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
|
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
|
||||||
static_ip_address: !secret esp-loungenorthswitch_ip
|
static_ip_address: !secret esp-loungenorthswitch_ip
|
||||||
#mqtt_command_main_topic: !secret mqtt_local_command_main_topic
|
|
||||||
#mqtt_status_main_topic: !secret mqtt_local_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
|
# Device Settings
|
||||||
log_level: "DEBUG" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
log_level: "INFO" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
||||||
update_interval: "60s" # update time for for general sensors etc
|
update_interval: "60s" # update time for for general sensors etc
|
||||||
|
|
||||||
# MQTT LOCAL Controls
|
# MQTT LOCAL Controls
|
||||||
@@ -49,14 +94,15 @@ substitutions:
|
|||||||
#mqtt_remote_status_topic: "${mqtt_status_main_topic}/${mqtt_remote_device_name}" # Topic we will use to view status locally without HA
|
#mqtt_remote_status_topic: "${mqtt_status_main_topic}/${mqtt_remote_device_name}" # Topic we will use to view status locally without HA
|
||||||
#mqtt_remote_device_command_on: "On"
|
#mqtt_remote_device_command_on: "On"
|
||||||
#mqtt_remote_device_command_off: "Off"
|
#mqtt_remote_device_command_off: "Off"
|
||||||
|
|
||||||
# Switch/Relay/Button Naming & Icons
|
# Switch/Relay/Button Naming & Icons
|
||||||
switch_1_name: "Main Lights" # NOTE there is no physical connection to the lights on this switch, it is connected to the dimmer ESPhome for the pelmet lights
|
switch_1_name: "Main Lights" # NOTE there is no physical connection to the lights on this switch, it is connected to the dimmer ESPhome for the pelmet lights
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# PACKAGES: Included Common Packages
|
# PACKAGES:
|
||||||
|
# Included Common Packages
|
||||||
# https://esphome.io/components/packages.html
|
# https://esphome.io/components/packages.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
packages:
|
packages:
|
||||||
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
||||||
common_wifi: !include
|
common_wifi: !include
|
||||||
@@ -64,6 +110,7 @@ packages:
|
|||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
local_static_ip_address: "${static_ip_address}"
|
local_static_ip_address: "${static_ip_address}"
|
||||||
|
local_current_ip_address: "${current_ip_address}"
|
||||||
local_ota_pass: "${ota_pass}"
|
local_ota_pass: "${ota_pass}"
|
||||||
|
|
||||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||||
@@ -78,23 +125,23 @@ packages:
|
|||||||
file: common/mqtt_common.yaml
|
file: common/mqtt_common.yaml
|
||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
|
|
||||||
#### WEB PORTAL ####
|
#### WEB PORTAL ####
|
||||||
#common_webportal: !include common/webportal_common.yaml
|
#common_webportal: !include common/webportal_common.yaml
|
||||||
|
|
||||||
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
||||||
#common_sntp: !include common/sntp_common.yaml
|
#common_sntp: !include common/sntp_common.yaml
|
||||||
|
|
||||||
#### DIAGNOSTICS Sensors ####
|
#### DIAGNOSTICS Sensors ####
|
||||||
diag_basic: !include common/include_basic_diag_sensors.yaml
|
diag_basic: !include common/include_basic_diag_sensors.yaml
|
||||||
diag_more: !include common/include_more_diag_sensors.yaml
|
diag_more: !include common/include_more_diag_sensors.yaml
|
||||||
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
||||||
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# ESPHome
|
# ESPHOME:
|
||||||
# https://esphome.io/components/esphome.html
|
# https://esphome.io/components/esphome.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
esphome:
|
esphome:
|
||||||
name: "${device_name}"
|
name: "${device_name}"
|
||||||
friendly_name: "${friendly_name}"
|
friendly_name: "${friendly_name}"
|
||||||
@@ -104,6 +151,9 @@ esphome:
|
|||||||
name: "${project_name}"
|
name: "${project_name}"
|
||||||
version: "${project_version}"
|
version: "${project_version}"
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# HOME ASSISTANT API:
|
||||||
|
#:########################################################################################:#
|
||||||
api:
|
api:
|
||||||
on_client_connected:
|
on_client_connected:
|
||||||
then:
|
then:
|
||||||
@@ -125,44 +175,44 @@ api:
|
|||||||
level: WARN
|
level: WARN
|
||||||
format: "API disconnected: switching to manual/offline behavior"
|
format: "API disconnected: switching to manual/offline behavior"
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# ESP Platform and Framework
|
# ESP PLATFORM AND FRAMEWORK:
|
||||||
# https://esphome.io/components/esp32.html
|
# https://esphome.io/components/esp8266.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
esp8266:
|
esp8266:
|
||||||
board: esp01_1m
|
board: esp01_1m
|
||||||
early_pin_init: False # Initialise pins early to known values. Recommended false where switches are involved. Defaults to True.
|
early_pin_init: false # Initialise pins early to known values. Recommended false where switches are involved. Defaults to True.
|
||||||
board_flash_mode: dout # Default is dout
|
board_flash_mode: dout # Default is dout
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# ESPHome Logging Enable
|
# LOGGER:
|
||||||
# https://esphome.io/components/logger.html
|
# https://esphome.io/components/logger.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
logger:
|
logger:
|
||||||
level: "${log_level}" #INFO Level suggested, or DEBUG for testing
|
level: "${log_level}" #INFO Level suggested, or DEBUG for testing
|
||||||
#baud_rate: 0 #set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
#baud_rate: 0 #set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
||||||
#esp8266_store_log_strings_in_flash: false
|
#esp8266_store_log_strings_in_flash: false
|
||||||
#tx_buffer_size: 64
|
#tx_buffer_size: 64
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# STATUS LED
|
# STATUS LED:
|
||||||
# https://esphome.io/components/status_led.html
|
# https://esphome.io/components/status_led.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
status_led:
|
status_led:
|
||||||
pin:
|
pin:
|
||||||
number: GPIO02
|
number: GPIO2
|
||||||
inverted: yes
|
inverted: true
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# BINARY SENSORS
|
# BINARY SENSORS:
|
||||||
# https://esphome.io/components/binary_sensor/
|
# https://esphome.io/components/binary_sensor/
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
pin:
|
pin:
|
||||||
number: GPIO0
|
number: GPIO0
|
||||||
mode: INPUT
|
mode: INPUT
|
||||||
inverted: True
|
inverted: true
|
||||||
name: "Button 1: ${switch_1_name}"
|
name: "Button 1: ${switch_1_name}"
|
||||||
on_multi_click:
|
on_multi_click:
|
||||||
|
|
||||||
@@ -183,7 +233,7 @@ binary_sensor:
|
|||||||
scene_name: "Night Light"
|
scene_name: "Night Light"
|
||||||
- logger.log:
|
- logger.log:
|
||||||
level: INFO
|
level: INFO
|
||||||
format: "BTN: Double click → Scene Night Light"
|
format: "BTN: Double click -> Scene Night Light"
|
||||||
else:
|
else:
|
||||||
- logger.log:
|
- logger.log:
|
||||||
level: INFO
|
level: INFO
|
||||||
@@ -191,8 +241,8 @@ binary_sensor:
|
|||||||
|
|
||||||
# --- Single short click ---
|
# --- Single short click ---
|
||||||
# Online (and override ON): use HA's last scene to decide.
|
# Online (and override ON): use HA's last scene to decide.
|
||||||
# If last != "All Off" → send "All Off"
|
# If last != "All Off" -> send "All Off"
|
||||||
# If last == "All Off" → send "Bright"
|
# If last == "All Off" -> send "Bright"
|
||||||
# Offline (and override ON): toggle physical Relay_1
|
# Offline (and override ON): toggle physical Relay_1
|
||||||
- timing:
|
- timing:
|
||||||
- ON for at most 0.5s
|
- ON for at most 0.5s
|
||||||
@@ -218,7 +268,7 @@ binary_sensor:
|
|||||||
scene_name: "All Off"
|
scene_name: "All Off"
|
||||||
- logger.log:
|
- logger.log:
|
||||||
level: INFO
|
level: INFO
|
||||||
format: "BTN: Single click (online) → Last scene was not 'All Off' → Set 'All Off'"
|
format: "BTN: Single click (online) -> Last scene was not 'All Off' -> Set 'All Off'"
|
||||||
else:
|
else:
|
||||||
- homeassistant.service:
|
- homeassistant.service:
|
||||||
service: script.lounge_set_scene
|
service: script.lounge_set_scene
|
||||||
@@ -226,7 +276,7 @@ binary_sensor:
|
|||||||
scene_name: "Bright"
|
scene_name: "Bright"
|
||||||
- logger.log:
|
- logger.log:
|
||||||
level: INFO
|
level: INFO
|
||||||
format: "BTN: Single click (online) → Last scene was 'All Off' → Set 'Bright'"
|
format: "BTN: Single click (online) -> Last scene was 'All Off' -> Set 'Bright'"
|
||||||
else:
|
else:
|
||||||
# OFFLINE path: only act if override ON; toggle physical relay
|
# OFFLINE path: only act if override ON; toggle physical relay
|
||||||
- if:
|
- if:
|
||||||
@@ -238,17 +288,18 @@ binary_sensor:
|
|||||||
then:
|
then:
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
lambda: 'return id(Relay_1).state;'
|
lambda: |-
|
||||||
|
return id(Relay_1).state;
|
||||||
then:
|
then:
|
||||||
- switch.turn_off: Relay_1
|
- switch.turn_off: Relay_1
|
||||||
- logger.log:
|
- logger.log:
|
||||||
level: INFO
|
level: INFO
|
||||||
format: "BTN: Single click (offline) → Relay_1 OFF"
|
format: "BTN: Single click (offline) -> Relay_1 OFF"
|
||||||
else:
|
else:
|
||||||
- switch.turn_on: Relay_1
|
- switch.turn_on: Relay_1
|
||||||
- logger.log:
|
- logger.log:
|
||||||
level: INFO
|
level: INFO
|
||||||
format: "BTN: Single click (offline) → Relay_1 ON"
|
format: "BTN: Single click (offline) -> Relay_1 ON"
|
||||||
else:
|
else:
|
||||||
- logger.log:
|
- logger.log:
|
||||||
level: INFO
|
level: INFO
|
||||||
@@ -272,16 +323,16 @@ binary_sensor:
|
|||||||
action: "hold"
|
action: "hold"
|
||||||
- logger.log:
|
- logger.log:
|
||||||
level: INFO
|
level: INFO
|
||||||
format: "BTN: Long press → Scene All Off + HA event (hold)"
|
format: "BTN: Long press -> Scene All Off + HA event (hold)"
|
||||||
else:
|
else:
|
||||||
- logger.log:
|
- logger.log:
|
||||||
level: INFO
|
level: INFO
|
||||||
format: "BTN: Long press ignored (no HA connection)"
|
format: "BTN: Long press ignored (no HA connection)"
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# TEXT SENSOR COMPONENT
|
# TEXT SENSOR COMPONENT:
|
||||||
#
|
# https://esphome.io/components/text_sensor/
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
text_sensor:
|
text_sensor:
|
||||||
- platform: homeassistant
|
- platform: homeassistant
|
||||||
id: ha_last_scene
|
id: ha_last_scene
|
||||||
@@ -292,13 +343,13 @@ text_sensor:
|
|||||||
level: DEBUG
|
level: DEBUG
|
||||||
format: "HA last scene now: %s"
|
format: "HA last scene now: %s"
|
||||||
args: ["x.c_str()"]
|
args: ["x.c_str()"]
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# SWITCH COMPONENT
|
# SWITCH COMPONENT:
|
||||||
# https://esphome.io/components/switch/
|
# https://esphome.io/components/switch/
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
switch:
|
switch:
|
||||||
# GPIO13 for KS-811 first button UNLESS it is KS-811-1 then it is GPIO12
|
# GPIO13 for KS-811 first button UNLESS it is KS-811-1 then it is GPIO12
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
name: "Relay 1: ${switch_1_name}"
|
name: "Relay 1: ${switch_1_name}"
|
||||||
pin: GPIO12
|
pin: GPIO12
|
||||||
@@ -310,6 +361,4 @@ switch:
|
|||||||
name: "HA Loss manual override"
|
name: "HA Loss manual override"
|
||||||
id: ha_loss_override
|
id: ha_loss_override
|
||||||
optimistic: true
|
optimistic: true
|
||||||
restore_mode: RESTORE_DEFAULT_ON
|
restore_mode: RESTORE_DEFAULT_ON
|
||||||
|
|
||||||
|
|
||||||
@@ -1,83 +1,95 @@
|
|||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# TITLE: LOUNGE - PELMET LEDS (H801, 2x Monochrome PWM)
|
||||||
# Title: LOUNGE - PELMET LEDS (H801, 2x Monochrome PWM)
|
# zorruno.com layout v1.1 2026
|
||||||
# Repo: (new)
|
#:########################################################################################:#
|
||||||
|
# REPO:
|
||||||
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-loungepelmetleds2.yaml
|
||||||
|
#:########################################################################################:#
|
||||||
|
# VERSIONS:
|
||||||
|
# V2.8 2026-03-11 Updated yaml to zorruno layout V1.1
|
||||||
|
# V2.7 2025-09-30 A bunch of fixes for final version
|
||||||
|
# V2.0 2025-09-30 Based on single MOSFET version; adapted to H801 dual-monochrome (A/B)
|
||||||
|
# V1.x History from single-channel base maintained in prior comments
|
||||||
|
#:########################################################################################:#
|
||||||
|
# HARDWARE:
|
||||||
|
# - H801 (ESP8266, 5 MOSFET outputs)
|
||||||
|
# - Used here as 2 independent monochrome PWM channels (A and B)
|
||||||
|
# - Reference hardware:
|
||||||
|
# https://devices.esphome.io/devices/Sinilink-XY-WFMS
|
||||||
|
# - Device GPIO as used here:
|
||||||
|
# - GPIO02 Blue status LED, active-low (ESPHome status)
|
||||||
|
# - GPIO15 MOSFET output A (PWM)
|
||||||
|
# - GPIO13 MOSFET output B (PWM)
|
||||||
|
# - GPIO05 Red LED (used to display status for Channel A)
|
||||||
|
# - GPIO01 Green LED (used to display status for Channel B) [UART TX, logger baud=0]
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OPERATION NOTES:
|
||||||
|
# - General-purpose LED controller using an H801 board.
|
||||||
|
# - Designed for 2 independent monochrome outputs:
|
||||||
|
# - Channel A
|
||||||
|
# - Channel B
|
||||||
|
# - Minimum and maximum output limits are defined in SUBSTITUTIONS per channel.
|
||||||
|
# - Minimum output allows the light to switch fully OFF at or below the threshold to avoid low-PWM flicker.
|
||||||
|
# - PWM frequency is set in SUBSTITUTIONS.
|
||||||
|
# - Restart behaviours:
|
||||||
|
# - Fade up to full
|
||||||
|
# - Restore Brightness
|
||||||
|
# - Remain Off
|
||||||
|
# - Fade timing scales with the configured values.
|
||||||
|
# - Exposed in Home Assistant for both A and B:
|
||||||
|
# - Restart action
|
||||||
|
# - Fade Up-Down switch
|
||||||
|
# - Fade up/down times
|
||||||
|
# - Output percentage
|
||||||
|
# - Output Set slider
|
||||||
|
# - Shared maximum ON time
|
||||||
|
# - Fade Up-Down switch auto-syncs to brightness thresholds and does not itself trigger a ramp during sync.
|
||||||
|
# - This yaml currently uses Home Assistant API and diagnostics packages.
|
||||||
|
# - MQTT and SNTP packages are currently disabled in this file.
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OFFLINE NOTES:
|
||||||
|
# a) Home Assistant offline (network online):
|
||||||
|
# - Device continues to run its local light logic and stored restart behaviour.
|
||||||
|
# - Existing light states, watchdog timers, and fades continue locally.
|
||||||
|
# - No Home Assistant control is available until API connectivity returns.
|
||||||
#
|
#
|
||||||
# v2.7 - a bunch of fixes for final version
|
# b) MQTT offline (or HA/MQTT offline):
|
||||||
# v2.0-dual - 2025-09-30 Based on single MOSFET version; adapted to H801 dual-monochrome (A/B).
|
# - MQTT is not enabled in this yaml, so MQTT offline has no direct effect on device logic.
|
||||||
# v1.x (history from single-channel base maintained in comments below)
|
# - If Home Assistant/API is also offline, control from HA is unavailable.
|
||||||
#
|
#
|
||||||
# ------------------------------------------
|
# c) Entire WiFi/Network offline:
|
||||||
# OPERATION (as of v2.x)
|
# - Device continues to run its local light logic and stored restart behaviour.
|
||||||
# ------------------------------------------
|
# - No HA or MQTT control is available.
|
||||||
# 1. General-purpose LED controller.
|
# - Accurate time is not needed; SNTP is not required for operation.
|
||||||
# 2. Designed here for the H801 5-MOSFET board (ESP8266). Using 2 channels as independent
|
#:########################################################################################:#
|
||||||
# monochrome outputs (A and B). The remaining 3 MOSFETs are ignored.
|
|
||||||
# 3. (In SUBSTITUTIONS) setting for MAX % output to extend LED life (ie can ensure it is only ever 95%)
|
|
||||||
# 4. (In SUBSTITUTIONS) Minimum output setting; switches fully OFF at/below the minimum to avoid low-PWM flicker.
|
|
||||||
# 5. (In SUBSTITUTIONS) PWM frequency is set to 1kHz by default. You can increase it, but higher values caused
|
|
||||||
# resets on some ESP8266 boards. On ESP32 you can run much higher (~40 kHz).
|
|
||||||
# 6. Min/Max output settings are not exposed in Home Assistant/MQTT by default, but could be.
|
|
||||||
# With a 1 MB flash, space is tight and only minimal optimisation has been done so far.
|
|
||||||
# 7. (PACKAGES) include common items: network settings, diagnostic entities, MQTT, and SNTP (optional).
|
|
||||||
# 8. Default behaviours, for recovery from lost power or reset:
|
|
||||||
# - "Fade up to full": fade from floor to max on boot.
|
|
||||||
# - "Restore Brightness": fade from floor to the last non-zero brightness on boot (no on/off blip/flash).
|
|
||||||
# - "Remain Off": stays off on boot.
|
|
||||||
# 9. The board LEDs show output on status. Channel A uses the **RED** LED on GPIO5.
|
|
||||||
# Channel B uses the **GREEN** LED on GPIO1 (UART TX; logger baud=0)
|
|
||||||
# 10. Fade timing scales with the configured values (proportionally when starting mid-brightness).
|
|
||||||
# 11. Exposed in Home Assistant/MQTT (duplicated for A and B):
|
|
||||||
# - Startup action (On,Off,Restore)
|
|
||||||
# - Fade Up/Down toggle switch
|
|
||||||
# - Normal On/Off switch (quick ramp up/down)
|
|
||||||
# - Fade up/down times (0-60s)
|
|
||||||
# - Output % (pre-gamma)
|
|
||||||
# - Output Set (1-100, respects min/max). This also changes with other output so reflects value.
|
|
||||||
# - Many device diagnostics (from the included 'diagnostics' package)
|
|
||||||
# - Maximum 'on' time before automatic fade-down (1-48 h, 0 = no limit)
|
|
||||||
# 12. The Fade Up/Down switch auto-syncs to brightness (no ramp is triggered by the sync itself):
|
|
||||||
# - Stops <33% of cap → switch shows OFF
|
|
||||||
# - Stops >66% of cap → switch shows ON
|
|
||||||
###########################################################################################
|
|
||||||
# Hardware: H801 (ESP8266, 5 MOSFET outputs)
|
|
||||||
# ------------------------------------------
|
|
||||||
# DEVICE GPIO (H801, as used here)
|
|
||||||
# ------------------------------------------
|
|
||||||
# GPIO02 Blue Status LED, active-low (ESPHOME status)
|
|
||||||
# GPIO12 MOSFET output A (PWM)
|
|
||||||
# GPIO13 MOSFET output B (PWM)
|
|
||||||
# GPIO05 Red LED (used to display status for Channel A)
|
|
||||||
# GPIO01 Green LED (used to display status for Channel B) [UART TX, logger baud=0]
|
|
||||||
#
|
|
||||||
##########################################################################################
|
|
||||||
##########################################################################################
|
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
|
# SUBSTITUTIONS:
|
||||||
|
# Specific device variable substitutions
|
||||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
substitutions:
|
substitutions:
|
||||||
# Device Naming
|
# Device Naming
|
||||||
device_name: "esp-loungepelmetleds2" # yaml file should be device_name.yaml
|
device_name: "esp-loungepelmetleds2" # yaml file should be device_name.yaml
|
||||||
friendly_name: "Lounge Pelmet LEDs"
|
friendly_name: "Lounge Pelmet LEDs"
|
||||||
description_comment: "Lounge Pelmet LEDs :: H801 dual-channel monochrome"
|
description_comment: "Lounge Pelmet LEDs :: H801 dual-channel monochrome (Layout V1.1)"
|
||||||
device_area: "Lounge" # Allows the ESP device to be automatically linked to an 'Area' in Home Assistant.
|
device_area: "Lounge" # Allows the ESP device to be automatically linked to an 'Area' in Home Assistant.
|
||||||
|
|
||||||
# Project Naming
|
# Project Naming
|
||||||
project_name: "H801.5xMOSFET" # Manufacturer before the dot, device after the dot.
|
project_name: "H801.5xMOSFET" # Manufacturer before the dot, device after the dot.
|
||||||
project_version: "v2.7" # Project version denotes release of the YAML file
|
project_version: "v2.8" # Project version denotes release of the YAML file
|
||||||
|
|
||||||
# Passwords & Secrets (Unfortunately, you can't use substitutions inside secret names)
|
# Passwords & Secrets (Unfortunately, you can't use substitutions inside secret names)
|
||||||
api_key: !secret esp-api_key
|
api_key: !secret esp-api_key
|
||||||
ota_pass: !secret esp-ota_pass
|
ota_pass: !secret esp-ota_pass
|
||||||
static_ip_address: !secret esp-loungepelmetleds2_ip # CHANGE THIS
|
static_ip_address: !secret esp-loungepelmetleds2_ip
|
||||||
|
current_ip_address: ${static_ip_address}
|
||||||
|
|
||||||
# Device Specific Settings (shared defaults applied per channel below)
|
# Device Specific Settings (shared defaults applied per channel below)
|
||||||
log_level: "NONE" # Use INFO while testing; flip back to NONE later
|
log_level: "NONE" # Use INFO while testing; flip back to NONE later
|
||||||
update_interval: "60s"
|
update_interval: "60s"
|
||||||
led_gamma: "1.6"
|
led_gamma: "1.6"
|
||||||
pwm_frequency: "1000Hz"
|
pwm_frequency: "1000Hz"
|
||||||
max_on_default_hours: "24"
|
max_on_default_hours: "24"
|
||||||
|
|
||||||
# Per-channel output caps (%), internal-only (no HA sliders)
|
# Per-channel output caps (%), internal-only (no HA sliders)
|
||||||
@@ -87,49 +99,64 @@ substitutions:
|
|||||||
maximum_led_output_B: "90"
|
maximum_led_output_B: "90"
|
||||||
|
|
||||||
# Device Specific GPIO
|
# Device Specific GPIO
|
||||||
#device_status_led: GPIO05
|
#device_status_led: GPIO5
|
||||||
device_mosfet_out_A: GPIO15
|
device_mosfet_out_A: GPIO15
|
||||||
device_mosfet_out_B: GPIO13
|
device_mosfet_out_B: GPIO13
|
||||||
device_fading_led_A: GPIO05
|
device_fading_led_A: GPIO5
|
||||||
device_fading_led_B: GPIO01
|
device_fading_led_B: GPIO1
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# PACKAGES
|
# PACKAGES:
|
||||||
##########################################################################################
|
# Included Common Packages
|
||||||
|
# https://esphome.io/components/packages.html
|
||||||
|
#:########################################################################################:#
|
||||||
packages:
|
packages:
|
||||||
|
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
||||||
common_wifi: !include
|
common_wifi: !include
|
||||||
file: common/network_common.yaml
|
file: common/network_common.yaml
|
||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
local_static_ip_address: "${static_ip_address}"
|
local_static_ip_address: "${static_ip_address}"
|
||||||
|
local_current_ip_address: "${current_ip_address}"
|
||||||
local_ota_pass: "${ota_pass}"
|
local_ota_pass: "${ota_pass}"
|
||||||
|
|
||||||
|
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||||
common_api: !include
|
common_api: !include
|
||||||
|
#file: common/api_common.yaml
|
||||||
file: common/api_common_noencryption.yaml
|
file: common/api_common_noencryption.yaml
|
||||||
vars:
|
vars:
|
||||||
local_api_key: "${api_key}"
|
local_api_key: "${api_key}"
|
||||||
|
|
||||||
|
#### MQTT ####
|
||||||
#common_mqtt: !include
|
#common_mqtt: !include
|
||||||
# file: common/mqtt_common.yaml
|
# file: common/mqtt_common.yaml
|
||||||
# vars:
|
# vars:
|
||||||
# local_device_name: "${device_name}"
|
# local_device_name: "${device_name}"
|
||||||
|
|
||||||
|
#### WEB PORTAL ####
|
||||||
#common_webportal: !include common/webportal_common.yaml
|
#common_webportal: !include common/webportal_common.yaml
|
||||||
#common_sntp: !include common/sntp_common.yaml
|
|
||||||
|
|
||||||
diag_basic: !include common/include_basic_diag_sensors.yaml
|
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
||||||
#diag_more: !include common/include_more_diag_sensors.yaml
|
#common_sntp: !include common/sntp_common.yaml
|
||||||
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
|
||||||
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
|
||||||
|
|
||||||
##########################################################################################
|
#### DIAGNOSTICS Sensors ####
|
||||||
# ESPHome CORE CONFIGURATION
|
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 CORE CONFIGURATION:
|
||||||
|
# https://esphome.io/components/esphome.html
|
||||||
|
#:########################################################################################:#
|
||||||
esphome:
|
esphome:
|
||||||
name: "${device_name}"
|
name: "${device_name}"
|
||||||
friendly_name: "${friendly_name}"
|
friendly_name: "${friendly_name}"
|
||||||
comment: "${description_comment}"
|
comment: "${description_comment}"
|
||||||
area: "${device_area}"
|
area: "${device_area}"
|
||||||
|
project:
|
||||||
|
name: "${project_name}"
|
||||||
|
version: "${project_version}"
|
||||||
on_boot:
|
on_boot:
|
||||||
priority: 200
|
priority: 200
|
||||||
then:
|
then:
|
||||||
@@ -171,9 +198,22 @@ esphome:
|
|||||||
transition_length: 0s
|
transition_length: 0s
|
||||||
- lambda: 'id(booting) = false;'
|
- lambda: 'id(booting) = false;'
|
||||||
|
|
||||||
##########################################################################################
|
# Only if you want to play with build flags...
|
||||||
# ESP PLATFORM AND FRAMEWORK
|
# platformio_options:
|
||||||
##########################################################################################
|
# build_unflags:
|
||||||
|
# - -flto
|
||||||
|
# build_flags:
|
||||||
|
# - -fno-lto
|
||||||
|
# - -Wl,--gc-sections
|
||||||
|
# - -ffunction-sections
|
||||||
|
# - -fdata-sections
|
||||||
|
# - -DNDEBUG
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# ESP PLATFORM AND FRAMEWORK:
|
||||||
|
# https://esphome.io/components/esp8266.html
|
||||||
|
# https://esphome.io/components/esp32.html
|
||||||
|
#:########################################################################################:#
|
||||||
esp8266:
|
esp8266:
|
||||||
board: esp01_1m
|
board: esp01_1m
|
||||||
restore_from_flash: true
|
restore_from_flash: true
|
||||||
@@ -182,25 +222,29 @@ mdns:
|
|||||||
disabled: true
|
disabled: true
|
||||||
|
|
||||||
preferences:
|
preferences:
|
||||||
flash_write_interval: 5min # reduce flash churn while testing
|
flash_write_interval: 5min
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# GLOBAL VARIABLES
|
# GLOBAL VARIABLES:
|
||||||
##########################################################################################
|
# https://esphome.io/components/globals.html
|
||||||
|
#:########################################################################################:#
|
||||||
globals:
|
globals:
|
||||||
# Per-channel brightness caps (internal; set via YAML substitutions)
|
# Per-channel brightness caps (internal; set via YAML substitutions)
|
||||||
- id: min_brightness_pct_A
|
- id: min_brightness_pct_A
|
||||||
type: int
|
type: int
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: "${minimum_led_output_A}"
|
initial_value: "${minimum_led_output_A}"
|
||||||
|
|
||||||
- id: max_brightness_pct_A
|
- id: max_brightness_pct_A
|
||||||
type: int
|
type: int
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: "${maximum_led_output_A}"
|
initial_value: "${maximum_led_output_A}"
|
||||||
|
|
||||||
- id: min_brightness_pct_B
|
- id: min_brightness_pct_B
|
||||||
type: int
|
type: int
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: "${minimum_led_output_B}"
|
initial_value: "${minimum_led_output_B}"
|
||||||
|
|
||||||
- id: max_brightness_pct_B
|
- id: max_brightness_pct_B
|
||||||
type: int
|
type: int
|
||||||
restore_value: false
|
restore_value: false
|
||||||
@@ -216,123 +260,146 @@ globals:
|
|||||||
- id: ramp_up_ms_A
|
- id: ramp_up_ms_A
|
||||||
type: int
|
type: int
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: '5000'
|
initial_value: "5000"
|
||||||
|
|
||||||
- id: ramp_down_ms_A
|
- id: ramp_down_ms_A
|
||||||
type: int
|
type: int
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: '10000'
|
initial_value: "10000"
|
||||||
|
|
||||||
- id: ramp_up_ms_B
|
- id: ramp_up_ms_B
|
||||||
type: int
|
type: int
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: '5000'
|
initial_value: "5000"
|
||||||
|
|
||||||
- id: ramp_down_ms_B
|
- id: ramp_down_ms_B
|
||||||
type: int
|
type: int
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: '10000'
|
initial_value: "10000"
|
||||||
|
|
||||||
# Restart Action. (0=Fade full, 1=Restore brightness, 2=Remain off)
|
# Restart Action. (0=Fade full, 1=Restore brightness, 2=Remain off)
|
||||||
- id: restart_mode
|
- id: restart_mode
|
||||||
type: int
|
type: int
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: '1' # align with select initial_option "Restore Brightness"
|
initial_value: "1" # align with select initial_option "Restore Brightness"
|
||||||
|
|
||||||
# Per-channel runtime state (A)
|
# Per-channel runtime state (A)
|
||||||
- id: ramp_switch_target_on_A
|
- id: ramp_switch_target_on_A
|
||||||
type: bool
|
type: bool
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: 'false'
|
initial_value: "false"
|
||||||
|
|
||||||
- id: suppress_slider_sync_A
|
- id: suppress_slider_sync_A
|
||||||
type: bool
|
type: bool
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: 'false'
|
initial_value: "false"
|
||||||
- id: suppress_quick_on_A # guard to prevent quick-to-cap on slider turn-on
|
|
||||||
|
- id: suppress_quick_on_A
|
||||||
type: bool
|
type: bool
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: 'false'
|
initial_value: "false"
|
||||||
|
|
||||||
- id: last_brightness_pct_A
|
- id: last_brightness_pct_A
|
||||||
type: float
|
type: float
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: '0.0'
|
initial_value: "0.0"
|
||||||
|
|
||||||
- id: last_set_pos_A
|
- id: last_set_pos_A
|
||||||
type: int
|
type: int
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: '-1'
|
initial_value: "-1"
|
||||||
|
|
||||||
- id: last_ramp_ms_A
|
- id: last_ramp_ms_A
|
||||||
type: uint32_t
|
type: uint32_t
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: '0'
|
initial_value: "0"
|
||||||
|
|
||||||
- id: last_nonzero_brightness_pct_A
|
- id: last_nonzero_brightness_pct_A
|
||||||
type: float
|
type: float
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: '0.0'
|
initial_value: "0.0"
|
||||||
|
|
||||||
- id: restore_target_pct_A
|
- id: restore_target_pct_A
|
||||||
type: float
|
type: float
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: '0.0'
|
initial_value: "0.0"
|
||||||
|
|
||||||
- id: is_ramping_A
|
- id: is_ramping_A
|
||||||
type: bool
|
type: bool
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: 'false'
|
initial_value: "false"
|
||||||
|
|
||||||
- id: last_nonzero_tmp_A
|
- id: last_nonzero_tmp_A
|
||||||
type: float
|
type: float
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: '0.0'
|
initial_value: "0.0"
|
||||||
|
|
||||||
- id: ramping_for_off_A
|
- id: ramping_for_off_A
|
||||||
type: bool
|
type: bool
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: 'false'
|
initial_value: "false"
|
||||||
|
|
||||||
# Per-channel runtime state (B)
|
# Per-channel runtime state (B)
|
||||||
- id: ramp_switch_target_on_B
|
- id: ramp_switch_target_on_B
|
||||||
type: bool
|
type: bool
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: 'false'
|
initial_value: "false"
|
||||||
|
|
||||||
- id: suppress_slider_sync_B
|
- id: suppress_slider_sync_B
|
||||||
type: bool
|
type: bool
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: 'false'
|
initial_value: "false"
|
||||||
- id: suppress_quick_on_B # guard to prevent quick-to-cap on slider turn-on
|
|
||||||
|
- id: suppress_quick_on_B
|
||||||
type: bool
|
type: bool
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: 'false'
|
initial_value: "false"
|
||||||
|
|
||||||
- id: last_brightness_pct_B
|
- id: last_brightness_pct_B
|
||||||
type: float
|
type: float
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: '0.0'
|
initial_value: "0.0"
|
||||||
|
|
||||||
- id: last_set_pos_B
|
- id: last_set_pos_B
|
||||||
type: int
|
type: int
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: '-1'
|
initial_value: "-1"
|
||||||
|
|
||||||
- id: last_ramp_ms_B
|
- id: last_ramp_ms_B
|
||||||
type: uint32_t
|
type: uint32_t
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: '0'
|
initial_value: "0"
|
||||||
|
|
||||||
- id: last_nonzero_brightness_pct_B
|
- id: last_nonzero_brightness_pct_B
|
||||||
type: float
|
type: float
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: '0.0'
|
initial_value: "0.0"
|
||||||
|
|
||||||
- id: restore_target_pct_B
|
- id: restore_target_pct_B
|
||||||
type: float
|
type: float
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: '0.0'
|
initial_value: "0.0"
|
||||||
|
|
||||||
- id: is_ramping_B
|
- id: is_ramping_B
|
||||||
type: bool
|
type: bool
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: 'false'
|
initial_value: "false"
|
||||||
|
|
||||||
- id: last_nonzero_tmp_B
|
- id: last_nonzero_tmp_B
|
||||||
type: float
|
type: float
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: '0.0'
|
initial_value: "0.0"
|
||||||
|
|
||||||
- id: ramping_for_off_B
|
- id: ramping_for_off_B
|
||||||
type: bool
|
type: bool
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: 'false'
|
initial_value: "false"
|
||||||
|
|
||||||
# Guard for startup behaviour
|
# Guard for startup behaviour
|
||||||
- id: booting
|
- id: booting
|
||||||
type: bool
|
type: bool
|
||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: 'true'
|
initial_value: "true"
|
||||||
|
|
||||||
# Compile time Gamma (cached; currently unused since PWM% sensors were removed)
|
# Compile time Gamma (cached; currently unused since PWM% sensors were removed)
|
||||||
- id: led_gamma_f
|
- id: led_gamma_f
|
||||||
@@ -340,48 +407,51 @@ globals:
|
|||||||
restore_value: false
|
restore_value: false
|
||||||
initial_value: ${led_gamma}
|
initial_value: ${led_gamma}
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# LOGGER
|
# LOGGER:
|
||||||
##########################################################################################
|
# https://esphome.io/components/logger.html
|
||||||
|
#:########################################################################################:#
|
||||||
logger:
|
logger:
|
||||||
level: "${log_level}"
|
level: "${log_level}"
|
||||||
baud_rate: 0
|
baud_rate: 0
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# STATUS LED
|
# STATUS LED:
|
||||||
#########################################################################################
|
# https://esphome.io/components/status_led.html
|
||||||
|
#:########################################################################################:#
|
||||||
#status_led:
|
#status_led:
|
||||||
# pin:
|
# pin:
|
||||||
# number: ${device_status_led}
|
# number: ${device_status_led}
|
||||||
# inverted: true
|
# inverted: true
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# MQTT COMMANDS
|
# MQTT COMMANDS:
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
#mqtt:
|
#mqtt:
|
||||||
# on_message handlers commented for efficiency (S8). Uncomment if you need local MQTT control again.
|
# on_message handlers commented for efficiency. Uncomment if you need local MQTT control again.
|
||||||
#on_message:
|
# on_message:
|
||||||
# - topic: "${mqtt_local_command_topic_A}/lightA/set"
|
# - topic: "${mqtt_local_command_topic_A}/lightA/set"
|
||||||
# payload: "${mqtt_local_device_command_ON}"
|
# payload: "${mqtt_local_device_command_ON}"
|
||||||
# then:
|
# then:
|
||||||
# - switch.turn_on: mosfet_ramp_switch_a
|
# - switch.turn_on: mosfet_ramp_switch_a
|
||||||
# - topic: "${mqtt_local_command_topic_A}/lightA/set"}
|
# - topic: "${mqtt_local_command_topic_A}/lightA/set"
|
||||||
# payload: "${mqtt_local_device_command_OFF}"
|
# payload: "${mqtt_local_device_command_OFF}"
|
||||||
# then:
|
# then:
|
||||||
# - switch.turn_off: mosfet_ramp_switch_a
|
# - switch.turn_off: mosfet_ramp_switch_a
|
||||||
#
|
#
|
||||||
# - topic: "${mqtt_local_command_topic_B}/lightB/set"
|
# - topic: "${mqtt_local_command_topic_B}/lightB/set"
|
||||||
# payload: "${mqtt_local_device_command_ON}"
|
# payload: "${mqtt_local_device_command_ON}"
|
||||||
# then:
|
# then:
|
||||||
# - switch.turn_on: mosfet_ramp_switch_b
|
# - switch.turn_on: mosfet_ramp_switch_b
|
||||||
# - topic: "${mqtt_local_command_topic_B}/lightB/set"
|
# - topic: "${mqtt_local_command_topic_B}/lightB/set"
|
||||||
# payload: "${mqtt_local_device_command_OFF}"
|
# payload: "${mqtt_local_device_command_OFF}"
|
||||||
# then:
|
# then:
|
||||||
# - switch.turn_off: mosfet_ramp_switch_b
|
# - switch.turn_off: mosfet_ramp_switch_b
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SWITCHES
|
# SWITCH COMPONENT:
|
||||||
##########################################################################################
|
# https://esphome.io/components/switch/
|
||||||
|
#:########################################################################################:#
|
||||||
switch:
|
switch:
|
||||||
- platform: template
|
- platform: template
|
||||||
id: mosfet_ramp_switch_a
|
id: mosfet_ramp_switch_a
|
||||||
@@ -417,13 +487,15 @@ switch:
|
|||||||
- script.stop: ramp_on_script_B
|
- script.stop: ramp_on_script_B
|
||||||
- script.execute: ramp_off_script_B
|
- script.execute: ramp_off_script_B
|
||||||
|
|
||||||
#################################################################################################
|
#:########################################################################################:#
|
||||||
# BUTTONS (none)
|
# BUTTON COMPONENT:
|
||||||
#################################################################################################
|
# No standalone template button entities in this yaml
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# SELECTS
|
# SELECT COMPONENT:
|
||||||
#########################################################################################
|
# https://esphome.io/components/select/index.html
|
||||||
|
#:########################################################################################:#
|
||||||
select:
|
select:
|
||||||
- platform: template
|
- platform: template
|
||||||
id: restart_action
|
id: restart_action
|
||||||
@@ -445,9 +517,10 @@ select:
|
|||||||
id(restart_mode) = 2;
|
id(restart_mode) = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SENSORS
|
# SENSOR COMPONENT:
|
||||||
##########################################################################################
|
# https://esphome.io/components/sensor/
|
||||||
|
#:########################################################################################:#
|
||||||
sensor:
|
sensor:
|
||||||
# Channel A: Output % (pre-gamma)
|
# Channel A: Output % (pre-gamma)
|
||||||
- platform: template
|
- platform: template
|
||||||
@@ -456,7 +529,7 @@ sensor:
|
|||||||
unit_of_measurement: "%"
|
unit_of_measurement: "%"
|
||||||
icon: mdi:percent
|
icon: mdi:percent
|
||||||
accuracy_decimals: 0
|
accuracy_decimals: 0
|
||||||
update_interval: 200ms # show real-time ramp
|
update_interval: 200ms
|
||||||
disabled_by_default: true
|
disabled_by_default: true
|
||||||
lambda: |-
|
lambda: |-
|
||||||
const auto &cv = id(mosfet_leds_A).current_values;
|
const auto &cv = id(mosfet_leds_A).current_values;
|
||||||
@@ -488,22 +561,21 @@ sensor:
|
|||||||
id(led_output_set_pct_A).publish_state(pos_i);
|
id(led_output_set_pct_A).publish_state(pos_i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Auto-sync fade switch to brightness thresholds (no scripts)
|
|
||||||
if (!id(booting) && !id(is_ramping_A)) {
|
if (!id(booting) && !id(is_ramping_A)) {
|
||||||
float cap = (float) id(max_brightness_pct_A); // cap in %
|
float cap = (float) id(max_brightness_pct_A);
|
||||||
float low_th = cap * 0.33f;
|
float low_th = cap * 0.33f;
|
||||||
float high_th = cap * 0.66f;
|
float high_th = cap * 0.66f;
|
||||||
if (cv_now.is_on()) {
|
if (cv_now.is_on()) {
|
||||||
float b = x; // current brightness in %
|
float b = x;
|
||||||
if (b < low_th - 0.25f) { // hysteresis margin
|
if (b < low_th - 0.25f) {
|
||||||
if (id(ramp_switch_target_on_A)) {
|
if (id(ramp_switch_target_on_A)) {
|
||||||
id(ramp_switch_target_on_A) = false;
|
id(ramp_switch_target_on_A) = false;
|
||||||
id(mosfet_ramp_switch_a).publish_state(false); // UI-only; no ramp
|
id(mosfet_ramp_switch_a).publish_state(false);
|
||||||
}
|
}
|
||||||
} else if (b > high_th + 0.25f) {
|
} else if (b > high_th + 0.25f) {
|
||||||
if (!id(ramp_switch_target_on_A)) {
|
if (!id(ramp_switch_target_on_A)) {
|
||||||
id(ramp_switch_target_on_A) = true;
|
id(ramp_switch_target_on_A) = true;
|
||||||
id(mosfet_ramp_switch_a).publish_state(true); // UI-only; no ramp
|
id(mosfet_ramp_switch_a).publish_state(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -548,10 +620,9 @@ sensor:
|
|||||||
id(led_output_set_pct_B).publish_state(pos_i);
|
id(led_output_set_pct_B).publish_state(pos_i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Auto-sync fade switch to brightness thresholds (no scripts)
|
|
||||||
if (!id(booting) && !id(is_ramping_B)) {
|
if (!id(booting) && !id(is_ramping_B)) {
|
||||||
float cap = (float) id(max_brightness_pct_B);
|
float cap = (float) id(max_brightness_pct_B);
|
||||||
float low_th = cap * 0.33f;
|
float low_th = cap * 0.33f;
|
||||||
float high_th = cap * 0.66f;
|
float high_th = cap * 0.66f;
|
||||||
if (cv_now.is_on()) {
|
if (cv_now.is_on()) {
|
||||||
float b = x;
|
float b = x;
|
||||||
@@ -569,14 +640,16 @@ sensor:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# OUTPUTS
|
# OUTPUT COMPONENT:
|
||||||
##########################################################################################
|
# https://esphome.io/components/output/
|
||||||
|
#:########################################################################################:#
|
||||||
output:
|
output:
|
||||||
- platform: esp8266_pwm
|
- platform: esp8266_pwm
|
||||||
id: mosfet_pwm_A
|
id: mosfet_pwm_A
|
||||||
pin: ${device_mosfet_out_A}
|
pin: ${device_mosfet_out_A}
|
||||||
frequency: ${pwm_frequency}
|
frequency: ${pwm_frequency}
|
||||||
|
|
||||||
- platform: esp8266_pwm
|
- platform: esp8266_pwm
|
||||||
id: mosfet_pwm_B
|
id: mosfet_pwm_B
|
||||||
pin: ${device_mosfet_out_B}
|
pin: ${device_mosfet_out_B}
|
||||||
@@ -587,27 +660,28 @@ output:
|
|||||||
pin:
|
pin:
|
||||||
number: ${device_fading_led_A}
|
number: ${device_fading_led_A}
|
||||||
inverted: false
|
inverted: false
|
||||||
|
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
id: fading_led_out_B
|
id: fading_led_out_B
|
||||||
pin:
|
pin:
|
||||||
number: ${device_fading_led_B}
|
number: ${device_fading_led_B}
|
||||||
inverted: false
|
inverted: false
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# LIGHTS
|
# LIGHT COMPONENT:
|
||||||
##########################################################################################
|
# https://esphome.io/components/light/
|
||||||
|
#:########################################################################################:#
|
||||||
light:
|
light:
|
||||||
- platform: monochromatic
|
- platform: monochromatic
|
||||||
id: mosfet_leds_A
|
id: mosfet_leds_A
|
||||||
name: "${friendly_name} A"
|
name: "${friendly_name} A"
|
||||||
output: mosfet_pwm_A
|
output: mosfet_pwm_A
|
||||||
restore_mode: RESTORE_DEFAULT_OFF
|
restore_mode: RESTORE_DEFAULT_OFF
|
||||||
default_transition_length: 250ms # quick ramp for normal light toggle
|
default_transition_length: 250ms
|
||||||
icon: mdi:led-strip-variant
|
icon: mdi:led-strip-variant
|
||||||
gamma_correct: "${led_gamma}"
|
gamma_correct: "${led_gamma}"
|
||||||
|
|
||||||
on_turn_on:
|
on_turn_on:
|
||||||
# Start/refresh Max-On watchdog quietly whenever light turns on
|
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
lambda: 'return id(max_on_hours) > 0;'
|
lambda: 'return id(max_on_hours) > 0;'
|
||||||
@@ -628,13 +702,11 @@ light:
|
|||||||
|
|
||||||
on_state:
|
on_state:
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
// Mirror board RED LED to this channel's on/off
|
|
||||||
const auto &cv_s = id(mosfet_leds_A).current_values;
|
const auto &cv_s = id(mosfet_leds_A).current_values;
|
||||||
const bool is_on = cv_s.is_on() && (cv_s.get_brightness() > 0.0005f);
|
const bool is_on = cv_s.is_on() && (cv_s.get_brightness() > 0.0005f);
|
||||||
if (is_on) id(fading_led_out_A).turn_on();
|
if (is_on) id(fading_led_out_A).turn_on();
|
||||||
else id(fading_led_out_A).turn_off();
|
else id(fading_led_out_A).turn_off();
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
// Enforce cap if anyone tries to exceed it
|
|
||||||
const float cap = id(max_brightness_pct_A) / 100.0f;
|
const float cap = id(max_brightness_pct_A) / 100.0f;
|
||||||
const auto &cv = id(mosfet_leds_A).current_values;
|
const auto &cv = id(mosfet_leds_A).current_values;
|
||||||
if (!cv.is_on()) return;
|
if (!cv.is_on()) return;
|
||||||
@@ -651,7 +723,7 @@ light:
|
|||||||
name: "${friendly_name} B"
|
name: "${friendly_name} B"
|
||||||
output: mosfet_pwm_B
|
output: mosfet_pwm_B
|
||||||
restore_mode: RESTORE_DEFAULT_OFF
|
restore_mode: RESTORE_DEFAULT_OFF
|
||||||
default_transition_length: 250ms # quick ramp for normal light toggle
|
default_transition_length: 250ms
|
||||||
icon: mdi:led-strip-variant
|
icon: mdi:led-strip-variant
|
||||||
gamma_correct: "${led_gamma}"
|
gamma_correct: "${led_gamma}"
|
||||||
|
|
||||||
@@ -676,7 +748,6 @@ light:
|
|||||||
|
|
||||||
on_state:
|
on_state:
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
// Mirror board GREEN LED to this channel's on/off
|
|
||||||
const auto &cv_s = id(mosfet_leds_B).current_values;
|
const auto &cv_s = id(mosfet_leds_B).current_values;
|
||||||
const bool is_on = cv_s.is_on() && (cv_s.get_brightness() > 0.0005f);
|
const bool is_on = cv_s.is_on() && (cv_s.get_brightness() > 0.0005f);
|
||||||
if (is_on) id(fading_led_out_B).turn_on();
|
if (is_on) id(fading_led_out_B).turn_on();
|
||||||
@@ -693,9 +764,10 @@ light:
|
|||||||
call.set_transition_length(0);
|
call.set_transition_length(0);
|
||||||
call.perform();
|
call.perform();
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# NUMBERS
|
# NUMBER COMPONENT:
|
||||||
##########################################################################################
|
# https://esphome.io/components/number/
|
||||||
|
#:########################################################################################:#
|
||||||
number:
|
number:
|
||||||
- platform: template
|
- platform: template
|
||||||
id: cfg_ramp_up_s_A
|
id: cfg_ramp_up_s_A
|
||||||
@@ -777,7 +849,6 @@ number:
|
|||||||
id(ramp_down_ms_B) = secs * 1000;
|
id(ramp_down_ms_B) = secs * 1000;
|
||||||
id(cfg_ramp_down_s_B).publish_state((float) secs);
|
id(cfg_ramp_down_s_B).publish_state((float) secs);
|
||||||
|
|
||||||
# Per-channel position slider (0..100 mapped into [min..max])
|
|
||||||
- platform: template
|
- platform: template
|
||||||
id: led_output_set_pct_A
|
id: led_output_set_pct_A
|
||||||
name: "${friendly_name} A Output Set (0-100)"
|
name: "${friendly_name} A Output Set (0-100)"
|
||||||
@@ -788,11 +859,11 @@ number:
|
|||||||
step: 1
|
step: 1
|
||||||
lambda: |-
|
lambda: |-
|
||||||
const auto &cv = id(mosfet_leds_A).current_values;
|
const auto &cv = id(mosfet_leds_A).current_values;
|
||||||
float actual = cv.is_on() ? (cv.get_brightness() * 100.0f) : 0.0f; // 0..100 actual
|
float actual = cv.is_on() ? (cv.get_brightness() * 100.0f) : 0.0f;
|
||||||
float minp = (float) id(min_brightness_pct_A);
|
float minp = (float) id(min_brightness_pct_A);
|
||||||
float maxp = (float) id(max_brightness_pct_A);
|
float maxp = (float) id(max_brightness_pct_A);
|
||||||
if (maxp <= minp) maxp = minp + 1.0f; // avoid div/0
|
if (maxp <= minp) maxp = minp + 1.0f;
|
||||||
if (actual <= 0.0f) return 0.0f; // when OFF, show 0
|
if (actual <= 0.0f) return 0.0f;
|
||||||
float pos = (actual - minp) * 100.0f / (maxp - minp);
|
float pos = (actual - minp) * 100.0f / (maxp - minp);
|
||||||
if (pos < 0.0f) pos = 0.0f;
|
if (pos < 0.0f) pos = 0.0f;
|
||||||
if (pos > 100.0f) pos = 100.0f;
|
if (pos > 100.0f) pos = 100.0f;
|
||||||
@@ -817,22 +888,19 @@ number:
|
|||||||
else:
|
else:
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
id(suppress_slider_sync_A) = true;
|
id(suppress_slider_sync_A) = true;
|
||||||
float pos = x; // 0..100
|
float pos = x;
|
||||||
if (pos < 1.0f) pos = 1.0f; // 0 is OFF
|
if (pos < 1.0f) pos = 1.0f;
|
||||||
if (pos > 100.0f) pos = 100.0f;
|
if (pos > 100.0f) pos = 100.0f;
|
||||||
id(led_output_set_pct_A).publish_state((int) floorf(pos + 0.5f));
|
id(led_output_set_pct_A).publish_state((int) floorf(pos + 0.5f));
|
||||||
|
|
||||||
// Map slider position into absolute % within [min..max]
|
|
||||||
float minp = (float) id(min_brightness_pct_A);
|
float minp = (float) id(min_brightness_pct_A);
|
||||||
float maxp = (float) id(max_brightness_pct_A);
|
float maxp = (float) id(max_brightness_pct_A);
|
||||||
if (maxp <= minp) maxp = minp + 1.0f;
|
if (maxp <= minp) maxp = minp + 1.0f;
|
||||||
float out_pct = minp + (pos * (maxp - minp) / 100.0f);
|
float out_pct = minp + (pos * (maxp - minp) / 100.0f);
|
||||||
if (out_pct > maxp) out_pct = maxp;
|
if (out_pct > maxp) out_pct = maxp;
|
||||||
|
|
||||||
// Stash target for the ramp script
|
|
||||||
id(restore_target_pct_A) = out_pct;
|
id(restore_target_pct_A) = out_pct;
|
||||||
|
|
||||||
// Choose duration by direction (up vs down)
|
|
||||||
const auto &cv = id(mosfet_leds_A).current_values;
|
const auto &cv = id(mosfet_leds_A).current_values;
|
||||||
float curr = cv.is_on() ? (cv.get_brightness() * 100.0f) : 0.0f;
|
float curr = cv.is_on() ? (cv.get_brightness() * 100.0f) : 0.0f;
|
||||||
id(last_ramp_ms_A) = (out_pct > curr) ? id(ramp_up_ms_A) : id(ramp_down_ms_A);
|
id(last_ramp_ms_A) = (out_pct > curr) ? id(ramp_up_ms_A) : id(ramp_down_ms_A);
|
||||||
@@ -852,11 +920,11 @@ number:
|
|||||||
step: 1
|
step: 1
|
||||||
lambda: |-
|
lambda: |-
|
||||||
const auto &cv = id(mosfet_leds_B).current_values;
|
const auto &cv = id(mosfet_leds_B).current_values;
|
||||||
float actual = cv.is_on() ? (cv.get_brightness() * 100.0f) : 0.0f; // 0..100 actual
|
float actual = cv.is_on() ? (cv.get_brightness() * 100.0f) : 0.0f;
|
||||||
float minp = (float) id(min_brightness_pct_B);
|
float minp = (float) id(min_brightness_pct_B);
|
||||||
float maxp = (float) id(max_brightness_pct_B);
|
float maxp = (float) id(max_brightness_pct_B);
|
||||||
if (maxp <= minp) maxp = minp + 1.0f; // avoid div/0
|
if (maxp <= minp) maxp = minp + 1.0f;
|
||||||
if (actual <= 0.0f) return 0.0f; // when OFF, show 0
|
if (actual <= 0.0f) return 0.0f;
|
||||||
float pos = (actual - minp) * 100.0f / (maxp - minp);
|
float pos = (actual - minp) * 100.0f / (maxp - minp);
|
||||||
if (pos < 0.0f) pos = 0.0f;
|
if (pos < 0.0f) pos = 0.0f;
|
||||||
if (pos > 100.0f) pos = 100.0f;
|
if (pos > 100.0f) pos = 100.0f;
|
||||||
@@ -881,22 +949,19 @@ number:
|
|||||||
else:
|
else:
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
id(suppress_slider_sync_B) = true;
|
id(suppress_slider_sync_B) = true;
|
||||||
float pos = x; // 0..100
|
float pos = x;
|
||||||
if (pos < 1.0f) pos = 1.0f; // 0 is OFF
|
if (pos < 1.0f) pos = 1.0f;
|
||||||
if (pos > 100.0f) pos = 100.0f;
|
if (pos > 100.0f) pos = 100.0f;
|
||||||
id(led_output_set_pct_B).publish_state((int) floorf(pos + 0.5f));
|
id(led_output_set_pct_B).publish_state((int) floorf(pos + 0.5f));
|
||||||
|
|
||||||
// Map slider position into absolute % within [min..max]
|
|
||||||
float minp = (float) id(min_brightness_pct_B);
|
float minp = (float) id(min_brightness_pct_B);
|
||||||
float maxp = (float) id(max_brightness_pct_B);
|
float maxp = (float) id(max_brightness_pct_B);
|
||||||
if (maxp <= minp) maxp = minp + 1.0f;
|
if (maxp <= minp) maxp = minp + 1.0f;
|
||||||
float out_pct = minp + (pos * (maxp - minp) / 100.0f);
|
float out_pct = minp + (pos * (maxp - minp) / 100.0f);
|
||||||
if (out_pct > maxp) out_pct = maxp;
|
if (out_pct > maxp) out_pct = maxp;
|
||||||
|
|
||||||
// Stash target for the ramp script
|
|
||||||
id(restore_target_pct_B) = out_pct;
|
id(restore_target_pct_B) = out_pct;
|
||||||
|
|
||||||
// Choose duration by direction (up vs down)
|
|
||||||
const auto &cv = id(mosfet_leds_B).current_values;
|
const auto &cv = id(mosfet_leds_B).current_values;
|
||||||
float curr = cv.is_on() ? (cv.get_brightness() * 100.0f) : 0.0f;
|
float curr = cv.is_on() ? (cv.get_brightness() * 100.0f) : 0.0f;
|
||||||
id(last_ramp_ms_B) = (out_pct > curr) ? id(ramp_up_ms_B) : id(ramp_down_ms_B);
|
id(last_ramp_ms_B) = (out_pct > curr) ? id(ramp_up_ms_B) : id(ramp_down_ms_B);
|
||||||
@@ -906,8 +971,6 @@ number:
|
|||||||
- delay: !lambda 'return (uint32_t) id(last_ramp_ms_B);'
|
- delay: !lambda 'return (uint32_t) id(last_ramp_ms_B);'
|
||||||
- lambda: 'id(suppress_slider_sync_B) = false;'
|
- lambda: 'id(suppress_slider_sync_B) = false;'
|
||||||
|
|
||||||
|
|
||||||
# Shared "Max On" hours (0=disabled). When light is turned on, watchdog restarts.
|
|
||||||
- platform: template
|
- platform: template
|
||||||
id: cfg_max_on_hours
|
id: cfg_max_on_hours
|
||||||
name: "${friendly_name} Max On (h)"
|
name: "${friendly_name} Max On (h)"
|
||||||
@@ -923,11 +986,10 @@ number:
|
|||||||
set_action:
|
set_action:
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
int hrs = (int) x;
|
int hrs = (int) x;
|
||||||
if (hrs < 0) hrs = 0;
|
if (hrs < 0) hrs = 0;
|
||||||
if (hrs > 48) hrs = 48;
|
if (hrs > 48) hrs = 48;
|
||||||
id(max_on_hours) = hrs;
|
id(max_on_hours) = hrs;
|
||||||
id(cfg_max_on_hours).publish_state((float) hrs);
|
id(cfg_max_on_hours).publish_state((float) hrs);
|
||||||
# Restart/stop watchdogs appropriately for both channels
|
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
lambda: 'return id(mosfet_leds_A).current_values.is_on();'
|
lambda: 'return id(mosfet_leds_A).current_values.is_on();'
|
||||||
@@ -949,9 +1011,10 @@ number:
|
|||||||
then:
|
then:
|
||||||
- script.execute: max_on_watchdog_B
|
- script.execute: max_on_watchdog_B
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SCRIPTS
|
# SCRIPT COMPONENT:
|
||||||
##########################################################################################
|
# https://esphome.io/components/script.html
|
||||||
|
#:########################################################################################:#
|
||||||
script:
|
script:
|
||||||
# Ramps: Channel A
|
# Ramps: Channel A
|
||||||
- id: ramp_on_script_A
|
- id: ramp_on_script_A
|
||||||
@@ -959,7 +1022,6 @@ script:
|
|||||||
then:
|
then:
|
||||||
- lambda: 'id(is_ramping_A) = true;'
|
- lambda: 'id(is_ramping_A) = true;'
|
||||||
- script.stop: ramp_off_script_A
|
- script.stop: ramp_off_script_A
|
||||||
# Single transition to CAP for the full configured time
|
|
||||||
- light.turn_on:
|
- light.turn_on:
|
||||||
id: mosfet_leds_A
|
id: mosfet_leds_A
|
||||||
brightness: !lambda 'return id(max_brightness_pct_A) / 100.0f;'
|
brightness: !lambda 'return id(max_brightness_pct_A) / 100.0f;'
|
||||||
@@ -1000,7 +1062,6 @@ script:
|
|||||||
id(is_ramping_A) = true;
|
id(is_ramping_A) = true;
|
||||||
id(ramping_for_off_A) = true;
|
id(ramping_for_off_A) = true;
|
||||||
- script.stop: ramp_on_script_A
|
- script.stop: ramp_on_script_A
|
||||||
# Single transition directly to OFF for the full configured time
|
|
||||||
- light.turn_off:
|
- light.turn_off:
|
||||||
id: mosfet_leds_A
|
id: mosfet_leds_A
|
||||||
transition_length: !lambda 'return (uint32_t) id(ramp_down_ms_A);'
|
transition_length: !lambda 'return (uint32_t) id(ramp_down_ms_A);'
|
||||||
@@ -1039,7 +1100,7 @@ script:
|
|||||||
float minp = (float) id(min_brightness_pct_A);
|
float minp = (float) id(min_brightness_pct_A);
|
||||||
float maxp = (float) id(max_brightness_pct_A);
|
float maxp = (float) id(max_brightness_pct_A);
|
||||||
if (target > 0.0f && target < minp) target = minp;
|
if (target > 0.0f && target < minp) target = minp;
|
||||||
if (target > maxp) target = maxp;
|
if (target > maxp) target = maxp;
|
||||||
id(restore_target_pct_A) = target;
|
id(restore_target_pct_A) = target;
|
||||||
id(last_ramp_ms_A) = id(ramp_up_ms_A);
|
id(last_ramp_ms_A) = id(ramp_up_ms_A);
|
||||||
- if:
|
- if:
|
||||||
@@ -1048,14 +1109,14 @@ script:
|
|||||||
then:
|
then:
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
id(ramp_switch_target_on_A) = true;
|
id(ramp_switch_target_on_A) = true;
|
||||||
id(suppress_slider_sync_A) = true;
|
id(suppress_slider_sync_A) = true;
|
||||||
id(suppress_quick_on_A) = true;
|
id(suppress_quick_on_A) = true;
|
||||||
- script.stop: ramp_off_script_A
|
- script.stop: ramp_off_script_A
|
||||||
- script.execute: ramp_to_target_script_A
|
- script.execute: ramp_to_target_script_A
|
||||||
- delay: !lambda 'return (uint32_t) id(last_ramp_ms_A);'
|
- delay: !lambda 'return (uint32_t) id(last_ramp_ms_A);'
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
id(suppress_slider_sync_A) = false;
|
id(suppress_slider_sync_A) = false;
|
||||||
id(suppress_quick_on_A) = false;
|
id(suppress_quick_on_A) = false;
|
||||||
else:
|
else:
|
||||||
- lambda: 'id(ramp_switch_target_on_A) = false;'
|
- lambda: 'id(ramp_switch_target_on_A) = false;'
|
||||||
- light.turn_off:
|
- light.turn_off:
|
||||||
@@ -1146,7 +1207,7 @@ script:
|
|||||||
float minp = (float) id(min_brightness_pct_B);
|
float minp = (float) id(min_brightness_pct_B);
|
||||||
float maxp = (float) id(max_brightness_pct_B);
|
float maxp = (float) id(max_brightness_pct_B);
|
||||||
if (target > 0.0f && target < minp) target = minp;
|
if (target > 0.0f && target < minp) target = minp;
|
||||||
if (target > maxp) target = maxp;
|
if (target > maxp) target = maxp;
|
||||||
id(restore_target_pct_B) = target;
|
id(restore_target_pct_B) = target;
|
||||||
id(last_ramp_ms_B) = id(ramp_up_ms_B);
|
id(last_ramp_ms_B) = id(ramp_up_ms_B);
|
||||||
- if:
|
- if:
|
||||||
@@ -1155,18 +1216,16 @@ script:
|
|||||||
then:
|
then:
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
id(ramp_switch_target_on_B) = true;
|
id(ramp_switch_target_on_B) = true;
|
||||||
id(suppress_slider_sync_B) = true;
|
id(suppress_slider_sync_B) = true;
|
||||||
id(suppress_quick_on_B) = true;
|
id(suppress_quick_on_B) = true;
|
||||||
- script.stop: ramp_off_script_B
|
- script.stop: ramp_off_script_B
|
||||||
- script.execute: ramp_to_target_script_B
|
- script.execute: ramp_to_target_script_B
|
||||||
- delay: !lambda 'return (uint32_t) id(last_ramp_ms_B);'
|
- delay: !lambda 'return (uint32_t) id(last_ramp_ms_B);'
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
id(suppress_slider_sync_B) = false;
|
id(suppress_slider_sync_B) = false;
|
||||||
id(suppress_quick_on_B) = false;
|
id(suppress_quick_on_B) = false;
|
||||||
else:
|
else:
|
||||||
- lambda: 'id(ramp_switch_target_on_B) = false;'
|
- lambda: 'id(ramp_switch_target_on_B) = false;'
|
||||||
- light.turn_off:
|
- light.turn_off:
|
||||||
id: mosfet_leds_B
|
id: mosfet_leds_B
|
||||||
transition_length: 0s
|
transition_length: 0s
|
||||||
##########################################################################################
|
|
||||||
##########################################################################################
|
|
||||||
@@ -1,35 +1,86 @@
|
|||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# TITLE: LOUNGE SOUTH LEFT LIGHTSWITCH
|
||||||
# LOUNGE SOUTH LEFT LIGHTSWITCH
|
# zorruno.com layout v1.1 2026
|
||||||
|
#:########################################################################################:#
|
||||||
|
# REPO:
|
||||||
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-loungesouthleftswitch.yaml
|
||||||
|
#:########################################################################################:#
|
||||||
|
# VERSIONS:
|
||||||
|
# V4.1 2026-03-11 Updated yaml to zorruno layout V1.1
|
||||||
# V4.0 2025-10-04 Copied from other device
|
# V4.0 2025-10-04 Copied from other device
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# Zemismart KS-811 Double push button
|
# HARDWARE:
|
||||||
# pinout/schematic https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
|
# - Zemismart KS-811 Double push button
|
||||||
|
# - ESP8266 based
|
||||||
|
# - pinout/schematic:
|
||||||
|
# https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
|
||||||
|
# - Relay 1 output on GPIO13
|
||||||
|
# - Relay 2 output on GPIO12
|
||||||
|
# - Button 1 input on GPIO16
|
||||||
|
# - Button 2 input on GPIO5
|
||||||
|
# - Status LED on GPIO2
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OPERATION NOTES:
|
||||||
|
# - Lounge South Left switch with 2 outputs:
|
||||||
|
# 1) Wall Washer Left
|
||||||
|
# 2) Outside Light 1
|
||||||
|
# - Button 1 toggles Relay_1 locally
|
||||||
|
# - Button 2 toggles Relay_2 locally
|
||||||
|
# - Relay_2 is synchronised with a remote MQTT device:
|
||||||
|
# - Remote device name: garage-corridor-lights
|
||||||
|
# - Remote ON/OFF commands are mirrored locally
|
||||||
|
# - Local Relay_2 ON/OFF changes are published back to the remote topic
|
||||||
|
# - A guard flag is used to prevent MQTT feedback loops when Relay_2 state changes originate remotely
|
||||||
|
#:########################################################################################:#
|
||||||
|
# MQTT COMMANDS:
|
||||||
|
# - Remote command topic:
|
||||||
|
# - ${mqtt_remote_command_topic}
|
||||||
|
# - Remote status topic:
|
||||||
|
# - ${mqtt_remote_status_topic}
|
||||||
|
# - Payloads used:
|
||||||
|
# - ON
|
||||||
|
# - OFF
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OFFLINE NOTES:
|
||||||
|
# a) Home Assistant offline (network and MQTT online):
|
||||||
|
# - Local button control continues to operate both relays
|
||||||
|
# - Relay_2 MQTT sync with the remote device continues if MQTT broker is online
|
||||||
#
|
#
|
||||||
# NOTES
|
# b) MQTT offline (or HA/MQTT offline):
|
||||||
# -
|
# - Local button control continues to operate both relays
|
||||||
##########################################################################################
|
# - Relay_2 sync to the remote MQTT device is unavailable
|
||||||
##########################################################################################
|
#
|
||||||
|
# c) Entire WiFi/Network offline:
|
||||||
|
# - Local button control continues to operate both relays
|
||||||
|
# - Relay_2 sync to the remote MQTT device is unavailable
|
||||||
|
# - Accurate time is not needed; SNTP is not required for operation
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
|
# SUBSTITUTIONS:
|
||||||
|
# Specific device variable substitutions
|
||||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
substitutions:
|
substitutions:
|
||||||
# Device Naming
|
# Device Naming
|
||||||
device_name: "esp-loungesouthleftswitch"
|
device_name: "esp-loungesouthleftswitch"
|
||||||
friendly_name: "Lounge South Left Lightswitch (2)"
|
friendly_name: "Lounge South Left Lightswitch (2)"
|
||||||
description_comment: "Lounge South Left Lightswitch using a Zemismart KS-811 Double Push Button. Wall Washer Left (1), Outside Light 1 (2)"
|
description_comment: "Lounge South Left Lightswitch using a Zemismart KS-811 Double Push Button. Wall Washer Left (1), Outside Light 1 (2) (Layout V1.1)"
|
||||||
device_area: "Lounge" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
device_area: "Lounge" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
||||||
|
|
||||||
# Project Naming
|
# Project Naming
|
||||||
project_name: "Zemismart Technologies.KS-811 Double" # Project Details
|
project_name: "Zemismart Technologies.KS-811 Double" # Project Details
|
||||||
project_version: "v4.0" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
project_version: "v4.1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
||||||
|
|
||||||
# Passwords & Secrets
|
# Passwords & Secrets
|
||||||
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
||||||
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
|
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
|
||||||
static_ip_address: !secret esp-loungesouthleftswitch_ip
|
static_ip_address: !secret esp-loungesouthleftswitch_ip
|
||||||
|
|
||||||
|
# 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}
|
||||||
|
|
||||||
mqtt_command_main_topic: !secret mqtt_command_main_topic
|
mqtt_command_main_topic: !secret mqtt_command_main_topic
|
||||||
mqtt_status_main_topic: !secret mqtt_status_main_topic
|
mqtt_status_main_topic: !secret mqtt_status_main_topic
|
||||||
|
|
||||||
@@ -41,19 +92,19 @@ substitutions:
|
|||||||
# MQTT REMOTE Controls
|
# MQTT REMOTE Controls
|
||||||
mqtt_remote_device_name: "garage-corridor-lights"
|
mqtt_remote_device_name: "garage-corridor-lights"
|
||||||
mqtt_remote_command_topic: "${mqtt_command_main_topic}/${mqtt_remote_device_name}"
|
mqtt_remote_command_topic: "${mqtt_command_main_topic}/${mqtt_remote_device_name}"
|
||||||
mqtt_remote_status_topic: "${mqtt_status_main_topic}/${mqtt_remote_device_name}"
|
mqtt_remote_status_topic: "${mqtt_status_main_topic}/${mqtt_remote_device_name}"
|
||||||
mqtt_remote_device_command_ON: "ON"
|
mqtt_remote_device_command_ON: "ON"
|
||||||
mqtt_remote_device_command_OFF: "OFF"
|
mqtt_remote_device_command_OFF: "OFF"
|
||||||
|
|
||||||
# Switch Naming
|
# Switch Naming
|
||||||
switch_1_name: "Wall Washer Left"
|
switch_1_name: "Wall Washer Left"
|
||||||
switch_2_name: "Outside Light 1"
|
switch_2_name: "Outside Light 1"
|
||||||
#switch_3_name: "Nil"
|
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# PACKAGES: Included Common Packages
|
# PACKAGES:
|
||||||
|
# Included Common Packages
|
||||||
# https://esphome.io/components/packages.html
|
# https://esphome.io/components/packages.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
packages:
|
packages:
|
||||||
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
||||||
common_wifi: !include
|
common_wifi: !include
|
||||||
@@ -62,6 +113,7 @@ packages:
|
|||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
local_static_ip_address: "${static_ip_address}"
|
local_static_ip_address: "${static_ip_address}"
|
||||||
local_ota_pass: "${ota_pass}"
|
local_ota_pass: "${ota_pass}"
|
||||||
|
local_current_ip_address: "${current_ip_address}"
|
||||||
|
|
||||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||||
common_api: !include
|
common_api: !include
|
||||||
@@ -75,23 +127,23 @@ packages:
|
|||||||
file: common/mqtt_common.yaml
|
file: common/mqtt_common.yaml
|
||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
|
|
||||||
#### WEB PORTAL ####
|
#### WEB PORTAL ####
|
||||||
#common_webportal: !include common/webportal_common.yaml
|
#common_webportal: !include common/webportal_common.yaml
|
||||||
|
|
||||||
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
||||||
#common_sntp: !include common/sntp_common.yaml
|
#common_sntp: !include common/sntp_common.yaml
|
||||||
|
|
||||||
#### DIAGNOSTICS Sensors ####
|
#### DIAGNOSTICS Sensors ####
|
||||||
diag_basic: !include common/include_basic_diag_sensors.yaml
|
diag_basic: !include common/include_basic_diag_sensors.yaml
|
||||||
diag_more: !include common/include_more_diag_sensors.yaml
|
diag_more: !include common/include_more_diag_sensors.yaml
|
||||||
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
||||||
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# ESPHome
|
# ESPHOME:
|
||||||
# https://esphome.io/components/esphome.html
|
# https://esphome.io/components/esphome.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
esphome:
|
esphome:
|
||||||
name: "${device_name}"
|
name: "${device_name}"
|
||||||
friendly_name: "${friendly_name}"
|
friendly_name: "${friendly_name}"
|
||||||
@@ -101,64 +153,71 @@ esphome:
|
|||||||
name: "${project_name}"
|
name: "${project_name}"
|
||||||
version: "${project_version}"
|
version: "${project_version}"
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# ESP Platform and Framework
|
# ESP PLATFORM AND FRAMEWORK:
|
||||||
# https://esphome.io/components/esp32.html
|
# https://esphome.io/components/esp8266.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
esp8266:
|
esp8266:
|
||||||
board: esp01_1m
|
board: esp01_1m
|
||||||
early_pin_init: False # Initialise pins early to known values. Recommended false where switches are involved. Defaults to True.
|
early_pin_init: false # Initialise pins early to known values. Recommended false where switches are involved. Defaults to True.
|
||||||
board_flash_mode: dout # Default is dout
|
board_flash_mode: dout # Default is dout
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# ESPHome Logging Enable
|
# LOGGER:
|
||||||
# https://esphome.io/components/logger.html
|
# https://esphome.io/components/logger.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
logger:
|
logger:
|
||||||
level: "${log_level}" #INFO Level suggested, or DEBUG for testing
|
level: "${log_level}" #INFO Level suggested, or DEBUG for testing
|
||||||
#baud_rate: 0 #set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
#baud_rate: 0 #set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
||||||
#esp8266_store_log_strings_in_flash: false
|
#esp8266_store_log_strings_in_flash: false
|
||||||
#tx_buffer_size: 64
|
#tx_buffer_size: 64
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# GLOBAL VARIABLES:
|
||||||
|
#:########################################################################################:#
|
||||||
globals:
|
globals:
|
||||||
- id: relay2_change_origin_remote
|
- id: relay2_change_origin_remote
|
||||||
type: bool
|
type: bool
|
||||||
restore_value: no
|
restore_value: false
|
||||||
initial_value: "false"
|
initial_value: "false"
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# STATUS LED
|
# STATUS LED:
|
||||||
# https://esphome.io/components/status_led.html
|
# https://esphome.io/components/status_led.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
status_led:
|
status_led:
|
||||||
pin:
|
pin:
|
||||||
number: GPIO2
|
number: GPIO2
|
||||||
inverted: yes
|
inverted: true
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# BINARY SENSORS
|
# BINARY SENSORS:
|
||||||
# https://esphome.io/components/binary_sensor/
|
# https://esphome.io/components/binary_sensor/
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
pin:
|
pin:
|
||||||
number: GPIO16
|
number: GPIO16
|
||||||
mode: INPUT
|
mode: INPUT
|
||||||
inverted: True
|
inverted: true
|
||||||
use_interrupt: false # This pin doesn't support interrupts so use polling. Only supresses a warning.
|
use_interrupt: false # This pin doesn't support interrupts so use polling. Only suppresses a warning.
|
||||||
name: "Button 1: ${switch_1_name}"
|
name: "Button 1: ${switch_1_name}"
|
||||||
on_press:
|
on_press:
|
||||||
- switch.toggle: Relay_1
|
- switch.toggle: Relay_1
|
||||||
|
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
pin:
|
pin:
|
||||||
number: GPIO05
|
number: GPIO5
|
||||||
mode: INPUT
|
mode: INPUT
|
||||||
inverted: True
|
inverted: true
|
||||||
name: "Button 2: ${switch_2_name}"
|
name: "Button 2: ${switch_2_name}"
|
||||||
on_press:
|
on_press:
|
||||||
- switch.toggle: Relay_2
|
- switch.toggle: Relay_2
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# TEXT SENSOR COMPONENT:
|
||||||
|
# https://esphome.io/components/text_sensor/
|
||||||
|
#:########################################################################################:#
|
||||||
text_sensor:
|
text_sensor:
|
||||||
- platform: mqtt_subscribe
|
- platform: mqtt_subscribe
|
||||||
id: remote2_status
|
id: remote2_status
|
||||||
@@ -192,10 +251,10 @@ text_sensor:
|
|||||||
id(relay2_change_origin_remote) = true;
|
id(relay2_change_origin_remote) = true;
|
||||||
- switch.turn_off: Relay_2
|
- switch.turn_off: Relay_2
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# SWITCH COMPONENT
|
# SWITCH COMPONENT:
|
||||||
# https://esphome.io/components/switch/
|
# https://esphome.io/components/switch/
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
switch:
|
switch:
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
name: "Relay 1: ${switch_1_name}"
|
name: "Relay 1: ${switch_1_name}"
|
||||||
@@ -223,7 +282,4 @@ switch:
|
|||||||
- mqtt.publish:
|
- mqtt.publish:
|
||||||
topic: "${mqtt_remote_command_topic}"
|
topic: "${mqtt_remote_command_topic}"
|
||||||
payload: "${mqtt_remote_device_command_OFF}"
|
payload: "${mqtt_remote_device_command_OFF}"
|
||||||
- lambda: 'id(relay2_change_origin_remote) = false;'
|
- lambda: 'id(relay2_change_origin_remote) = false;'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,37 +1,82 @@
|
|||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# TITLE: LOUNGE SOUTH RIGHT LIGHTSWITCH
|
||||||
# LOUNGE SOUTH RIGHT LIGHTSWITCH
|
# zorruno.com layout v1.1 2026
|
||||||
|
#:########################################################################################:#
|
||||||
|
# REPO:
|
||||||
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-loungesouthrightswitch.yaml
|
||||||
|
#:########################################################################################:#
|
||||||
|
# VERSIONS:
|
||||||
|
# V4.1 2026-03-11 Updated yaml to zorruno layout V1.1
|
||||||
# V4.0 2025-10-04 Copied from other device
|
# V4.0 2025-10-04 Copied from other device
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# Zemismart KS-811 Triple push button
|
# HARDWARE:
|
||||||
# pinout/schematic https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
|
# - Zemismart KS-811 Triple push button
|
||||||
#
|
# - ESP8266 based
|
||||||
# NOTES
|
# - pinout/schematic:
|
||||||
# -
|
# https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
|
||||||
##########################################################################################
|
# - Relay 1 output on GPIO13
|
||||||
##########################################################################################
|
# - Relay 2 output on GPIO12
|
||||||
|
# - Relay 3 output on GPIO14
|
||||||
|
# - Button 1 input on GPIO16
|
||||||
|
# - Button 2 input on GPIO5
|
||||||
|
# - Button 3 input on GPIO4
|
||||||
|
# - Status LED on GPIO2
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OPERATION NOTES:
|
||||||
|
# - Lounge South Right switch with 3 outputs:
|
||||||
|
# 1) Spare
|
||||||
|
# 2) Wall Washer Right
|
||||||
|
# 3) Breakfast Bar LEDs
|
||||||
|
# - Button 1 toggles Relay_1 locally
|
||||||
|
# - Button 2 toggles Relay_2 locally
|
||||||
|
# - Button 3 single click:
|
||||||
|
# - Offline and HA Loss manual override ON:
|
||||||
|
# - Toggles Relay_3 locally
|
||||||
|
# - Online:
|
||||||
|
# - No local action is taken
|
||||||
|
# - On API client connect:
|
||||||
|
# - Applies HA Loss manual override state to Relay_3
|
||||||
|
# - HA Loss manual override defaults ON and is restored after reboot
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OFFLINE NOTES:
|
||||||
|
# a) Home Assistant offline (network online):
|
||||||
|
# - API disconnects and device switches to manual/offline behavior
|
||||||
|
# - Button 1 and Button 2 continue to toggle relays locally
|
||||||
|
# - Button 3 can toggle Relay_3 locally when HA Loss manual override is ON
|
||||||
|
# b) MQTT offline (or HA/MQTT offline):
|
||||||
|
# - This yaml does not currently depend on MQTT for its switch logic
|
||||||
|
# - Local button control continues to work
|
||||||
|
# - Button 3 can toggle Relay_3 locally when HA Loss manual override is ON
|
||||||
|
# c) Entire WiFi/Network offline:
|
||||||
|
# - Device operates in local manual/offline behavior only
|
||||||
|
# - Local button control continues to work
|
||||||
|
# - Accurate time is not needed; SNTP is not required for operation
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
|
# SUBSTITUTIONS:
|
||||||
|
# Specific device variable substitutions
|
||||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
substitutions:
|
substitutions:
|
||||||
# Device Naming
|
# Device Naming
|
||||||
device_name: "esp-loungesouthrightswitch"
|
device_name: "esp-loungesouthrightswitch"
|
||||||
friendly_name: "Lounge South Right Lightswitch (3)"
|
friendly_name: "Lounge South Right Lightswitch (3)"
|
||||||
description_comment: "Lounge South Right Lightswitch using a Zemismart KS-811 Triple Push Button. Spare (1), Wall Washer Right (2), Breakfastbar LEDs (3)"
|
description_comment: "Lounge South Right Lightswitch using a Zemismart KS-811 Triple Push Button. Spare (1), Wall Washer Right (2), Breakfastbar LEDs (3) (Layout V1.1)"
|
||||||
device_area: "Lounge" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
device_area: "Lounge" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
||||||
|
|
||||||
# Project Naming
|
# Project Naming
|
||||||
project_name: "Zemismart Technologies.KS-811 Triple" # Project Details
|
project_name: "Zemismart Technologies.KS-811 Triple" # Project Details
|
||||||
project_version: "v4.0" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
project_version: "v4.1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
||||||
|
|
||||||
# Passwords & Secrets
|
# Passwords & Secrets
|
||||||
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
||||||
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
|
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
|
||||||
static_ip_address: !secret esp-loungesouthrightswitch_ip
|
static_ip_address: !secret esp-loungesouthrightswitch_ip
|
||||||
#mqtt_local_command_main_topic: !secret mqtt_local_command_main_topic
|
|
||||||
#mqtt_local_status_main_topic: !secret mqtt_local_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
|
# Device Settings
|
||||||
#relay_icon: "mdi:lightbulb-group"
|
#relay_icon: "mdi:lightbulb-group"
|
||||||
@@ -46,12 +91,13 @@ substitutions:
|
|||||||
# Switch Naming
|
# Switch Naming
|
||||||
switch_1_name: "Spare"
|
switch_1_name: "Spare"
|
||||||
switch_2_name: "Wall Washer Right"
|
switch_2_name: "Wall Washer Right"
|
||||||
switch_3_name: "Breakfast Bar LEDs" # Connected to another esphome device at the breakfast bar LEDs
|
switch_3_name: "Breakfast Bar LEDs" # Connected to another esphome device at the breakfast bar LEDs
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# PACKAGES: Included Common Packages
|
# PACKAGES:
|
||||||
|
# Included Common Packages
|
||||||
# https://esphome.io/components/packages.html
|
# https://esphome.io/components/packages.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
packages:
|
packages:
|
||||||
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
||||||
common_wifi: !include
|
common_wifi: !include
|
||||||
@@ -59,6 +105,7 @@ packages:
|
|||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
local_static_ip_address: "${static_ip_address}"
|
local_static_ip_address: "${static_ip_address}"
|
||||||
|
local_current_ip_address: "${current_ip_address}"
|
||||||
local_ota_pass: "${ota_pass}"
|
local_ota_pass: "${ota_pass}"
|
||||||
|
|
||||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||||
@@ -73,23 +120,23 @@ packages:
|
|||||||
file: common/mqtt_common.yaml
|
file: common/mqtt_common.yaml
|
||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
|
|
||||||
#### WEB PORTAL ####
|
#### WEB PORTAL ####
|
||||||
#common_webportal: !include common/webportal_common.yaml
|
#common_webportal: !include common/webportal_common.yaml
|
||||||
|
|
||||||
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
||||||
#common_sntp: !include common/sntp_common.yaml
|
#common_sntp: !include common/sntp_common.yaml
|
||||||
|
|
||||||
#### DIAGNOSTICS Sensors ####
|
#### DIAGNOSTICS Sensors ####
|
||||||
diag_basic: !include common/include_basic_diag_sensors.yaml
|
diag_basic: !include common/include_basic_diag_sensors.yaml
|
||||||
diag_more: !include common/include_more_diag_sensors.yaml
|
diag_more: !include common/include_more_diag_sensors.yaml
|
||||||
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
||||||
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# ESPHome
|
# ESPHOME:
|
||||||
# https://esphome.io/components/esphome.html
|
# https://esphome.io/components/esphome.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
esphome:
|
esphome:
|
||||||
name: "${device_name}"
|
name: "${device_name}"
|
||||||
friendly_name: "${friendly_name}"
|
friendly_name: "${friendly_name}"
|
||||||
@@ -99,6 +146,9 @@ esphome:
|
|||||||
name: "${project_name}"
|
name: "${project_name}"
|
||||||
version: "${project_version}"
|
version: "${project_version}"
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# HOME ASSISTANT API:
|
||||||
|
#:########################################################################################:#
|
||||||
api:
|
api:
|
||||||
on_client_connected:
|
on_client_connected:
|
||||||
then:
|
then:
|
||||||
@@ -120,54 +170,54 @@ api:
|
|||||||
level: WARN
|
level: WARN
|
||||||
format: "API disconnected: switching to manual/offline behavior"
|
format: "API disconnected: switching to manual/offline behavior"
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# ESP Platform and Framework
|
# ESP PLATFORM AND FRAMEWORK:
|
||||||
# https://esphome.io/components/esp32.html
|
# https://esphome.io/components/esp8266.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
esp8266:
|
esp8266:
|
||||||
board: esp01_1m
|
board: esp01_1m
|
||||||
early_pin_init: False # Initialise pins early to known values. Recommended false where switches are involved. Defaults to True.
|
early_pin_init: false # Initialise pins early to known values. Recommended false where switches are involved. Defaults to True.
|
||||||
board_flash_mode: dout # Default is dout
|
board_flash_mode: dout # Default is dout
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# ESPHome Logging Enable
|
# LOGGER:
|
||||||
# https://esphome.io/components/logger.html
|
# https://esphome.io/components/logger.html
|
||||||
#############################################
|
#:########################################################################################:#
|
||||||
logger:
|
logger:
|
||||||
level: "${log_level}" #INFO Level suggested, or DEBUG for testing
|
level: "${log_level}" #INFO Level suggested, or DEBUG for testing
|
||||||
#baud_rate: 0 #set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
#baud_rate: 0 #set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
||||||
#esp8266_store_log_strings_in_flash: false
|
#esp8266_store_log_strings_in_flash: false
|
||||||
#tx_buffer_size: 64
|
#tx_buffer_size: 64
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# STATUS LED
|
# STATUS LED:
|
||||||
# https://esphome.io/components/status_led.html
|
# https://esphome.io/components/status_led.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
status_led:
|
status_led:
|
||||||
pin:
|
pin:
|
||||||
number: GPIO2
|
number: GPIO2
|
||||||
inverted: yes
|
inverted: true
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# BINARY SENSORS
|
# BINARY SENSORS:
|
||||||
# https://esphome.io/components/binary_sensor/
|
# https://esphome.io/components/binary_sensor/
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
pin:
|
pin:
|
||||||
number: GPIO16
|
number: GPIO16
|
||||||
mode: INPUT
|
mode: INPUT
|
||||||
inverted: True
|
inverted: true
|
||||||
use_interrupt: false # GPO16 pin doesn't support interrupts so use polling. Only supresses a warning.
|
use_interrupt: false # GPIO16 pin doesn't support interrupts so use polling. Only suppresses a warning.
|
||||||
name: "Button 1: ${switch_1_name}"
|
name: "Button 1: ${switch_1_name}"
|
||||||
on_press:
|
on_press:
|
||||||
- switch.toggle: Relay_1
|
- switch.toggle: Relay_1
|
||||||
|
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
pin:
|
pin:
|
||||||
number: GPIO05
|
number: GPIO5
|
||||||
mode: INPUT
|
mode: INPUT
|
||||||
inverted: True
|
inverted: true
|
||||||
name: "Button 2: ${switch_2_name}"
|
name: "Button 2: ${switch_2_name}"
|
||||||
on_press:
|
on_press:
|
||||||
- switch.toggle: Relay_2
|
- switch.toggle: Relay_2
|
||||||
@@ -176,7 +226,7 @@ binary_sensor:
|
|||||||
pin:
|
pin:
|
||||||
number: GPIO4
|
number: GPIO4
|
||||||
mode: INPUT
|
mode: INPUT
|
||||||
inverted: True
|
inverted: true
|
||||||
name: "Button 3: ${switch_3_name}"
|
name: "Button 3: ${switch_3_name}"
|
||||||
on_multi_click:
|
on_multi_click:
|
||||||
- timing:
|
- timing:
|
||||||
@@ -186,16 +236,17 @@ binary_sensor:
|
|||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
and:
|
and:
|
||||||
- not: api.connected
|
- not:
|
||||||
|
api.connected:
|
||||||
- switch.is_on: ha_loss_override
|
- switch.is_on: ha_loss_override
|
||||||
then:
|
then:
|
||||||
- switch.toggle: Relay_3
|
- switch.toggle: Relay_3
|
||||||
else: []
|
else: []
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# SWITCH COMPONENT
|
# SWITCH COMPONENT:
|
||||||
# https://esphome.io/components/switch/
|
# https://esphome.io/components/switch/
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
switch:
|
switch:
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
name: "Relay 1: ${switch_1_name}"
|
name: "Relay 1: ${switch_1_name}"
|
||||||
@@ -218,5 +269,4 @@ switch:
|
|||||||
name: "HA Loss manual override"
|
name: "HA Loss manual override"
|
||||||
id: ha_loss_override
|
id: ha_loss_override
|
||||||
optimistic: true
|
optimistic: true
|
||||||
restore_mode: RESTORE_DEFAULT_ON
|
restore_mode: RESTORE_DEFAULT_ON
|
||||||
|
|
||||||
@@ -1,38 +1,83 @@
|
|||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# TITLE: LOUNGE WEST SWITCH (Single Switch from entranceway)
|
||||||
# LOUNGE WEST SWITCH (Single Switch from entranceway)
|
# zorruno.com layout v1.1 2026
|
||||||
|
#:########################################################################################:#
|
||||||
|
# REPO:
|
||||||
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-loungewestswitch.yaml
|
||||||
|
#:########################################################################################:#
|
||||||
|
# VERSIONS:
|
||||||
|
# V4.1 2026-03-11 Updated yaml to zorruno layout V1.1
|
||||||
# V4.0 2025-10-04 Copy from other device
|
# V4.0 2025-10-04 Copy from other device
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# Zemismart KS-811 Single push button
|
# HARDWARE:
|
||||||
# pinout/schematic https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
|
# - Zemismart KS-811 Single push button
|
||||||
|
# - ESP8266 based
|
||||||
|
# - pinout/schematic:
|
||||||
|
# https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
|
||||||
|
# - Button input on GPIO0
|
||||||
|
# - Relay output on GPIO12
|
||||||
|
# - Status LED on GPIO2
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OPERATION NOTES:
|
||||||
|
# - Single wall switch used for Lounge West / entranceway control
|
||||||
|
# - This device uses Home Assistant scene calls when API is connected
|
||||||
|
# - Single click:
|
||||||
|
# - Online and HA Loss manual override ON:
|
||||||
|
# - If last scene is not "All Off", call scene "All Off"
|
||||||
|
# - If last scene is "All Off", call scene "Bright"
|
||||||
|
# - Offline and HA Loss manual override ON:
|
||||||
|
# - Toggle physical Relay_1
|
||||||
|
# - Double click:
|
||||||
|
# - Online only, calls Home Assistant script for scene "Night Light"
|
||||||
|
# - Long hold (4s+):
|
||||||
|
# - Online only, calls Home Assistant script for scene "All Off"
|
||||||
|
# - Also fires Home Assistant event esphome.lounge_switch_hold
|
||||||
|
# - On API client connect:
|
||||||
|
# - Applies override state to Relay_1
|
||||||
|
# - HA Loss manual override switch defaults ON and is restored after reboot
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OFFLINE NOTES:
|
||||||
|
# a) Home Assistant offline (network online):
|
||||||
|
# - API will disconnect and device switches to manual/offline behavior
|
||||||
|
# - Single click can still toggle Relay_1 when HA Loss manual override is ON
|
||||||
|
# - Double click and long hold actions that require Home Assistant are ignored
|
||||||
#
|
#
|
||||||
# NOTES
|
# b) MQTT offline (or HA/MQTT offline):
|
||||||
# -
|
# - This yaml does not currently depend on MQTT for its switch logic
|
||||||
|
# - If Home Assistant/API is offline, device falls back to manual/offline behavior
|
||||||
|
# - Single click can still toggle Relay_1 when HA Loss manual override is ON
|
||||||
#
|
#
|
||||||
##########################################################################################
|
# c) Entire WiFi/Network offline:
|
||||||
##########################################################################################
|
# - Device operates in local manual/offline behavior only
|
||||||
|
# - Single click can still toggle Relay_1 when HA Loss manual override is ON
|
||||||
|
# - Double click and long hold Home Assistant scene/event actions are unavailable
|
||||||
|
# - Accurate time is not needed; SNTP is not required for operation
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
|
# SUBSTITUTIONS:
|
||||||
|
# Specific device variable substitutions
|
||||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
substitutions:
|
substitutions:
|
||||||
# Device Naming
|
# Device Naming
|
||||||
device_name: "esp-loungewestswitch"
|
device_name: "esp-loungewestswitch"
|
||||||
friendly_name: "Lounge West Single Switch (1)"
|
friendly_name: "Lounge West Single Switch (1)"
|
||||||
description_comment: "Main Lounge from entranceway lightswitch using a Zemismart KS-811 Single Push Button. Main Lights (1)"
|
description_comment: "Main Lounge from entranceway lightswitch using a Zemismart KS-811 Single Push Button. Main Lights (1) (Layout V1.1)"
|
||||||
device_area: "Lounge" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
device_area: "Lounge" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
||||||
|
|
||||||
# Project Naming
|
# Project Naming
|
||||||
project_name: "Zemismart Technologies.KS-811 Single" # Project Details
|
project_name: "Zemismart Technologies.KS-811 Single" # Project Details
|
||||||
project_version: "v4.0" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
project_version: "v4.1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
||||||
|
|
||||||
# Passwords & Secrets
|
# Passwords & Secrets
|
||||||
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
||||||
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
|
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
|
||||||
static_ip_address: !secret esp-loungewestswitch_ip
|
static_ip_address: !secret esp-loungewestswitch_ip
|
||||||
#mqtt_command_main_topic: !secret mqtt_local_command_main_topic
|
|
||||||
#mqtt_status_main_topic: !secret mqtt_local_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
|
# Device Settings
|
||||||
log_level: "DEBUG" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
log_level: "DEBUG" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
||||||
@@ -49,14 +94,15 @@ substitutions:
|
|||||||
#mqtt_remote_status_topic: "${mqtt_status_main_topic}/${mqtt_remote_device_name}" # Topic we will use to view status locally without HA
|
#mqtt_remote_status_topic: "${mqtt_status_main_topic}/${mqtt_remote_device_name}" # Topic we will use to view status locally without HA
|
||||||
#mqtt_remote_device_command_on: "On"
|
#mqtt_remote_device_command_on: "On"
|
||||||
#mqtt_remote_device_command_off: "Off"
|
#mqtt_remote_device_command_off: "Off"
|
||||||
|
|
||||||
# Switch/Relay/Button Naming & Icons
|
# Switch/Relay/Button Naming & Icons
|
||||||
switch_1_name: "Main Lights" # NOTE there is no physical connection to the lights on this switch, it is connected to the dimmer ESPhome for the pelmet lights
|
switch_1_name: "Main Lights" # NOTE there is no physical connection to the lights on this switch, it is connected to the dimmer ESPhome for the pelmet lights
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# PACKAGES: Included Common Packages
|
# PACKAGES:
|
||||||
|
# Included Common Packages
|
||||||
# https://esphome.io/components/packages.html
|
# https://esphome.io/components/packages.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
packages:
|
packages:
|
||||||
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
||||||
common_wifi: !include
|
common_wifi: !include
|
||||||
@@ -64,6 +110,7 @@ packages:
|
|||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
local_static_ip_address: "${static_ip_address}"
|
local_static_ip_address: "${static_ip_address}"
|
||||||
|
local_current_ip_address: "${current_ip_address}"
|
||||||
local_ota_pass: "${ota_pass}"
|
local_ota_pass: "${ota_pass}"
|
||||||
|
|
||||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||||
@@ -78,10 +125,10 @@ packages:
|
|||||||
file: common/mqtt_common.yaml
|
file: common/mqtt_common.yaml
|
||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
|
|
||||||
#### WEB PORTAL ####
|
#### WEB PORTAL ####
|
||||||
#common_webportal: !include common/webportal_common.yaml
|
#common_webportal: !include common/webportal_common.yaml
|
||||||
|
|
||||||
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
||||||
#common_sntp: !include common/sntp_common.yaml
|
#common_sntp: !include common/sntp_common.yaml
|
||||||
|
|
||||||
@@ -91,10 +138,10 @@ packages:
|
|||||||
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
||||||
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# ESPHome
|
# ESPHOME:
|
||||||
# https://esphome.io/components/esphome.html
|
# https://esphome.io/components/esphome.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
esphome:
|
esphome:
|
||||||
name: "${device_name}"
|
name: "${device_name}"
|
||||||
friendly_name: "${friendly_name}"
|
friendly_name: "${friendly_name}"
|
||||||
@@ -125,44 +172,44 @@ api:
|
|||||||
level: WARN
|
level: WARN
|
||||||
format: "API disconnected: switching to manual/offline behavior"
|
format: "API disconnected: switching to manual/offline behavior"
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# ESP Platform and Framework
|
# ESP PLATFORM AND FRAMEWORK:
|
||||||
# https://esphome.io/components/esp32.html
|
# https://esphome.io/components/esp8266.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
esp8266:
|
esp8266:
|
||||||
board: esp01_1m
|
board: esp01_1m
|
||||||
early_pin_init: False # Initialise pins early to known values. Recommended false where switches are involved. Defaults to True.
|
early_pin_init: false # Initialise pins early to known values. Recommended false where switches are involved. Defaults to True.
|
||||||
board_flash_mode: dout # Default is dout
|
board_flash_mode: dout # Default is dout
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# ESPHome Logging Enable
|
# LOGGER:
|
||||||
# https://esphome.io/components/logger.html
|
# https://esphome.io/components/logger.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
logger:
|
logger:
|
||||||
level: "${log_level}" #INFO Level suggested, or DEBUG for testing
|
level: "${log_level}" #INFO Level suggested, or DEBUG for testing
|
||||||
#baud_rate: 0 #set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
#baud_rate: 0 #set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
||||||
#esp8266_store_log_strings_in_flash: false
|
#esp8266_store_log_strings_in_flash: false
|
||||||
#tx_buffer_size: 64
|
#tx_buffer_size: 64
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# STATUS LED
|
# STATUS LED:
|
||||||
# https://esphome.io/components/status_led.html
|
# https://esphome.io/components/status_led.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
status_led:
|
status_led:
|
||||||
pin:
|
pin:
|
||||||
number: GPIO02
|
number: GPIO2
|
||||||
inverted: yes
|
inverted: true
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# BINARY SENSORS
|
# BINARY SENSORS:
|
||||||
# https://esphome.io/components/binary_sensor/
|
# https://esphome.io/components/binary_sensor/
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
pin:
|
pin:
|
||||||
number: GPIO0
|
number: GPIO0
|
||||||
mode: INPUT
|
mode: INPUT
|
||||||
inverted: True
|
inverted: true
|
||||||
name: "Button 1: ${switch_1_name}"
|
name: "Button 1: ${switch_1_name}"
|
||||||
on_multi_click:
|
on_multi_click:
|
||||||
|
|
||||||
@@ -183,7 +230,7 @@ binary_sensor:
|
|||||||
scene_name: "Night Light"
|
scene_name: "Night Light"
|
||||||
- logger.log:
|
- logger.log:
|
||||||
level: INFO
|
level: INFO
|
||||||
format: "BTN: Double click → Scene Night Light"
|
format: "BTN: Double click -> Scene Night Light"
|
||||||
else:
|
else:
|
||||||
- logger.log:
|
- logger.log:
|
||||||
level: INFO
|
level: INFO
|
||||||
@@ -191,8 +238,8 @@ binary_sensor:
|
|||||||
|
|
||||||
# --- Single short click ---
|
# --- Single short click ---
|
||||||
# Online (and override ON): use HA's last scene to decide.
|
# Online (and override ON): use HA's last scene to decide.
|
||||||
# If last != "All Off" → send "All Off"
|
# If last != "All Off" -> send "All Off"
|
||||||
# If last == "All Off" → send "Bright"
|
# If last == "All Off" -> send "Bright"
|
||||||
# Offline (and override ON): toggle physical Relay_1
|
# Offline (and override ON): toggle physical Relay_1
|
||||||
- timing:
|
- timing:
|
||||||
- ON for at most 0.5s
|
- ON for at most 0.5s
|
||||||
@@ -218,7 +265,7 @@ binary_sensor:
|
|||||||
scene_name: "All Off"
|
scene_name: "All Off"
|
||||||
- logger.log:
|
- logger.log:
|
||||||
level: INFO
|
level: INFO
|
||||||
format: "BTN: Single click (online) → Last scene was not 'All Off' → Set 'All Off'"
|
format: "BTN: Single click (online) -> Last scene was not 'All Off' -> Set 'All Off'"
|
||||||
else:
|
else:
|
||||||
- homeassistant.service:
|
- homeassistant.service:
|
||||||
service: script.lounge_set_scene
|
service: script.lounge_set_scene
|
||||||
@@ -226,7 +273,7 @@ binary_sensor:
|
|||||||
scene_name: "Bright"
|
scene_name: "Bright"
|
||||||
- logger.log:
|
- logger.log:
|
||||||
level: INFO
|
level: INFO
|
||||||
format: "BTN: Single click (online) → Last scene was 'All Off' → Set 'Bright'"
|
format: "BTN: Single click (online) -> Last scene was 'All Off' -> Set 'Bright'"
|
||||||
else:
|
else:
|
||||||
# OFFLINE path: only act if override ON; toggle physical relay
|
# OFFLINE path: only act if override ON; toggle physical relay
|
||||||
- if:
|
- if:
|
||||||
@@ -238,17 +285,18 @@ binary_sensor:
|
|||||||
then:
|
then:
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
lambda: 'return id(Relay_1).state;'
|
lambda: |-
|
||||||
|
return id(Relay_1).state;
|
||||||
then:
|
then:
|
||||||
- switch.turn_off: Relay_1
|
- switch.turn_off: Relay_1
|
||||||
- logger.log:
|
- logger.log:
|
||||||
level: INFO
|
level: INFO
|
||||||
format: "BTN: Single click (offline) → Relay_1 OFF"
|
format: "BTN: Single click (offline) -> Relay_1 OFF"
|
||||||
else:
|
else:
|
||||||
- switch.turn_on: Relay_1
|
- switch.turn_on: Relay_1
|
||||||
- logger.log:
|
- logger.log:
|
||||||
level: INFO
|
level: INFO
|
||||||
format: "BTN: Single click (offline) → Relay_1 ON"
|
format: "BTN: Single click (offline) -> Relay_1 ON"
|
||||||
else:
|
else:
|
||||||
- logger.log:
|
- logger.log:
|
||||||
level: INFO
|
level: INFO
|
||||||
@@ -272,33 +320,32 @@ binary_sensor:
|
|||||||
action: "hold"
|
action: "hold"
|
||||||
- logger.log:
|
- logger.log:
|
||||||
level: INFO
|
level: INFO
|
||||||
format: "BTN: Long press → Scene All Off + HA event (hold)"
|
format: "BTN: Long press -> Scene All Off + HA event (hold)"
|
||||||
else:
|
else:
|
||||||
- logger.log:
|
- logger.log:
|
||||||
level: INFO
|
level: INFO
|
||||||
format: "BTN: Long press ignored (no HA connection)"
|
format: "BTN: Long press ignored (no HA connection)"
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# TEXT SENSOR COMPONENT
|
# TEXT SENSOR COMPONENT:
|
||||||
#
|
# https://esphome.io/components/text_sensor/
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
text_sensor:
|
text_sensor:
|
||||||
- platform: homeassistant
|
- platform: homeassistant
|
||||||
id: ha_last_scene
|
id: ha_last_scene
|
||||||
entity_id: input_text.lounge_last_scene
|
entity_id: input_text.lounge_last_scene
|
||||||
# logging: helpful when testing
|
|
||||||
on_value:
|
on_value:
|
||||||
- logger.log:
|
- logger.log:
|
||||||
level: DEBUG
|
level: DEBUG
|
||||||
format: "HA last scene now: %s"
|
format: "HA last scene now: %s"
|
||||||
args: ["x.c_str()"]
|
args: ["x.c_str()"]
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# SWITCH COMPONENT
|
# SWITCH COMPONENT:
|
||||||
# https://esphome.io/components/switch/
|
# https://esphome.io/components/switch/
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
switch:
|
switch:
|
||||||
# GPIO13 for KS-811 first button UNLESS it is KS-811-1 then it is GPIO12
|
# GPIO13 for KS-811 first button UNLESS it is KS-811-1 then it is GPIO12
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
name: "Relay 1: ${switch_1_name}"
|
name: "Relay 1: ${switch_1_name}"
|
||||||
pin: GPIO12
|
pin: GPIO12
|
||||||
@@ -310,6 +357,4 @@ switch:
|
|||||||
name: "HA Loss manual override"
|
name: "HA Loss manual override"
|
||||||
id: ha_loss_override
|
id: ha_loss_override
|
||||||
optimistic: true
|
optimistic: true
|
||||||
restore_mode: RESTORE_DEFAULT_ON
|
restore_mode: RESTORE_DEFAULT_ON
|
||||||
|
|
||||||
|
|
||||||
@@ -1,38 +1,81 @@
|
|||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# TITLE: MAIN BATHROOM LIGHTSWITCH 2 (OBK Converted, BK7231N)
|
||||||
# MAIN BATHROOM LIGHTSWITCH 2 (OBK Converted, BK7231N)
|
# zorruno.com layout v1.1 2026
|
||||||
|
#:########################################################################################:#
|
||||||
|
# REPO:
|
||||||
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-mainbathroomlights.yaml
|
||||||
|
#:########################################################################################:#
|
||||||
|
# VERSIONS:
|
||||||
|
# V2.2 2026-03-11 Updated yaml to zorruno layout V1.1
|
||||||
# V2.1 2026-02-23 Button 3 multi-click publishes MQTT commands to bathroom fan (1x/2x/3x)
|
# V2.1 2026-02-23 Button 3 multi-click publishes MQTT commands to bathroom fan (1x/2x/3x)
|
||||||
# V2.0 2026-02-04 Reflash into new switch (old switch electrical failure, now a BK)
|
# V2.0 2026-02-04 Reflash into new switch (old switch electrical failure, now a BK)
|
||||||
# V1.0 2025-11-23 Initial
|
# V1.0 2025-11-23 Initial
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# Zemismart KS-811 Triple push button
|
# HARDWARE:
|
||||||
# pinout/schematic https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
|
# - Zemismart KS-811 Triple push button
|
||||||
#
|
# - BK7231N based switch
|
||||||
# NOTES
|
# - BK72XX board: generic-bk7231n-qfn32-tuya
|
||||||
# -
|
# - pinout/schematic:
|
||||||
#
|
# https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# OPERATION NOTES:
|
||||||
|
# - Main bathroom switch with 3 outputs:
|
||||||
|
# 1) Main Lights
|
||||||
|
# 2) Shower Lights
|
||||||
|
# 3) Cabinet Lights
|
||||||
|
# - Button 1 toggles Relay_2 (as currently coded in the source yaml)
|
||||||
|
# - Button 2 toggles Relay_2
|
||||||
|
# - Button 3 immediate press action turns OFF Relay_2 and Relay_3
|
||||||
|
# - Button 3 also sends MQTT commands to the bathroom fan based on click count:
|
||||||
|
# - 1 click -> command 1
|
||||||
|
# - 2 clicks -> command 2
|
||||||
|
# - 3 clicks -> command 3
|
||||||
|
# - Relay 1 turn_on action also turns ON Relay_2 and Relay_3
|
||||||
|
# - Virtual group switch "All Main Bathroom Lights" allows grouped control in Home Assistant
|
||||||
|
#:########################################################################################:#
|
||||||
|
# MQTT COMMANDS:
|
||||||
|
# - Remote device command topic:
|
||||||
|
# - ${mqtt_remote_device1_command_topic}
|
||||||
|
# - Button 3 single click publishes:
|
||||||
|
# - ${mqtt_remote_device1_command1}
|
||||||
|
# - Button 3 double click publishes:
|
||||||
|
# - ${mqtt_remote_device1_command2}
|
||||||
|
# - Button 3 triple click publishes:
|
||||||
|
# - ${mqtt_remote_device1_command3}
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OFFLINE NOTES:
|
||||||
|
# a) Home Assistant offline (network and MQTT online):
|
||||||
|
# - Local button control continues to operate the relays.
|
||||||
|
# - Button 3 MQTT fan commands can still publish if MQTT broker is online.
|
||||||
|
# - Virtual group switch in HA will be unavailable until HA returns.
|
||||||
|
# b) MQTT offline (or HA/MQTT offline):
|
||||||
|
# - Local button control continues to operate the relays.
|
||||||
|
# - Button 3 fan MQTT commands will not be sent.
|
||||||
|
# c) Entire WiFi/Network offline:
|
||||||
|
# - Local button control continues to operate the relays.
|
||||||
|
# - No MQTT control or status is available.
|
||||||
|
# - Accurate time is not needed; SNTP is not required for operation.
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
|
# SUBSTITUTIONS: Specific device variable substitutions
|
||||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
substitutions:
|
substitutions:
|
||||||
# Device Naming
|
# Device Naming
|
||||||
device_name: "esp-mainbathroomlights"
|
device_name: "esp-mainbathroomlights"
|
||||||
friendly_name: "Main Bathroom Lightswitch (3)"
|
friendly_name: "Main Bathroom Lightswitch (3)"
|
||||||
description_comment: "BK7231N - Main Bathroom Lightswitch using a Zemismart KS-811 Triple Push Button. Main Lights (1), Shower Lights (2), Cabinet Lights (3)"
|
description_comment: "BK7231N - Main Bathroom Lightswitch using a Zemismart KS-811 Triple Push Button. Main Lights (1), Shower Lights (2), Cabinet Lights (3) (Layout V1.1)"
|
||||||
device_area: "Main Bathroom" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
device_area: "Main Bathroom" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
||||||
|
|
||||||
# Project Naming
|
# Project Naming
|
||||||
project_name: "Zemismart Technologies.KS-811 Triple BK7231N" # Project Details
|
project_name: "Zemismart Technologies.KS-811 Triple BK7231N" # Project Details
|
||||||
project_version: "v2.1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
project_version: "v2.2" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
||||||
|
|
||||||
# Passwords
|
# Passwords
|
||||||
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
||||||
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
|
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
|
||||||
static_ip_address: !secret esp-garageentrylights2_ip
|
static_ip_address: !secret esp-mainbathroomlights_ip
|
||||||
mqtt_command_main_topic: !secret mqtt_command_main_topic
|
mqtt_command_main_topic: !secret mqtt_command_main_topic
|
||||||
#mqtt_status_main_topic: !secret mqtt_status_main_topic
|
#mqtt_status_main_topic: !secret mqtt_status_main_topic
|
||||||
|
|
||||||
@@ -65,10 +108,10 @@ substitutions:
|
|||||||
mqtt_remote_device1_command2: "20"
|
mqtt_remote_device1_command2: "20"
|
||||||
mqtt_remote_device1_command3: "30"
|
mqtt_remote_device1_command3: "30"
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# PACKAGES: Included Common Packages
|
# PACKAGES: Included Common Packages
|
||||||
# https://esphome.io/components/packages.html
|
# https://esphome.io/components/packages.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
packages:
|
packages:
|
||||||
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
||||||
common_wifi: !include
|
common_wifi: !include
|
||||||
@@ -94,28 +137,31 @@ packages:
|
|||||||
|
|
||||||
#### WEB PORTAL ####
|
#### WEB PORTAL ####
|
||||||
#common_webportal: !include common/webportal_common.yaml
|
#common_webportal: !include common/webportal_common.yaml
|
||||||
|
|
||||||
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
||||||
#common_sntp: !include common/sntp_common.yaml
|
#common_sntp: !include common/sntp_common.yaml
|
||||||
|
|
||||||
#### DIAGNOSTICS Sensors ####
|
#### DIAGNOSTICS Sensors ####
|
||||||
diag_basic: !include common/include_basic_diag_sensors.yaml
|
diag_basic: !include common/include_basic_diag_sensors.yaml
|
||||||
#diag_more: !include common/include_more_diag_sensors.yaml
|
#diag_more: !include common/include_more_diag_sensors.yaml
|
||||||
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
||||||
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
||||||
|
|
||||||
# Package item removals
|
#:########################################################################################:#
|
||||||
|
# PACKAGE ITEM REMOVALS / OVERRIDES:
|
||||||
|
#:########################################################################################:#
|
||||||
wifi:
|
wifi:
|
||||||
min_auth_mode: !remove # The WPA2 only works on esp32/8266
|
min_auth_mode: !remove # The WPA2 only works on esp32/8266
|
||||||
reboot_timeout: 15min # override the selection from from the common package
|
reboot_timeout: 15min # override the selection from the common package
|
||||||
fast_connect: false # (optional) force off, in case package vars change
|
fast_connect: false # optional; force off in case package vars change
|
||||||
|
|
||||||
mqtt:
|
mqtt:
|
||||||
keepalive: 15s # overriding the value from the common package
|
keepalive: 15s # overriding the value from the common package
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# ESPHome
|
# ESPHOME:
|
||||||
# https://esphome.io/components/esphome.html
|
# https://esphome.io/components/esphome.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
esphome:
|
esphome:
|
||||||
name: "${device_name}"
|
name: "${device_name}"
|
||||||
friendly_name: "${friendly_name}"
|
friendly_name: "${friendly_name}"
|
||||||
@@ -129,36 +175,36 @@ esphome:
|
|||||||
# then:
|
# then:
|
||||||
# - switch.turn_on: Relay_3
|
# - switch.turn_on: Relay_3
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# BUILD FOR BK CHIPSET
|
# BUILD FOR BK CHIPSET:
|
||||||
# bk72xx
|
# bk72xx
|
||||||
# https://devices.esphome.io/board/bk72xx/
|
# https://devices.esphome.io/board/bk72xx/
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
bk72xx:
|
bk72xx:
|
||||||
board: generic-bk7231n-qfn32-tuya
|
board: generic-bk7231n-qfn32-tuya
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# ESPHome Logging Enable
|
# LOGGER:
|
||||||
# https://esphome.io/components/logger.html
|
# https://esphome.io/components/logger.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
logger:
|
logger:
|
||||||
level: "${log_level}" #INFO Level suggested, or DEBUG for testing
|
level: "${log_level}" # INFO Level suggested, or DEBUG for testing
|
||||||
baud_rate: 0 #set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
baud_rate: 0 # set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
||||||
id: logger_id
|
id: logger_id
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# STATUS LED
|
# STATUS LED:
|
||||||
# https://esphome.io/components/status_led.html
|
# https://esphome.io/components/status_led.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
status_led:
|
status_led:
|
||||||
pin:
|
pin:
|
||||||
number: P22 #GPIO22
|
number: P22 #GPIO22
|
||||||
inverted: true
|
inverted: true
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# BINARY SENSORS
|
# BINARY SENSORS:
|
||||||
# https://esphome.io/components/binary_sensor/
|
# https://esphome.io/components/binary_sensor/
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
pin:
|
pin:
|
||||||
@@ -235,10 +281,10 @@ binary_sensor:
|
|||||||
topic: "${mqtt_remote_device1_command_topic}"
|
topic: "${mqtt_remote_device1_command_topic}"
|
||||||
payload: "${mqtt_remote_device1_command3}"
|
payload: "${mqtt_remote_device1_command3}"
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SWITCH COMPONENT
|
# SWITCH COMPONENT:
|
||||||
# https://esphome.io/components/switch/
|
# https://esphome.io/components/switch/
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
switch:
|
switch:
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
name: "Relay 1: ${switch_1_name}"
|
name: "Relay 1: ${switch_1_name}"
|
||||||
@@ -261,10 +307,10 @@ switch:
|
|||||||
id: Relay_3
|
id: Relay_3
|
||||||
restore_mode: ${relay_restore_mode}
|
restore_mode: ${relay_restore_mode}
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# TEMPLATE COMPONENT
|
# TEMPLATE COMPONENT:
|
||||||
##########################################################################################
|
|
||||||
# Virtual group switch for Home Assistant
|
# Virtual group switch for Home Assistant
|
||||||
|
#:########################################################################################:#
|
||||||
- platform: template
|
- platform: template
|
||||||
name: "All Main Bathroom Lights"
|
name: "All Main Bathroom Lights"
|
||||||
id: all_main_bathroom_lights
|
id: all_main_bathroom_lights
|
||||||
|
|||||||
@@ -1,34 +1,67 @@
|
|||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# TITLE: MAIN DISHWASHER POWER
|
||||||
# MAIN DISHWASHER POWER
|
# zorruno.com layout v1.1 2026
|
||||||
# Controlled by a Athom Smart Plug V3
|
#:########################################################################################:#
|
||||||
# package_import_url: github://athom-tech/athom-configs/athom-smart-plug.yaml
|
# REPO:
|
||||||
#
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-maindishwasherpower.yaml
|
||||||
|
#:########################################################################################:#
|
||||||
|
# VERSIONS:
|
||||||
|
# V3.5 2026-03-11 Updated yaml to zorruno layout V1.1
|
||||||
# V3.4 2025-07-30 Changed to Athom V3
|
# V3.4 2025-07-30 Changed to Athom V3
|
||||||
# V1.1 2025-06-12 package added for energy entities
|
# V1.1 2025-06-12 package added for energy entities
|
||||||
# V1.0 2025-06-10 YAML Tidyups
|
# V1.0 2025-06-10 YAML Tidyups
|
||||||
#
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# HARDWARE:
|
||||||
##########################################################################################
|
# - Athom Smart Plug V3
|
||||||
|
# - ESP32-C3 based
|
||||||
|
# - Relay output on GPIO5
|
||||||
|
# - Local power button on GPIO3
|
||||||
|
# - Power monitoring via Athom V3 common package
|
||||||
|
# - package_import_url reference: github://athom-tech/athom-configs/athom-smart-plug.yaml
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OPERATION NOTES:
|
||||||
|
# - Controls power to the main dishwasher
|
||||||
|
# - Uses Athom Smart Plug V3 hardware and Athom V3 common power monitor package
|
||||||
|
# - Relay is turned ON at boot
|
||||||
|
# - Local power button toggles the relay
|
||||||
|
# - Relay status is exposed as a template binary sensor
|
||||||
|
# - Power/energy monitoring entities are provided by the included Athom V3 package
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OFFLINE NOTES:
|
||||||
|
# a) Home Assistant offline (network and MQTT online):
|
||||||
|
# - Device continues operating normally
|
||||||
|
# - Relay can still be controlled locally by the hardware power button
|
||||||
|
# - MQTT remains available if your broker is online
|
||||||
|
#
|
||||||
|
# b) MQTT offline (or HA/MQTT offline):
|
||||||
|
# - Device continues operating locally
|
||||||
|
# - Relay control and local power monitoring continue to work
|
||||||
|
#
|
||||||
|
# c) Entire WiFi/Network offline:
|
||||||
|
# - Device continues operating locally
|
||||||
|
# - Relay control and local power monitoring continue to work
|
||||||
|
# - Accurate time is not needed; SNTP is not required for operation
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
|
# SUBSTITUTIONS:
|
||||||
|
# Specific device variable substitutions
|
||||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
substitutions:
|
substitutions:
|
||||||
# Device Naming
|
# Device Naming
|
||||||
device_name: "esp-maindishwasherpower"
|
device_name: "esp-maindishwasherpower"
|
||||||
friendly_name: "Main Dishwasher Power"
|
friendly_name: "Main Dishwasher Power"
|
||||||
description_comment: "Main Dishwasher Power Monitor :: Athom Smart Plug Power Monitor V3"
|
description_comment: "Main Dishwasher Power Monitor :: Athom Smart Plug Power Monitor V3 (Layout V1.1)"
|
||||||
device_area: "Kitchen" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
device_area: "Kitchen"
|
||||||
|
|
||||||
# Project Naming
|
# Project Naming
|
||||||
project_name: "Athom Technology.Smart Plug V3" # Project Details
|
project_name: "Athom Technology.Smart Plug V3"
|
||||||
project_version: "v1.1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
project_version: "v3.5"
|
||||||
|
|
||||||
# Passwords
|
# Passwords
|
||||||
api_key: !secret esp-maindishwasherpower_api_key # unfortunately you can't use substitutions inside secrets names
|
api_key: !secret esp-maindishwasherpower_api_key
|
||||||
ota_pass: !secret esp-maindishwasherpower_ota_pass # unfortunately you can't use substitutions inside secrets names
|
ota_pass: !secret esp-maindishwasherpower_ota_pass
|
||||||
static_ip_address: !secret esp-maindishwasherpower_ip
|
static_ip_address: !secret esp-maindishwasherpower_ip
|
||||||
|
|
||||||
# If we are changing IP addresses, you must update the current IP address here, otherwise it remains
|
# If we are changing IP addresses, you must update the current IP address here, otherwise it remains
|
||||||
@@ -36,17 +69,18 @@ substitutions:
|
|||||||
current_ip_address: ${static_ip_address}
|
current_ip_address: ${static_ip_address}
|
||||||
|
|
||||||
# Device Settings
|
# Device Settings
|
||||||
log_level: "INFO" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
log_level: "INFO"
|
||||||
update_interval: "60s" # update time for for general sensors etc
|
update_interval: "60s"
|
||||||
|
|
||||||
# Device Settings
|
# Relay / Load Settings
|
||||||
relay_icon: "mdi:dishwasher"
|
relay_icon: "mdi:dishwasher"
|
||||||
current_limit : "10" # Current Limit in Amps. AU Plug = 10. IL, BR, EU, UK, US Plug = 16.
|
current_limit: "10" # Current Limit in Amps. AU Plug = 10. IL, BR, EU, UK, US Plug = 16.
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# PACKAGES: Included Common Packages
|
# PACKAGES:
|
||||||
|
# Included Common Packages
|
||||||
# https://esphome.io/components/packages.html
|
# https://esphome.io/components/packages.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
packages:
|
packages:
|
||||||
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
||||||
common_wifi: !include
|
common_wifi: !include
|
||||||
@@ -54,8 +88,8 @@ packages:
|
|||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
local_static_ip_address: "${static_ip_address}"
|
local_static_ip_address: "${static_ip_address}"
|
||||||
local_ota_pass: "${ota_pass}"
|
|
||||||
local_current_ip_address: "${current_ip_address}"
|
local_current_ip_address: "${current_ip_address}"
|
||||||
|
local_ota_pass: "${ota_pass}"
|
||||||
|
|
||||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||||
common_api: !include
|
common_api: !include
|
||||||
@@ -69,34 +103,35 @@ packages:
|
|||||||
file: common/mqtt_common.yaml
|
file: common/mqtt_common.yaml
|
||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
|
|
||||||
#### WEB PORTAL ####
|
#### WEB PORTAL ####
|
||||||
#common_webportal: !include common/webportal_common.yaml
|
#common_webportal: !include common/webportal_common.yaml
|
||||||
|
|
||||||
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
||||||
common_sntp: !include common/sntp_common.yaml
|
common_sntp: !include common/sntp_common.yaml
|
||||||
|
|
||||||
#### DIAGNOSTICS Sensors ####
|
#### DIAGNOSTICS Sensors ####
|
||||||
diag_basic: !include common/include_basic_diag_sensors.yaml
|
diag_basic: !include common/include_basic_diag_sensors.yaml
|
||||||
diag_more: !include common/include_more_diag_sensors.yaml
|
diag_more: !include common/include_more_diag_sensors.yaml
|
||||||
diag_debug: !include common/include_debug_diag_sensors.yaml
|
diag_debug: !include common/include_debug_diag_sensors.yaml
|
||||||
diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
||||||
|
|
||||||
# Device Specific included packages
|
#### DEVICE SPECIFIC INCLUDED PACKAGES ####
|
||||||
common_athompowermonV3: !include
|
common_athompowermonv3: !include
|
||||||
file: common/athompowermonv3_common.yaml
|
file: common/athompowermonv3_common.yaml
|
||||||
vars:
|
vars:
|
||||||
local_current_limit: "${current_limit}"
|
local_current_limit: "${current_limit}"
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# ESPHome
|
# ESPHOME:
|
||||||
# https://esphome.io/components/esphome.html
|
# https://esphome.io/components/esphome.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
esphome:
|
esphome:
|
||||||
name: "${device_name}"
|
name: "${device_name}"
|
||||||
friendly_name: "${friendly_name}"
|
friendly_name: "${friendly_name}"
|
||||||
comment: "${description_comment}" #Appears on the esphome page in HA
|
comment: "${description_comment}"
|
||||||
area: "${device_area}"
|
area: "${device_area}"
|
||||||
name_add_mac_suffix: False
|
name_add_mac_suffix: false
|
||||||
min_version: 2024.6.0
|
min_version: 2024.6.0
|
||||||
project:
|
project:
|
||||||
name: "${project_name}"
|
name: "${project_name}"
|
||||||
@@ -108,19 +143,19 @@ esphome:
|
|||||||
on_boot:
|
on_boot:
|
||||||
priority: 200
|
priority: 200
|
||||||
then:
|
then:
|
||||||
- switch.turn_on: "relay"
|
- switch.turn_on: relay
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# ESP Platform and Framework
|
# ESP PLATFORM AND FRAMEWORK:
|
||||||
# https://esphome.io/components/esp32.html
|
# https://esphome.io/components/esp32.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
esp32:
|
esp32:
|
||||||
board: esp32-c3-devkitm-1
|
board: esp32-c3-devkitm-1
|
||||||
flash_size: 4MB
|
flash_size: 4MB
|
||||||
variant: ESP32C3
|
variant: ESP32C3
|
||||||
framework:
|
framework:
|
||||||
type: esp-idf # "esp-idf" OR "arduino". Suggested ESP-IDF Framework, or Plug Out the UART Cable Might Cause ESP32 Hang.
|
type: esp-idf
|
||||||
version: recommended # recommended, latest or dev
|
version: recommended
|
||||||
|
|
||||||
preferences:
|
preferences:
|
||||||
flash_write_interval: 5min
|
flash_write_interval: 5min
|
||||||
@@ -128,24 +163,24 @@ preferences:
|
|||||||
esp32_improv:
|
esp32_improv:
|
||||||
authorizer: none
|
authorizer: none
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# ESPHome LOGGING
|
# LOGGER:
|
||||||
# https://esphome.io/components/logger.html
|
# https://esphome.io/components/logger.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
logger:
|
logger:
|
||||||
level: "${log_level}" #INFO Level suggested, or DEBUG for testing
|
level: "${log_level}"
|
||||||
#baud_rate: 0 # set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
#baud_rate: 0 # set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
||||||
#esp8266_store_log_strings_in_flash: false
|
#esp8266_store_log_strings_in_flash: false
|
||||||
#tx_buffer_size: 64
|
#tx_buffer_size: 64
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# BINARY SENSORS
|
# BINARY SENSORS:
|
||||||
# https://esphome.io/components/binary_sensor/
|
# https://esphome.io/components/binary_sensor/
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
pin:
|
pin:
|
||||||
number: GPIO03
|
number: GPIO3
|
||||||
mode: INPUT_PULLUP
|
mode: INPUT_PULLUP
|
||||||
inverted: true
|
inverted: true
|
||||||
name: "Power Button"
|
name: "Power Button"
|
||||||
@@ -156,24 +191,22 @@ binary_sensor:
|
|||||||
- min_length: 20ms
|
- min_length: 20ms
|
||||||
max_length: 500ms
|
max_length: 500ms
|
||||||
then:
|
then:
|
||||||
- switch.toggle:
|
- switch.toggle: relay
|
||||||
id: relay
|
|
||||||
|
|
||||||
- platform: template
|
- platform: template
|
||||||
name: "Relay Status"
|
name: "Relay Status"
|
||||||
lambda: |-
|
lambda: |-
|
||||||
return id(relay).state;
|
return id(relay).state;
|
||||||
|
|
||||||
#################################################################################################
|
#:########################################################################################:#
|
||||||
# SWITCH COMPONENT
|
# SWITCH COMPONENT:
|
||||||
# https://esphome.io/components/switch/
|
# https://esphome.io/components/switch/
|
||||||
#################################################################################################
|
#:########################################################################################:#
|
||||||
switch:
|
switch:
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
name: "Power Output"
|
name: "Power Output"
|
||||||
pin: GPIO05
|
pin: GPIO5
|
||||||
id: relay
|
id: relay
|
||||||
restore_mode: RESTORE_DEFAULT_ON # Ensures the relay is restored (or off) at boot
|
restore_mode: RESTORE_DEFAULT_ON
|
||||||
#internal: true # Hides the switch from Home Assistant
|
#internal: true
|
||||||
icon: "${relay_icon}"
|
icon: "${relay_icon}"
|
||||||
|
|
||||||
@@ -0,0 +1,187 @@
|
|||||||
|
#:########################################################################################:#
|
||||||
|
# TITLE: MAIN HALLWAY LIGHTSWITCH 1 (BK7231N)
|
||||||
|
# zorruno.com layout
|
||||||
|
#:########################################################################################:#
|
||||||
|
# REPO:
|
||||||
|
#
|
||||||
|
#:########################################################################################:#
|
||||||
|
# VERSIONS:
|
||||||
|
# V1.0 2026-04-03 Initial
|
||||||
|
#:########################################################################################:#
|
||||||
|
# HARDWARE:
|
||||||
|
# - Zemismart KS-811 Single push button
|
||||||
|
# - BK7231N based switch
|
||||||
|
# - BK72XX board: generic-bk7231n-qfn32-tuya
|
||||||
|
# - pinout/schematic:
|
||||||
|
# https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OPERATION NOTES:
|
||||||
|
# - Main bathroom switch with 1 output:
|
||||||
|
# 1) Main Hallway Lights
|
||||||
|
#
|
||||||
|
#:########################################################################################:#
|
||||||
|
# MQTT COMMANDS:
|
||||||
|
# -
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OFFLINE NOTES:
|
||||||
|
#
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# 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-mainhallwaylights1"
|
||||||
|
friendly_name: "Main Hallway Lightswitch (1)"
|
||||||
|
description_comment: "BK7231N - Main Hallway Lightswitch using a Zemismart KS-811 Single Push Button. Main Hallway Lights (1)"
|
||||||
|
device_area: "Main Hallway" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
||||||
|
|
||||||
|
# Project Naming
|
||||||
|
project_name: "Zemismart Technologies.KS-811 Triple BK7231N" # Project Details
|
||||||
|
project_version: "v1.0" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
||||||
|
|
||||||
|
# Passwords
|
||||||
|
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
||||||
|
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
|
||||||
|
static_ip_address: !secret esp-mainhallwaylights1_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" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
||||||
|
update_interval: "60s" # update time for for general sensors etc
|
||||||
|
|
||||||
|
# Default relay restore mode
|
||||||
|
# Options: RESTORE_DEFAULT_OFF, RESTORE_DEFAULT_ON, ALWAYS_ON, ALWAYS_OFF
|
||||||
|
relay_restore_mode: "RESTORE_DEFAULT_OFF"
|
||||||
|
|
||||||
|
# Switch Naming
|
||||||
|
switch_1_name: "Main Hallway Lights"
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# 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
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# PACKAGE ITEM REMOVALS / OVERRIDES:
|
||||||
|
#:########################################################################################:#
|
||||||
|
wifi:
|
||||||
|
min_auth_mode: !remove # The WPA2 only works on esp32/8266
|
||||||
|
reboot_timeout: 15min # override the selection from the common package
|
||||||
|
fast_connect: false # optional; force off in case package vars change
|
||||||
|
|
||||||
|
mqtt:
|
||||||
|
keepalive: 15s # overriding the value from the common package
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# 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}"
|
||||||
|
project:
|
||||||
|
name: "${project_name}"
|
||||||
|
version: "${project_version}"
|
||||||
|
# on_boot:
|
||||||
|
# priority: 200
|
||||||
|
# then:
|
||||||
|
# - switch.turn_on: Relay_3
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# BUILD FOR BK CHIPSET:
|
||||||
|
# bk72xx
|
||||||
|
# https://devices.esphome.io/board/bk72xx/
|
||||||
|
#:########################################################################################:#
|
||||||
|
bk72xx:
|
||||||
|
board: generic-bk7231n-qfn32-tuya
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# LOGGER:
|
||||||
|
# https://esphome.io/components/logger.html
|
||||||
|
#:########################################################################################:#
|
||||||
|
logger:
|
||||||
|
level: "${log_level}" # INFO Level suggested, or DEBUG for testing
|
||||||
|
baud_rate: 0 # set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
||||||
|
id: logger_id
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# STATUS LED:
|
||||||
|
# https://esphome.io/components/status_led.html
|
||||||
|
#:########################################################################################:#
|
||||||
|
status_led:
|
||||||
|
pin:
|
||||||
|
number: P22 #GPIO22
|
||||||
|
inverted: true
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# BINARY SENSORS:
|
||||||
|
# https://esphome.io/components/binary_sensor/
|
||||||
|
#:########################################################################################:#
|
||||||
|
binary_sensor:
|
||||||
|
- platform: gpio
|
||||||
|
pin:
|
||||||
|
number: P17
|
||||||
|
mode:
|
||||||
|
input: true
|
||||||
|
pullup: true
|
||||||
|
inverted: true
|
||||||
|
name: "Button 1: ${switch_1_name}"
|
||||||
|
on_press:
|
||||||
|
- delay: 50ms
|
||||||
|
- switch.toggle: Relay_1
|
||||||
|
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# SWITCH COMPONENT:
|
||||||
|
# https://esphome.io/components/switch/
|
||||||
|
#:########################################################################################:#
|
||||||
|
switch:
|
||||||
|
- platform: gpio
|
||||||
|
name: "Relay 1: ${switch_1_name}"
|
||||||
|
pin: P14 #GPIO14
|
||||||
|
id: Relay_1
|
||||||
|
restore_mode: ${relay_restore_mode}
|
||||||
@@ -0,0 +1,193 @@
|
|||||||
|
#:########################################################################################:#
|
||||||
|
# TITLE: MAIN HALLWAY LIGHTSWITCH 2 (BK7231N)
|
||||||
|
# zorruno.com layout v1.1 2026
|
||||||
|
#:########################################################################################:#
|
||||||
|
# REPO:
|
||||||
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-mainhallwaylights2.yaml
|
||||||
|
#:########################################################################################:#
|
||||||
|
# VERSIONS:
|
||||||
|
# V1.1 2026-04-03 Updated yaml to zorruno layout V1.1; corrected KS-811 single naming and operation notes; updated BK7231N single-switch pin mapping
|
||||||
|
# V1.0 2026-04-03 Initial
|
||||||
|
#:########################################################################################:#
|
||||||
|
# HARDWARE:
|
||||||
|
# - Zemismart KS-811 Single push button
|
||||||
|
# - BK7231N based switch
|
||||||
|
# - BK72XX board: generic-bk7231n-qfn32-tuya
|
||||||
|
# - BK7231N single-switch pin mapping checked against KS-811 BK references
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OPERATION NOTES:
|
||||||
|
# - Main hallway nightlight switch with 1 output:
|
||||||
|
# 1) Main Hallway Nightlights
|
||||||
|
# - A single press of the physical button toggles Relay 1 ON/OFF
|
||||||
|
# - Status LED uses P22
|
||||||
|
#:########################################################################################:#
|
||||||
|
# MQTT COMMANDS:
|
||||||
|
# - None
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OFFLINE NOTES:
|
||||||
|
# - a) Home Assistant offline (network and MQTT online):
|
||||||
|
# - Device remains on WiFi and MQTT
|
||||||
|
# - Physical button still toggles relay locally
|
||||||
|
# - b) MQTT offline (or Home Assistant and MQTT offline):
|
||||||
|
# - Physical button still toggles relay locally
|
||||||
|
# - Remote control/state sync is unavailable until MQTT returns
|
||||||
|
# - c) Entire WiFi/network offline:
|
||||||
|
# - Physical button still toggles relay locally
|
||||||
|
# - Accurate time is not needed; SNTP is not 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-mainhallwaylights2"
|
||||||
|
friendly_name: "Main Hallway Nightlights (1)"
|
||||||
|
description_comment: "BK7231N - Main Hallway Nightlights using a Zemismart KS-811 Single Push Button. Main Hallway Nightlights (1) (Layout V1.1)"
|
||||||
|
device_area: "Main Hallway" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
||||||
|
|
||||||
|
# Project Naming
|
||||||
|
project_name: "Zemismart Technologies.KS-811 Single BK7231N" # Project Details
|
||||||
|
project_version: "v1.1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
||||||
|
|
||||||
|
# Passwords
|
||||||
|
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
||||||
|
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
|
||||||
|
static_ip_address: !secret esp-mainhallwaylights2_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" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
||||||
|
update_interval: "60s" # update time for for general sensors etc
|
||||||
|
|
||||||
|
# Default relay restore mode
|
||||||
|
# Options: RESTORE_DEFAULT_OFF, RESTORE_DEFAULT_ON, ALWAYS_ON, ALWAYS_OFF
|
||||||
|
relay_restore_mode: "RESTORE_DEFAULT_OFF"
|
||||||
|
|
||||||
|
# Switch Naming
|
||||||
|
switch_1_name: "Main Hallway Nightlights"
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# 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
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# PACKAGE ITEM REMOVALS / OVERRIDES:
|
||||||
|
#:########################################################################################:#
|
||||||
|
wifi:
|
||||||
|
min_auth_mode: !remove # The WPA2 only works on esp32/8266
|
||||||
|
reboot_timeout: 15min # override the selection from the common package
|
||||||
|
fast_connect: false # optional; force off in case package vars change
|
||||||
|
|
||||||
|
mqtt:
|
||||||
|
keepalive: 15s # overriding the value from the common package
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# 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}"
|
||||||
|
project:
|
||||||
|
name: "${project_name}"
|
||||||
|
version: "${project_version}"
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# BUILD FOR BK CHIPSET:
|
||||||
|
# bk72xx
|
||||||
|
# https://devices.esphome.io/board/bk72xx/
|
||||||
|
#:########################################################################################:#
|
||||||
|
bk72xx:
|
||||||
|
board: generic-bk7231n-qfn32-tuya
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# LOGGER:
|
||||||
|
# https://esphome.io/components/logger.html
|
||||||
|
#:########################################################################################:#
|
||||||
|
logger:
|
||||||
|
level: "${log_level}" # INFO Level suggested, or DEBUG for testing
|
||||||
|
baud_rate: 0 # set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
||||||
|
id: logger_id
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# STATUS LED:
|
||||||
|
# https://esphome.io/components/status_led.html
|
||||||
|
#:########################################################################################:#
|
||||||
|
status_led:
|
||||||
|
pin:
|
||||||
|
number: P22 # GPIO22
|
||||||
|
inverted: true
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# BINARY SENSORS:
|
||||||
|
# https://esphome.io/components/binary_sensor/
|
||||||
|
#:########################################################################################:#
|
||||||
|
binary_sensor:
|
||||||
|
- platform: gpio
|
||||||
|
id: button_1
|
||||||
|
internal: true
|
||||||
|
pin:
|
||||||
|
number: P24 # GPIO24
|
||||||
|
mode:
|
||||||
|
input: true
|
||||||
|
pullup: true
|
||||||
|
inverted: true
|
||||||
|
filters:
|
||||||
|
- delayed_on: 20ms
|
||||||
|
on_press:
|
||||||
|
- switch.toggle: Relay_1
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# SWITCH COMPONENT:
|
||||||
|
# https://esphome.io/components/switch/
|
||||||
|
#:########################################################################################:#
|
||||||
|
switch:
|
||||||
|
- platform: gpio
|
||||||
|
name: "Relay 1: ${switch_1_name}"
|
||||||
|
pin: P16 # GPIO16
|
||||||
|
id: Relay_1
|
||||||
|
restore_mode: ${relay_restore_mode}
|
||||||
@@ -1,59 +1,77 @@
|
|||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
##########################################################################################
|
# TITLE: MAIN KITCHEN LIGHTSWITCH
|
||||||
# Main Kitchen LIGHTSWITCH
|
# zorruno.com layout v1.1 2026
|
||||||
# V3.7 2025-09-14 upload to this lightswitch from copy
|
#:########################################################################################:#
|
||||||
#
|
# REPO:
|
||||||
##########################################################################################
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-mainkitchenlights.yaml
|
||||||
# Zemismart KS-811 Double push button
|
#:########################################################################################:#
|
||||||
# pinout/schematic https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
|
# VERSIONS:
|
||||||
#
|
# V3.8 2026-03-11 Updated yaml to zorruno layout V1.1
|
||||||
# NOTES
|
# V3.7 2025-09-14 Upload to this lightswitch from copy
|
||||||
# - Light switch with 2 sets of lights
|
#:########################################################################################:#
|
||||||
#
|
# HARDWARE:
|
||||||
##########################################################################################
|
# - Zemismart KS-811 Double push button (KS-811-2)
|
||||||
##########################################################################################
|
# - ESP8266 (esp01_1m class)
|
||||||
|
# - Buttons: GPIO16 (Button 1), GPIO05 (Button 2)
|
||||||
|
# - Relays: GPIO13 (Relay 1), GPIO12 (Relay 2)
|
||||||
|
# - Status LED: GPIO2 (inverted)
|
||||||
|
# - Reference: https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OPERATION NOTES:
|
||||||
|
# - 2 button wall switch controlling 2 relays
|
||||||
|
# - Button 1 toggles Relay 1 (Main Lights)
|
||||||
|
# - Button 2 toggles Relay 2 (Benchtop Lights)
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OFFLINE NOTES:
|
||||||
|
# a) Home Assistant OFFLINE, but Network and MQTT ONLINE
|
||||||
|
# - Physical buttons still toggle the relays locally
|
||||||
|
# - If MQTT is online, any standard MQTT diagnostics from your common package continue to publish
|
||||||
|
# b) MQTT OFFLINE (but WiFi/Network and HA API ONLINE)
|
||||||
|
# - Physical buttons still toggle the relays locally
|
||||||
|
# - HA control via API remains available (switch entities still work)
|
||||||
|
# c) Entire WiFi/Network OFFLINE
|
||||||
|
# - Physical buttons still toggle the relays locally (standalone operation)
|
||||||
|
# - Accurate time is not needed (SNTP not required)
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
##########################################################################################
|
|
||||||
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
|
#:########################################################################################:#
|
||||||
|
# SUBSTITUTIONS: Specific device variable substitutions
|
||||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
substitutions:
|
substitutions:
|
||||||
# Device Naming
|
# Device Naming
|
||||||
device_name: "esp-mainkitchenlights"
|
device_name: "esp-mainkitchenlights"
|
||||||
friendly_name: "Main Kitchen Lightswitch (2)"
|
friendly_name: "Main Kitchen Lightswitch (2)"
|
||||||
description_comment: "Main Kitchen lightswitch using a Zemismart KS-811 Double Push Button. Main Lights (1), Bench Lights (2)"
|
description_comment: "Main Kitchen lightswitch using a Zemismart KS-811 Double Push Button. Main Lights (1), Bench Lights (2) (Layout V1.1)"
|
||||||
device_area: "Kitchen" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
device_area: "Kitchen" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
||||||
|
|
||||||
# Project Naming
|
# Project Naming
|
||||||
project_name: "Zemismart Technologies.KS-811 Double" # Project Details
|
project_name: "Zemismart Technologies.KS-811 Double" # Project Details
|
||||||
project_version: "v3.7" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
project_version: "v3.8" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
||||||
|
|
||||||
# Passwords & Secrets
|
# Passwords & Secrets
|
||||||
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
||||||
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
|
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
|
||||||
static_ip_address: !secret esp-mainkitchenlights_ip
|
static_ip_address: !secret esp-mainkitchenlights_ip
|
||||||
#mqtt_local_command_main_topic: !secret mqtt_local_command_main_topic
|
|
||||||
#mqtt_local_status_main_topic: !secret mqtt_local_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
|
# Device Settings
|
||||||
#relay_icon: "mdi:lightbulb-group"
|
log_level: "INFO" # NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
||||||
log_level: "INFO" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
|
||||||
update_interval: "60s" # update time for for general sensors etc
|
update_interval: "60s" # update time for for general sensors etc
|
||||||
|
|
||||||
# MQTT LOCAL Controls
|
|
||||||
#mqtt_device_name: "bedroom2-lights"
|
|
||||||
#mqtt_local_command_topic: "${mqtt_local_command_main_topic}/${mqtt_device_name}" # Topic we will use to command this locally without HA
|
|
||||||
#mqtt_local_status_topic: "${mqtt_local_status_main_topic}/${mqtt_device_name}" # Topic we will use to view status locally without HA
|
|
||||||
|
|
||||||
# Switch Naming
|
# Switch Naming
|
||||||
switch_1_name: "Main Lights"
|
switch_1_name: "Main Lights"
|
||||||
switch_2_name: "Benchtop Lights"
|
switch_2_name: "Benchtop Lights"
|
||||||
#switch_3_name: "Nil"
|
|
||||||
|
|
||||||
#########################################################################################
|
|
||||||
|
#:########################################################################################:#
|
||||||
# PACKAGES: Included Common Packages
|
# PACKAGES: Included Common Packages
|
||||||
# https://esphome.io/components/packages.html
|
# https://esphome.io/components/packages.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
packages:
|
packages:
|
||||||
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
||||||
common_wifi: !include
|
common_wifi: !include
|
||||||
@@ -62,6 +80,7 @@ packages:
|
|||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
local_static_ip_address: "${static_ip_address}"
|
local_static_ip_address: "${static_ip_address}"
|
||||||
local_ota_pass: "${ota_pass}"
|
local_ota_pass: "${ota_pass}"
|
||||||
|
local_current_ip_address: "${current_ip_address}"
|
||||||
|
|
||||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||||
common_api: !include
|
common_api: !include
|
||||||
@@ -75,73 +94,74 @@ packages:
|
|||||||
file: common/mqtt_common.yaml
|
file: common/mqtt_common.yaml
|
||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
|
|
||||||
#### WEB PORTAL ####
|
#### WEB PORTAL ####
|
||||||
common_webportal: !include common/webportal_common.yaml
|
common_webportal: !include common/webportal_common.yaml
|
||||||
|
|
||||||
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
||||||
#common_sntp: !include common/sntp_common.yaml
|
#common_sntp: !include common/sntp_common.yaml
|
||||||
|
|
||||||
#### DIAGNOSTICS Sensors ####
|
#### DIAGNOSTICS Sensors ####
|
||||||
diag_basic: !include common/include_basic_diag_sensors.yaml
|
diag_basic: !include common/include_basic_diag_sensors.yaml
|
||||||
diag_more: !include common/include_more_diag_sensors.yaml
|
diag_more: !include common/include_more_diag_sensors.yaml
|
||||||
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
||||||
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
||||||
|
|
||||||
#########################################################################################
|
|
||||||
# ESPHome
|
#:########################################################################################:#
|
||||||
|
# ESPHOME:
|
||||||
# https://esphome.io/components/esphome.html
|
# https://esphome.io/components/esphome.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
esphome:
|
esphome:
|
||||||
name: "${device_name}"
|
name: "${device_name}"
|
||||||
friendly_name: "${friendly_name}"
|
friendly_name: "${friendly_name}"
|
||||||
comment: "${description_comment}" # Appears on the esphome page in HA
|
comment: "${description_comment}" # Appears on the ESPHome page in HA
|
||||||
area: "${device_area}"
|
area: "${device_area}"
|
||||||
project:
|
project:
|
||||||
name: "${project_name}"
|
name: "${project_name}"
|
||||||
version: "${project_version}"
|
version: "${project_version}"
|
||||||
# on_boot:
|
|
||||||
# priority: 200
|
|
||||||
# then:
|
|
||||||
# - switch.turn_on: Relay_2 # Stays on permanently
|
|
||||||
|
|
||||||
#########################################################################################
|
|
||||||
# ESP Platform and Framework
|
#:########################################################################################:#
|
||||||
# https://esphome.io/components/esp32.html
|
# ESP PLATFORM AND FRAMEWORK:
|
||||||
#########################################################################################
|
# https://esphome.io/components/esp8266.html
|
||||||
|
#:########################################################################################:#
|
||||||
esp8266:
|
esp8266:
|
||||||
board: esp01_1m
|
board: esp01_1m
|
||||||
early_pin_init: False # Initialise pins early to known values. Recommended false where switches are involved. Defaults to True.
|
early_pin_init: false # Recommended false where switches are involved. Defaults to true.
|
||||||
board_flash_mode: dout # Default is dout
|
board_flash_mode: dout # Default is dout
|
||||||
|
|
||||||
#########################################################################################
|
|
||||||
# ESPHome Logging Enable
|
|
||||||
# https://esphome.io/components/logger.html
|
|
||||||
#############################################
|
|
||||||
logger:
|
|
||||||
level: "${log_level}" #INFO Level suggested, or DEBUG for testing
|
|
||||||
#baud_rate: 0 #set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
|
||||||
#esp8266_store_log_strings_in_flash: false
|
|
||||||
#tx_buffer_size: 64
|
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# STATUS LED
|
# LOGGING:
|
||||||
|
# https://esphome.io/components/logger.html
|
||||||
|
#:########################################################################################:#
|
||||||
|
logger:
|
||||||
|
level: "${log_level}"
|
||||||
|
#baud_rate: 0 # set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
||||||
|
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# STATUS LED:
|
||||||
# https://esphome.io/components/status_led.html
|
# https://esphome.io/components/status_led.html
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
status_led:
|
status_led:
|
||||||
pin:
|
pin:
|
||||||
number: GPIO2
|
number: GPIO2
|
||||||
inverted: yes
|
inverted: true
|
||||||
|
|
||||||
#########################################################################################
|
|
||||||
# BINARY SENSORS
|
#:########################################################################################:#
|
||||||
|
# BINARY SENSORS:
|
||||||
# https://esphome.io/components/binary_sensor/
|
# https://esphome.io/components/binary_sensor/
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
pin:
|
pin:
|
||||||
number: GPIO16
|
number: GPIO16
|
||||||
mode: INPUT
|
mode: INPUT
|
||||||
inverted: True
|
inverted: true
|
||||||
|
use_interrupt: false # GPIO16 pin doesn't support interrupts so use polling (suppresses warning).
|
||||||
name: "Button 1: ${switch_1_name}"
|
name: "Button 1: ${switch_1_name}"
|
||||||
on_press:
|
on_press:
|
||||||
- switch.toggle: Relay_1
|
- switch.toggle: Relay_1
|
||||||
@@ -150,25 +170,16 @@ binary_sensor:
|
|||||||
pin:
|
pin:
|
||||||
number: GPIO05
|
number: GPIO05
|
||||||
mode: INPUT
|
mode: INPUT
|
||||||
inverted: True
|
inverted: true
|
||||||
name: "Button 2: ${switch_2_name}"
|
name: "Button 2: ${switch_2_name}"
|
||||||
on_press:
|
on_press:
|
||||||
- switch.toggle: Relay_2
|
- switch.toggle: Relay_2
|
||||||
|
|
||||||
# KS-811-2 is a double only
|
|
||||||
# - platform: gpio
|
|
||||||
# pin:
|
|
||||||
# number: GPIO4
|
|
||||||
# mode: INPUT
|
|
||||||
# inverted: True
|
|
||||||
# name: "Button 3: ${switch_3_name}"
|
|
||||||
# on_press:
|
|
||||||
# - switch.toggle: Relay_3
|
|
||||||
|
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
# SWITCH COMPONENT
|
# SWITCH COMPONENT:
|
||||||
# https://esphome.io/components/switch/
|
# https://esphome.io/components/switch/
|
||||||
#########################################################################################
|
#:########################################################################################:#
|
||||||
switch:
|
switch:
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
name: "Relay 1: ${switch_1_name}"
|
name: "Relay 1: ${switch_1_name}"
|
||||||
@@ -178,12 +189,4 @@ switch:
|
|||||||
- platform: gpio
|
- platform: gpio
|
||||||
name: "Relay 2: ${switch_2_name}"
|
name: "Relay 2: ${switch_2_name}"
|
||||||
pin: GPIO12
|
pin: GPIO12
|
||||||
id: Relay_2
|
id: Relay_2
|
||||||
|
|
||||||
# KS-811-2 is a double only
|
|
||||||
# - platform: gpio
|
|
||||||
# name: "Relay 3: ${switch_3_name}"
|
|
||||||
# pin: GPIO14
|
|
||||||
# id: Relay_3
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
#:########################################################################################:#
|
#:########################################################################################:#
|
||||||
# TITLE: MASTER BATHROOM HEATED TOWEL RAIL
|
# TITLE: MASTER BATHROOM HEATED TOWEL RAIL
|
||||||
# zorruno.com layout v1.0 2026
|
# zorruno.com layout v1.1 2026
|
||||||
|
#:########################################################################################:#
|
||||||
|
# REPO:
|
||||||
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-masterbathtowelrail.yaml
|
||||||
#:########################################################################################:#
|
#:########################################################################################:#
|
||||||
# VERSIONS:
|
# VERSIONS:
|
||||||
|
# V2.3 2026-03-11 Updated yaml to zorruno layout V1.1
|
||||||
# V2.2 2026-01-30 Added Morning/Evening Timer enable switches (gate timer windows)
|
# V2.2 2026-01-30 Added Morning/Evening Timer enable switches (gate timer windows)
|
||||||
# V2.1 2025-06-12 Added select and button to chose modes, added countdown & startup to boost
|
# V2.1 2025-06-12 Added select and button to chose modes, added countdown & startup to boost
|
||||||
# V2.0 2025-06-05 YAML Tidyups
|
# V2.0 2025-06-05 YAML Tidyups
|
||||||
@@ -10,8 +14,8 @@
|
|||||||
# V1.0 2025-02-14 Initial Version
|
# V1.0 2025-02-14 Initial Version
|
||||||
#:########################################################################################:#
|
#:########################################################################################:#
|
||||||
# HARDWARE:
|
# HARDWARE:
|
||||||
# Controlled by a Sonoff Basic
|
# - Controlled by a Sonoff Basic
|
||||||
# pinout/schematic: https://devices.esphome.io/devices/sonoff-basic-r4-v1.0/
|
# - pinout/schematic: https://devices.esphome.io/devices/sonoff-basic-r4-v1.0/
|
||||||
#:########################################################################################:#
|
#:########################################################################################:#
|
||||||
# OPERATION NOTES:
|
# OPERATION NOTES:
|
||||||
# - It allows the device to work in a standalone timer style operation
|
# - It allows the device to work in a standalone timer style operation
|
||||||
@@ -21,7 +25,7 @@
|
|||||||
# - It uses SNTP for time setting (but obviously only if wifi & networking are working)
|
# - It uses SNTP for time setting (but obviously only if wifi & networking are working)
|
||||||
# - It will default to an internal timer if no wifi. To reset internal timer, reboot the device at 12pm (noon)
|
# - It will default to an internal timer if no wifi. To reset internal timer, reboot the device at 12pm (noon)
|
||||||
# - If on a network and there is a MQTT server, you can set the on/off times via MQTT (See below commands)
|
# - If on a network and there is a MQTT server, you can set the on/off times via MQTT (See below commands)
|
||||||
# - You can set 4 modes ON/OFF/TIMER/BOOST via MQTT. Setting BOOST gives you a oneshot operation
|
# - You can set 4 modes ON/OFF/TIMER/BOOST via MQTT. Setting BOOST gives you a oneshot operation
|
||||||
# - Any new timer times set via MQTT will be remembered though a reboot
|
# - Any new timer times set via MQTT will be remembered though a reboot
|
||||||
# - On startup, or a reboot, the device will always turn on for the BOOST Duration (BOOST mode, default 2 hours)
|
# - On startup, or a reboot, the device will always turn on for the BOOST Duration (BOOST mode, default 2 hours)
|
||||||
# - TIMER mode will always be switched on after BOOST mode is complete
|
# - TIMER mode will always be switched on after BOOST mode is complete
|
||||||
@@ -30,7 +34,7 @@
|
|||||||
#:########################################################################################:#
|
#:########################################################################################:#
|
||||||
# MQTT COMMANDS:
|
# MQTT COMMANDS:
|
||||||
# Values will be set in place on the update_interval time, not immediately
|
# Values will be set in place on the update_interval time, not immediately
|
||||||
# Use 00:00 in 24hr format for time setting. (Note there is no weekday/weekend setting)
|
# Use 00:00 in 24hr format for time setting. (Note there is no weekday/weekend setting)
|
||||||
# mqtt_timer_topic/morning-on/06:00 : Time device will go on
|
# mqtt_timer_topic/morning-on/06:00 : Time device will go on
|
||||||
# mqtt_timer_topic/morning-off/08:00 : Time device will go off
|
# mqtt_timer_topic/morning-off/08:00 : Time device will go off
|
||||||
# mqtt_timer_topic/evening-on/09:00 : Time device will go on
|
# mqtt_timer_topic/evening-on/09:00 : Time device will go on
|
||||||
@@ -39,7 +43,7 @@
|
|||||||
# mqtt_timer_topic/operation/ON : Device permanently on
|
# mqtt_timer_topic/operation/ON : Device permanently on
|
||||||
# mqtt_timer_topic/operation/OFF : Device permanently off
|
# mqtt_timer_topic/operation/OFF : Device permanently off
|
||||||
# mqtt_timer_topic/operation/TIMER : Device will obey timer settings
|
# mqtt_timer_topic/operation/TIMER : Device will obey timer settings
|
||||||
# mqtt_timer_topic/operation/BOOST : Turn on for (boost_duration) minutes then BOOST (also on startup)
|
# mqtt_timer_topic/operation/BOOST : Turn on for (boost_duration) minutes then BOOST (also on startup)
|
||||||
#
|
#
|
||||||
# operation_mode:
|
# operation_mode:
|
||||||
# 0 = OFF
|
# 0 = OFF
|
||||||
@@ -50,15 +54,14 @@
|
|||||||
# OFFLINE NOTES:
|
# OFFLINE NOTES:
|
||||||
# a) Home Assistant OFFLINE, but Network and MQTT ONLINE
|
# a) Home Assistant OFFLINE, but Network and MQTT ONLINE
|
||||||
# - The towel rail will stick to its assigned schedule (and should remember on reboot)
|
# - The towel rail will stick to its assigned schedule (and should remember on reboot)
|
||||||
# - Shedule times and on/off switching can still occur via MQTT
|
# - Schedule times and on/off switching can still occur via MQTT
|
||||||
# - Other switches such as the IR Heater/Fan combo can still command the towel rail
|
# - Other switches such as the IR Heater/Fan combo can still command the towel rail
|
||||||
# b) HA/MQTT OFFLINE
|
# b) HA/MQTT OFFLINE
|
||||||
# With no automation controllers, the HTR will still remember its timing functions, and will
|
# - With no automation controllers, the HTR will still remember its timing functions, and will
|
||||||
# turn on once or twice per day. If internet/wifi is still available, timing will be accurate.
|
# turn on once or twice per day. If internet/wifi is still available, timing will be accurate.
|
||||||
# c) Internet/Wifi OFFLINE
|
# c) Internet/Wifi OFFLINE
|
||||||
# The HTR will still come on once or twice per day (depending on previous settings) however
|
# - The HTR will still come on once or twice per day (depending on previous settings)
|
||||||
# timing will likely shift. To make timing more accurate, it can be powered down then up at 12pm.
|
# - Timeclocks will drift without SNTP and can be reset by power cycling at 12pm (midday)
|
||||||
# Obviously this may drift again over time.
|
|
||||||
#:########################################################################################:#
|
#:########################################################################################:#
|
||||||
|
|
||||||
#:########################################################################################:#
|
#:########################################################################################:#
|
||||||
@@ -69,12 +72,12 @@ substitutions:
|
|||||||
# Device Naming
|
# Device Naming
|
||||||
device_name: "esp-masterbathtowelrail"
|
device_name: "esp-masterbathtowelrail"
|
||||||
friendly_name: "Master Bathroom Towelrail"
|
friendly_name: "Master Bathroom Towelrail"
|
||||||
description_comment: "Sonoff Basic controlling ON/OFF/Timer for the Heated Towel Rail in the Master Bathroom"
|
description_comment: "Sonoff Basic controlling ON/OFF/Timer for the Heated Towel Rail in the Master Bathroom (Layout V1.1)"
|
||||||
device_area: "Main Bathroom" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
device_area: "Main Bathroom" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
||||||
|
|
||||||
# Project Naming
|
# Project Naming
|
||||||
project_name: "Sonoff Technologies.Sonoff Basic V1" # Project Details
|
project_name: "Sonoff Technologies.Sonoff Basic V1" # Project Details
|
||||||
project_version: "v2.2" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
project_version: "v2.3" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
||||||
|
|
||||||
# Passwords
|
# Passwords
|
||||||
api_key: !secret esp-masterbathtowelrail_api_key # unfortunately you can't use substitutions inside secrets names
|
api_key: !secret esp-masterbathtowelrail_api_key # unfortunately you can't use substitutions inside secrets names
|
||||||
@@ -109,8 +112,8 @@ packages:
|
|||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
local_static_ip_address: "${static_ip_address}"
|
local_static_ip_address: "${static_ip_address}"
|
||||||
local_ota_pass: "${ota_pass}"
|
|
||||||
local_current_ip_address: "${current_ip_address}"
|
local_current_ip_address: "${current_ip_address}"
|
||||||
|
local_ota_pass: "${ota_pass}"
|
||||||
|
|
||||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||||
common_api: !include
|
common_api: !include
|
||||||
@@ -606,7 +609,7 @@ sensor:
|
|||||||
unit_of_measurement: "mins"
|
unit_of_measurement: "mins"
|
||||||
accuracy_decimals: "0"
|
accuracy_decimals: "0"
|
||||||
update_interval: "${update_interval}"
|
update_interval: "${update_interval}"
|
||||||
internal: True # No need to show this in Home Assistant
|
internal: true # No need to show this in Home Assistant
|
||||||
lambda: |-
|
lambda: |-
|
||||||
return id(current_mins);
|
return id(current_mins);
|
||||||
|
|
||||||
@@ -787,4 +790,4 @@ interval:
|
|||||||
//id(mqtt_client).publish("${mqtt_timer_topic}/operation", "TIMER");
|
//id(mqtt_client).publish("${mqtt_timer_topic}/operation", "TIMER");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
- script.execute: evaluate_relay_state
|
- script.execute: evaluate_relay_state
|
||||||
@@ -1,204 +1,222 @@
|
|||||||
#############################################
|
#:########################################################################################:#
|
||||||
#############################################
|
# TITLE: OFFICE DUAL LIGHT CONTROL
|
||||||
# OFFICE DUAL LIGHT CONTROL
|
# zorruno.com layout v1.1 2026
|
||||||
# - Overhead cool white lights
|
#:########################################################################################:#
|
||||||
# - Right hand warm bunker light
|
# REPO:
|
||||||
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-officeduallights.yaml
|
||||||
|
#:########################################################################################:#
|
||||||
|
# VERSIONS:
|
||||||
|
# V2.5 2026-03-11 Updated yaml to zorruno layout V1.1
|
||||||
|
# V2.4 2025-06-30 Tidied up MQTT direct relay control (esps can control each other via MQTT)
|
||||||
|
# V2.3 2025-06-18 Added MQTT direct relay control
|
||||||
|
#:########################################################################################:#
|
||||||
|
# HARDWARE:
|
||||||
|
# - Sonoff Dual R1
|
||||||
|
# - ESP8266 based
|
||||||
|
# - 2 x relay outputs
|
||||||
|
# - 2 x local push buttons
|
||||||
|
# - Relay control via UART serial commands
|
||||||
|
# - Status LED on GPIO13
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OPERATION NOTES:
|
||||||
|
# - Controls 2 office light circuits:
|
||||||
|
# - Overhead cool white lights
|
||||||
|
# - Right hand warm bunker light
|
||||||
|
# - Local button 1 toggles relay/light 1
|
||||||
|
# - Local button 2 toggles relay/light 2
|
||||||
|
# - Relay state changes are sent out via MQTT status topics
|
||||||
|
# - Template binary lights drive the template relay switches
|
||||||
|
# - Sonoff Dual R1 requires UART serial packets to operate the physical relays
|
||||||
#
|
#
|
||||||
# Controlled by a Sonoff Dual R1
|
# MQTT COMMANDS:
|
||||||
# A sonoff dual uses serial data to turn the relays on/off
|
# - Command relay 1:
|
||||||
|
# - ${mqtt_local_command_topic}/relay1/set ON or OFF
|
||||||
|
# - Command relay 2:
|
||||||
|
# - ${mqtt_local_command_topic}/relay2/set ON or OFF
|
||||||
|
# - Relay 1 status publishes to:
|
||||||
|
# - ${mqtt_local_status_topic}/relay1/state
|
||||||
|
# - Relay 2 status publishes to:
|
||||||
|
# - ${mqtt_local_status_topic}/relay2/state
|
||||||
|
#:########################################################################################:#
|
||||||
|
# OFFLINE NOTES:
|
||||||
|
# a) Home Assistant offline (network and MQTT still online):
|
||||||
|
# - Device continues to operate from local buttons
|
||||||
|
# - Device can still be controlled directly by MQTT
|
||||||
|
# - Relay status still publishes by MQTT if broker is available
|
||||||
#
|
#
|
||||||
# V2.4 - 2025-06-30 Tidied up MQTT direct relay control (esps can control each other via MQTT)
|
# b) MQTT offline (or HA and MQTT both offline):
|
||||||
# V2.3 - 2025-06-18 Added MQTT direct relay control
|
# - Device continues to operate from local buttons only
|
||||||
|
# - No direct inter-ESP MQTT control available
|
||||||
|
# - No MQTT state feedback available
|
||||||
#
|
#
|
||||||
# NOTES:
|
# c) Entire WiFi / Network offline:
|
||||||
# Command the lights on with MQTT
|
# - Device continues to operate from local buttons only
|
||||||
# ${mqtt_local_command_full_topic}/relay1/set ON or OFF
|
# - No HA control or MQTT control/status available
|
||||||
# ${mqtt_local_command_full_topic}/relay2/set ON or OFF
|
# - Accurate time is not needed; SNTP is not required for operation
|
||||||
# ${mqtt_local_status_full_topic}/relay1/set ON or OFF
|
#:########################################################################################:#
|
||||||
# ${mqtt_local_status_full_topic}/relay2/set ON or OFF
|
|
||||||
#
|
|
||||||
##########################################################################################
|
|
||||||
##########################################################################################
|
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
|
# SUBSTITUTIONS:
|
||||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
# Specific device variable substitutions
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
substitutions:
|
substitutions:
|
||||||
# Device Naming
|
# Device Naming
|
||||||
device_name: "esp-officeduallights"
|
device_name: "esp-officeduallights"
|
||||||
friendly_name: "Office Dual Lights"
|
friendly_name: "Office Dual Lights"
|
||||||
description_comment: "Dual Office Lights (Overhead and right hand Bunker) :: Sonoff Dual R1"
|
description_comment: "Dual Office Lights (Overhead and right hand Bunker) :: Sonoff Dual R1 (Layout V1.1)"
|
||||||
device_area: "Office" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
device_area: "Office"
|
||||||
|
|
||||||
# Project Naming
|
# Project Naming
|
||||||
project_name: "Sonoff Technologies.Sonoff Dual R1" # Project Details
|
project_name: "Sonoff Technologies.Sonoff Dual R1"
|
||||||
project_version: "v2.3" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
project_version: "v2.5"
|
||||||
|
|
||||||
# Passwords & Secrets
|
# Passwords and Secrets
|
||||||
api_key: !secret esp-api_key
|
api_key: !secret esp-api_key
|
||||||
ota_pass: !secret esp-ota_pass
|
ota_pass: !secret esp-ota_pass
|
||||||
static_ip_address: !secret esp-officeduallights_ip # unfortunately you can't use substitutions inside secrets names
|
static_ip_address: !secret esp-officeduallights_ip
|
||||||
|
current_ip_address: ${static_ip_address}
|
||||||
mqtt_local_command_main_topic: !secret mqtt_command_main_topic
|
mqtt_local_command_main_topic: !secret mqtt_command_main_topic
|
||||||
mqtt_local_status_main_topic: !secret mqtt_status_main_topic
|
mqtt_local_status_main_topic: !secret mqtt_status_main_topic
|
||||||
|
|
||||||
# Device Settings
|
# Device Settings
|
||||||
relay_icon: "mdi:lightbulb-group"
|
relay_icon: "mdi:lightbulb-group"
|
||||||
log_level: "NONE" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
log_level: "NONE"
|
||||||
update_interval: "60s" # update time for for general sensors etc
|
update_interval: "60s"
|
||||||
|
|
||||||
# MQTT Controls
|
# MQTT Controls
|
||||||
mqtt_device_name: "office-dual-lights"
|
mqtt_device_name: "office-dual-lights"
|
||||||
mqtt_local_command_topic: "${mqtt_local_command_main_topic}/${mqtt_device_name}" # Topic we will use to command this locally without HA
|
mqtt_local_command_topic: "${mqtt_local_command_main_topic}/${mqtt_device_name}"
|
||||||
mqtt_local_status_topic: "${mqtt_local_status_main_topic}/${mqtt_device_name}" # Topic we will use to view status locally without HA
|
mqtt_local_status_topic: "${mqtt_local_status_main_topic}/${mqtt_device_name}"
|
||||||
|
|
||||||
# Switch Naming
|
# Switch Naming
|
||||||
switch_1_name: "Dual L1 Relay"
|
switch_1_name: "Dual L1 Relay"
|
||||||
relay_1_icon: "mdi:lightbulb"
|
relay_1_icon: "mdi:lightbulb"
|
||||||
light_1_name: "Light 1 (Right Hand Bunker Light)"
|
light_1_name: "Light 1 (Right Hand Bunker Light)"
|
||||||
switch_2_name: "Dual L2 Relay"
|
|
||||||
relay_2_icon: "mdi:lightbulb"
|
|
||||||
light_2_name: "Light 2 (Cool White Overhead Lights)"
|
|
||||||
|
|
||||||
##########################################################################################
|
switch_2_name: "Dual L2 Relay"
|
||||||
# PACKAGES: Included Common Packages
|
relay_2_icon: "mdi:lightbulb"
|
||||||
|
light_2_name: "Light 2 (Cool White Overhead Lights)"
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# PACKAGES:
|
||||||
|
# Included common packages
|
||||||
# https://esphome.io/components/packages.html
|
# https://esphome.io/components/packages.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
packages:
|
packages:
|
||||||
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
|
||||||
common_wifi: !include
|
common_wifi: !include
|
||||||
file: common/network_common.yaml
|
file: common/network_common.yaml
|
||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
local_device_name: "${device_name}"
|
||||||
local_static_ip_address: "${static_ip_address}"
|
local_static_ip_address: "${static_ip_address}"
|
||||||
|
local_current_ip_address: "${current_ip_address}"
|
||||||
local_ota_pass: "${ota_pass}"
|
local_ota_pass: "${ota_pass}"
|
||||||
|
|
||||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
|
||||||
common_api: !include
|
common_api: !include
|
||||||
file: common/api_common.yaml
|
file: common/api_common.yaml
|
||||||
#file: common/api_common_noencryption.yaml
|
# file: common/api_common_noencryption.yaml
|
||||||
vars:
|
vars:
|
||||||
local_api_key: "${api_key}"
|
local_api_key: "${api_key}"
|
||||||
|
|
||||||
#### MQTT ####
|
|
||||||
common_mqtt: !include
|
common_mqtt: !include
|
||||||
file: common/mqtt_common.yaml
|
file: common/mqtt_common.yaml
|
||||||
vars:
|
vars:
|
||||||
local_device_name: "${device_name}"
|
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 ####
|
# common_webportal: !include common/webportal_common.yaml
|
||||||
diag_basic: !include common/include_basic_diag_sensors.yaml
|
# common_sntp: !include common/sntp_common.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
|
|
||||||
|
|
||||||
##########################################################################################
|
diag_basic: !include common/include_basic_diag_sensors.yaml
|
||||||
# ESPHome
|
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
|
# https://esphome.io/components/esphome.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
esphome:
|
esphome:
|
||||||
name: "${device_name}"
|
name: "${device_name}"
|
||||||
friendly_name: "${friendly_name}"
|
friendly_name: "${friendly_name}"
|
||||||
comment: "${description_comment}" # Appears on the esphome page in HA
|
comment: "${description_comment}"
|
||||||
area: "${device_area}"
|
area: "${device_area}"
|
||||||
# platformio_options:
|
|
||||||
# build_flags:
|
|
||||||
# - "-Os" # optimize for size
|
|
||||||
# - "-Wl,--gc-sections" # drop unused code/data
|
|
||||||
# - "-fno-exceptions" # strip C++ exceptaions
|
|
||||||
# - "-fno-rtti" # strip C++ RTTI
|
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# ESP Platform and Framework
|
# ESP PLATFORM AND FRAMEWORK:
|
||||||
# https://esphome.io/components/esp32.html
|
# https://esphome.io/components/esp8266.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
esp8266:
|
esp8266:
|
||||||
board: esp01_1m # The original sonoff basic
|
board: esp01_1m
|
||||||
restore_from_flash: False # restore some values on reboot
|
restore_from_flash: false
|
||||||
|
|
||||||
preferences:
|
preferences:
|
||||||
flash_write_interval: 5min
|
flash_write_interval: 5min
|
||||||
|
|
||||||
mdns:
|
mdns:
|
||||||
disabled: True
|
disabled: true
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# ESPHome Logging Enable
|
# LOGGER:
|
||||||
|
# Sonoff Dual cannot use UART logging because UART is required for relay control
|
||||||
# https://esphome.io/components/logger.html
|
# https://esphome.io/components/logger.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# NOTE: Sonoff Dual CANNOT send serial data to log
|
|
||||||
###############################################
|
|
||||||
logger:
|
logger:
|
||||||
level: "${log_level}" #INFO Level suggested, or DEBUG for testing
|
level: "${log_level}"
|
||||||
baud_rate: 0 # set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM, Serial control)
|
baud_rate: 0
|
||||||
#esp8266_store_log_strings_in_flash: false
|
|
||||||
#tx_buffer_size: 64
|
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# UART Bus
|
# UART BUS:
|
||||||
# https://esphome.io/components/uart.html
|
# https://esphome.io/components/uart.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
uart:
|
uart:
|
||||||
tx_pin: GPIO01
|
tx_pin: GPIO01
|
||||||
rx_pin: GPIO03
|
rx_pin: GPIO03
|
||||||
baud_rate: 19200
|
baud_rate: 19200
|
||||||
#data_bits: 8
|
|
||||||
#stop_bits: 1
|
|
||||||
#parity: EVEN
|
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# MQTT COMMANDS
|
# MQTT:
|
||||||
# This adds device-specific MQTT command triggers to the common MQTT configuration.
|
# Device-specific MQTT command triggers
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
mqtt:
|
mqtt:
|
||||||
# Direct MQTT control for relays via serial commands
|
|
||||||
on_message:
|
on_message:
|
||||||
# Relay 1 control
|
|
||||||
- topic: "${mqtt_local_command_topic}/relay1/set"
|
- topic: "${mqtt_local_command_topic}/relay1/set"
|
||||||
payload: "ON"
|
payload: "ON"
|
||||||
then:
|
then:
|
||||||
- switch.turn_on: relay_1
|
- switch.turn_on: relay_1
|
||||||
- light.turn_on: light_1
|
- light.turn_on: light_1
|
||||||
|
|
||||||
- topic: "${mqtt_local_command_topic}/relay1/set"
|
- topic: "${mqtt_local_command_topic}/relay1/set"
|
||||||
payload: "OFF"
|
payload: "OFF"
|
||||||
then:
|
then:
|
||||||
- switch.turn_off: relay_1
|
- switch.turn_off: relay_1
|
||||||
- light.turn_off: light_1
|
- light.turn_off: light_1
|
||||||
|
|
||||||
# Relay 2 control
|
|
||||||
- topic: "${mqtt_local_command_topic}/relay2/set"
|
- topic: "${mqtt_local_command_topic}/relay2/set"
|
||||||
payload: "ON"
|
payload: "ON"
|
||||||
then:
|
then:
|
||||||
- switch.turn_on: relay_2
|
- switch.turn_on: relay_2
|
||||||
- light.turn_on: light_2
|
- light.turn_on: light_2
|
||||||
|
|
||||||
- topic: "${mqtt_local_command_topic}/relay2/set"
|
- topic: "${mqtt_local_command_topic}/relay2/set"
|
||||||
payload: "OFF"
|
payload: "OFF"
|
||||||
then:
|
then:
|
||||||
- switch.turn_off: relay_2
|
- switch.turn_off: relay_2
|
||||||
- light.turn_off: light_2
|
- light.turn_off: light_2
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# STATUS LED
|
# STATUS LED:
|
||||||
|
# Sonoff Dual LED is on GPIO13
|
||||||
# https://esphome.io/components/status_led.html
|
# https://esphome.io/components/status_led.html
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# Sonoff Dual LED is GPIO13
|
|
||||||
#############################################
|
|
||||||
status_led:
|
status_led:
|
||||||
pin:
|
pin:
|
||||||
number: GPIO13
|
number: GPIO13
|
||||||
inverted: yes
|
inverted: true
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# BINARY SENSORS
|
# BINARY SENSORS:
|
||||||
|
# Sonoff Dual R1 buttons are GPIO04 and GPIO14
|
||||||
# https://esphome.io/components/binary_sensor/
|
# https://esphome.io/components/binary_sensor/
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# Sonoff Dual R1 buttons are GPIO04, GPIO14
|
|
||||||
#############################################
|
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
pin:
|
pin:
|
||||||
@@ -218,12 +236,11 @@ binary_sensor:
|
|||||||
on_press:
|
on_press:
|
||||||
- switch.toggle: relay_2
|
- switch.toggle: relay_2
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# SWITCH COMPONENT
|
# SWITCH:
|
||||||
|
# Sonoff Dual R1 requires serial data packets to switch the relays
|
||||||
# https://esphome.io/components/switch/
|
# https://esphome.io/components/switch/
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# Sonoff Dual R1 requires serial data to switch
|
|
||||||
#############################################
|
|
||||||
switch:
|
switch:
|
||||||
- platform: template
|
- platform: template
|
||||||
name: "${switch_1_name}"
|
name: "${switch_1_name}"
|
||||||
@@ -234,7 +251,7 @@ switch:
|
|||||||
turn_on_action:
|
turn_on_action:
|
||||||
- mqtt.publish:
|
- mqtt.publish:
|
||||||
topic: "${mqtt_local_status_topic}/relay1/state"
|
topic: "${mqtt_local_status_topic}/relay1/state"
|
||||||
payload: "ON"
|
payload: "ON"
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
switch.is_off: relay_2
|
switch.is_off: relay_2
|
||||||
@@ -245,7 +262,7 @@ switch:
|
|||||||
turn_off_action:
|
turn_off_action:
|
||||||
- mqtt.publish:
|
- mqtt.publish:
|
||||||
topic: "${mqtt_local_status_topic}/relay1/state"
|
topic: "${mqtt_local_status_topic}/relay1/state"
|
||||||
payload: "OFF"
|
payload: "OFF"
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
switch.is_off: relay_2
|
switch.is_off: relay_2
|
||||||
@@ -253,6 +270,7 @@ switch:
|
|||||||
- uart.write: [0xA0, 0x04, 0x00, 0xA1]
|
- uart.write: [0xA0, 0x04, 0x00, 0xA1]
|
||||||
else:
|
else:
|
||||||
- uart.write: [0xA0, 0x04, 0x02, 0xA1]
|
- uart.write: [0xA0, 0x04, 0x02, 0xA1]
|
||||||
|
|
||||||
- platform: template
|
- platform: template
|
||||||
name: "${switch_2_name}"
|
name: "${switch_2_name}"
|
||||||
id: relay_2
|
id: relay_2
|
||||||
@@ -262,7 +280,7 @@ switch:
|
|||||||
turn_on_action:
|
turn_on_action:
|
||||||
- mqtt.publish:
|
- mqtt.publish:
|
||||||
topic: "${mqtt_local_status_topic}/relay2/state"
|
topic: "${mqtt_local_status_topic}/relay2/state"
|
||||||
payload: "ON"
|
payload: "ON"
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
switch.is_off: relay_1
|
switch.is_off: relay_1
|
||||||
@@ -273,7 +291,7 @@ switch:
|
|||||||
turn_off_action:
|
turn_off_action:
|
||||||
- mqtt.publish:
|
- mqtt.publish:
|
||||||
topic: "${mqtt_local_status_topic}/relay2/state"
|
topic: "${mqtt_local_status_topic}/relay2/state"
|
||||||
payload: "OFF"
|
payload: "OFF"
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
switch.is_off: relay_1
|
switch.is_off: relay_1
|
||||||
@@ -282,30 +300,38 @@ switch:
|
|||||||
else:
|
else:
|
||||||
- uart.write: [0xA0, 0x04, 0x01, 0xA1]
|
- uart.write: [0xA0, 0x04, 0x01, 0xA1]
|
||||||
|
|
||||||
################################################################################
|
#:########################################################################################:#
|
||||||
# TEMPLATE OUTPUTS: drive the real relays when the light state changes
|
# OUTPUTS:
|
||||||
################################################################################
|
# Template outputs drive the relay template switches when the light state changes
|
||||||
|
# https://esphome.io/components/output/
|
||||||
|
#:########################################################################################:#
|
||||||
output:
|
output:
|
||||||
- platform: template
|
- platform: template
|
||||||
id: light_output_1
|
id: light_output_1
|
||||||
type: binary
|
type: binary
|
||||||
write_action:
|
write_action:
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
if (state) id(relay_1).turn_on();
|
if (state) {
|
||||||
else id(relay_1).turn_off();
|
id(relay_1).turn_on();
|
||||||
|
} else {
|
||||||
|
id(relay_1).turn_off();
|
||||||
|
}
|
||||||
|
|
||||||
- platform: template
|
- platform: template
|
||||||
id: light_output_2
|
id: light_output_2
|
||||||
type: binary
|
type: binary
|
||||||
write_action:
|
write_action:
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
if (state) id(relay_2).turn_on();
|
if (state) {
|
||||||
else id(relay_2).turn_off();
|
id(relay_2).turn_on();
|
||||||
|
} else {
|
||||||
|
id(relay_2).turn_off();
|
||||||
|
}
|
||||||
|
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
# LIGHT COMPONENT
|
# LIGHT:
|
||||||
# https://esphome.io/components/light/
|
# https://esphome.io/components/light/
|
||||||
##########################################################################################
|
#:########################################################################################:#
|
||||||
light:
|
light:
|
||||||
- platform: binary
|
- platform: binary
|
||||||
name: "${light_1_name}"
|
name: "${light_1_name}"
|
||||||
@@ -313,6 +339,6 @@ light:
|
|||||||
output: light_output_1
|
output: light_output_1
|
||||||
|
|
||||||
- platform: binary
|
- platform: binary
|
||||||
name: "Light 2 (Cool White Overhead Lights)"
|
name: "${light_2_name}"
|
||||||
id: light_2
|
id: light_2
|
||||||
output: light_output_2
|
output: light_output_2
|
||||||
@@ -0,0 +1,177 @@
|
|||||||
|
#:########################################################################################:#
|
||||||
|
# TITLE: ENTRANCE SPOT PERSON DETECTION
|
||||||
|
# PACKAGE: entrance_spot_person_detection.yaml
|
||||||
|
#:########################################################################################:#
|
||||||
|
# PURPOSE:
|
||||||
|
# - Turn on the entrance illumination when a configured motion/visitor/presence source
|
||||||
|
# becomes active.
|
||||||
|
# - Temporarily force the illumination ramp number to 1 second for fast response.
|
||||||
|
# - Restore the original ramp value after the sequence completes.
|
||||||
|
# - Restart the timing whenever any configured trigger entity activates again.
|
||||||
|
#
|
||||||
|
# HOW THIS PACKAGE IS STRUCTURED:
|
||||||
|
# - Trigger entities are stored in groups for easy future maintenance.
|
||||||
|
# - The automation listens for state_changed events and checks whether the changed
|
||||||
|
# entity is a member of one of those groups.
|
||||||
|
# - This avoids the limitation of group-state triggers, which would not retrigger
|
||||||
|
# if the group was already active from an earlier sensor.
|
||||||
|
#
|
||||||
|
# TO ADD MORE TRIGGERS LATER:
|
||||||
|
# - Add more binary sensors under:
|
||||||
|
# group.entrance_spot_person_detection_binary_sensors
|
||||||
|
# - Add more device trackers under:
|
||||||
|
# group.entrance_spot_person_detection_device_trackers
|
||||||
|
#
|
||||||
|
# DEVICE TRACKER NOTE:
|
||||||
|
# - Device trackers often indicate presence using the state "home".
|
||||||
|
# - If a tracker uses a different detected/present state, change the
|
||||||
|
# tracker_active_state value below.
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
|
group:
|
||||||
|
entrance_spot_person_detection_binary_sensors:
|
||||||
|
name: Entrance Spot Person Detection Binary Sensors
|
||||||
|
entities:
|
||||||
|
#- binary_sensor.esp_entmulti_outside_entrance_multisensor_moving_target
|
||||||
|
- binary_sensor.view_road_front_door_visitor
|
||||||
|
#- binary_sensor.view_road_front_door_motion
|
||||||
|
- binary_sensor.view_road_front_door_person
|
||||||
|
|
||||||
|
entrance_spot_person_detection_device_trackers:
|
||||||
|
name: Entrance Spot Person Detection Device Trackers
|
||||||
|
entities:
|
||||||
|
- device_tracker.byd_atto3_ibeacon_bur4c2a_bermuda_tracker
|
||||||
|
|
||||||
|
input_number:
|
||||||
|
entrance_spot_person_detection_saved_ramp:
|
||||||
|
name: Entrance Spot Person Detection Saved Ramp
|
||||||
|
min: 0
|
||||||
|
max: 720
|
||||||
|
step: 1
|
||||||
|
mode: box
|
||||||
|
icon: mdi:timer-cog
|
||||||
|
|
||||||
|
input_boolean:
|
||||||
|
entrance_spot_person_detection_ramp_saved:
|
||||||
|
name: Entrance Spot Person Detection Ramp Saved
|
||||||
|
icon: mdi:content-save-check
|
||||||
|
|
||||||
|
automation:
|
||||||
|
- alias: Entrance Spot Person Detection
|
||||||
|
id: entrance_spot_person_detection
|
||||||
|
description: >
|
||||||
|
Turn on the front entranceway doorbell illumination when a configured binary
|
||||||
|
sensor or device tracker activates. Temporarily force the ramp to 1 second,
|
||||||
|
then restore the previous ramp setting after the sequence completes.
|
||||||
|
mode: restart
|
||||||
|
trigger:
|
||||||
|
# Listen for all entity state changes, then filter below so we only respond
|
||||||
|
# to configured sensors/trackers becoming active.
|
||||||
|
- platform: event
|
||||||
|
event_type: state_changed
|
||||||
|
|
||||||
|
variables:
|
||||||
|
# Easy-edit entities.
|
||||||
|
light_switch_entity: switch.front_entranceway_led_light_controls_doorbell_illumination
|
||||||
|
ramp_number_entity: number.front_entranceway_led_light_controls_doorbell_illumination_ramp
|
||||||
|
|
||||||
|
# Easy-edit groups.
|
||||||
|
binary_sensor_group_entity: group.entrance_spot_person_detection_binary_sensors
|
||||||
|
device_tracker_group_entity: group.entrance_spot_person_detection_device_trackers
|
||||||
|
|
||||||
|
# Easy-edit active states.
|
||||||
|
binary_sensor_active_state: "on"
|
||||||
|
tracker_active_state: "home"
|
||||||
|
|
||||||
|
# State-change details from the event trigger.
|
||||||
|
changed_entity_id: "{{ trigger.event.data.entity_id if trigger.event.data is defined else none }}"
|
||||||
|
old_state_value: >
|
||||||
|
{{ trigger.event.data.old_state.state if trigger.event.data.old_state is not none else none }}
|
||||||
|
new_state_value: >
|
||||||
|
{{ trigger.event.data.new_state.state if trigger.event.data.new_state is not none else none }}
|
||||||
|
|
||||||
|
# Members of the configured groups.
|
||||||
|
binary_sensor_entities: >
|
||||||
|
{{ state_attr(binary_sensor_group_entity, 'entity_id') | default([], true) }}
|
||||||
|
device_tracker_entities: >
|
||||||
|
{{ state_attr(device_tracker_group_entity, 'entity_id') | default([], true) }}
|
||||||
|
|
||||||
|
# Trigger logic.
|
||||||
|
binary_sensor_triggered: >
|
||||||
|
{{
|
||||||
|
changed_entity_id in binary_sensor_entities
|
||||||
|
and old_state_value != binary_sensor_active_state
|
||||||
|
and new_state_value == binary_sensor_active_state
|
||||||
|
}}
|
||||||
|
|
||||||
|
device_tracker_triggered: >
|
||||||
|
{{
|
||||||
|
changed_entity_id in device_tracker_entities
|
||||||
|
and old_state_value != tracker_active_state
|
||||||
|
and new_state_value == tracker_active_state
|
||||||
|
}}
|
||||||
|
|
||||||
|
condition:
|
||||||
|
# Only continue if the changed entity is one of our configured trigger entities
|
||||||
|
# and it has transitioned into its active/detected state.
|
||||||
|
- condition: template
|
||||||
|
value_template: >
|
||||||
|
{{ binary_sensor_triggered or device_tracker_triggered }}
|
||||||
|
|
||||||
|
action:
|
||||||
|
# Save the original ramp value only once per active detection cycle.
|
||||||
|
# Because the automation uses restart mode, repeated triggers will restart
|
||||||
|
# the sequence without overwriting the original saved ramp value.
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.entrance_spot_person_detection_ramp_saved
|
||||||
|
state: "off"
|
||||||
|
sequence:
|
||||||
|
- service: input_number.set_value
|
||||||
|
target:
|
||||||
|
entity_id: input_number.entrance_spot_person_detection_saved_ramp
|
||||||
|
data:
|
||||||
|
value: >
|
||||||
|
{{ states(ramp_number_entity) | float(1) }}
|
||||||
|
|
||||||
|
- service: input_boolean.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: input_boolean.entrance_spot_person_detection_ramp_saved
|
||||||
|
|
||||||
|
# Force the illumination ramp to 1 second for a fast response.
|
||||||
|
- service: number.set_value
|
||||||
|
target:
|
||||||
|
entity_id: "{{ ramp_number_entity }}"
|
||||||
|
data:
|
||||||
|
value: 5
|
||||||
|
|
||||||
|
# Turn on the entrance illumination.
|
||||||
|
# The controlled device/light logic is expected to turn itself off later.
|
||||||
|
- service: switch.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: "{{ light_switch_entity }}"
|
||||||
|
|
||||||
|
# Hold briefly, then restore the ramp once activity has stopped retriggering
|
||||||
|
# the automation for this cycle.
|
||||||
|
- delay: "00:00:03"
|
||||||
|
|
||||||
|
# Restore the original ramp value that was active before detection.
|
||||||
|
- service: number.set_value
|
||||||
|
target:
|
||||||
|
entity_id: "{{ ramp_number_entity }}"
|
||||||
|
data:
|
||||||
|
value: >
|
||||||
|
{{ states('input_number.entrance_spot_person_detection_saved_ramp') | float(1) }}
|
||||||
|
|
||||||
|
# Clear the saved-state flag ready for the next fresh trigger cycle.
|
||||||
|
- service: input_boolean.turn_off
|
||||||
|
target:
|
||||||
|
entity_id: input_boolean.entrance_spot_person_detection_ramp_saved
|
||||||
|
|
||||||
|
# Optional tidy reset of the helper value.
|
||||||
|
- service: input_number.set_value
|
||||||
|
target:
|
||||||
|
entity_id: input_number.entrance_spot_person_detection_saved_ramp
|
||||||
|
data:
|
||||||
|
value: 0
|
||||||
@@ -1,144 +1,546 @@
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
# PACKAGE: OpenHASP Thermostat (MQTT-only, all BUTTON objects)
|
# PACKAGE: OpenHASP Thermostat / Gas Heater Control
|
||||||
# NODE/TOPIC ROOT: hasp/openhasp_1/
|
# NODE/TOPIC ROOT: hasp/openhasp_1/
|
||||||
|
#
|
||||||
|
# PAGE OBJECTS USED
|
||||||
|
# - p1b1 = main temperature display
|
||||||
|
# - p1b2 = alternating Setpoint / Humidity display
|
||||||
|
# - p1b3 = setpoint down
|
||||||
|
# - p1b4 = setpoint up
|
||||||
|
# - p1b5 = heater status text
|
||||||
|
# - p1b6 = heater operation / flame button
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# HELPERS
|
||||||
|
###############################################################################
|
||||||
|
input_boolean:
|
||||||
|
hasp_setpoint_hold_active:
|
||||||
|
name: HASP Setpoint Hold Active
|
||||||
|
initial: false
|
||||||
|
|
||||||
input_number:
|
input_number:
|
||||||
lounge_setpoint:
|
# How long Setpoint and Humidity are each shown before rotating
|
||||||
name: Lounge Setpoint
|
hasp_setpoint_humidity_cycle_seconds:
|
||||||
min: 10
|
name: HASP Setpoint Humidity Cycle Seconds
|
||||||
max: 30
|
min: 1
|
||||||
step: 0.5
|
max: 60
|
||||||
|
step: 1
|
||||||
mode: box
|
mode: box
|
||||||
unit_of_measurement: "℃"
|
unit_of_measurement: s
|
||||||
initial: 21.5
|
initial: 10
|
||||||
|
|
||||||
|
# After the setpoint changes, hold the setpoint screen for this long
|
||||||
|
hasp_setpoint_hold_seconds:
|
||||||
|
name: HASP Setpoint Hold Seconds
|
||||||
|
min: 1
|
||||||
|
max: 60
|
||||||
|
step: 1
|
||||||
|
mode: box
|
||||||
|
unit_of_measurement: s
|
||||||
|
initial: 15
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# MQTT ENTITIES
|
||||||
|
###############################################################################
|
||||||
|
mqtt:
|
||||||
|
sensor:
|
||||||
|
- name: "Lounge Environment Humidity MQTT"
|
||||||
|
unique_id: "lounge_environment_humidity_mqtt"
|
||||||
|
state_topic: "viewroad-status/lounge-environment/humidity"
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# AUTOMATIONS
|
# AUTOMATIONS
|
||||||
###############################################################################
|
###############################################################################
|
||||||
automation:
|
automation:
|
||||||
# --- PUSH LABEL TEXTS (on buttons) ----------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
# Main temperature display
|
||||||
|
# - Shows normal lounge temperature
|
||||||
|
# - If heater test mode is ON, shows the test temperature instead
|
||||||
|
# - Normalises values so we do not get duplicated °C or long float strings
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
- id: hasp_temp_to_btn_text
|
- id: hasp_temp_to_btn_text
|
||||||
alias: "HASP: update temp (p1b1.text)"
|
alias: "HASP: update temp (p1b1.text)"
|
||||||
mode: queued
|
mode: queued
|
||||||
trigger:
|
trigger:
|
||||||
- platform: state
|
- platform: state
|
||||||
entity_id: sensor.lounge_environment_lounge_environment_temperature
|
entity_id:
|
||||||
|
- sensor.lounge_environment_lounge_environment_temperature
|
||||||
|
- switch.rinnai_neo_gas_heater_rinnai_neo_gas_heater_test_mode
|
||||||
|
- sensor.rinnai_neo_gas_heater_rinnai_neo_gas_heater_test_mode_temp
|
||||||
action:
|
action:
|
||||||
- service: mqtt.publish
|
- service: mqtt.publish
|
||||||
data:
|
data:
|
||||||
topic: "hasp/openhasp_1/command/p1b1.text"
|
topic: "hasp/openhasp_1/command/p1b1.text"
|
||||||
payload: "{{ states('sensor.lounge_environment_lounge_environment_temperature')|float(0)|round(1) }} °C"
|
payload: >
|
||||||
|
{% if is_state('switch.rinnai_neo_gas_heater_rinnai_neo_gas_heater_test_mode', 'on') %}
|
||||||
- id: hasp_setpoint_to_btn_text
|
{% set raw = states('sensor.rinnai_neo_gas_heater_rinnai_neo_gas_heater_test_mode_temp') %}
|
||||||
alias: "HASP: update setpoint (p1b2.text)"
|
{% else %}
|
||||||
mode: queued
|
{% set raw = states('sensor.lounge_environment_lounge_environment_temperature') %}
|
||||||
trigger:
|
{% endif %}
|
||||||
- platform: state
|
{% set cleaned = raw
|
||||||
entity_id: input_number.lounge_setpoint
|
| replace('°C', '')
|
||||||
action:
|
| replace('° C', '')
|
||||||
- service: mqtt.publish
|
| replace('C', '')
|
||||||
data:
|
| trim %}
|
||||||
topic: "hasp/openhasp_1/command/p1b2.text"
|
{% if cleaned not in ['unknown', 'unavailable', '', 'none', 'None'] %}
|
||||||
payload: "Set: {{ states('input_number.lounge_setpoint')|float(0)|round(1) }} °C"
|
{{ cleaned | float(0) | round(1) }} °C
|
||||||
qos: 1
|
{% else %}
|
||||||
retain: true
|
-- °C
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# Heater status text at bottom of screen
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
- id: hasp_heater_status_to_btn_text
|
- id: hasp_heater_status_to_btn_text
|
||||||
alias: "HASP: update heater status (p1b5.text)"
|
alias: "HASP: update heater status (p1b5.text)"
|
||||||
mode: queued
|
mode: queued
|
||||||
trigger:
|
trigger:
|
||||||
- platform: state
|
- platform: state
|
||||||
entity_id: switch.lounge_heater
|
entity_id: sensor.rinnai_neo_gas_heater_rinnai_neo_gas_heater_status_text
|
||||||
action:
|
action:
|
||||||
- service: mqtt.publish
|
- service: mqtt.publish
|
||||||
data:
|
data:
|
||||||
topic: "hasp/openhasp_1/command/p1b5.text"
|
topic: "hasp/openhasp_1/command/p1b5.text"
|
||||||
payload: >
|
payload: >
|
||||||
{% if is_state('sensor.gas_heater_operating','ON') %}
|
{% set s = states('sensor.rinnai_neo_gas_heater_rinnai_neo_gas_heater_status_text') %}
|
||||||
HEAT ON
|
{{ s if s not in ['unknown', 'unavailable', ''] else 'HEATER --' }}
|
||||||
{% else %}
|
|
||||||
HEAT OFF
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
# --- BUTTON HANDLING FROM THE PLATE (listens on /state/) ------------------
|
# -------------------------------------------------------------------------
|
||||||
- id: hasp_btn_up_increment
|
# When setpoint changes:
|
||||||
alias: "HASP: p1b3 up -> increment setpoint"
|
# - immediately show Setpoint
|
||||||
|
# - hold it for hold_seconds
|
||||||
|
# - then allow normal Setpoint/Humidity rotation again
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
- id: hasp_setpoint_changed_hold_display
|
||||||
|
alias: "HASP: show setpoint immediately and hold"
|
||||||
|
mode: restart
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id: sensor.rinnai_neo_gas_heater_setpoint_text
|
||||||
|
action:
|
||||||
|
- service: input_boolean.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: input_boolean.hasp_setpoint_hold_active
|
||||||
|
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b2.text"
|
||||||
|
payload: >
|
||||||
|
{% set s = states('sensor.rinnai_neo_gas_heater_setpoint_text') %}
|
||||||
|
{{ 'Setpoint: ' ~ (s if s not in ['unknown', 'unavailable', ''] else '--') }}
|
||||||
|
|
||||||
|
- delay:
|
||||||
|
seconds: "{{ states('input_number.hasp_setpoint_hold_seconds') | int(15) }}"
|
||||||
|
|
||||||
|
- service: input_boolean.turn_off
|
||||||
|
target:
|
||||||
|
entity_id: input_boolean.hasp_setpoint_hold_active
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# Up / Down buttons on the HASP plate
|
||||||
|
# These call the existing HA button entities
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
- id: hasp_btn_up_press
|
||||||
|
alias: "HASP: p1b4 up -> heater setpoint UP"
|
||||||
mode: queued
|
mode: queued
|
||||||
trigger:
|
trigger:
|
||||||
- platform: mqtt
|
- platform: mqtt
|
||||||
topic: "hasp/openhasp_1/state/p1b4"
|
topic: "hasp/openhasp_1/state/p1b4"
|
||||||
condition:
|
condition:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ trigger.payload_json.event|default('') == 'up' }}"
|
value_template: "{{ trigger.payload_json.event | default('') == 'up' }}"
|
||||||
action:
|
action:
|
||||||
- service: input_number.increment
|
- service: button.press
|
||||||
target:
|
target:
|
||||||
entity_id: input_number.lounge_setpoint
|
entity_id: button.rinnai_neo_gas_heater_rinnai_neo_gas_heater_setpoint_up
|
||||||
|
|
||||||
- id: hasp_btn_down_decrement
|
- id: hasp_btn_down_press
|
||||||
alias: "HASP: p1b4 up -> decrement setpoint"
|
alias: "HASP: p1b3 up -> heater setpoint DOWN"
|
||||||
mode: queued
|
mode: queued
|
||||||
trigger:
|
trigger:
|
||||||
- platform: mqtt
|
- platform: mqtt
|
||||||
topic: "hasp/openhasp_1/state/p1b3"
|
topic: "hasp/openhasp_1/state/p1b3"
|
||||||
condition:
|
condition:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ trigger.payload_json.event|default('') == 'up' }}"
|
value_template: "{{ trigger.payload_json.event | default('') == 'up' }}"
|
||||||
action:
|
action:
|
||||||
- service: input_number.decrement
|
- service: button.press
|
||||||
target:
|
target:
|
||||||
entity_id: input_number.lounge_setpoint
|
entity_id: button.rinnai_neo_gas_heater_rinnai_neo_gas_heater_setpoint_down
|
||||||
|
|
||||||
# --- PUSH INITIAL VALUES ON HA START / PANEL ONLINE -----------------------
|
# -------------------------------------------------------------------------
|
||||||
- id: hasp_push_on_ha_start
|
# Middle flame button
|
||||||
alias: "HASP: push texts on HA start"
|
# - Tap toggles heater operation
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
- id: hasp_btn_heat_toggle
|
||||||
|
alias: "HASP: p1b6 up -> heater operation toggle"
|
||||||
mode: queued
|
mode: queued
|
||||||
|
trigger:
|
||||||
|
- platform: mqtt
|
||||||
|
topic: "hasp/openhasp_1/state/p1b6"
|
||||||
|
condition:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ trigger.payload_json.event | default('') == 'up' }}"
|
||||||
|
action:
|
||||||
|
- service: switch.toggle
|
||||||
|
target:
|
||||||
|
entity_id: switch.rinnai_neo_gas_heater_heater_operation
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# Flame button appearance
|
||||||
|
# - Operation OFF: solid light grey background, white flame
|
||||||
|
# - Operation ON, flame OFF: solid dark background, white flame
|
||||||
|
# - Operation ON, flame ON: solid dark background, continuous red/orange flicker
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
- id: hasp_heat_button_state
|
||||||
|
alias: "HASP: update heat button state (p1b6)"
|
||||||
|
mode: restart
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id:
|
||||||
|
- switch.rinnai_neo_gas_heater_heater_operation
|
||||||
|
- switch.rinnai_neo_gas_heater_rinnai_neo_gas_heater_power
|
||||||
|
action:
|
||||||
|
- choose:
|
||||||
|
# OFF → dark grey (same as your other inactive buttons)
|
||||||
|
- conditions:
|
||||||
|
- condition: state
|
||||||
|
entity_id: switch.rinnai_neo_gas_heater_heater_operation
|
||||||
|
state: "off"
|
||||||
|
sequence:
|
||||||
|
- service: script.turn_off
|
||||||
|
target:
|
||||||
|
entity_id: script.hasp_heat_flame_flicker
|
||||||
|
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.text"
|
||||||
|
payload: "\uE238"
|
||||||
|
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.text_color"
|
||||||
|
payload: "#FFFFFF"
|
||||||
|
|
||||||
|
# solid dark grey (no gradient)
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.bg_color"
|
||||||
|
payload: "#2F3240"
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.bg_grad_color"
|
||||||
|
payload: "#2F3240"
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.border_color"
|
||||||
|
payload: "#2F3240"
|
||||||
|
|
||||||
|
# ON (not firing) → theme blue
|
||||||
|
- conditions:
|
||||||
|
- condition: state
|
||||||
|
entity_id: switch.rinnai_neo_gas_heater_heater_operation
|
||||||
|
state: "on"
|
||||||
|
- condition: state
|
||||||
|
entity_id: switch.rinnai_neo_gas_heater_rinnai_neo_gas_heater_power
|
||||||
|
state: "off"
|
||||||
|
sequence:
|
||||||
|
- service: script.turn_off
|
||||||
|
target:
|
||||||
|
entity_id: script.hasp_heat_flame_flicker
|
||||||
|
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.text"
|
||||||
|
payload: "\uE238"
|
||||||
|
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.text_color"
|
||||||
|
payload: "#FFFFFF"
|
||||||
|
|
||||||
|
# MATCH THEME BLUE
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.bg_color"
|
||||||
|
payload: "#0095D9"
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.bg_grad_color"
|
||||||
|
payload: "#00B6FF"
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.border_color"
|
||||||
|
payload: "#0095D9"
|
||||||
|
|
||||||
|
# ON + flame → blue background + flicker
|
||||||
|
- conditions:
|
||||||
|
- condition: state
|
||||||
|
entity_id: switch.rinnai_neo_gas_heater_heater_operation
|
||||||
|
state: "on"
|
||||||
|
- condition: state
|
||||||
|
entity_id: switch.rinnai_neo_gas_heater_rinnai_neo_gas_heater_power
|
||||||
|
state: "on"
|
||||||
|
sequence:
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.text"
|
||||||
|
payload: "\uE238"
|
||||||
|
|
||||||
|
# keep blue background
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.bg_color"
|
||||||
|
payload: "#0095D9"
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.bg_grad_color"
|
||||||
|
payload: "#00B6FF"
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.border_color"
|
||||||
|
payload: "#0095D9"
|
||||||
|
|
||||||
|
- service: script.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: script.hasp_heat_flame_flicker
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# Start / restart display when HA starts
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
- id: hasp_start_on_ha_start
|
||||||
|
alias: "HASP: start display loop on HA start"
|
||||||
trigger:
|
trigger:
|
||||||
- platform: homeassistant
|
- platform: homeassistant
|
||||||
event: start
|
event: start
|
||||||
action:
|
action:
|
||||||
- service: script.hasp_push_all_texts
|
- service: script.hasp_push_static_texts
|
||||||
|
- service: script.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: script.hasp_rotate_setpoint_humidity
|
||||||
|
|
||||||
- id: hasp_push_on_panel_online
|
# -------------------------------------------------------------------------
|
||||||
alias: "HASP: push texts when panel goes online"
|
# Re-push screen state when panel comes online
|
||||||
mode: queued
|
# -------------------------------------------------------------------------
|
||||||
|
- id: hasp_start_on_panel_online
|
||||||
|
alias: "HASP: start display loop when panel goes online"
|
||||||
trigger:
|
trigger:
|
||||||
- platform: mqtt
|
- platform: mqtt
|
||||||
topic: "hasp/openhasp_1/status"
|
topic: "hasp/openhasp_1/LWT"
|
||||||
condition:
|
condition:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ trigger.payload == 'online' }}"
|
value_template: "{{ trigger.payload == 'online' }}"
|
||||||
action:
|
action:
|
||||||
- delay: "00:00:05"
|
- delay: "00:00:05"
|
||||||
- service: script.hasp_push_all_texts
|
- service: script.hasp_push_static_texts
|
||||||
|
- service: script.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: script.hasp_rotate_setpoint_humidity
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# SCRIPT: Push all texts to buttons
|
# SCRIPTS
|
||||||
###############################################################################
|
###############################################################################
|
||||||
script:
|
script:
|
||||||
hasp_push_all_texts:
|
# -------------------------------------------------------------------------
|
||||||
alias: "HASP: push all texts"
|
# Push all current values / colours to the panel
|
||||||
|
# Useful on HA startup and panel reconnect
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
hasp_push_static_texts:
|
||||||
|
alias: "HASP: push static texts"
|
||||||
mode: queued
|
mode: queued
|
||||||
sequence:
|
sequence:
|
||||||
- service: mqtt.publish
|
- service: mqtt.publish
|
||||||
data:
|
data:
|
||||||
topic: "hasp/openhasp_1/command/p1b1.text"
|
topic: "hasp/openhasp_1/command/p1b1.text"
|
||||||
payload: "{{ states('sensor.lounge_environment_lounge_environment_temperature')|float(0)|round(1) }} °C"
|
payload: >
|
||||||
|
{% if is_state('switch.rinnai_neo_gas_heater_rinnai_neo_gas_heater_test_mode', 'on') %}
|
||||||
- service: mqtt.publish
|
{% set raw = states('sensor.rinnai_neo_gas_heater_rinnai_neo_gas_heater_test_mode_temp') %}
|
||||||
data:
|
{% else %}
|
||||||
topic: "hasp/openhasp_1/command/p1b2.text"
|
{% set raw = states('sensor.lounge_environment_lounge_environment_temperature') %}
|
||||||
payload: "Set: {{ states('input_number.lounge_setpoint')|float(0)|round(1) }} °C"
|
{% endif %}
|
||||||
qos: 1
|
{% set cleaned = raw
|
||||||
retain: true
|
| replace('°C', '')
|
||||||
|
| replace('° C', '')
|
||||||
|
| replace('C', '')
|
||||||
|
| trim %}
|
||||||
|
{% if cleaned not in ['unknown', 'unavailable', '', 'none', 'None'] %}
|
||||||
|
{{ cleaned | float(0) | round(1) }} °C
|
||||||
|
{% else %}
|
||||||
|
-- °C
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
- service: mqtt.publish
|
- service: mqtt.publish
|
||||||
data:
|
data:
|
||||||
topic: "hasp/openhasp_1/command/p1b5.text"
|
topic: "hasp/openhasp_1/command/p1b5.text"
|
||||||
payload: >
|
payload: >
|
||||||
{% if is_state('sensor.gas_heater_operating','ON') %}
|
{% set s = states('sensor.rinnai_neo_gas_heater_rinnai_neo_gas_heater_status_text') %}
|
||||||
HEAT ON
|
{{ s if s not in ['unknown', 'unavailable', ''] else 'HEATER --' }}
|
||||||
{% else %}
|
|
||||||
HEAT OFF
|
- service: mqtt.publish
|
||||||
{% endif %}
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b2.text"
|
||||||
|
payload: >
|
||||||
|
{% set s = states('sensor.rinnai_neo_gas_heater_setpoint_text') %}
|
||||||
|
{{ 'Setpoint: ' ~ (s if s not in ['unknown', 'unavailable', ''] else '--') }}
|
||||||
|
|
||||||
|
# Push middle flame button state
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.text"
|
||||||
|
payload: "\uE238"
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: state
|
||||||
|
entity_id: switch.rinnai_neo_gas_heater_heater_operation
|
||||||
|
state: "off"
|
||||||
|
sequence:
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.text_color"
|
||||||
|
payload: "#FFFFFF"
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.bg_color"
|
||||||
|
payload: "#2F3240"
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.bg_grad_color"
|
||||||
|
payload: "#2F3240"
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.border_color"
|
||||||
|
payload: "#2F3240"
|
||||||
|
|
||||||
|
- conditions:
|
||||||
|
- condition: state
|
||||||
|
entity_id: switch.rinnai_neo_gas_heater_heater_operation
|
||||||
|
state: "on"
|
||||||
|
- condition: state
|
||||||
|
entity_id: switch.rinnai_neo_gas_heater_rinnai_neo_gas_heater_power
|
||||||
|
state: "off"
|
||||||
|
sequence:
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.text_color"
|
||||||
|
payload: "#FFFFFF"
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.bg_color"
|
||||||
|
payload: "#0095D9"
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.bg_grad_color"
|
||||||
|
payload: "#00B6FF"
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.border_color"
|
||||||
|
payload: "#0095D9"
|
||||||
|
|
||||||
|
- conditions:
|
||||||
|
- condition: state
|
||||||
|
entity_id: switch.rinnai_neo_gas_heater_heater_operation
|
||||||
|
state: "on"
|
||||||
|
- condition: state
|
||||||
|
entity_id: switch.rinnai_neo_gas_heater_rinnai_neo_gas_heater_power
|
||||||
|
state: "on"
|
||||||
|
sequence:
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.bg_color"
|
||||||
|
payload: "#0095D9"
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.bg_grad_color"
|
||||||
|
payload: "#00B6FF"
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.border_color"
|
||||||
|
payload: "#0095D9"
|
||||||
|
- service: script.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: script.hasp_heat_flame_flicker
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# Rotate the middle information line between Setpoint and Humidity
|
||||||
|
# Pauses humidity display while the setpoint hold flag is active
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
hasp_rotate_setpoint_humidity:
|
||||||
|
alias: "HASP: rotate setpoint and humidity"
|
||||||
|
mode: restart
|
||||||
|
sequence:
|
||||||
|
- repeat:
|
||||||
|
while:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ true }}"
|
||||||
|
sequence:
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b2.text"
|
||||||
|
payload: >
|
||||||
|
{% set s = states('sensor.rinnai_neo_gas_heater_setpoint_text') %}
|
||||||
|
{{ 'Setpoint: ' ~ (s if s not in ['unknown', 'unavailable', ''] else '--') }}
|
||||||
|
|
||||||
|
- delay:
|
||||||
|
seconds: "{{ states('input_number.hasp_setpoint_humidity_cycle_seconds') | int(10) }}"
|
||||||
|
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.hasp_setpoint_hold_active
|
||||||
|
state: "off"
|
||||||
|
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b2.text"
|
||||||
|
payload: >
|
||||||
|
{% set h = states('sensor.lounge_environment_humidity_mqtt') %}
|
||||||
|
{% if h in ['unknown', 'unavailable', ''] %}
|
||||||
|
Humidity: Unknown
|
||||||
|
{% else %}
|
||||||
|
Humidity: {{ h }}%
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
- delay:
|
||||||
|
seconds: "{{ states('input_number.hasp_setpoint_humidity_cycle_seconds') | int(10) }}"
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# Continuous flame flicker while heater operation is ON and flame/power is ON
|
||||||
|
# Only the icon colour flickers. Background stays fixed.
|
||||||
|
# Flicker colours are red <-> orange
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
hasp_heat_flame_flicker:
|
||||||
|
alias: "HASP: heat flame flicker"
|
||||||
|
mode: restart
|
||||||
|
sequence:
|
||||||
|
- repeat:
|
||||||
|
while:
|
||||||
|
- condition: state
|
||||||
|
entity_id: switch.rinnai_neo_gas_heater_heater_operation
|
||||||
|
state: "on"
|
||||||
|
- condition: state
|
||||||
|
entity_id: switch.rinnai_neo_gas_heater_rinnai_neo_gas_heater_power
|
||||||
|
state: "on"
|
||||||
|
sequence:
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.text_color"
|
||||||
|
payload: "#FF3030"
|
||||||
|
- delay: "00:00:00.35"
|
||||||
|
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.text_color"
|
||||||
|
payload: "#FF8C00"
|
||||||
|
- delay: "00:00:00.20"
|
||||||
|
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.text_color"
|
||||||
|
payload: "#FF5A36"
|
||||||
|
- delay: "00:00:00.30"
|
||||||
|
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "hasp/openhasp_1/command/p1b6.text_color"
|
||||||
|
payload: "#FFA500"
|
||||||
|
- delay: "00:00:00.18"
|
||||||
|
|||||||
@@ -1,98 +0,0 @@
|
|||||||
# ESPresence Sensing
|
|
||||||
# https://espresense.com/home_assistant
|
|
||||||
#
|
|
||||||
|
|
||||||
# In the secrets.yaml file you want something like this to match each one.
|
|
||||||
# Obviously you don't need to use secrets, but it helps if you are sharing your
|
|
||||||
# home assistant config with others.
|
|
||||||
#
|
|
||||||
# btb09_uID: My_tracked_item_name_(ID)"
|
|
||||||
# btb09_dID: "known:xxxxxxxxxxxx"
|
|
||||||
# btb09_name: "My Tracked Item Name (ID)"
|
|
||||||
# btb09_topic: espresense/devices/known:xxxxxxxxxxxx
|
|
||||||
|
|
||||||
sensor:
|
|
||||||
- platform: mqtt_room
|
|
||||||
unique_id: !secret btb01_uID
|
|
||||||
device_id: !secret btb01_dID
|
|
||||||
name: !secret btb01_name
|
|
||||||
state_topic: !secret btb01_topic
|
|
||||||
timeout: 60
|
|
||||||
away_timeout: 120 # number of seconds after which the enitity will get status not_home
|
|
||||||
- platform: mqtt_room
|
|
||||||
unique_id: !secret btb02_uID
|
|
||||||
device_id: !secret btb02_dID
|
|
||||||
name: !secret btb02_name
|
|
||||||
state_topic: !secret btb02_topic
|
|
||||||
timeout: 60
|
|
||||||
away_timeout: 120 # number of seconds after which the enitity will get status not_home
|
|
||||||
- platform: mqtt_room
|
|
||||||
unique_id: !secret btb03_uID
|
|
||||||
device_id: !secret btb03_dID
|
|
||||||
name: !secret btb03_name
|
|
||||||
state_topic: !secret btb03_topic
|
|
||||||
timeout: 60
|
|
||||||
away_timeout: 120 # number of seconds after which the enitity will get status not_home
|
|
||||||
- platform: mqtt_room
|
|
||||||
unique_id: !secret btb04_uID
|
|
||||||
device_id: !secret btb04_dID
|
|
||||||
name: !secret btb04_name
|
|
||||||
state_topic: !secret btb04_topic
|
|
||||||
timeout: 60
|
|
||||||
away_timeout: 120 # number of seconds after which the enitity will get status not_home
|
|
||||||
- platform: mqtt_room
|
|
||||||
unique_id: !secret btb05_uID
|
|
||||||
device_id: !secret btb05_dID
|
|
||||||
name: !secret btb05_name
|
|
||||||
state_topic: !secret btb05_topic
|
|
||||||
timeout: 60
|
|
||||||
away_timeout: 120 # number of seconds after which the enitity will get status not_home
|
|
||||||
- platform: mqtt_room
|
|
||||||
unique_id: !secret btb06_uID
|
|
||||||
device_id: !secret btb06_dID
|
|
||||||
name: !secret btb06_name
|
|
||||||
state_topic: !secret btb06_topic
|
|
||||||
timeout: 60
|
|
||||||
away_timeout: 120 # number of seconds after which the enitity will get status not_home
|
|
||||||
- platform: mqtt_room
|
|
||||||
unique_id: !secret btb07_uID
|
|
||||||
device_id: !secret btb07_dID
|
|
||||||
name: !secret btb07_name
|
|
||||||
state_topic: !secret btb07_topic
|
|
||||||
timeout: 60
|
|
||||||
away_timeout: 120 # number of seconds after which the enitity will get status not_home
|
|
||||||
- platform: mqtt_room
|
|
||||||
unique_id: !secret btb08_uID
|
|
||||||
device_id: !secret btb08_dID
|
|
||||||
name: !secret btb08_name
|
|
||||||
state_topic: !secret btb08_topic
|
|
||||||
timeout: 60
|
|
||||||
away_timeout: 120 # number of seconds after which the enitity will get status not_home
|
|
||||||
- platform: mqtt_room
|
|
||||||
unique_id: !secret btb09_uID
|
|
||||||
device_id: !secret btb09_dID
|
|
||||||
name: !secret btb09_name
|
|
||||||
state_topic: !secret btb09_topic
|
|
||||||
timeout: 60
|
|
||||||
away_timeout: 120 # number of seconds after which the enitity will get status not_home
|
|
||||||
- platform: mqtt_room
|
|
||||||
unique_id: !secret btb10_uID
|
|
||||||
device_id: !secret btb10_dID
|
|
||||||
name: !secret btb10_name
|
|
||||||
state_topic: !secret btb10_topic
|
|
||||||
timeout: 60
|
|
||||||
away_timeout: 120 # number of seconds after which the enitity will get status not_home
|
|
||||||
- platform: mqtt_room
|
|
||||||
unique_id: !secret btb11_uID
|
|
||||||
device_id: !secret btb11_dID
|
|
||||||
name: !secret btb11_name
|
|
||||||
state_topic: !secret btb11_topic
|
|
||||||
timeout: 60
|
|
||||||
away_timeout: 120 # number of seconds after which the enitity will get status not_home
|
|
||||||
- platform: mqtt_room
|
|
||||||
unique_id: !secret btb12_uID
|
|
||||||
device_id: !secret btb12_dID
|
|
||||||
name: !secret btb12_name
|
|
||||||
state_topic: !secret btb12_topic
|
|
||||||
timeout: 60
|
|
||||||
away_timeout: 120 # number of seconds after which the enitity will get status not_home
|
|
||||||