more esphome devices and fixes

This commit is contained in:
root
2026-04-03 21:34:23 +13:00
parent e09931360a
commit f7bfa78835
96 changed files with 4870 additions and 2523 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 612 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

+1 -1
View File
@@ -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}
+9 -9
View File
@@ -6,9 +6,10 @@
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-entrancebathrmlights.yaml
#:########################################################################################:#
# VERSIONS:
# v3.8 2026-02-25 Updated yaml to zorruno layout V1.1
# v3.7 2025-09-34 Upload to this bathroom (as noted in original header)
# v3.5 2025-07-24 YAML tidyups
# V3.9 2026-03-11 Updated yaml to zorruno layout V1.1
# V3.8 2026-02-25 Updated yaml to zorruno layout V1.1
# V3.7 2025-09-34 Upload to this bathroom (as noted in original header)
# V3.5 2025-07-24 YAML tidyups
#:########################################################################################:#
# HARDWARE:
# - Zemismart KS-811 Double push button (ESP8266)
@@ -33,7 +34,6 @@
# - Accurate time is NOT needed (SNTP not needed).
#:########################################################################################:#
#:########################################################################################:#
# SUBSTITUTIONS: Specific device variable substitutions
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
@@ -47,7 +47,7 @@ substitutions:
# Project Naming
project_name: "Zemismart Technologies.KS-811 Double"
project_version: "v3.8"
project_version: "v3.9"
# Passwords & Secrets
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
@@ -144,7 +144,7 @@ logger:
status_led:
pin:
number: GPIO2
inverted: yes
inverted: true
#:########################################################################################:#
# BINARY SENSORS
@@ -155,7 +155,7 @@ binary_sensor:
pin:
number: GPIO16
mode: INPUT
inverted: True
inverted: true
use_interrupt: false # GPIO16 pin doesn't support interrupts so use polling. Only suppresses a warning.
name: "Button 1: ${switch_1_name}"
on_press:
@@ -163,9 +163,9 @@ binary_sensor:
- platform: gpio
pin:
number: GPIO05
number: GPIO5
mode: INPUT
inverted: True
inverted: true
name: "Button 2: ${switch_2_name}"
on_press:
- switch.toggle: Relay_2
+310 -82
View File
@@ -1,14 +1,19 @@
##########################################################################################
##########################################################################################
# FRONT ENTRANCEWAY LED LIGHT CONTROLS
# File: esp-entranceoutsideledlights.yaml
#
# v1.0 - 2026-02-23 Initial version (converted from Tasmota)
#
# Hardware: H801 (ESP8266EX) 5-channel PWM MOSFET LED controller
#
###########################################################################################
# NOTES
#:########################################################################################:#
# TITLE: FRONT ENTRANCEWAY LED LIGHT CONTROLS
# zorruno.com layout v1.1 2026
#:########################################################################################:#
# REPO:
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-entranceoutsideledlights.yaml
#:########################################################################################:#
# 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
# 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):
# PWM1 / R -> GPIO15
# PWM2 / G -> GPIO13
@@ -23,43 +28,56 @@
# * Brightness slider 0-100% normalized to the per-channel hard limit
# * Ramp time (seconds) for a full 0 -> hard limit transition
# * 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.
#
##########################################################################################
##########################################################################################
#:########################################################################################:#
# 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)
##########################################################################################
#:########################################################################################:#
substitutions:
# Device Naming
device_name: "esp-entranceoutsideledlights"
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.
# Project Naming
project_name: "H801.5CH PWM LED Controller"
project_version: "v1.0"
project_version: "v1.2"
# Passwords & Secrets
api_key: !secret esp-api_key
ota_pass: !secret esp-ota_pass
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
# Don't forget to switch it back when changed.
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
log_level: "INFO" # NONE, ERROR, WARN, INFO, DEBUG, VERBOSE, VERY_VERBOSE
update_interval: "60s"
@@ -68,9 +86,28 @@ substitutions:
out1_name: "Main Entrance Outside LED Lights"
out2_name: "Number 16 LED Light"
out3_name: "Spare 3"
out4_name: "Spare 4"
out4_name: "Doorbell Illumination"
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)
out1_pwm_pin: "GPIO15"
out2_pwm_pin: "GPIO13"
@@ -79,10 +116,11 @@ substitutions:
out5_pwm_pin: "GPIO4"
pwm_frequency: "1000 Hz"
##########################################################################################
#:########################################################################################:#
# PACKAGES: Included Common Packages
# https://esphome.io/components/packages.html
##########################################################################################
#:########################################################################################:#
packages:
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
common_wifi: !include
@@ -115,38 +153,43 @@ packages:
diag_debug: !include common/include_debug_diag_sensors.yaml
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
#############################################
# ESPHome
# https://esphome.io/components/esphome.html
#############################################
esphome:
name: ${device_name}
friendly_name: ${friendly_name}
comment: ${description_comment} # appears on the esphome page in HA
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
#############################################
#:########################################################################################:#
esp8266:
board: esp01_1m
#############################################
# ESPHome Logging Enable
#:########################################################################################:#
# LOGGING:
# https://esphome.io/components/logger.html
#############################################
#:########################################################################################:#
logger:
level: ${log_level}
level: "${log_level}"
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:
- platform: esp8266_pwm
id: out1_pwm
@@ -173,9 +216,11 @@ output:
pin: ${out5_pwm_pin}
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:
- platform: monochromatic
id: out1_light_raw
@@ -212,9 +257,11 @@ light:
internal: true
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:
- id: out1_last_nonzero_pct
type: float
@@ -241,9 +288,11 @@ globals:
restore_value: true
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:
#############################################
# OUT1
@@ -319,6 +368,14 @@ script:
call.set_transition_length(trans_ms);
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
#############################################
@@ -393,6 +450,14 @@ script:
call.set_transition_length(trans_ms);
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
#############################################
@@ -467,6 +532,14 @@ script:
call.set_transition_length(trans_ms);
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
#############################################
@@ -541,6 +614,14 @@ script:
call.set_transition_length(trans_ms);
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
#############################################
@@ -615,9 +696,19 @@ script:
call.set_transition_length(trans_ms);
call.perform();
##########################################################################################
# NUMBERS (brightness normalized to limit, plus per-channel ramp and hard limit)
##########################################################################################
- id: out5_auto_off_timer
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:
#############################################
# OUT1
@@ -632,7 +723,7 @@ number:
max_value: 30.0
step: 0.1
restore_value: true
initial_value: 2.0
initial_value: ${out1_ramp_default_s}
optimistic: true
set_action:
- script.execute: out1_apply_target
@@ -647,11 +738,24 @@ number:
max_value: 100
step: 1
restore_value: true
initial_value: 100
initial_value: ${out1_max_limit_default_pct}
optimistic: true
set_action:
- 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
id: out1_brightness_pct
name: "${out1_name} Brightness"
@@ -667,6 +771,16 @@ number:
- lambda: |-
if (x > 0.0f) id(out1_last_nonzero_pct) = x;
- 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
@@ -681,7 +795,7 @@ number:
max_value: 30.0
step: 0.1
restore_value: true
initial_value: 2.0
initial_value: ${out2_ramp_default_s}
optimistic: true
set_action:
- script.execute: out2_apply_target
@@ -696,11 +810,24 @@ number:
max_value: 100
step: 1
restore_value: true
initial_value: 100
initial_value: ${out2_max_limit_default_pct}
optimistic: true
set_action:
- 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
id: out2_brightness_pct
name: "${out2_name} Brightness"
@@ -716,6 +843,16 @@ number:
- lambda: |-
if (x > 0.0f) id(out2_last_nonzero_pct) = x;
- 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
@@ -730,7 +867,7 @@ number:
max_value: 30.0
step: 0.1
restore_value: true
initial_value: 2.0
initial_value: ${out3_ramp_default_s}
optimistic: true
set_action:
- script.execute: out3_apply_target
@@ -745,11 +882,24 @@ number:
max_value: 100
step: 1
restore_value: true
initial_value: 100
initial_value: ${out3_max_limit_default_pct}
optimistic: true
set_action:
- 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
id: out3_brightness_pct
name: "${out3_name} Brightness"
@@ -765,6 +915,16 @@ number:
- lambda: |-
if (x > 0.0f) id(out3_last_nonzero_pct) = x;
- 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
@@ -779,7 +939,7 @@ number:
max_value: 30.0
step: 0.1
restore_value: true
initial_value: 2.0
initial_value: ${out4_ramp_default_s}
optimistic: true
set_action:
- script.execute: out4_apply_target
@@ -794,11 +954,24 @@ number:
max_value: 100
step: 1
restore_value: true
initial_value: 100
initial_value: ${out4_max_limit_default_pct}
optimistic: true
set_action:
- 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
id: out4_brightness_pct
name: "${out4_name} Brightness"
@@ -814,6 +987,16 @@ number:
- lambda: |-
if (x > 0.0f) id(out4_last_nonzero_pct) = x;
- 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
@@ -828,7 +1011,7 @@ number:
max_value: 30.0
step: 0.1
restore_value: true
initial_value: 2.0
initial_value: ${out5_ramp_default_s}
optimistic: true
set_action:
- script.execute: out5_apply_target
@@ -843,11 +1026,24 @@ number:
max_value: 100
step: 1
restore_value: true
initial_value: 100
initial_value: ${out5_max_limit_default_pct}
optimistic: true
set_action:
- 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
id: out5_brightness_pct
name: "${out5_name} Brightness"
@@ -863,14 +1059,26 @@ number:
- lambda: |-
if (x > 0.0f) id(out5_last_nonzero_pct) = x;
- 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:
- platform: template
id: out1_switch
name: ${out1_name}
name: "${out1_name}"
icon: mdi:lightbulb
lambda: |-
return id(out1_light_raw).current_values.is_on();
@@ -885,12 +1093,16 @@ switch:
value: !lambda "return id(out1_last_nonzero_pct);"
else:
- 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:
- script.stop: out1_auto_off_timer
- script.execute: out1_turn_off
- platform: template
id: out2_switch
name: ${out2_name}
name: "${out2_name}"
icon: mdi:lightbulb
lambda: |-
return id(out2_light_raw).current_values.is_on();
@@ -905,12 +1117,16 @@ switch:
value: !lambda "return id(out2_last_nonzero_pct);"
else:
- 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:
- script.stop: out2_auto_off_timer
- script.execute: out2_turn_off
- platform: template
id: out3_switch
name: ${out3_name}
name: "${out3_name}"
icon: mdi:lightbulb
lambda: |-
return id(out3_light_raw).current_values.is_on();
@@ -925,12 +1141,16 @@ switch:
value: !lambda "return id(out3_last_nonzero_pct);"
else:
- 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:
- script.stop: out3_auto_off_timer
- script.execute: out3_turn_off
- platform: template
id: out4_switch
name: ${out4_name}
name: "${out4_name}"
icon: mdi:lightbulb
lambda: |-
return id(out4_light_raw).current_values.is_on();
@@ -945,12 +1165,16 @@ switch:
value: !lambda "return id(out4_last_nonzero_pct);"
else:
- 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:
- script.stop: out4_auto_off_timer
- script.execute: out4_turn_off
- platform: template
id: out5_switch
name: ${out5_name}
name: "${out5_name}"
icon: mdi:lightbulb
lambda: |-
return id(out5_light_raw).current_values.is_on();
@@ -965,5 +1189,9 @@ switch:
value: !lambda "return id(out5_last_nonzero_pct);"
else:
- 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:
- script.stop: out5_auto_off_timer
- script.execute: out5_turn_off
+84 -73
View File
@@ -1,49 +1,66 @@
#############################################
#############################################
# ESP32 - Garage
# Bluetooth Proxy
#############################################
#############################################
#:########################################################################################:#
# TITLE: GARAGE ENTRANCE BLUETOOTH PROXY
# zorruno.com layout v1.1 2026
#:########################################################################################:#
# 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)
#############################################
#:########################################################################################:#
substitutions:
# Device Naming
device_name: "esp-garagebtproxy"
friendly_name: "Garage Entrance Bluetooth Proxy"
description_comment: "ESP32-WROOM garage entrance with BT Proxy"
device_area: "Garage" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
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.
# Project Naming
project_name: "Zemismart Technologies.KS-811-3 (Triple)" # Project Details
project_version: "v1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
#entity_prefix: "Main Bathroom" # Simple device name where we want to prefix a sensor or switch, eg "Load" Current.
project_name: "ESPHome.Bluetooth Proxy"
project_version: "v1.1"
# 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
#relay_icon: "mdi:heating-coil"
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
log_level: "INFO" # NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
update_interval: "60s" # update time for general sensors etc
#############################################
# SPECIFIC PROJECT VARIABLE SUBSTITUTIONS
#############################################
#
#
##########################################################################################
#:########################################################################################:#
# PACKAGES: Included Common Packages
# https://esphome.io/components/packages.html
##########################################################################################
#:########################################################################################:#
packages:
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
common_wifi: !include
@@ -52,6 +69,7 @@ packages:
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
@@ -65,69 +83,62 @@ packages:
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
common_sntp: !include common/sntp_common.yaml
#### DIAGNOSTICS Sensors ####
diag_basic: !include common/include_basic_diag_sensors.yaml
diag_more: !include common/include_more_diag_sensors.yaml
#diag_debug: !include common/include_debug_diag_sensors.yaml
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
#############################################
# ESPHome
diag_basic: !include common/include_basic_diag_sensors.yaml
diag_more: !include common/include_more_diag_sensors.yaml
#diag_debug: !include common/include_debug_diag_sensors.yaml
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
#:########################################################################################:#
# ESPHOME:
# https://esphome.io/components/esphome.html
#############################################
#:########################################################################################:#
esphome:
name: ${device_name}
friendly_name: ${friendly_name}
comment: ${description_comment} #appears on the esphome page in HA
min_version: 2024.6.0 #
comment: ${description_comment} # appears on the esphome page in HA
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
#############################################
#:########################################################################################:#
esp32:
board: esp32dev
framework:
#type: arduino
type: esp-idf #Suggested Use ESP-IDF Framework, or Plug Out the UART Cable Might Cause ESP32 Hang.
version: recommended #recommended, latest or dev
type: esp-idf
version: recommended
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
#############################################
#:########################################################################################:#
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
level: ${log_level}
#############################################
# Bluetooth
#:########################################################################################:#
# BLUETOOTH:
# https://esphome.io/components/bluetooth_proxy.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:
active: true
esp32_ble_tracker:
scan_parameters:
# We currently use the defaults to ensure Bluetooth
# can co-exist with WiFi In the future we may be able to
# enable the built-in coexistence logic in ESP-IDF
active: true
active: true
+117 -87
View File
@@ -1,54 +1,91 @@
#############################################
#############################################
# GARAGE ENTRY LIGHTSWITCH (OBK Converted, BK7231N)
#:########################################################################################:#
# TITLE: 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
#############################################
# Zemismart KS-811 Triple push button
# pinout/schematic https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
#
# NOTES
# -
#
#############################################
#############################################
#:########################################################################################:#
# HARDWARE:
# - Zemismart KS-811 Triple push button (OBK converted, BK7231N)
# - ESPHome bk72xx: generic-bk7231n-qfn32-tuya
# - 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)
#############################################
#:########################################################################################:#
substitutions:
# Device Naming
device_name: "esp-garageentrylights"
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)"
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
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.
# 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
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
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
log_level: "NONE" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
update_interval: "60s" # update time for for general sensors etc
log_level: "NONE" # NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
update_interval: "60s" # update time 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: "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
# https://esphome.io/components/packages.html
##########################################################################################
#:########################################################################################:#
packages:
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
common_wifi: !include
@@ -57,6 +94,7 @@ packages:
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
@@ -70,86 +108,75 @@ packages:
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
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
#:########################################################################################:#
# PACKAGE OVERRIDES:
# These override or remove items from included packages above
#:########################################################################################:#
wifi:
min_auth_mode: !remove # The WPA2 only works on esp32/8266
reboot_timeout: 15min # override the selection from from the common package
fast_connect: false # (optional) force off, in case package vars change
min_auth_mode: !remove # The WPA2-only mode works on esp32/esp8266, not bk72xx
reboot_timeout: 15min # override selection from common package
fast_connect: false # force off, in case package vars change
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
#############################################
#:########################################################################################:#
esphome:
name: "${device_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}"
project:
name: "${project_name}"
version: "${project_version}"
# on_boot:
# priority: 200
# then:
# - switch.turn_on: Relay_3
mdns:
disabled: true
#############################################
# BUILD FOR BK CHIPSET
# bk72xx
#:########################################################################################:#
# BK72XX:
# https://devices.esphome.io/board/bk72xx/
#############################################
#:########################################################################################:#
bk72xx:
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
#############################################
#:########################################################################################:#
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)
level: "${log_level}"
id: logger_id
#############################################
# STATUS LED
#:########################################################################################:#
# STATUS LED:
# https://esphome.io/components/status_led.html
#############################################
#:########################################################################################:#
status_led:
pin:
number: P22 #GPIO22
number: P22
inverted: true
#############################################
# BINARY SENSORS
#:########################################################################################:#
# BINARY SENSORS:
# https://esphome.io/components/binary_sensor/
#############################################
#:########################################################################################:#
binary_sensor:
- platform: gpio
pin:
@@ -172,8 +199,8 @@ binary_sensor:
inverted: true
name: "Button 2: ${switch_2_name}"
on_press:
- delay: 50ms
- switch.toggle: Relay_2
- delay: 50ms
- switch.toggle: Relay_2
- platform: gpio
pin:
@@ -184,26 +211,29 @@ binary_sensor:
inverted: true
name: "Button 3: ${switch_3_name}"
on_press:
- delay: 50ms
- switch.toggle: Relay_3
- delay: 50ms
- switch.toggle: Relay_3
#############################################
# SWITCH COMPONENT
#:########################################################################################:#
# SWITCH COMPONENT:
# https://esphome.io/components/switch/
#############################################
#:########################################################################################:#
switch:
- platform: gpio
name: "Relay 1: ${switch_1_name}"
pin: P14 #GPIO14
pin: P14
id: Relay_1
restore_mode: ${relay_restore_mode}
- platform: gpio
name: "Relay 2: ${switch_2_name}"
pin: P16 #GPIO16
pin: P16
id: Relay_2
restore_mode: ${relay_restore_mode}
- platform: gpio
name: "Relay 3: ${switch_3_name}"
pin: P15 #GPIO15
pin: P15
id: Relay_3
restore_mode: ${relay_restore_mode}
+120 -85
View File
@@ -1,54 +1,90 @@
#############################################
#############################################
# GARAGE LIGHTS
# Controlled by a Sonoff Basic R1
#
#:########################################################################################:#
# TITLE: GARAGE EXTERNAL CORNER LIGHT
# zorruno.com layout v1.1 2026
#:########################################################################################:#
# 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
# 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)
##########################################################################################
#:########################################################################################:#
substitutions:
# Device Custom Naming
device_name: "esp-garageextcornerlight"
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.
static_ip_address: !secret esp-garageextcornerlight_ip
mqtt_device_name: "garage-externalcorner-light"
# Project Naming
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
# Passwords
project_name: "Sonoff Technologies.Sonoff Basic V1" # Project Details
project_version: "v2.1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
# 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
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
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
# Device Naming
# I/O Naming
relay_1_name: "Garage External Light"
button_1_name: "Power Button"
# 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}"
##########################################################################################
#:########################################################################################:#
# PACKAGES: Included Common Packages
# https://esphome.io/components/packages.html
##########################################################################################
#:########################################################################################:#
packages:
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
common_wifi: !include
@@ -57,6 +93,7 @@ packages:
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
@@ -70,80 +107,85 @@ packages:
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
#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
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
#:########################################################################################:#
# 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
comment: "${description_comment}" # Appears on the ESPHome page in HA
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:
board: esp01_1m # The original sonoff basic
restore_from_flash: True # restore some values on reboot
board: esp01_1m # The original Sonoff Basic
restore_from_flash: true # restore some values on reboot
#:########################################################################################:#
# PREFERENCES:
# https://esphome.io/components/preferences.html
#:########################################################################################:#
preferences:
flash_write_interval: 5min
#:########################################################################################:#
# MDNS:
# https://esphome.io/components/mdns.html
#:########################################################################################:#
mdns:
disabled: False
disabled: false
##########################################################################################
# ESPHome Logging Enable
#:########################################################################################:#
# LOGGING:
# https://esphome.io/components/logger.html
##########################################################################################
#:########################################################################################:#
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
##########################################################################################
# SWITCH COMPONENT
#:########################################################################################:#
# SWITCH COMPONENT:
# https://esphome.io/components/switch/
##########################################################################################
# Sonoff Basic R1 Relay Switch is GPIO12
#############################################
# Sonoff Basic R1 relay is GPIO12
#:########################################################################################:#
switch:
- platform: gpio
name: "${relay_1_name}"
pin: GPIO12
id: relay1
restore_mode: RESTORE_DEFAULT_OFF
icon: "${relay_icon}"
icon: "${relay_icon}"
##########################################################################################
# BINARY SENSORS
#:########################################################################################:#
# BINARY SENSORS:
# https://esphome.io/components/binary_sensor/
##########################################################################################
# Sonoff Basic R1 Button is GPIO03
#############################################
# Sonoff Basic R1 button is GPIO03
#:########################################################################################:#
binary_sensor:
# Actual button input
- platform: gpio
pin:
@@ -166,8 +208,8 @@ binary_sensor:
// Relay is OFF: turn it ON
id(relay1).turn_on();
}
# Mimics actual relay status
# Mimics actual relay status (publishes MQTT state)
- platform: template
name: "${relay_1_name} Status"
lambda: |-
@@ -175,34 +217,30 @@ binary_sensor:
on_press:
- mqtt.publish:
topic: "${mqtt_status_topic}"
payload: "ON"
payload: "ON"
on_release:
- mqtt.publish:
topic: "${mqtt_status_topic}"
payload: "OFF"
##########################################################################################
# STATUS LED
payload: "OFF"
#:########################################################################################:#
# STATUS LED:
# https://esphome.io/components/status_led.html
##########################################################################################
# Sonoff Basic R1 LED is GPIO13
##########################################################################################
# Sonoff Basic R1 LED is GPIO13
#:########################################################################################:#
status_led:
pin:
number: GPIO13
inverted: yes
inverted: true
##########################################################################################
# MQTT COMMANDS
# This adds device-specific MQTT command triggers to the common MQTT configuration.
# Requires you to define:
# substitutions:
# mqtt_command_topic: "<your/command/topic>"
# mqtt_state_topic: "<your/state/topic>"
##########################################################################################
#:########################################################################################:#
# MQTT: Device-specific command triggers
#:########################################################################################:#
mqtt:
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}"
payload: "ON"
then:
@@ -215,7 +253,6 @@ mqtt:
- mqtt.publish:
topic: "${mqtt_status_topic}"
payload: "ON"
#retain: true
- topic: "${mqtt_command_topic}"
payload: "OFF"
@@ -229,7 +266,6 @@ mqtt:
- mqtt.publish:
topic: "${mqtt_status_topic}"
payload: "OFF"
#retain: true
# Announce current state whenever MQTT (re)connects
on_connect:
@@ -237,4 +273,3 @@ mqtt:
- mqtt.publish:
topic: "${mqtt_status_topic}"
payload: !lambda 'return id(relay1).state ? "ON" : "OFF";'
#retain: true
+561 -303
View File
File diff suppressed because it is too large Load Diff
+147 -86
View File
@@ -1,39 +1,82 @@
#############################################
#############################################
# LAUNDRY DRYER MACHINE POWER
#:########################################################################################:#
# TITLE: 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
#############################################
# Sonoff POW R1
# https://devices.esphome.io/devices/Sonoff-POW-R1
#:########################################################################################:#
# HARDWARE:
# - 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)
#############################################
#:########################################################################################:#
substitutions:
device_name: "esp-laundrydrypow" # Reference name for the device in the system.
project_name: "Sonoff Technologies.POW R1" # Project Details
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.
# Device Naming
device_name: "esp-laundrydrypow"
friendly_name: "Laundry Dryer Power"
description_comment: "Laundry Dryer 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-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
description_comment: "Laundry Dryer Power using a Sonoff Pow R1. (Layout V1.1)"
device_area: "Laundry"
##########################################################################################
# PACKAGES: Included Common Packages
# Project Naming
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
##########################################################################################
#:########################################################################################:#
packages:
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
common_wifi: !include
@@ -41,12 +84,13 @@ packages:
vars:
local_device_name: "${device_name}"
local_static_ip_address: "${static_ip_address}"
local_current_ip_address: "${current_ip_address}"
local_ota_pass: "${ota_pass}"
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
common_api: !include
file: common/api_common.yaml
#file: common/api_common_noencryption.yaml
# file: common/api_common_noencryption.yaml
vars:
local_api_key: "${api_key}"
@@ -55,137 +99,154 @@ packages:
file: common/mqtt_common.yaml
vars:
local_device_name: "${device_name}"
#### 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) ####
#common_sntp: !include common/sntp_common.yaml
# 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
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
#:########################################################################################:#
# 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
comment: "${description_comment}"
area: "${device_area}"
project:
name: "${project_name}"
version: "${project_version}"
on_boot:
on_boot:
priority: 200
then:
- switch.turn_on: "virtual_button"
- switch.turn_on: virtual_button
#############################################
# ESP Platform and Framework
# https://esphome.io/components/esp32.html
#############################################
#:########################################################################################:#
# ESP PLATFORM AND FRAMEWORK:
# https://esphome.io/components/esp8266.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
early_pin_init: false
board_flash_mode: dout
#############################################
# ESPHome Logging Enable
#:########################################################################################:#
# 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)
#esp8266_store_log_strings_in_flash: false
#tx_buffer_size: 64
level: "${log_level}"
# baud_rate: 0
# esp8266_store_log_strings_in_flash: false
# tx_buffer_size: 64
#############################################
# STATUS LED
#:########################################################################################:#
# STATUS LED:
# https://esphome.io/components/status_led.html
#############################################
#status_led:
# pin:
# number: GPIO2
# inverted: yes
#:########################################################################################:#
# status_led:
# pin:
# number: GPIO2
# inverted: true
#############################################
# SENSORS
#:########################################################################################:#
# BINARY SENSORS:
# https://esphome.io/components/binary_sensor/
#############################################
#:########################################################################################:#
binary_sensor:
- platform: gpio
pin:
number: GPIO0
mode: INPUT_PULLUP
inverted: True
name: Button
inverted: true
name: "Button"
on_press:
- switch.toggle: virtual_button
- platform: template
name: ${entity_prefix} Running
name: "${entity_prefix} Running"
filters:
- delayed_off: 15s
lambda: |-
if (isnan(id(power).state)) {
return {};
} else if (id(power).state > 4) {
// Running
return true;
} else {
// Not running
return false;
}
#:########################################################################################:#
# SENSORS:
# https://esphome.io/components/sensor/
#:########################################################################################:#
sensor:
- platform: hlw8012
sel_pin: 5
cf_pin: 14
cf1_pin: 13
sel_pin: GPIO5
cf_pin: GPIO14
cf1_pin: GPIO13
update_interval: 2s
current:
name: ${entity_prefix} Current
name: "${entity_prefix} Current"
voltage:
name: ${entity_prefix} Voltage
name: "${entity_prefix} Voltage"
power:
name: ${entity_prefix} Power
name: "${entity_prefix} Power"
id: power
#on_value_range:
# - above: 4.0
# then:
# - light.turn_on: led
# - below: 3.0
# then:
# - light.turn_off: led
# on_value_range:
# - above: 4.0
# then:
# - light.turn_on: led
# - below: 3.0
# then:
# - light.turn_off: led
#:########################################################################################:#
# SWITCH:
# https://esphome.io/components/switch/
#:########################################################################################:#
switch:
- platform: template
name: "Relay"
optimistic: true
id: virtual_button
optimistic: true
turn_on_action:
- switch.turn_on: relay
- light.turn_on: led
turn_off_action:
- switch.turn_off: relay
- light.turn_off: led
- platform: gpio
id: relay
pin: GPIO12
#restore_mode: ALWAYS_ON # Or RESTORE_DEFAULT_ON/RESTORE_DEFAULT_OFF
# restore_mode: ALWAYS_ON
#:########################################################################################:#
# OUTPUT:
# https://esphome.io/components/output/
#:########################################################################################:#
output:
- platform: esp8266_pwm
id: pow_blue_led
pin:
number: GPIO15
inverted: True
inverted: true
#:########################################################################################:#
# LIGHT:
# https://esphome.io/components/light/
#:########################################################################################:#
light:
- platform: monochromatic
name: Status LED
name: "Status LED"
output: pow_blue_led
id: led
+105 -63
View File
@@ -1,39 +1,78 @@
#############################################
#############################################
# LAUNDRY ENVIRONMENT - SONOFF DEV
#:########################################################################################:#
# TITLE: 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
#############################################
# Sonoff Dev
# https://wiki.iteadstudio.com/Sonoff_DEV
#:########################################################################################:#
# HARDWARE:
# - 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)
#############################################
#:########################################################################################:#
substitutions:
device_name: "esp-laundryenv" # Reference name for the device in the system.
project_name: "Sonoff Technologies.Sonoff DEV" # Project Details
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.
# Device Naming
device_name: "esp-laundryenv"
friendly_name: "Laundry Environment"
description_comment: "Laundry Environment Sensor, PIR and Smoke Detector using Sonoff DEV"
device_area: "Laundry" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
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
description_comment: "Laundry Environment Sensor, PIR and Smoke Detector using Sonoff DEV (Layout V1.1)"
device_area: "Laundry"
##########################################################################################
# PACKAGES: Included Common Packages
# Project Naming
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
##########################################################################################
#:########################################################################################:#
packages:
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
common_wifi: !include
@@ -41,6 +80,7 @@ packages:
vars:
local_device_name: "${device_name}"
local_static_ip_address: "${static_ip_address}"
local_current_ip_address: "${current_ip_address}"
local_ota_pass: "${ota_pass}"
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
@@ -55,63 +95,68 @@ packages:
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
#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
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
#:########################################################################################:#
# 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
comment: "${description_comment}"
area: "${device_area}"
project:
name: "${project_name}"
version: "${project_version}"
#############################################
# ESP Platform and Framework
# https://esphome.io/components/esp32.html
#############################################
#:########################################################################################:#
# ESP PLATFORM AND FRAMEWORK:
# https://esphome.io/components/esp8266.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
early_pin_init: false
board_flash_mode: dout
#############################################
# ESPHome Logging Enable
#:########################################################################################:#
# 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)
level: "${log_level}"
#baud_rate: 0
#esp8266_store_log_strings_in_flash: false
#tx_buffer_size: 64
#############################################
# SENSORS
# https://esphome.io/components/binary_sensor/
#############################################
#:########################################################################################:#
# SENSORS:
# https://esphome.io/components/sensor/
#:########################################################################################:#
sensor:
- platform: dht
pin: GPIO14
temperature:
name: ${entity_prefix} Temperature
name: "${entity_prefix} Temperature"
humidity:
name: ${entity_prefix} Humidity
update_interval: ${update_interval}
name: "${entity_prefix} Humidity"
update_interval: "${update_interval}"
#:########################################################################################:#
# BINARY SENSORS:
# https://esphome.io/components/binary_sensor/
#:########################################################################################:#
binary_sensor:
- platform: gpio
pin:
@@ -119,19 +164,16 @@ binary_sensor:
mode:
input: true
pullup: false
name: ${entity_prefix} PIR
name: "${entity_prefix} PIR"
device_class: motion
#filters:
# - invert:
# - invert:
- platform: gpio
pin:
number: GPIO05
number: GPIO5
mode:
input: true
pullup: true
inverted: True
name: ${entity_prefix} Smoke Detector
inverted: true
name: "${entity_prefix} Smoke Detector"
+130 -74
View File
@@ -1,39 +1,90 @@
##########################################################################################
##########################################################################################
# LAUNDRY MAIN LIGHTSWITCH
#:########################################################################################:#
# TITLE: 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.0 2025-06-05 YAML tidyups
# V2.0 2025-06-01 Was initially a 3 button switch, now 2
# V1.0 2025-05-30 Initial Version
##########################################################################################
# Zemismart KS-811 Double push button
# pinout/schematic https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
#:########################################################################################:#
# HARDWARE:
# - 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)
##########################################################################################
#:########################################################################################:#
substitutions:
# Device Naming
# Device Naming
device_name: "esp-laundrylights"
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)"
device_area: "Laundry" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
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.
# Project Naming
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_name: "Zemismart Technologies.KS-811 Double" # Project Details
project_version: "v3.6" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
# 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-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_status_main_topic: !secret mqtt_status_main_topic
@@ -49,14 +100,15 @@ substitutions:
# Switch Naming
switch_1_name: "Laundry Lights"
switch_2_name: "Laundry Power Enable" # This is virtual only, no power connected to 3rd relay
#switch_3_name: "Fan 3 Relay"
#switch_4_name: "Fan 4 Relay"
switch_2_name: "Laundry Power Enable" # This is virtual only, no power connected to 3rd relay
#switch_3_name: "Fan 3 Relay"
#switch_4_name: "Fan 4 Relay"
#########################################################################################
# PACKAGES: Included Common Packages
#:########################################################################################:#
# PACKAGES:
# Included Common Packages
# https://esphome.io/components/packages.html
##########################################################################################
#:########################################################################################:#
packages:
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
common_wifi: !include
@@ -64,6 +116,7 @@ packages:
vars:
local_device_name: "${device_name}"
local_static_ip_address: "${static_ip_address}"
local_current_ip_address: "${current_ip_address}"
local_ota_pass: "${ota_pass}"
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
@@ -78,22 +131,23 @@ packages:
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
#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
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
#:########################################################################################:#
# ESPHOME:
# https://esphome.io/components/esphome.html
#########################################################################################
#:########################################################################################:#
esphome:
name: "${device_name}"
friendly_name: "${friendly_name}"
@@ -102,70 +156,70 @@ esphome:
project:
name: "${project_name}"
version: "${project_version}"
on_boot:
on_boot:
priority: 200
then:
- switch.turn_on: Relay_2
#########################################################################################
# ESP Platform and Framework
# https://esphome.io/components/esp32.html
#########################################################################################
#:########################################################################################:#
# ESP PLATFORM AND FRAMEWORK:
# https://esphome.io/components/esp8266.html
#:########################################################################################:#
esp8266:
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
#########################################################################################
# ESPHome Logging Enable
#:########################################################################################:#
# 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)
#esp8266_store_log_strings_in_flash: false
#tx_buffer_size: 64
#########################################################################################
# STATUS LED
#:########################################################################################:#
# STATUS LED:
# https://esphome.io/components/status_led.html
#########################################################################################
#:########################################################################################:#
status_led:
pin:
number: GPIO2
inverted: yes
inverted: true
#########################################################################################
# GLOBAL VARIABLES
#
#########################################################################################
#:########################################################################################:#
# GLOBAL VARIABLES:
#:########################################################################################:#
globals:
- id: remote1_state
type: bool
restore_value: no
initial_value: 'false'
restore_value: false
initial_value: "false"
- id: remote1_known
type: bool
restore_value: no
initial_value: 'false'
restore_value: false
initial_value: "false"
#########################################################################################
# BINARY SENSORS
#:########################################################################################:#
# BINARY SENSORS:
# https://esphome.io/components/binary_sensor/
#########################################################################################
#:########################################################################################:#
binary_sensor:
- platform: gpio
pin:
number: GPIO16
mode: INPUT
inverted: True
inverted: true
name: "Button 1: ${switch_1_name}"
on_press:
- switch.toggle: Relay_1
- platform: gpio
pin:
number: GPIO05
number: GPIO5
mode: INPUT
inverted: true
name: "Button 2: ${switch_2_name}"
@@ -177,18 +231,21 @@ binary_sensor:
then:
- if:
condition:
lambda: 'return id(Relay_2).state;'
lambda: |-
return id(Relay_2).state;
then:
- switch.turn_off: Relay_2
else:
- switch.turn_on: Relay_2
# HOLD: pressed for 2s or more -> toggle remote; default to ON if unknown
- timing:
- ON for at least 2s
then:
- if:
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:
- mqtt.publish:
topic: "${mqtt_remote1_command_topic}"
@@ -200,10 +257,9 @@ binary_sensor:
payload: "ON"
retain: false
#########################################################################################
# TEXT SENSORS
#
#########################################################################################
#:########################################################################################:#
# TEXT SENSORS:
#:########################################################################################:#
text_sensor:
- platform: mqtt_subscribe
id: remote1_status
@@ -214,11 +270,13 @@ text_sensor:
- lambda: |-
// copy, trim whitespace, uppercase
std::string s = x;
// 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(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;
if (s == "ON" || s == "1" || s == "TRUE") {
@@ -233,15 +291,16 @@ text_sensor:
// unknown payload (e.g. "ONLINE", "OFFLINE", JSON, etc.)
id(remote1_known) = false;
}
ESP_LOGI("remote1_status", "Parsed status='%s' -> known=%s state=%s",
s.c_str(),
id(remote1_known) ? "true" : "false",
id(remote1_state) ? "ON" : "OFF");
#########################################################################################
# SWITCH COMPONENT
#:########################################################################################:#
# SWITCH COMPONENT:
# https://esphome.io/components/switch/
#########################################################################################
#:########################################################################################:#
switch:
- platform: gpio
name: "Relay 1: ${switch_1_name}"
@@ -251,7 +310,4 @@ switch:
- platform: gpio
name: "Relay 2: ${switch_2_name}"
pin: GPIO12
id: Relay_2
id: Relay_2
+147 -86
View File
@@ -1,39 +1,82 @@
#############################################
#############################################
# LAUNDRY BENCH PLUGS POWER AND SWITCH
#:########################################################################################:#
# TITLE: 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
#############################################
# Sonoff POW R1
# https://devices.esphome.io/devices/Sonoff-POW-R1
#:########################################################################################:#
# HARDWARE:
# - 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)
#############################################
#:########################################################################################:#
substitutions:
device_name: "esp-laundryplugpow" # Reference name for the device in the system.
project_name: "Sonoff Technologies.POW R1" # Project Details
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.
# Device Naming
device_name: "esp-laundryplugpow"
friendly_name: "Laundry Bench Plug Power"
description_comment: "Laundry Bench Plug Power and switch override 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-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
description_comment: "Laundry Bench Plug Power and switch override using a Sonoff Pow R1. (Layout V1.1)"
device_area: "Laundry"
##########################################################################################
# PACKAGES: Included Common Packages
# Project Naming
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
##########################################################################################
#:########################################################################################:#
packages:
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
common_wifi: !include
@@ -41,12 +84,13 @@ packages:
vars:
local_device_name: "${device_name}"
local_static_ip_address: "${static_ip_address}"
local_current_ip_address: "${current_ip_address}"
local_ota_pass: "${ota_pass}"
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
common_api: !include
file: common/api_common.yaml
#file: common/api_common_noencryption.yaml
# file: common/api_common_noencryption.yaml
vars:
local_api_key: "${api_key}"
@@ -55,137 +99,154 @@ packages:
file: common/mqtt_common.yaml
vars:
local_device_name: "${device_name}"
#### 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) ####
#common_sntp: !include common/sntp_common.yaml
# 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
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
#:########################################################################################:#
# 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
comment: "${description_comment}"
area: "${device_area}"
project:
name: "${project_name}"
version: "${project_version}"
on_boot:
on_boot:
priority: 200
then:
- switch.turn_on: "virtual_button"
- switch.turn_on: virtual_button
#############################################
# ESP Platform and Framework
# https://esphome.io/components/esp32.html
#############################################
#:########################################################################################:#
# ESP PLATFORM AND FRAMEWORK:
# https://esphome.io/components/esp8266.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
early_pin_init: false
board_flash_mode: dout
#############################################
# ESPHome Logging Enable
#:########################################################################################:#
# 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)
#esp8266_store_log_strings_in_flash: false
#tx_buffer_size: 64
level: "${log_level}"
# baud_rate: 0
# esp8266_store_log_strings_in_flash: false
# tx_buffer_size: 64
#############################################
# STATUS LED
#:########################################################################################:#
# STATUS LED:
# https://esphome.io/components/status_led.html
#############################################
#status_led:
# pin:
# number: GPIO2
# inverted: yes
#:########################################################################################:#
# status_led:
# pin:
# number: GPIO2
# inverted: true
#############################################
# SENSORS
#:########################################################################################:#
# BINARY SENSORS:
# https://esphome.io/components/binary_sensor/
#############################################
#:########################################################################################:#
binary_sensor:
- platform: gpio
pin:
number: GPIO0
mode: INPUT_PULLUP
inverted: True
name: Button
inverted: true
name: "Button"
on_press:
- switch.toggle: virtual_button
- platform: template
name: ${entity_prefix} Running
name: "${entity_prefix} Running"
filters:
- delayed_off: 15s
lambda: |-
if (isnan(id(power).state)) {
return {};
} else if (id(power).state > 4) {
// Running
return true;
} else {
// Not running
return false;
}
#:########################################################################################:#
# SENSORS:
# https://esphome.io/components/sensor/
#:########################################################################################:#
sensor:
- platform: hlw8012
sel_pin: 5
cf_pin: 14
cf1_pin: 13
sel_pin: GPIO5
cf_pin: GPIO14
cf1_pin: GPIO13
update_interval: 2s
current:
name: ${entity_prefix} Current
name: "${entity_prefix} Current"
voltage:
name: ${entity_prefix} Voltage
name: "${entity_prefix} Voltage"
power:
name: ${entity_prefix} Power
name: "${entity_prefix} Power"
id: power
#on_value_range:
# - above: 4.0
# then:
# - light.turn_on: led
# - below: 3.0
# then:
# - light.turn_off: led
# on_value_range:
# - above: 4.0
# then:
# - light.turn_on: led
# - below: 3.0
# then:
# - light.turn_off: led
#:########################################################################################:#
# SWITCH:
# https://esphome.io/components/switch/
#:########################################################################################:#
switch:
- platform: template
name: "Relay"
optimistic: true
id: virtual_button
optimistic: true
turn_on_action:
- switch.turn_on: relay
- light.turn_on: led
turn_off_action:
- switch.turn_off: relay
- light.turn_off: led
- platform: gpio
id: relay
pin: GPIO12
#restore_mode: ALWAYS_ON # Or RESTORE_DEFAULT_ON/RESTORE_DEFAULT_OFF
# restore_mode: ALWAYS_ON
#:########################################################################################:#
# OUTPUT:
# https://esphome.io/components/output/
#:########################################################################################:#
output:
- platform: esp8266_pwm
id: pow_blue_led
pin:
number: GPIO15
inverted: True
inverted: true
#:########################################################################################:#
# LIGHT:
# https://esphome.io/components/light/
#:########################################################################################:#
light:
- platform: monochromatic
name: Status LED
name: "Status LED"
output: pow_blue_led
id: led
+148 -87
View File
@@ -1,39 +1,82 @@
#############################################
#############################################
# LAUNDRY WASHING MACHINE POWER
#:########################################################################################:#
# TITLE: 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
#############################################
# Sonoff POW R1
# https://devices.esphome.io/devices/Sonoff-POW-R1
#:########################################################################################:#
# HARDWARE:
# - 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)
#############################################
#:########################################################################################:#
substitutions:
device_name: "esp-laundrywashpow" # Reference name for the device in the system.
project_name: "Sonoff Technologies.POW R1" # Project Details
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 Washing Machine Power" # Friendly name to show in Home Assistant.
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
# Device Naming
device_name: "esp-laundrywashpow"
friendly_name: "Laundry Washing Machine Power"
description_comment: "Laundry Washing Machine Power using a Sonoff Pow R1. (Layout V1.1)"
device_area: "Laundry"
##########################################################################################
# PACKAGES: Included Common Packages
# Project Naming
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
##########################################################################################
#:########################################################################################:#
packages:
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
common_wifi: !include
@@ -41,12 +84,13 @@ packages:
vars:
local_device_name: "${device_name}"
local_static_ip_address: "${static_ip_address}"
local_current_ip_address: "${current_ip_address}"
local_ota_pass: "${ota_pass}"
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
common_api: !include
file: common/api_common.yaml
#file: common/api_common_noencryption.yaml
# file: common/api_common_noencryption.yaml
vars:
local_api_key: "${api_key}"
@@ -55,137 +99,154 @@ packages:
file: common/mqtt_common.yaml
vars:
local_device_name: "${device_name}"
#### 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) ####
#common_sntp: !include common/sntp_common.yaml
# 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
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
#:########################################################################################:#
# 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
comment: "${description_comment}"
area: "${device_area}"
project:
name: "${project_name}"
version: "${project_version}"
on_boot:
on_boot:
priority: 200
then:
- switch.turn_on: "virtual_button"
- switch.turn_on: virtual_button
#############################################
# ESP Platform and Framework
# https://esphome.io/components/esp32.html
#############################################
#:########################################################################################:#
# ESP PLATFORM AND FRAMEWORK:
# https://esphome.io/components/esp8266.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
early_pin_init: false
board_flash_mode: dout
#############################################
# ESPHome Logging Enable
#:########################################################################################:#
# 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)
#esp8266_store_log_strings_in_flash: false
#tx_buffer_size: 64
level: "${log_level}"
# baud_rate: 0
# esp8266_store_log_strings_in_flash: false
# tx_buffer_size: 64
#############################################
# STATUS LED
#:########################################################################################:#
# STATUS LED:
# https://esphome.io/components/status_led.html
#############################################
#status_led:
# pin:
# number: GPIO2
# inverted: yes
#:########################################################################################:#
# status_led:
# pin:
# number: GPIO2
# inverted: true
#############################################
# SENSORS
#:########################################################################################:#
# BINARY SENSORS:
# https://esphome.io/components/binary_sensor/
#############################################
#:########################################################################################:#
binary_sensor:
- platform: gpio
pin:
number: GPIO0
mode: INPUT_PULLUP
inverted: True
name: Button
inverted: true
name: "Button"
on_press:
- switch.toggle: virtual_button
- platform: template
name: ${entity_prefix} Running
name: "${entity_prefix} Running"
filters:
- delayed_off: 15s
lambda: |-
if (isnan(id(power).state)) {
return {};
} else if (id(power).state > 4) {
// Running
return true;
} else {
// Not running
return false;
}
#:########################################################################################:#
# SENSORS:
# https://esphome.io/components/sensor/
#:########################################################################################:#
sensor:
- platform: hlw8012
sel_pin: 5
cf_pin: 14
cf1_pin: 13
sel_pin: GPIO5
cf_pin: GPIO14
cf1_pin: GPIO13
update_interval: 2s
current:
name: ${entity_prefix} Current
name: "${entity_prefix} Current"
voltage:
name: ${entity_prefix} Voltage
name: "${entity_prefix} Voltage"
power:
name: ${entity_prefix} Power
name: "${entity_prefix} Power"
id: power
#on_value_range:
# - above: 4.0
# then:
# - light.turn_on: led
# - below: 3.0
# then:
# - light.turn_off: led
# on_value_range:
# - above: 4.0
# then:
# - light.turn_on: led
# - below: 3.0
# then:
# - light.turn_off: led
#:########################################################################################:#
# SWITCH:
# https://esphome.io/components/switch/
#:########################################################################################:#
switch:
- platform: template
name: "Relay"
optimistic: true
id: virtual_button
optimistic: true
turn_on_action:
- switch.turn_on: relay
- light.turn_on: led
turn_off_action:
- switch.turn_off: relay
- light.turn_off: led
- platform: gpio
id: relay
pin: GPIO12
#restore_mode: ALWAYS_ON # Or RESTORE_DEFAULT_ON/RESTORE_DEFAULT_OFF
# restore_mode: ALWAYS_ON
#:########################################################################################:#
# OUTPUT:
# https://esphome.io/components/output/
#:########################################################################################:#
output:
- platform: esp8266_pwm
id: pow_blue_led
pin:
number: GPIO15
inverted: True
inverted: true
#:########################################################################################:#
# LIGHT:
# https://esphome.io/components/light/
#:########################################################################################:#
light:
- platform: monochromatic
name: Status LED
name: "Status LED"
output: pow_blue_led
id: led
+108 -73
View File
@@ -1,29 +1,59 @@
##########################################################################################
##########################################################################################
# Nissan Leaf 12V Battery Monitor
# Monitoring the status of a vehicle 12V battery with
# an esp8266 (D1 Mini). It will obviously only
# transmit when the vehicle is within wifi range.
# Voltage is measured with a resistor voltage divider
# into the analogue GPIO on the esp8266.
# https://zorruno.com/2022/vehicle-12v-battery-monitoring/
##########################################################################################
##########################################################################################
#:########################################################################################:#
# TITLE: NISSAN LEAF 12V BATTERY MONITOR
# zorruno.com layout v1.1 2026
#:########################################################################################:#
# REPO:
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-leafbattery.yaml
#:########################################################################################:#
# VERSIONS:
# 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)
##########################################################################################
#:########################################################################################:#
substitutions:
# Device Naming
# Device Naming
device_name: "esp-leafbattery"
friendly_name: "Nissan Leaf 12V Battery Monitor"
description_comment: "Nissan Leaf 12V Battery Monitor (when home)"
device_area: "Garage" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
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.
# Project Naming
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_name: "Generic ESP8266.D1 Mini" # Project Details
project_version: "v1.1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
# Passwords & Secrets
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_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_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_status_topic: "${mqtt_status_main_topic}/${mqtt_device_name}" # Topic we will use to view status locally without HA
# Device Settings
#relay_icon: "mdi:lightbulb-group"
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
wake_interval: "20s"
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
##########################################################################################
# Comment some of these out where not needed, eg MQTT, Web portal, SNTP, General Sensors
##########################################################################################
#:########################################################################################:#
packages:
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
common_wifi: !include
@@ -60,6 +92,7 @@ packages:
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
@@ -73,28 +106,32 @@ packages:
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
#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
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
#:########################################################################################:#
# 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
name: "${device_name}"
friendly_name: "${friendly_name}"
comment: "${description_comment}" # appears on the esphome page in HA
area: "${device_area}"
min_version: 2024.6.0
project:
name: "${project_name}"
version: "${project_version}"
on_boot:
priority: 600
then:
@@ -115,41 +152,41 @@ esphome:
- logger.log: "MQTT unreachable after 30s -> entering FALLBACK sleep for ${mqtt_fail_sleep}."
- deep_sleep.enter:
id: deep_sleep_1
sleep_duration: ${mqtt_fail_sleep} # override only this cycle
sleep_duration: ${mqtt_fail_sleep} # override only this cycle
else:
- 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/esp32.html
##########################################################################################
#:########################################################################################:#
esp8266:
board: d1_mini
framework:
version: latest #recommended, latest or dev
version: latest # recommended, latest or dev
##########################################################################################
# ESPHome Logging Enable
#:########################################################################################:#
# 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)
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
#############################################
# Enable Over the Air Update Capability
# https://esphome.io/components/ota.html?highlight=ota
#############################################
#:########################################################################################:#
# OTA:
# https://esphome.io/components/ota.html
#:########################################################################################:#
ota:
- 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.
##########################################################################################
#:########################################################################################:#
mqtt:
# Availability Topic
birth_message:
@@ -173,19 +210,19 @@ mqtt:
- deep_sleep.prevent: deep_sleep_1
- logger.log: "Deep sleep PREVENTED via MQTT."
##########################################################################################
# Deep Sleep
#:########################################################################################:#
# DEEP SLEEP:
# https://esphome.io/components/deep_sleep.html
##########################################################################################
#:########################################################################################:#
deep_sleep:
id: deep_sleep_1
run_duration: ${wake_interval}
sleep_duration: ${sleep_interval}
##########################################################################################
# SENSOR COMPONENT
run_duration: ${wake_interval}
sleep_duration: ${sleep_interval}
#:########################################################################################:#
# SENSOR COMPONENT:
# https://esphome.io/components/sensor/
##########################################################################################
#:########################################################################################:#
sensor:
- platform: adc
pin: A0
@@ -208,8 +245,8 @@ sensor:
- 0.32 -> 07.00
- 0.28 -> 06.00
- 0.23 -> 05.00
- delta: 0.05 # publish immediately if change >= 0.05 V
- throttle: 2s # avoid bursts if noisy
- delta: 0.05 # publish immediately if change >= 0.05 V
- throttle: 2s # avoid bursts if noisy
on_value:
then:
- mqtt.publish:
@@ -221,9 +258,10 @@ sensor:
snprintf(buf, sizeof(buf), "%.2f", x);
return std::string(buf);
##########################################################################################
# INTERVAL COMPONENT
##########################################################################################
#:########################################################################################:#
# INTERVAL COMPONENT:
# https://esphome.io/components/interval.html
#:########################################################################################:#
interval:
- interval: 60s
then:
@@ -237,6 +275,3 @@ interval:
snprintf(buf, sizeof(buf), "%.2f", v);
return std::string(buf);
+189 -165
View File
@@ -1,72 +1,97 @@
##########################################################################################
##########################################################################################
# Title: LOUNGE BOOKSHELF LEDS
# Repo: https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-loungebookshelfleds.yaml
#
# 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)
#:########################################################################################:#
# 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
#:########################################################################################:#
# 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)
#
# ------------------------------------------
# OPERATION (as of v2.0)
# ------------------------------------------
# 1. General-purpose LED controller.
# 2. Designed for the Sinilink XY-WFMS board with a MOSFET output (claimed 5A, 5-36 V DC), but will suit similar mosfet boards.
# 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 Sinilink device. 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 (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: 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)
##########################################################################################
##########################################################################################
# MQTT COMMANDS:
# - ${mqtt_local_command_topic}/light/set = ON
# - ${mqtt_local_command_topic}/light/set = OFF
# - State publishes to:
# - ${mqtt_local_status_topic}/light/state
#:########################################################################################:#
# OFFLINE NOTES:
# a) Home Assistant offline (network and MQTT online):
# - LED control continues locally on the device
# - Direct local MQTT commands still work if the broker is available
# - Stored brightness/ramp settings and restart behaviour continue to work
#
# b) MQTT offline (or HA/MQTT offline):
# - LED control continues locally on the device
# - Physical button control and local ramp logic continue to work
# - No MQTT control/state publishing available
#
# c) Entire WiFi/Network offline:
# - LED control continues locally on the device
# - Physical button control and local ramp logic 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)
##########################################################################################
#:########################################################################################:#
substitutions:
# Device Naming
device_name: "esp-loungebookshelfleds" # yaml file should be device_name.yaml
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.
# Project Naming
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_name: "Magichome Single Colour V1.1 LED Controller.Generic ESP8266" # Project details. Manufacturer before the dot, device after the dot.
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)
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
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_device_name: "lounge-bookshelfleds"
mqtt_local_command_main_topic: !secret mqtt_command_main_topic
@@ -77,24 +102,25 @@ substitutions:
mqtt_local_device_command_OFF: "OFF"
# Device Specific Settings
log_level: "NONE" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (default), VERBOSE, VERY_VERBOSE
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
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
log_level: "NONE" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (default), VERBOSE, VERY_VERBOSE
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
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
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_status_led: GPIO02
device_status_led: GPIO2
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
##########################################################################################
# PACKAGES: Included Common Packages
#:########################################################################################:#
# PACKAGES:
# Included Common Packages
# https://esphome.io/components/packages.html
##########################################################################################
#:########################################################################################:#
packages:
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
common_wifi: !include
@@ -102,6 +128,7 @@ packages:
vars:
local_device_name: "${device_name}"
local_static_ip_address: "${static_ip_address}"
local_current_ip_address: "${current_ip_address}"
local_ota_pass: "${ota_pass}"
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
@@ -116,22 +143,23 @@ packages:
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
#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
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
#:########################################################################################:#
# ESPHOME CORE CONFIGURATION
# https://esphome.io/components/esphome.html
##########################################################################################
#:########################################################################################:#
esphome:
name: "${device_name}"
friendly_name: "${friendly_name}"
@@ -152,32 +180,32 @@ esphome:
# Mode 0: Fade up to full (obeys fade settings; no on/off flicker)
- if:
condition:
lambda: 'return id(restart_mode) == 0;'
lambda: "return id(restart_mode) == 0;"
then:
- lambda: 'id(ramp_switch_target_on) = true;'
- lambda: "id(ramp_switch_target_on) = true;"
- script.execute: ramp_on_script
# Mode 1: Restore Brightness (deferred to avoid races)
- if:
condition:
lambda: 'return id(restart_mode) == 1;'
lambda: "return id(restart_mode) == 1;"
then:
- script.execute: deferred_restore_brightness
# Mode 2: Remain Off (no blip; stays off)
- if:
condition:
lambda: 'return id(restart_mode) == 2;'
lambda: "return id(restart_mode) == 2;"
then:
- script.stop: ramp_on_script
- script.stop: ramp_off_script
- lambda: 'id(ramp_switch_target_on) = false;'
- lambda: "id(ramp_switch_target_on) = false;"
- light.turn_off:
id: mosfet_leds
transition_length: 0s
# Boot complete: allow OFF handlers again
- lambda: 'id(booting) = false;'
- lambda: "id(booting) = false;"
# NEW: force indicator OFF after boot logic
# (Removed: output.turn_off: green_led_out)
@@ -193,11 +221,11 @@ esphome:
# - -fdata-sections
# - -DNDEBUG
##########################################################################################
#:########################################################################################:#
# ESP PLATFORM AND FRAMEWORK
# https://esphome.io/components/esp8266.html
# https://esphome.io/components/esp32.html
##########################################################################################
#:########################################################################################:#
esp8266:
board: esp01_1m
restore_from_flash: true # restore some values on reboot
@@ -208,10 +236,10 @@ mdns:
preferences:
flash_write_interval: 2min # enough time to update values for reboots, but not enough to wear flash
##########################################################################################
#:########################################################################################:#
# GLOBAL VARIABLES
# https://esphome.io/components/globals.html
##########################################################################################
#:########################################################################################:#
globals:
# Minimum Brightness % for LEDs (will switch off if <=)
- id: min_brightness_pct
@@ -223,7 +251,7 @@ globals:
type: int
restore_value: false
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
type: int
restore_value: true
@@ -232,23 +260,23 @@ globals:
- id: led_gamma_f
type: float
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)
- id: ramp_up_ms # fade-in when turned ON
type: int
restore_value: true
initial_value: '5000' # 5 s
initial_value: "5000" # 5 s
# Default Fading Down Time (Selectable and will be retained)
- id: ramp_down_ms # fade-out when turned OFF
type: int
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)
- id: restart_mode
- id: restart_mode
type: int
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.
# true when you asked the light to end up ON (Ramp Up)
@@ -256,70 +284,70 @@ globals:
- id: ramp_switch_target_on
type: bool
restore_value: true
initial_value: 'false'
initial_value: "false"
# Prevent jitter when adjusting the slider
- id: suppress_slider_sync
type: bool
restore_value: false
initial_value: 'false'
# actual 0..100 seen last time, for restart
- id: last_brightness_pct
initial_value: "false"
# actual 0..100 seen last time, for restart
- id: last_brightness_pct
type: float
restore_value: true
initial_value: '0.0'
initial_value: "0.0"
# last published "Output Set (0-100)" integer
- id: last_set_pos
type: int
restore_value: false
initial_value: '-1'
# helper to keep blink time == transition time
initial_value: "-1"
# helper to keep blink time == transition time
- id: last_ramp_ms
type: int
restore_value: false
initial_value: '0'
initial_value: "0"
# target for "Restore Brightness" scripted ramp
- id: restore_target_pct
type: float
restore_value: false
initial_value: '0.0'
initial_value: "0.0"
# true while a scripted ramp is in progress (to limit flash writes)
- id: is_ramping
type: bool
restore_value: false
initial_value: 'false'
initial_value: "false"
# guards OFF persistence during startup caused by restore_mode: ALWAYS_OFF
- id: booting
type: bool
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
- id: ramping_for_off
type: bool
restore_value: false
initial_value: 'false'
initial_value: "false"
##########################################################################################
#:########################################################################################:#
# LOGGER COMPONENT
# https://esphome.io/components/logger.html
# Logs all log messages through the serial port and through MQTT topics.
##########################################################################################
#:########################################################################################:#
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, Serial control)
#########################################################################################
#:########################################################################################:#
# STATUS LED
# https://esphome.io/components/status_led.html
#########################################################################################
#:########################################################################################:#
status_led:
pin:
number: ${device_status_led}
inverted: true
##########################################################################################
#:########################################################################################:#
# MQTT COMMANDS
# This adds device-specific MQTT command triggers to the common MQTT configuration.
##########################################################################################
#:########################################################################################:#
mqtt:
on_message:
# Light control to ramp up
@@ -333,10 +361,10 @@ mqtt:
then:
- switch.turn_off: mosfet_ramp_switch
##########################################################################################
#:########################################################################################:#
# SWITCH COMPONENT
# https://esphome.io/components/switch/
##########################################################################################
#:########################################################################################:#
switch:
# Ramp-aware ON/OFF for HA (asymmetric, eased; no bounce)
- platform: template
@@ -356,10 +384,10 @@ switch:
- script.stop: ramp_on_script
- script.execute: ramp_off_script
#################################################################################################
#:########################################################################################:#
# BUTTON COMPONENT
# https://esphome.io/components/button/index.html
#################################################################################################
#:########################################################################################:#
button:
# Start ramping UP (from current level)
- platform: template
@@ -399,7 +427,7 @@ button:
id(ramping_for_off) = 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;
if (cv.is_on()) {
auto call = id(mosfet_leds).make_call();
@@ -415,12 +443,10 @@ button:
id(last_brightness_pct) = pct;
}
#########################################################################################
#:########################################################################################:#
# SELECT COMPONENT
# https://esphome.io/components/select/index.html
#########################################################################################
#:########################################################################################:#
select:
- platform: template
id: restart_action
@@ -442,10 +468,10 @@ select:
id(restart_mode) = 2;
}
#########################################################################################
#:########################################################################################:#
# BINARY SENSORS
# https://esphome.io/components/binary_sensor/
#########################################################################################
#:########################################################################################:#
binary_sensor:
- platform: gpio
id: btn_gpio12
@@ -462,7 +488,7 @@ binary_sensor:
on_press:
- if:
condition:
lambda: 'return id(ramp_switch_target_on);'
lambda: "return id(ramp_switch_target_on);"
then:
# Target is currently ON -> press should go OFF (start ramp-down)
- lambda: |-
@@ -478,10 +504,10 @@ binary_sensor:
- script.stop: ramp_off_script
- script.execute: ramp_on_script
##########################################################################################
#:########################################################################################:#
# SENSOR COMPONENT
# https://esphome.io/components/sensor/
##########################################################################################
#:########################################################################################:#
sensor:
- platform: template
id: mosfet_output_pct
@@ -489,7 +515,7 @@ sensor:
unit_of_measurement: "%"
icon: mdi:percent
accuracy_decimals: 0
update_interval: 2s # consider 200ms if you want fewer updates
update_interval: 2s
lambda: |-
const auto &cv = id(mosfet_leds).current_values;
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;
return pwm * 100.0f;
##########################################################################################
#:########################################################################################:#
# OUTPUT COMPONENT
# https://esphome.io/components/light/index.html
##########################################################################################
#:########################################################################################:#
# 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
##########################################################################################
#:########################################################################################:#
output:
- platform: esp8266_pwm
id: mosfet_pwm
pin: ${device_mosfet_out}
frequency: ${pwm_frequency}
- platform: gpio
id: green_led_out # Green LED
pin:
number: ${device_fading_led}
inverted: false
##########################################################################################
#:########################################################################################:#
# LIGHT COMPONENT
# https://esphome.io/components/light/
##########################################################################################
#:########################################################################################:#
light:
- platform: monochromatic
id: mosfet_leds
@@ -570,14 +597,14 @@ light:
payload: "${mqtt_local_device_command_ON}"
retain: true
- 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)) {
id(ramp_switch_target_on) = true;
}
- script.stop: max_on_watchdog
- if:
condition:
lambda: 'return id(max_on_hours) > 0;'
lambda: "return id(max_on_hours) > 0;"
then:
- script.execute: max_on_watchdog
@@ -587,13 +614,13 @@ light:
- output.turn_off: green_led_out
- if:
condition:
lambda: 'return !id(booting);'
lambda: "return !id(booting);"
then:
- mqtt.publish:
topic: "${mqtt_local_status_topic}/light/state"
payload: "${mqtt_local_device_command_OFF}"
retain: true
- lambda: 'id(ramp_switch_target_on) = false;'
- lambda: "id(ramp_switch_target_on) = false;"
- script.stop: max_on_watchdog
- lambda: |-
id(last_brightness_pct) = 0.0f;
@@ -614,11 +641,10 @@ light:
call.set_transition_length(0);
call.perform();
##########################################################################################
#:########################################################################################:#
# NUMBER COMPONENT
# https://esphome.io/components/number/
##########################################################################################
#:########################################################################################:#
number:
- platform: template
id: cfg_ramp_up_s
@@ -683,10 +709,10 @@ number:
set_action:
- if:
condition:
lambda: 'return x <= 0.0f;'
lambda: "return x <= 0.0f;"
then:
# 0 means OFF
- lambda: 'id(suppress_slider_sync) = true;'
- lambda: "id(suppress_slider_sync) = true;"
- script.stop: ramp_on_script
- script.stop: ramp_off_script
- light.turn_off:
@@ -698,7 +724,7 @@ number:
id(last_brightness_pct) = 0.0f; // persist OFF immediately
id(last_set_pos) = 0;
- delay: 400ms
- lambda: 'id(suppress_slider_sync) = false;'
- lambda: "id(suppress_slider_sync) = false;"
else:
# Map 1..100 - [min..max] and set ON
- lambda: |-
@@ -730,7 +756,7 @@ number:
if (out_pct > maxp) out_pct = maxp;
id(last_brightness_pct) = out_pct; // persist exact target now
- delay: 400ms
- lambda: 'id(suppress_slider_sync) = false;'
- lambda: "id(suppress_slider_sync) = false;"
- platform: template
id: cfg_max_on_hours
@@ -753,27 +779,26 @@ number:
id(cfg_max_on_hours).publish_state((float) hrs);
- if:
condition:
lambda: 'return id(mosfet_leds).current_values.is_on();'
lambda: "return id(mosfet_leds).current_values.is_on();"
then:
- script.stop: max_on_watchdog
- if:
condition:
lambda: 'return id(max_on_hours) > 0;'
lambda: "return id(max_on_hours) > 0;"
then:
- script.execute: max_on_watchdog
##########################################################################################
#:########################################################################################:#
# SCRIPT COMPONENT
# https://esphome.io/components/script.html
# Scripts can be executed nearly anywhere in your device configuration with a single call.
##########################################################################################
#:########################################################################################:#
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
mode: restart
then:
- lambda: 'id(is_ramping) = true;'
- lambda: "id(is_ramping) = true;"
- script.stop: ramp_off_script
# Ensure we start at at least the floor without a visible "pop".
- if:
@@ -785,12 +810,12 @@ script:
then:
- light.turn_on:
id: mosfet_leds
brightness: !lambda 'return id(min_brightness_pct) / 100.0f;'
brightness: !lambda "return id(min_brightness_pct) / 100.0f;"
transition_length: 80ms
# Ramp from current (>= floor) to cap over a fraction of ramp_up_ms.
- light.turn_on:
id: mosfet_leds
brightness: !lambda 'return id(max_brightness_pct) / 100.0f;'
brightness: !lambda "return id(max_brightness_pct) / 100.0f;"
transition_length: !lambda |-
const auto &cv = id(mosfet_leds).current_values;
const float floor = id(min_brightness_pct) / 100.0f;
@@ -810,7 +835,7 @@ script:
if (frac > 1.0f) frac = 1.0f;
id(last_ramp_ms) = (int) (id(ramp_up_ms) * frac);
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: |-
id(is_ramping) = false;
const auto &cv = id(mosfet_leds).current_values;
@@ -823,7 +848,7 @@ script:
- id: ramp_to_target_script
mode: restart
then:
- lambda: 'id(is_ramping) = true;'
- lambda: "id(is_ramping) = true;"
- script.stop: ramp_off_script
# Ensure we start at the floor cleanly.
- if:
@@ -835,7 +860,7 @@ script:
then:
- light.turn_on:
id: mosfet_leds
brightness: !lambda 'return id(min_brightness_pct) / 100.0f;'
brightness: !lambda "return id(min_brightness_pct) / 100.0f;"
transition_length: 80ms
# Ramp from current (>= floor) to restore_target_pct over a fraction of ramp_up_ms.
- light.turn_on:
@@ -866,7 +891,7 @@ script:
if (frac > 1.0f) frac = 1.0f;
id(last_ramp_ms) = (int) (id(ramp_up_ms) * frac);
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: |-
id(is_ramping) = false;
const auto &cv = id(mosfet_leds).current_values;
@@ -875,7 +900,6 @@ script:
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)
- id: ramp_off_script
mode: restart
@@ -886,7 +910,7 @@ script:
- script.stop: ramp_on_script
- light.turn_on:
id: mosfet_leds
brightness: !lambda 'return id(min_brightness_pct) / 100.0f;'
brightness: !lambda "return id(min_brightness_pct) / 100.0f;"
transition_length: !lambda |-
const auto &cv = id(mosfet_leds).current_values;
const float floor = id(min_brightness_pct) / 100.0f;
@@ -899,7 +923,7 @@ script:
if (frac > 1.0f) frac = 1.0f;
id(last_ramp_ms) = (int) (id(ramp_down_ms) * frac);
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:
id: mosfet_leds
transition_length: 150ms
@@ -916,12 +940,12 @@ script:
then:
- if:
condition:
lambda: 'return id(max_on_hours) > 0;'
lambda: "return id(max_on_hours) > 0;"
then:
- delay: !lambda 'return (uint32_t) (id(max_on_hours) * 3600000UL);'
- delay: !lambda "return (uint32_t) (id(max_on_hours) * 3600000UL);"
- if:
condition:
lambda: 'return id(mosfet_leds).current_values.is_on();'
lambda: "return id(mosfet_leds).current_values.is_on();"
then:
- lambda: |-
id(ramp_switch_target_on) = false;
@@ -948,18 +972,18 @@ script:
- if:
condition:
lambda: 'return id(restore_target_pct) > 0.5f;'
lambda: "return id(restore_target_pct) > 0.5f;"
then:
- lambda: |-
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.execute: ramp_to_target_script
- delay: !lambda 'return (uint32_t) id(last_ramp_ms);'
- lambda: 'id(suppress_slider_sync) = false;'
- delay: !lambda "return (uint32_t) id(last_ramp_ms);"
- lambda: "id(suppress_slider_sync) = false;"
else:
# Exact last was 0 -> remain OFF
- lambda: 'id(ramp_switch_target_on) = false;'
- lambda: "id(ramp_switch_target_on) = false;"
- light.turn_off:
id: mosfet_leds
transition_length: 0s
@@ -1,76 +1,95 @@
##########################################################################################
##########################################################################################
# Title: LOUNGE CABINET LEDS
# Repo: https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-loungecabinetleds.yaml
#:########################################################################################:#
# 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
#:########################################################################################:#
# 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
# v1.5 - 2025-09-11 First setup (copied from another template)
#
# ------------------------------------------
# OPERATION (as of v2.0)
# ------------------------------------------
# 1. General-purpose LED controller.
# 2. Designed for the Sinilink XY-WFMS board with a MOSFET output (claimed 5A, 5-36 V DC), but will suit similar mosfet boards.
# 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 Sinilink device. 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 (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
#
##########################################################################################
##########################################################################################
# MQTT COMMANDS:
# - ${mqtt_local_command_topic}/light/set = ON
# - ${mqtt_local_command_topic}/light/set = OFF
# - State publishes to:
# - ${mqtt_local_status_topic}/light/state
#:########################################################################################:#
# OFFLINE NOTES:
# a) Home Assistant offline (network and MQTT online)
# - Local light logic, fades, restart behaviour, and watchdog timing continue to operate.
# - Local MQTT control and status publishing continue if the MQTT broker is online.
# b) MQTT offline (or HA/MQTT offline)
# - Local light logic, fades, restart behaviour, and watchdog timing continue to operate.
# - MQTT control and MQTT state publishing are unavailable.
# c) Entire WiFi/Network offline
# - Local light logic, fades, restart behaviour, and watchdog timing continue to operate.
# - Accurate time is not needed (SNTP not needed).
#:########################################################################################:#
##########################################################################################
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
#:########################################################################################:#
# 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-loungecabinetleds2" # yaml file should be device_name.yaml
device_name: "esp-loungecabinetleds" # yaml file should be device_name.yaml
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.
# Project Naming
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_name: "Sinilink.XY-WFMS" # Project details. Manufacturer before the dot, device after the dot.
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)
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
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_device_name: "lounge-cabinetleds"
@@ -82,24 +101,24 @@ substitutions:
mqtt_local_device_command_OFF: "OFF"
# Device Specific Settings
log_level: "NONE" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (default), VERBOSE, VERY_VERBOSE
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
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
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
log_level: "NONE" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (default), VERBOSE, VERY_VERBOSE
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
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
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
# Device Specific GPIO (so we can easily update for other devices)
device_status_led: GPIO02
device_mosfet_out: GPIO04
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_status_led: GPIO2
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_fading_led: GPIO13 # if no LED, this is just a fake/safeish choice so it compiles with the generic yaml
##########################################################################################
#:########################################################################################:#
# PACKAGES: Included Common Packages
# https://esphome.io/components/packages.html
##########################################################################################
#:########################################################################################:#
packages:
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
common_wifi: !include
@@ -108,6 +127,7 @@ packages:
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
@@ -121,27 +141,31 @@ packages:
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
#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
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
#:########################################################################################:#
# ESPHOME CORE CONFIGURATION
# https://esphome.io/components/esphome.html
##########################################################################################
#:########################################################################################:#
esphome:
name: "${device_name}"
friendly_name: "${friendly_name}"
comment: "${description_comment}"
area: "${device_area}"
project:
name: "${project_name}"
version: "${project_version}"
on_boot:
# Run later so everything is initialised before we touch states.
priority: 200
@@ -198,11 +222,11 @@ esphome:
# - -fdata-sections
# - -DNDEBUG
##########################################################################################
#:########################################################################################:#
# ESP PLATFORM AND FRAMEWORK
# https://esphome.io/components/esp8266.html
# https://esphome.io/components/esp32.html
##########################################################################################
#:########################################################################################:#
esp8266:
board: esp01_1m
restore_from_flash: true # restore some values on reboot
@@ -213,47 +237,52 @@ mdns:
preferences:
flash_write_interval: 2min # enough time to update values for reboots, but not enough to wear flash
##########################################################################################
#:########################################################################################:#
# GLOBAL VARIABLES
# https://esphome.io/components/globals.html
##########################################################################################
#:########################################################################################:#
globals:
# Minimum Brightness % for LEDs (will switch off if <=)
- id: min_brightness_pct
type: int
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)
- id: max_brightness_pct
type: int
restore_value: false
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
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
- id: max_on_hours
type: int
restore_value: true
initial_value: "${max_on_default_hours}"
# Compile time Gamma
- id: led_gamma_f
type: float
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)
- id: ramp_up_ms # fade-in when turned ON
- id: ramp_up_ms # fade-in when turned ON
type: int
restore_value: true
initial_value: '5000' # 5 s
initial_value: "5000" # 5 s
# 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
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)
- id: restart_mode
- id: restart_mode
type: int
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.
# true when you asked the light to end up ON (Ramp Up)
@@ -261,70 +290,78 @@ globals:
- id: ramp_switch_target_on
type: bool
restore_value: true
initial_value: 'false'
initial_value: "false"
# Prevent jitter when adjusting the slider
- id: suppress_slider_sync
type: bool
restore_value: false
initial_value: 'false'
# actual 0..100 seen last time, for restart
- id: last_brightness_pct
initial_value: "false"
# actual 0..100 seen last time, for restart
- id: last_brightness_pct
type: float
restore_value: true
initial_value: '0.0'
initial_value: "0.0"
# last published "Output Set (0-100)" integer
- id: last_set_pos
type: int
restore_value: false
initial_value: '-1'
# helper to keep blink time == transition time
initial_value: "-1"
# helper to keep blink time == transition time
- id: last_ramp_ms
type: int
restore_value: false
initial_value: '0'
initial_value: "0"
# target for "Restore Brightness" scripted ramp
- id: restore_target_pct
type: float
restore_value: false
initial_value: '0.0'
initial_value: "0.0"
# true while a scripted ramp is in progress (to limit flash writes)
- id: is_ramping
type: bool
restore_value: false
initial_value: 'false'
initial_value: "false"
# guards OFF persistence during startup caused by restore_mode: ALWAYS_OFF
- id: booting
type: bool
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
- id: ramping_for_off
type: bool
restore_value: false
initial_value: 'false'
initial_value: "false"
##########################################################################################
#:########################################################################################:#
# LOGGER COMPONENT
# https://esphome.io/components/logger.html
# Logs all log messages through the serial port and through MQTT topics.
##########################################################################################
#:########################################################################################:#
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)
#########################################################################################
#:########################################################################################:#
# STATUS LED
# https://esphome.io/components/status_led.html
#########################################################################################
#:########################################################################################:#
status_led:
pin:
number: ${device_status_led}
inverted: true
##########################################################################################
#:########################################################################################:#
# MQTT COMMANDS
# This adds device-specific MQTT command triggers to the common MQTT configuration.
##########################################################################################
#:########################################################################################:#
mqtt:
on_message:
# Light control to ramp up
@@ -332,16 +369,17 @@ mqtt:
payload: "${mqtt_local_device_command_ON}"
then:
- switch.turn_on: mosfet_ramp_switch
# Light control to ramp down
- topic: "${mqtt_local_command_topic}/light/set"
payload: "${mqtt_local_device_command_OFF}"
then:
- switch.turn_off: mosfet_ramp_switch
##########################################################################################
#:########################################################################################:#
# SWITCH COMPONENT
# https://esphome.io/components/switch/
##########################################################################################
#:########################################################################################:#
switch:
# Ramp-aware ON/OFF for HA (asymmetric, eased; no bounce)
- platform: template
@@ -361,10 +399,10 @@ switch:
- script.stop: ramp_on_script
- script.execute: ramp_off_script
#################################################################################################
#:########################################################################################:#
# BUTTON COMPONENT
# https://esphome.io/components/button/index.html
#################################################################################################
#:########################################################################################:#
button:
# Start ramping UP (from current level)
- platform: template
@@ -404,7 +442,7 @@ button:
id(ramping_for_off) = 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;
if (cv.is_on()) {
auto call = id(mosfet_leds).make_call();
@@ -420,12 +458,10 @@ button:
id(last_brightness_pct) = pct;
}
#########################################################################################
#:########################################################################################:#
# SELECT COMPONENT
# https://esphome.io/components/select/index.html
#########################################################################################
#:########################################################################################:#
select:
- platform: template
id: restart_action
@@ -447,10 +483,10 @@ select:
id(restart_mode) = 2;
}
#########################################################################################
#:########################################################################################:#
# BINARY SENSORS
# https://esphome.io/components/binary_sensor/
#########################################################################################
#:########################################################################################:#
binary_sensor:
- platform: gpio
id: btn_gpio12
@@ -483,10 +519,10 @@ binary_sensor:
- script.stop: ramp_off_script
- script.execute: ramp_on_script
##########################################################################################
#:########################################################################################:#
# SENSOR COMPONENT
# https://esphome.io/components/sensor/
##########################################################################################
#:########################################################################################:#
sensor:
- platform: template
id: mosfet_output_pct
@@ -494,7 +530,7 @@ sensor:
unit_of_measurement: "%"
icon: mdi:percent
accuracy_decimals: 0
update_interval: 2s # consider 200ms if you want fewer updates
update_interval: 2s # consider 200ms if you want fewer updates
lambda: |-
const auto &cv = id(mosfet_leds).current_values;
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;
return pwm * 100.0f;
##########################################################################################
#:########################################################################################:#
# 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.
# PWM Outputs such as "ledc" are float. https://esphome.io/components/output/ledc.html
##########################################################################################
#:########################################################################################:#
output:
- platform: esp8266_pwm
id: mosfet_pwm
pin: ${device_mosfet_out}
frequency: ${pwm_frequency}
- platform: gpio
id: green_led_out # Green LED
id: green_led_out # Green LED
pin:
number: ${device_fading_led}
inverted: false
##########################################################################################
#:########################################################################################:#
# LIGHT COMPONENT
# https://esphome.io/components/light/
##########################################################################################
#:########################################################################################:#
light:
- platform: monochromatic
id: mosfet_leds
@@ -619,11 +656,10 @@ light:
call.set_transition_length(0);
call.perform();
##########################################################################################
#:########################################################################################:#
# NUMBER COMPONENT
# https://esphome.io/components/number/
##########################################################################################
#:########################################################################################:#
number:
- platform: template
id: cfg_ramp_up_s
@@ -767,14 +803,13 @@ number:
then:
- script.execute: max_on_watchdog
##########################################################################################
#:########################################################################################:#
# SCRIPT COMPONENT
# https://esphome.io/components/script.html
# Scripts can be executed nearly anywhere in your device configuration with a single call.
##########################################################################################
#:########################################################################################:#
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
mode: restart
then:
@@ -880,7 +915,6 @@ script:
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)
- id: ramp_off_script
mode: restart
@@ -938,7 +972,7 @@ script:
- id: deferred_restore_brightness
mode: restart
then:
- delay: 5s # let preferences/globals load and light settle
- delay: 5s # let preferences/globals load and light settle
- lambda: |-
// Use ONLY the exact last saved brightness.
float target = id(last_brightness_pct);
@@ -968,4 +1002,4 @@ script:
- light.turn_off:
id: mosfet_leds
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
+155 -34
View File
@@ -1,31 +1,86 @@
##########################################################################################
##########################################################################################
# LOUNGE ENVIRONMENT SENSOR
#
# ESP32-C3 SuperMini + BME280 (I2C)
#
#:########################################################################################:#
# TITLE: LOUNGE ENVIRONMENT SENSOR
#:########################################################################################:#
# REPO:
# 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.1 2026-02-16 Added derived min/max sensors and pressure trend text sensors
# 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:
# Device Naming
device_name: "esp-loungeenvironment"
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"
# Project Naming
project_name: "ESP32-C3 SuperMini.BME280"
project_version: "v1.2"
project_version: "v1.5"
# Passwords
api_key: !secret esp-api_key
ota_pass: !secret esp-ota_pass
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
log_level: "WARN"
update_interval: "60s"
@@ -54,6 +109,7 @@ packages:
vars:
local_device_name: "${device_name}"
local_static_ip_address: "${static_ip_address}"
local_current_ip_address: "${current_ip_address}"
local_ota_pass: "${ota_pass}"
common_api: !include
@@ -73,10 +129,10 @@ packages:
common_sntp: !include common/sntp_common.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:
name: "${device_name}"
@@ -292,17 +348,26 @@ sensor:
name: "${friendly_name} Temperature"
id: lounge_temperature
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
accuracy_decimals: 2
on_value:
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: |-
auto now = id(sntp_time).now();
// We only need hour buckets and month stats if we have valid SNTP.
if (!now.is_valid()) return;
const int hour = now.hour;
const uint32_t now_ts = now.timestamp;
// Update hourly bucket (rolling 24h)
{
int idx = hour;
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;
}
// 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 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_max_temp_this_month)) || x > id(g_max_temp_this_month)) id(g_max_temp_this_month) = x;
pressure:
name: "${friendly_name} 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:
name: "${friendly_name} Humidity"
id: lounge_humidity
unit_of_measurement: "%"
device_class: humidity
state_class: measurement
accuracy_decimals: 1
on_value:
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: |-
auto now = id(sntp_time).now();
if (!now.is_valid()) return;
@@ -350,7 +436,6 @@ sensor:
const int hour = now.hour;
const uint32_t now_ts = now.timestamp;
// Update hourly bucket (rolling 24h)
{
int idx = hour;
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;
}
// Daily window tracking uses current_mins so it still works during fallback.
const int mins = id(current_mins);
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_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"
id: min_temp_today_overnight
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
accuracy_decimals: 2
update_interval: 60s
lambda: |-
return id(g_min_temp_today_overnight);
@@ -394,6 +480,9 @@ sensor:
name: "Highest Temp Today (Daytime)"
id: max_temp_today_daytime
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
accuracy_decimals: 2
update_interval: 60s
lambda: |-
return id(g_max_temp_today_daytime);
@@ -403,6 +492,9 @@ sensor:
name: "Highest Temp This Month"
id: max_temp_this_month
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
accuracy_decimals: 2
update_interval: 60s
lambda: |-
return id(g_max_temp_this_month);
@@ -412,6 +504,9 @@ sensor:
name: "Highest Temp Last Month"
id: max_temp_last_month
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
accuracy_decimals: 2
update_interval: 60s
lambda: |-
return id(g_max_temp_last_month);
@@ -421,6 +516,9 @@ sensor:
name: "Lowest Temp This Month"
id: min_temp_this_month
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
accuracy_decimals: 2
update_interval: 60s
lambda: |-
return id(g_min_temp_this_month);
@@ -430,6 +528,9 @@ sensor:
name: "Lowest Temp Last Month"
id: min_temp_last_month
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
accuracy_decimals: 2
update_interval: 60s
lambda: |-
return id(g_min_temp_last_month);
@@ -439,6 +540,9 @@ sensor:
name: "Lowest Temp Last 24 Hours"
id: min_temp_today
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
accuracy_decimals: 2
update_interval: 60s
lambda: |-
auto now = id(sntp_time).now();
@@ -460,6 +564,9 @@ sensor:
name: "Highest Temp Last 24 Hours"
id: max_temp_today
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
accuracy_decimals: 2
update_interval: 60s
lambda: |-
auto now = id(sntp_time).now();
@@ -481,6 +588,9 @@ sensor:
name: "Lowest Humidity Overnight"
id: min_humidity_today_overnight
unit_of_measurement: "%"
device_class: humidity
state_class: measurement
accuracy_decimals: 1
update_interval: 60s
lambda: |-
return id(g_min_humidity_today_overnight);
@@ -490,6 +600,9 @@ sensor:
name: "Highest Humidity Today (Daytime)"
id: max_humidity_today_daytime
unit_of_measurement: "%"
device_class: humidity
state_class: measurement
accuracy_decimals: 1
update_interval: 60s
lambda: |-
return id(g_max_humidity_today_daytime);
@@ -499,6 +612,9 @@ sensor:
name: "Highest Humidity This Month"
id: max_humidity_this_month
unit_of_measurement: "%"
device_class: humidity
state_class: measurement
accuracy_decimals: 1
update_interval: 60s
lambda: |-
return id(g_max_humidity_this_month);
@@ -508,6 +624,9 @@ sensor:
name: "Highest Humidity Last Month"
id: max_humidity_last_month
unit_of_measurement: "%"
device_class: humidity
state_class: measurement
accuracy_decimals: 1
update_interval: 60s
lambda: |-
return id(g_max_humidity_last_month);
@@ -517,6 +636,9 @@ sensor:
name: "Lowest Humidity This Month"
id: min_humidity_this_month
unit_of_measurement: "%"
device_class: humidity
state_class: measurement
accuracy_decimals: 1
update_interval: 60s
lambda: |-
return id(g_min_humidity_this_month);
@@ -526,6 +648,9 @@ sensor:
name: "Lowest Humidity Last Month"
id: min_humidity_last_month
unit_of_measurement: "%"
device_class: humidity
state_class: measurement
accuracy_decimals: 1
update_interval: 60s
lambda: |-
return id(g_min_humidity_last_month);
@@ -535,6 +660,9 @@ sensor:
name: "Lowest Humidity Last 24 Hours"
id: min_humidity_today
unit_of_measurement: "%"
device_class: humidity
state_class: measurement
accuracy_decimals: 1
update_interval: 60s
lambda: |-
auto now = id(sntp_time).now();
@@ -556,6 +684,9 @@ sensor:
name: "Highest Humidity Last 24 Hours"
id: max_humidity_today
unit_of_measurement: "%"
device_class: humidity
state_class: measurement
accuracy_decimals: 1
update_interval: 60s
lambda: |-
auto now = id(sntp_time).now();
@@ -577,6 +708,7 @@ sensor:
name: "Pressure Rate Per Hour (3h)"
id: pressure_rate_per_hour_3h
unit_of_measurement: "hPa/h"
state_class: measurement
accuracy_decimals: 2
update_interval: 60s
lambda: |-
@@ -584,7 +716,7 @@ sensor:
if (!now.is_valid()) return NAN;
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;
uint32_t best_dt = 0xFFFFFFFF;
@@ -610,12 +742,6 @@ sensor:
##########################################################################################
text_sensor:
# 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
name: "Pressure Direction, Last 3 Hours"
id: pressure_rising_or_falling_3_hours
@@ -625,7 +751,7 @@ text_sensor:
if (!now.is_valid()) return std::string("unknown");
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;
uint32_t best_dt = 0xFFFFFFFF;
@@ -689,7 +815,6 @@ interval:
const bool at_0700 = (mins == 420);
const bool at_2300 = (mins == 1380);
// Roll overnight window at 07:00
if (at_0700) {
id(g_min_temp_today_overnight) = id(g_work_min_temp_overnight);
id(g_work_min_temp_overnight) = NAN;
@@ -698,7 +823,6 @@ interval:
id(g_work_min_humidity_overnight) = NAN;
}
// Roll daytime window at 23:00
if (at_2300) {
id(g_max_temp_today_daytime) = id(g_work_max_temp_daytime);
id(g_work_max_temp_daytime) = NAN;
@@ -707,7 +831,6 @@ interval:
id(g_work_max_humidity_daytime) = NAN;
}
// Month rollover requires real date/time (SNTP valid)
auto now = id(sntp_time).now();
if (!now.is_valid()) return;
@@ -720,13 +843,11 @@ interval:
}
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_min_temp_last_month) = id(g_min_temp_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);
// Reset current month stats
id(g_max_temp_this_month) = NAN;
id(g_min_temp_this_month) = NAN;
id(g_max_humidity_this_month) = NAN;
+119 -60
View File
@@ -1,38 +1,90 @@
##########################################################################################
##########################################################################################
# LOUNGE MIDDLE LIGHTSwITCH
#:########################################################################################:#
# TITLE: 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
##########################################################################################
# Zemismart KS-811 Triple push button
# pinout/schematic https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
#
# NOTES
# -
#
##########################################################################################
##########################################################################################
#:########################################################################################:#
# HARDWARE:
# - Zemismart KS-811 Triple 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
# - 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)
##########################################################################################
#:########################################################################################:#
substitutions:
# Device Naming
device_name: "esp-loungemiddleswitch"
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.
# Project Naming
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
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-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
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_3_name: "Downlights North" # Lights are directly connected (2 downlights)
#########################################################################################
# PACKAGES: Included Common Packages
#:########################################################################################:#
# PACKAGES:
# Included Common Packages
# https://esphome.io/components/packages.html
##########################################################################################
#:########################################################################################:#
packages:
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
common_wifi: !include
@@ -62,6 +115,7 @@ packages:
vars:
local_device_name: "${device_name}"
local_static_ip_address: "${static_ip_address}"
local_current_ip_address: "${current_ip_address}"
local_ota_pass: "${ota_pass}"
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
@@ -79,6 +133,7 @@ packages:
#### 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
@@ -88,10 +143,10 @@ packages:
#diag_debug: !include common/include_debug_diag_sensors.yaml
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
#########################################################################################
# ESPHome
#:########################################################################################:#
# ESPHOME:
# https://esphome.io/components/esphome.html
#########################################################################################
#:########################################################################################:#
esphome:
name: "${device_name}"
friendly_name: "${friendly_name}"
@@ -101,9 +156,9 @@ esphome:
name: "${project_name}"
version: "${project_version}"
#########################################################################################
# Home Assistant API
#########################################################################################
#:########################################################################################:#
# HOME ASSISTANT API:
#:########################################################################################:#
api:
on_client_connected:
then:
@@ -137,38 +192,38 @@ api:
level: WARN
format: "API disconnected: switching to manual/offline behavior"
#########################################################################################
# ESP Platform and Framework
# https://esphome.io/components/esp32.html
#########################################################################################
#:########################################################################################:#
# ESP PLATFORM AND FRAMEWORK:
# https://esphome.io/components/esp8266.html
#:########################################################################################:#
esp8266:
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
#########################################################################################
# ESPHome Logging Enable
#:########################################################################################:#
# 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)
#esp8266_store_log_strings_in_flash: false
#tx_buffer_size: 64
#########################################################################################
# STATUS LED
#:########################################################################################:#
# STATUS LED:
# https://esphome.io/components/status_led.html
#########################################################################################
#:########################################################################################:#
status_led:
pin:
number: GPIO02
inverted: yes
number: GPIO2
inverted: true
#########################################################################################
# BINARY SENSORS
#:########################################################################################:#
# BINARY SENSORS:
# https://esphome.io/components/binary_sensor/
#########################################################################################
#:########################################################################################:#
binary_sensor:
# GPIO16 for KS-811 first button UNLESS
# it is a single button KS-811 in which case it is GPIO00
@@ -176,7 +231,7 @@ binary_sensor:
pin:
number: GPIO16
mode: INPUT
inverted: True
inverted: true
use_interrupt: false # This pin doesn't support interrupts so use polling. Only suppresses a warning.
name: "Button 1: ${switch_1_name}"
on_multi_click:
@@ -231,7 +286,8 @@ binary_sensor:
then:
- if:
condition:
lambda: 'return id(Relay_1).state;'
lambda: |-
return id(Relay_1).state;
then:
- switch.turn_off: Relay_1
- logger.log:
@@ -250,9 +306,9 @@ binary_sensor:
# GPIO05 for second button (only for KS-811-2 Double or -3 Triple)
- platform: gpio
pin:
number: GPIO05
number: GPIO5
mode: INPUT
inverted: True
inverted: true
name: "Button 2: ${switch_2_name}"
on_multi_click:
# --- Single short click ---
@@ -289,7 +345,8 @@ binary_sensor:
then:
- if:
condition:
lambda: 'return id(Relay_2).state;'
lambda: |-
return id(Relay_2).state;
then:
- switch.turn_off: Relay_2
- logger.log:
@@ -310,7 +367,7 @@ binary_sensor:
pin:
number: GPIO4
mode: INPUT
inverted: True
inverted: true
name: "Button 3: ${switch_3_name}"
on_multi_click:
# --- Single short click ---
@@ -347,7 +404,8 @@ binary_sensor:
then:
- if:
condition:
lambda: 'return id(Relay_3).state;'
lambda: |-
return id(Relay_3).state;
then:
- switch.turn_off: Relay_3
- logger.log:
@@ -363,9 +421,10 @@ binary_sensor:
level: INFO
format: "BTN3: Single click ignored (override OFF)"
#########################################################################################
# TEXT SENSOR COMPONENT
#########################################################################################
#:########################################################################################:#
# TEXT SENSOR COMPONENT:
# https://esphome.io/components/text_sensor/
#:########################################################################################:#
text_sensor:
- platform: homeassistant
id: ha_last_scene
@@ -376,10 +435,10 @@ text_sensor:
format: "HA last scene now: %s"
args: ["x.c_str()"]
#########################################################################################
# SWITCH COMPONENT
#:########################################################################################:#
# SWITCH COMPONENT:
# https://esphome.io/components/switch/
#########################################################################################
#:########################################################################################:#
switch:
# GPIO13 for KS-811 first button UNLESS it is KS-811-1 then it is GPIO12
- platform: gpio
@@ -436,7 +495,8 @@ switch:
- homeassistant.service:
service: script.lounge_set_scene
data:
scene_name: !lambda 'return id(ha_last_scene).state;'
scene_name: !lambda |-
return id(ha_last_scene).state;
- logger.log:
level: INFO
format: "HA Loss Test OFF: restored last scene: %s"
@@ -444,5 +504,4 @@ switch:
else:
- logger.log:
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)"
+123 -74
View File
@@ -1,41 +1,86 @@
##########################################################################################
##########################################################################################
# LOUNGE NORTH SWITCH (Single Switch into hallway)
#:########################################################################################:#
# TITLE: 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
##########################################################################################
# Zemismart KS-811 Single push button
# pinout/schematic https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
#:########################################################################################:#
# HARDWARE:
# - 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)
##########################################################################################
#:########################################################################################:#
substitutions:
# Device Naming
# Device Naming
device_name: "esp-loungenorthswitch"
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)"
device_area: "Lounge" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
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.
# Project Naming
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_name: "Zemismart Technologies.KS-811 Single" # Project Details
project_version: "v4.1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
# 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-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
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
# 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_device_command_on: "On"
#mqtt_remote_device_command_off: "Off"
# 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
#########################################################################################
# PACKAGES: Included Common Packages
#:########################################################################################:#
# PACKAGES:
# Included Common Packages
# https://esphome.io/components/packages.html
##########################################################################################
#:########################################################################################:#
packages:
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
common_wifi: !include
@@ -64,6 +110,7 @@ packages:
vars:
local_device_name: "${device_name}"
local_static_ip_address: "${static_ip_address}"
local_current_ip_address: "${current_ip_address}"
local_ota_pass: "${ota_pass}"
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
@@ -78,23 +125,23 @@ packages:
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
#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
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
#:########################################################################################:#
# ESPHOME:
# https://esphome.io/components/esphome.html
#########################################################################################
#:########################################################################################:#
esphome:
name: "${device_name}"
friendly_name: "${friendly_name}"
@@ -104,6 +151,9 @@ esphome:
name: "${project_name}"
version: "${project_version}"
#:########################################################################################:#
# HOME ASSISTANT API:
#:########################################################################################:#
api:
on_client_connected:
then:
@@ -125,44 +175,44 @@ api:
level: WARN
format: "API disconnected: switching to manual/offline behavior"
#########################################################################################
# ESP Platform and Framework
# https://esphome.io/components/esp32.html
#########################################################################################
#:########################################################################################:#
# ESP PLATFORM AND FRAMEWORK:
# https://esphome.io/components/esp8266.html
#:########################################################################################:#
esp8266:
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
#########################################################################################
# ESPHome Logging Enable
#:########################################################################################:#
# 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)
#esp8266_store_log_strings_in_flash: false
#tx_buffer_size: 64
#########################################################################################
# STATUS LED
#:########################################################################################:#
# STATUS LED:
# https://esphome.io/components/status_led.html
#########################################################################################
#:########################################################################################:#
status_led:
pin:
number: GPIO02
inverted: yes
number: GPIO2
inverted: true
#########################################################################################
# BINARY SENSORS
#:########################################################################################:#
# BINARY SENSORS:
# https://esphome.io/components/binary_sensor/
#########################################################################################
#:########################################################################################:#
binary_sensor:
- platform: gpio
pin:
number: GPIO0
mode: INPUT
inverted: True
inverted: true
name: "Button 1: ${switch_1_name}"
on_multi_click:
@@ -183,7 +233,7 @@ binary_sensor:
scene_name: "Night Light"
- logger.log:
level: INFO
format: "BTN: Double click Scene Night Light"
format: "BTN: Double click -> Scene Night Light"
else:
- logger.log:
level: INFO
@@ -191,8 +241,8 @@ binary_sensor:
# --- Single short click ---
# Online (and override ON): use HA's last scene to decide.
# If last != "All Off" send "All Off"
# If last == "All Off" send "Bright"
# If last != "All Off" -> send "All Off"
# If last == "All Off" -> send "Bright"
# Offline (and override ON): toggle physical Relay_1
- timing:
- ON for at most 0.5s
@@ -218,7 +268,7 @@ binary_sensor:
scene_name: "All Off"
- logger.log:
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:
- homeassistant.service:
service: script.lounge_set_scene
@@ -226,7 +276,7 @@ binary_sensor:
scene_name: "Bright"
- logger.log:
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:
# OFFLINE path: only act if override ON; toggle physical relay
- if:
@@ -238,17 +288,18 @@ binary_sensor:
then:
- if:
condition:
lambda: 'return id(Relay_1).state;'
lambda: |-
return id(Relay_1).state;
then:
- switch.turn_off: Relay_1
- logger.log:
level: INFO
format: "BTN: Single click (offline) Relay_1 OFF"
format: "BTN: Single click (offline) -> Relay_1 OFF"
else:
- switch.turn_on: Relay_1
- logger.log:
level: INFO
format: "BTN: Single click (offline) Relay_1 ON"
format: "BTN: Single click (offline) -> Relay_1 ON"
else:
- logger.log:
level: INFO
@@ -272,16 +323,16 @@ binary_sensor:
action: "hold"
- logger.log:
level: INFO
format: "BTN: Long press Scene All Off + HA event (hold)"
format: "BTN: Long press -> Scene All Off + HA event (hold)"
else:
- logger.log:
level: INFO
format: "BTN: Long press ignored (no HA connection)"
#########################################################################################
# TEXT SENSOR COMPONENT
#
#########################################################################################
#:########################################################################################:#
# TEXT SENSOR COMPONENT:
# https://esphome.io/components/text_sensor/
#:########################################################################################:#
text_sensor:
- platform: homeassistant
id: ha_last_scene
@@ -292,13 +343,13 @@ text_sensor:
level: DEBUG
format: "HA last scene now: %s"
args: ["x.c_str()"]
#########################################################################################
# SWITCH COMPONENT
#:########################################################################################:#
# SWITCH COMPONENT:
# https://esphome.io/components/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
name: "Relay 1: ${switch_1_name}"
pin: GPIO12
@@ -310,6 +361,4 @@ switch:
name: "HA Loss manual override"
id: ha_loss_override
optimistic: true
restore_mode: RESTORE_DEFAULT_ON
restore_mode: RESTORE_DEFAULT_ON
+280 -221
View File
@@ -1,83 +1,95 @@
##########################################################################################
##########################################################################################
# Title: LOUNGE - PELMET LEDS (H801, 2x Monochrome PWM)
# Repo: (new)
#:########################################################################################:#
# TITLE: LOUNGE - PELMET LEDS (H801, 2x Monochrome PWM)
# zorruno.com layout v1.1 2026
#:########################################################################################:#
# 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
# v2.0-dual - 2025-09-30 Based on single MOSFET version; adapted to H801 dual-monochrome (A/B).
# v1.x (history from single-channel base maintained in comments below)
# b) MQTT offline (or HA/MQTT offline):
# - MQTT is not enabled in this yaml, so MQTT offline has no direct effect on device logic.
# - If Home Assistant/API is also offline, control from HA is unavailable.
#
# ------------------------------------------
# OPERATION (as of v2.x)
# ------------------------------------------
# 1. General-purpose LED controller.
# 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]
#
##########################################################################################
##########################################################################################
# c) Entire WiFi/Network offline:
# - Device continues to run its local light logic and stored restart behaviour.
# - No HA or MQTT control 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)
##########################################################################################
#:########################################################################################:#
substitutions:
# Device Naming
device_name: "esp-loungepelmetleds2" # yaml file should be device_name.yaml
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.
# Project Naming
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
ota_pass: !secret esp-ota_pass
static_ip_address: !secret esp-loungepelmetleds2_ip # CHANGE THIS
ota_pass: !secret esp-ota_pass
static_ip_address: !secret esp-loungepelmetleds2_ip
current_ip_address: ${static_ip_address}
# Device Specific Settings (shared defaults applied per channel below)
log_level: "NONE" # Use INFO while testing; flip back to NONE later
update_interval: "60s"
led_gamma: "1.6"
pwm_frequency: "1000Hz"
log_level: "NONE" # Use INFO while testing; flip back to NONE later
update_interval: "60s"
led_gamma: "1.6"
pwm_frequency: "1000Hz"
max_on_default_hours: "24"
# Per-channel output caps (%), internal-only (no HA sliders)
@@ -87,49 +99,64 @@ substitutions:
maximum_led_output_B: "90"
# Device Specific GPIO
#device_status_led: GPIO05
#device_status_led: GPIO5
device_mosfet_out_A: GPIO15
device_mosfet_out_B: GPIO13
device_fading_led_A: GPIO05
device_fading_led_B: GPIO01
device_fading_led_A: GPIO5
device_fading_led_B: GPIO1
##########################################################################################
# PACKAGES
##########################################################################################
#:########################################################################################:#
# 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_current_ip_address: "${current_ip_address}"
local_ota_pass: "${ota_pass}"
#### 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
#common_sntp: !include common/sntp_common.yaml
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
#### SNTP (Only use if you want/need accurate timeclocks) ####
#common_sntp: !include common/sntp_common.yaml
##########################################################################################
# ESPHome CORE CONFIGURATION
##########################################################################################
#### DIAGNOSTICS Sensors ####
diag_basic: !include common/include_basic_diag_sensors.yaml
#diag_more: !include common/include_more_diag_sensors.yaml
#diag_debug: !include common/include_debug_diag_sensors.yaml
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
#:########################################################################################:#
# ESPHOME CORE CONFIGURATION:
# https://esphome.io/components/esphome.html
#:########################################################################################:#
esphome:
name: "${device_name}"
friendly_name: "${friendly_name}"
comment: "${description_comment}"
area: "${device_area}"
project:
name: "${project_name}"
version: "${project_version}"
on_boot:
priority: 200
then:
@@ -171,9 +198,22 @@ esphome:
transition_length: 0s
- lambda: 'id(booting) = false;'
##########################################################################################
# ESP PLATFORM AND FRAMEWORK
##########################################################################################
# Only if you want to play with build flags...
# 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:
board: esp01_1m
restore_from_flash: true
@@ -182,25 +222,29 @@ mdns:
disabled: true
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:
# Per-channel brightness caps (internal; set via YAML substitutions)
- id: min_brightness_pct_A
type: int
restore_value: true
initial_value: "${minimum_led_output_A}"
- id: max_brightness_pct_A
type: int
restore_value: false
initial_value: "${maximum_led_output_A}"
- id: min_brightness_pct_B
type: int
restore_value: true
initial_value: "${minimum_led_output_B}"
- id: max_brightness_pct_B
type: int
restore_value: false
@@ -216,123 +260,146 @@ globals:
- id: ramp_up_ms_A
type: int
restore_value: true
initial_value: '5000'
initial_value: "5000"
- id: ramp_down_ms_A
type: int
restore_value: true
initial_value: '10000'
initial_value: "10000"
- id: ramp_up_ms_B
type: int
restore_value: true
initial_value: '5000'
initial_value: "5000"
- id: ramp_down_ms_B
type: int
restore_value: true
initial_value: '10000'
initial_value: "10000"
# Restart Action. (0=Fade full, 1=Restore brightness, 2=Remain off)
- id: restart_mode
type: int
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)
- id: ramp_switch_target_on_A
type: bool
restore_value: true
initial_value: 'false'
initial_value: "false"
- id: suppress_slider_sync_A
type: bool
restore_value: false
initial_value: 'false'
- id: suppress_quick_on_A # guard to prevent quick-to-cap on slider turn-on
initial_value: "false"
- id: suppress_quick_on_A
type: bool
restore_value: false
initial_value: 'false'
initial_value: "false"
- id: last_brightness_pct_A
type: float
restore_value: true
initial_value: '0.0'
initial_value: "0.0"
- id: last_set_pos_A
type: int
restore_value: false
initial_value: '-1'
initial_value: "-1"
- id: last_ramp_ms_A
type: uint32_t
restore_value: false
initial_value: '0'
initial_value: "0"
- id: last_nonzero_brightness_pct_A
type: float
restore_value: true
initial_value: '0.0'
initial_value: "0.0"
- id: restore_target_pct_A
type: float
restore_value: false
initial_value: '0.0'
initial_value: "0.0"
- id: is_ramping_A
type: bool
restore_value: false
initial_value: 'false'
initial_value: "false"
- id: last_nonzero_tmp_A
type: float
restore_value: false
initial_value: '0.0'
initial_value: "0.0"
- id: ramping_for_off_A
type: bool
restore_value: false
initial_value: 'false'
initial_value: "false"
# Per-channel runtime state (B)
- id: ramp_switch_target_on_B
type: bool
restore_value: true
initial_value: 'false'
initial_value: "false"
- id: suppress_slider_sync_B
type: bool
restore_value: false
initial_value: 'false'
- id: suppress_quick_on_B # guard to prevent quick-to-cap on slider turn-on
initial_value: "false"
- id: suppress_quick_on_B
type: bool
restore_value: false
initial_value: 'false'
initial_value: "false"
- id: last_brightness_pct_B
type: float
restore_value: true
initial_value: '0.0'
initial_value: "0.0"
- id: last_set_pos_B
type: int
restore_value: false
initial_value: '-1'
initial_value: "-1"
- id: last_ramp_ms_B
type: uint32_t
restore_value: false
initial_value: '0'
initial_value: "0"
- id: last_nonzero_brightness_pct_B
type: float
restore_value: true
initial_value: '0.0'
initial_value: "0.0"
- id: restore_target_pct_B
type: float
restore_value: false
initial_value: '0.0'
initial_value: "0.0"
- id: is_ramping_B
type: bool
restore_value: false
initial_value: 'false'
initial_value: "false"
- id: last_nonzero_tmp_B
type: float
restore_value: false
initial_value: '0.0'
initial_value: "0.0"
- id: ramping_for_off_B
type: bool
restore_value: false
initial_value: 'false'
initial_value: "false"
# Guard for startup behaviour
- id: booting
type: bool
restore_value: false
initial_value: 'true'
initial_value: "true"
# Compile time Gamma (cached; currently unused since PWM% sensors were removed)
- id: led_gamma_f
@@ -340,48 +407,51 @@ globals:
restore_value: false
initial_value: ${led_gamma}
##########################################################################################
# LOGGER
##########################################################################################
#:########################################################################################:#
# LOGGER:
# https://esphome.io/components/logger.html
#:########################################################################################:#
logger:
level: "${log_level}"
baud_rate: 0
#########################################################################################
# STATUS LED
#########################################################################################
#:########################################################################################:#
# STATUS LED:
# https://esphome.io/components/status_led.html
#:########################################################################################:#
#status_led:
# pin:
# number: ${device_status_led}
# inverted: true
##########################################################################################
# MQTT COMMANDS
##########################################################################################
#:########################################################################################:#
# MQTT COMMANDS:
#:########################################################################################:#
#mqtt:
# on_message handlers commented for efficiency (S8). Uncomment if you need local MQTT control again.
#on_message:
# - topic: "${mqtt_local_command_topic_A}/lightA/set"
# payload: "${mqtt_local_device_command_ON}"
# then:
# - switch.turn_on: mosfet_ramp_switch_a
# - topic: "${mqtt_local_command_topic_A}/lightA/set"}
# payload: "${mqtt_local_device_command_OFF}"
# then:
# - switch.turn_off: mosfet_ramp_switch_a
#
# - topic: "${mqtt_local_command_topic_B}/lightB/set"
# payload: "${mqtt_local_device_command_ON}"
# then:
# - switch.turn_on: mosfet_ramp_switch_b
# - topic: "${mqtt_local_command_topic_B}/lightB/set"
# payload: "${mqtt_local_device_command_OFF}"
# then:
# - switch.turn_off: mosfet_ramp_switch_b
# on_message handlers commented for efficiency. Uncomment if you need local MQTT control again.
# on_message:
# - topic: "${mqtt_local_command_topic_A}/lightA/set"
# payload: "${mqtt_local_device_command_ON}"
# then:
# - switch.turn_on: mosfet_ramp_switch_a
# - topic: "${mqtt_local_command_topic_A}/lightA/set"
# payload: "${mqtt_local_device_command_OFF}"
# then:
# - switch.turn_off: mosfet_ramp_switch_a
#
# - topic: "${mqtt_local_command_topic_B}/lightB/set"
# payload: "${mqtt_local_device_command_ON}"
# then:
# - switch.turn_on: mosfet_ramp_switch_b
# - topic: "${mqtt_local_command_topic_B}/lightB/set"
# payload: "${mqtt_local_device_command_OFF}"
# then:
# - switch.turn_off: mosfet_ramp_switch_b
##########################################################################################
# SWITCHES
##########################################################################################
#:########################################################################################:#
# SWITCH COMPONENT:
# https://esphome.io/components/switch/
#:########################################################################################:#
switch:
- platform: template
id: mosfet_ramp_switch_a
@@ -417,13 +487,15 @@ switch:
- script.stop: ramp_on_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:
- platform: template
id: restart_action
@@ -445,9 +517,10 @@ select:
id(restart_mode) = 2;
}
##########################################################################################
# SENSORS
##########################################################################################
#:########################################################################################:#
# SENSOR COMPONENT:
# https://esphome.io/components/sensor/
#:########################################################################################:#
sensor:
# Channel A: Output % (pre-gamma)
- platform: template
@@ -456,7 +529,7 @@ sensor:
unit_of_measurement: "%"
icon: mdi:percent
accuracy_decimals: 0
update_interval: 200ms # show real-time ramp
update_interval: 200ms
disabled_by_default: true
lambda: |-
const auto &cv = id(mosfet_leds_A).current_values;
@@ -488,22 +561,21 @@ sensor:
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)) {
float cap = (float) id(max_brightness_pct_A); // cap in %
float low_th = cap * 0.33f;
float cap = (float) id(max_brightness_pct_A);
float low_th = cap * 0.33f;
float high_th = cap * 0.66f;
if (cv_now.is_on()) {
float b = x; // current brightness in %
if (b < low_th - 0.25f) { // hysteresis margin
float b = x;
if (b < low_th - 0.25f) {
if (id(ramp_switch_target_on_A)) {
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) {
if (!id(ramp_switch_target_on_A)) {
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);
}
}
// Auto-sync fade switch to brightness thresholds (no scripts)
if (!id(booting) && !id(is_ramping_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;
if (cv_now.is_on()) {
float b = x;
@@ -569,14 +640,16 @@ sensor:
}
}
##########################################################################################
# OUTPUTS
##########################################################################################
#:########################################################################################:#
# OUTPUT COMPONENT:
# https://esphome.io/components/output/
#:########################################################################################:#
output:
- platform: esp8266_pwm
id: mosfet_pwm_A
pin: ${device_mosfet_out_A}
frequency: ${pwm_frequency}
- platform: esp8266_pwm
id: mosfet_pwm_B
pin: ${device_mosfet_out_B}
@@ -587,27 +660,28 @@ output:
pin:
number: ${device_fading_led_A}
inverted: false
- platform: gpio
id: fading_led_out_B
pin:
number: ${device_fading_led_B}
inverted: false
##########################################################################################
# LIGHTS
##########################################################################################
#:########################################################################################:#
# LIGHT COMPONENT:
# https://esphome.io/components/light/
#:########################################################################################:#
light:
- platform: monochromatic
id: mosfet_leds_A
name: "${friendly_name} A"
output: mosfet_pwm_A
restore_mode: RESTORE_DEFAULT_OFF
default_transition_length: 250ms # quick ramp for normal light toggle
default_transition_length: 250ms
icon: mdi:led-strip-variant
gamma_correct: "${led_gamma}"
on_turn_on:
# Start/refresh Max-On watchdog quietly whenever light turns on
- if:
condition:
lambda: 'return id(max_on_hours) > 0;'
@@ -628,13 +702,11 @@ light:
on_state:
- lambda: |-
// Mirror board RED LED to this channel's on/off
const auto &cv_s = id(mosfet_leds_A).current_values;
const bool is_on = cv_s.is_on() && (cv_s.get_brightness() > 0.0005f);
if (is_on) id(fading_led_out_A).turn_on();
else id(fading_led_out_A).turn_off();
- lambda: |-
// Enforce cap if anyone tries to exceed it
const float cap = id(max_brightness_pct_A) / 100.0f;
const auto &cv = id(mosfet_leds_A).current_values;
if (!cv.is_on()) return;
@@ -651,7 +723,7 @@ light:
name: "${friendly_name} B"
output: mosfet_pwm_B
restore_mode: RESTORE_DEFAULT_OFF
default_transition_length: 250ms # quick ramp for normal light toggle
default_transition_length: 250ms
icon: mdi:led-strip-variant
gamma_correct: "${led_gamma}"
@@ -676,7 +748,6 @@ light:
on_state:
- lambda: |-
// Mirror board GREEN LED to this channel's on/off
const auto &cv_s = id(mosfet_leds_B).current_values;
const bool is_on = cv_s.is_on() && (cv_s.get_brightness() > 0.0005f);
if (is_on) id(fading_led_out_B).turn_on();
@@ -693,9 +764,10 @@ light:
call.set_transition_length(0);
call.perform();
##########################################################################################
# NUMBERS
##########################################################################################
#:########################################################################################:#
# NUMBER COMPONENT:
# https://esphome.io/components/number/
#:########################################################################################:#
number:
- platform: template
id: cfg_ramp_up_s_A
@@ -777,7 +849,6 @@ number:
id(ramp_down_ms_B) = secs * 1000;
id(cfg_ramp_down_s_B).publish_state((float) secs);
# Per-channel position slider (0..100 mapped into [min..max])
- platform: template
id: led_output_set_pct_A
name: "${friendly_name} A Output Set (0-100)"
@@ -788,11 +859,11 @@ number:
step: 1
lambda: |-
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 maxp = (float) id(max_brightness_pct_A);
if (maxp <= minp) maxp = minp + 1.0f; // avoid div/0
if (actual <= 0.0f) return 0.0f; // when OFF, show 0
if (maxp <= minp) maxp = minp + 1.0f;
if (actual <= 0.0f) return 0.0f;
float pos = (actual - minp) * 100.0f / (maxp - minp);
if (pos < 0.0f) pos = 0.0f;
if (pos > 100.0f) pos = 100.0f;
@@ -817,22 +888,19 @@ number:
else:
- lambda: |-
id(suppress_slider_sync_A) = true;
float pos = x; // 0..100
if (pos < 1.0f) pos = 1.0f; // 0 is OFF
float pos = x;
if (pos < 1.0f) pos = 1.0f;
if (pos > 100.0f) pos = 100.0f;
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 maxp = (float) id(max_brightness_pct_A);
if (maxp <= minp) maxp = minp + 1.0f;
float out_pct = minp + (pos * (maxp - minp) / 100.0f);
if (out_pct > maxp) out_pct = maxp;
// Stash target for the ramp script
id(restore_target_pct_A) = out_pct;
// Choose duration by direction (up vs down)
const auto &cv = id(mosfet_leds_A).current_values;
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);
@@ -852,11 +920,11 @@ number:
step: 1
lambda: |-
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 maxp = (float) id(max_brightness_pct_B);
if (maxp <= minp) maxp = minp + 1.0f; // avoid div/0
if (actual <= 0.0f) return 0.0f; // when OFF, show 0
if (maxp <= minp) maxp = minp + 1.0f;
if (actual <= 0.0f) return 0.0f;
float pos = (actual - minp) * 100.0f / (maxp - minp);
if (pos < 0.0f) pos = 0.0f;
if (pos > 100.0f) pos = 100.0f;
@@ -881,22 +949,19 @@ number:
else:
- lambda: |-
id(suppress_slider_sync_B) = true;
float pos = x; // 0..100
if (pos < 1.0f) pos = 1.0f; // 0 is OFF
float pos = x;
if (pos < 1.0f) pos = 1.0f;
if (pos > 100.0f) pos = 100.0f;
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 maxp = (float) id(max_brightness_pct_B);
if (maxp <= minp) maxp = minp + 1.0f;
float out_pct = minp + (pos * (maxp - minp) / 100.0f);
if (out_pct > maxp) out_pct = maxp;
// Stash target for the ramp script
id(restore_target_pct_B) = out_pct;
// Choose duration by direction (up vs down)
const auto &cv = id(mosfet_leds_B).current_values;
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);
@@ -906,8 +971,6 @@ number:
- delay: !lambda 'return (uint32_t) id(last_ramp_ms_B);'
- lambda: 'id(suppress_slider_sync_B) = false;'
# Shared "Max On" hours (0=disabled). When light is turned on, watchdog restarts.
- platform: template
id: cfg_max_on_hours
name: "${friendly_name} Max On (h)"
@@ -923,11 +986,10 @@ number:
set_action:
- lambda: |-
int hrs = (int) x;
if (hrs < 0) hrs = 0;
if (hrs < 0) hrs = 0;
if (hrs > 48) hrs = 48;
id(max_on_hours) = hrs;
id(cfg_max_on_hours).publish_state((float) hrs);
# Restart/stop watchdogs appropriately for both channels
- if:
condition:
lambda: 'return id(mosfet_leds_A).current_values.is_on();'
@@ -949,9 +1011,10 @@ number:
then:
- script.execute: max_on_watchdog_B
##########################################################################################
# SCRIPTS
##########################################################################################
#:########################################################################################:#
# SCRIPT COMPONENT:
# https://esphome.io/components/script.html
#:########################################################################################:#
script:
# Ramps: Channel A
- id: ramp_on_script_A
@@ -959,7 +1022,6 @@ script:
then:
- lambda: 'id(is_ramping_A) = true;'
- script.stop: ramp_off_script_A
# Single transition to CAP for the full configured time
- light.turn_on:
id: mosfet_leds_A
brightness: !lambda 'return id(max_brightness_pct_A) / 100.0f;'
@@ -1000,7 +1062,6 @@ script:
id(is_ramping_A) = true;
id(ramping_for_off_A) = true;
- script.stop: ramp_on_script_A
# Single transition directly to OFF for the full configured time
- light.turn_off:
id: mosfet_leds_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 maxp = (float) id(max_brightness_pct_A);
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(last_ramp_ms_A) = id(ramp_up_ms_A);
- if:
@@ -1048,14 +1109,14 @@ script:
then:
- lambda: |-
id(ramp_switch_target_on_A) = true;
id(suppress_slider_sync_A) = true;
id(suppress_quick_on_A) = true;
id(suppress_slider_sync_A) = true;
id(suppress_quick_on_A) = true;
- script.stop: ramp_off_script_A
- script.execute: ramp_to_target_script_A
- delay: !lambda 'return (uint32_t) id(last_ramp_ms_A);'
- lambda: |-
id(suppress_slider_sync_A) = false;
id(suppress_quick_on_A) = false;
id(suppress_slider_sync_A) = false;
id(suppress_quick_on_A) = false;
else:
- lambda: 'id(ramp_switch_target_on_A) = false;'
- light.turn_off:
@@ -1146,7 +1207,7 @@ script:
float minp = (float) id(min_brightness_pct_B);
float maxp = (float) id(max_brightness_pct_B);
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(last_ramp_ms_B) = id(ramp_up_ms_B);
- if:
@@ -1155,18 +1216,16 @@ script:
then:
- lambda: |-
id(ramp_switch_target_on_B) = true;
id(suppress_slider_sync_B) = true;
id(suppress_quick_on_B) = true;
id(suppress_slider_sync_B) = true;
id(suppress_quick_on_B) = true;
- script.stop: ramp_off_script_B
- script.execute: ramp_to_target_script_B
- delay: !lambda 'return (uint32_t) id(last_ramp_ms_B);'
- lambda: |-
id(suppress_slider_sync_B) = false;
id(suppress_quick_on_B) = false;
id(suppress_slider_sync_B) = false;
id(suppress_quick_on_B) = false;
else:
- lambda: 'id(ramp_switch_target_on_B) = false;'
- light.turn_off:
id: mosfet_leds_B
transition_length: 0s
##########################################################################################
##########################################################################################
transition_length: 0s
+116 -60
View File
@@ -1,35 +1,86 @@
##########################################################################################
##########################################################################################
# LOUNGE SOUTH LEFT LIGHTSWITCH
#:########################################################################################:#
# TITLE: 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
##########################################################################################
# Zemismart KS-811 Double push button
# pinout/schematic https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
#:########################################################################################:#
# HARDWARE:
# - 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)
##########################################################################################
#:########################################################################################:#
substitutions:
# Device Naming
# Device Naming
device_name: "esp-loungesouthleftswitch"
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)"
device_area: "Lounge" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
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.
# Project Naming
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_name: "Zemismart Technologies.KS-811 Double" # Project Details
project_version: "v4.1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
# 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-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_status_main_topic: !secret mqtt_status_main_topic
@@ -41,19 +92,19 @@ substitutions:
# MQTT REMOTE Controls
mqtt_remote_device_name: "garage-corridor-lights"
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_OFF: "OFF"
# Switch Naming
switch_1_name: "Wall Washer Left"
switch_2_name: "Outside Light 1"
#switch_3_name: "Nil"
#########################################################################################
# PACKAGES: Included Common Packages
#:########################################################################################:#
# PACKAGES:
# Included Common Packages
# https://esphome.io/components/packages.html
##########################################################################################
#:########################################################################################:#
packages:
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
common_wifi: !include
@@ -62,6 +113,7 @@ packages:
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
@@ -75,23 +127,23 @@ packages:
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
#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
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
#:########################################################################################:#
# ESPHOME:
# https://esphome.io/components/esphome.html
#########################################################################################
#:########################################################################################:#
esphome:
name: "${device_name}"
friendly_name: "${friendly_name}"
@@ -101,64 +153,71 @@ esphome:
name: "${project_name}"
version: "${project_version}"
#########################################################################################
# ESP Platform and Framework
# https://esphome.io/components/esp32.html
#########################################################################################
#:########################################################################################:#
# ESP PLATFORM AND FRAMEWORK:
# https://esphome.io/components/esp8266.html
#:########################################################################################:#
esp8266:
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
#########################################################################################
# ESPHome Logging Enable
#:########################################################################################:#
# 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)
#esp8266_store_log_strings_in_flash: false
#tx_buffer_size: 64
#:########################################################################################:#
# GLOBAL VARIABLES:
#:########################################################################################:#
globals:
- id: relay2_change_origin_remote
type: bool
restore_value: no
restore_value: false
initial_value: "false"
#########################################################################################
# STATUS LED
#:########################################################################################:#
# STATUS LED:
# https://esphome.io/components/status_led.html
#########################################################################################
#:########################################################################################:#
status_led:
pin:
number: GPIO2
inverted: yes
inverted: true
#########################################################################################
# BINARY SENSORS
#:########################################################################################:#
# BINARY SENSORS:
# https://esphome.io/components/binary_sensor/
#########################################################################################
#:########################################################################################:#
binary_sensor:
- platform: gpio
pin:
number: GPIO16
mode: INPUT
inverted: True
use_interrupt: false # This pin doesn't support interrupts so use polling. Only supresses a warning.
inverted: true
use_interrupt: false # This pin doesn't support interrupts so use polling. Only suppresses a warning.
name: "Button 1: ${switch_1_name}"
on_press:
- switch.toggle: Relay_1
- platform: gpio
pin:
number: GPIO05
number: GPIO5
mode: INPUT
inverted: True
inverted: true
name: "Button 2: ${switch_2_name}"
on_press:
- switch.toggle: Relay_2
#:########################################################################################:#
# TEXT SENSOR COMPONENT:
# https://esphome.io/components/text_sensor/
#:########################################################################################:#
text_sensor:
- platform: mqtt_subscribe
id: remote2_status
@@ -192,10 +251,10 @@ text_sensor:
id(relay2_change_origin_remote) = true;
- switch.turn_off: Relay_2
#########################################################################################
# SWITCH COMPONENT
#:########################################################################################:#
# SWITCH COMPONENT:
# https://esphome.io/components/switch/
#########################################################################################
#:########################################################################################:#
switch:
- platform: gpio
name: "Relay 1: ${switch_1_name}"
@@ -223,7 +282,4 @@ switch:
- mqtt.publish:
topic: "${mqtt_remote_command_topic}"
payload: "${mqtt_remote_device_command_OFF}"
- lambda: 'id(relay2_change_origin_remote) = false;'
- lambda: 'id(relay2_change_origin_remote) = false;'
+111 -61
View File
@@ -1,37 +1,82 @@
##########################################################################################
##########################################################################################
# LOUNGE SOUTH RIGHT LIGHTSWITCH
#:########################################################################################:#
# TITLE: 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
##########################################################################################
# Zemismart KS-811 Triple push button
# pinout/schematic https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
#
# NOTES
# -
##########################################################################################
##########################################################################################
#:########################################################################################:#
# HARDWARE:
# - Zemismart KS-811 Triple 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
# - 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)
##########################################################################################
#:########################################################################################:#
substitutions:
# Device Naming
# Device Naming
device_name: "esp-loungesouthrightswitch"
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)"
device_area: "Lounge" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
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.
# Project Naming
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_name: "Zemismart Technologies.KS-811 Triple" # Project Details
project_version: "v4.1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
# 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-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
#relay_icon: "mdi:lightbulb-group"
@@ -46,12 +91,13 @@ substitutions:
# Switch Naming
switch_1_name: "Spare"
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
##########################################################################################
#:########################################################################################:#
packages:
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
common_wifi: !include
@@ -59,6 +105,7 @@ packages:
vars:
local_device_name: "${device_name}"
local_static_ip_address: "${static_ip_address}"
local_current_ip_address: "${current_ip_address}"
local_ota_pass: "${ota_pass}"
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
@@ -73,23 +120,23 @@ packages:
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
#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
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
#:########################################################################################:#
# ESPHOME:
# https://esphome.io/components/esphome.html
#########################################################################################
#:########################################################################################:#
esphome:
name: "${device_name}"
friendly_name: "${friendly_name}"
@@ -99,6 +146,9 @@ esphome:
name: "${project_name}"
version: "${project_version}"
#:########################################################################################:#
# HOME ASSISTANT API:
#:########################################################################################:#
api:
on_client_connected:
then:
@@ -120,54 +170,54 @@ api:
level: WARN
format: "API disconnected: switching to manual/offline behavior"
#########################################################################################
# ESP Platform and Framework
# https://esphome.io/components/esp32.html
#########################################################################################
#:########################################################################################:#
# ESP PLATFORM AND FRAMEWORK:
# https://esphome.io/components/esp8266.html
#:########################################################################################:#
esp8266:
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
#########################################################################################
# ESPHome Logging Enable
#:########################################################################################:#
# 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)
#esp8266_store_log_strings_in_flash: false
#tx_buffer_size: 64
#########################################################################################
# STATUS LED
#:########################################################################################:#
# STATUS LED:
# https://esphome.io/components/status_led.html
#########################################################################################
#:########################################################################################:#
status_led:
pin:
number: GPIO2
inverted: yes
inverted: true
#########################################################################################
# BINARY SENSORS
#:########################################################################################:#
# BINARY SENSORS:
# https://esphome.io/components/binary_sensor/
#########################################################################################
#:########################################################################################:#
binary_sensor:
- platform: gpio
pin:
number: GPIO16
mode: INPUT
inverted: True
use_interrupt: false # GPO16 pin doesn't support interrupts so use polling. Only supresses a warning.
inverted: true
use_interrupt: false # GPIO16 pin doesn't support interrupts so use polling. Only suppresses a warning.
name: "Button 1: ${switch_1_name}"
on_press:
- switch.toggle: Relay_1
- platform: gpio
pin:
number: GPIO05
number: GPIO5
mode: INPUT
inverted: True
inverted: true
name: "Button 2: ${switch_2_name}"
on_press:
- switch.toggle: Relay_2
@@ -176,7 +226,7 @@ binary_sensor:
pin:
number: GPIO4
mode: INPUT
inverted: True
inverted: true
name: "Button 3: ${switch_3_name}"
on_multi_click:
- timing:
@@ -186,16 +236,17 @@ binary_sensor:
- if:
condition:
and:
- not: api.connected
- not:
api.connected:
- switch.is_on: ha_loss_override
then:
- switch.toggle: Relay_3
else: []
#########################################################################################
# SWITCH COMPONENT
#:########################################################################################:#
# SWITCH COMPONENT:
# https://esphome.io/components/switch/
#########################################################################################
#:########################################################################################:#
switch:
- platform: gpio
name: "Relay 1: ${switch_1_name}"
@@ -218,5 +269,4 @@ switch:
name: "HA Loss manual override"
id: ha_loss_override
optimistic: true
restore_mode: RESTORE_DEFAULT_ON
restore_mode: RESTORE_DEFAULT_ON
+114 -69
View File
@@ -1,38 +1,83 @@
##########################################################################################
##########################################################################################
# LOUNGE WEST SWITCH (Single Switch from entranceway)
#:########################################################################################:#
# TITLE: 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
##########################################################################################
# Zemismart KS-811 Single push button
# pinout/schematic https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
#:########################################################################################:#
# HARDWARE:
# - 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)
##########################################################################################
#:########################################################################################:#
substitutions:
# Device Naming
# Device Naming
device_name: "esp-loungewestswitch"
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)"
device_area: "Lounge" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
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.
# Project Naming
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_name: "Zemismart Technologies.KS-811 Single" # Project Details
project_version: "v4.1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
# 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-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
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_device_command_on: "On"
#mqtt_remote_device_command_off: "Off"
# 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
#########################################################################################
# PACKAGES: Included Common Packages
#:########################################################################################:#
# PACKAGES:
# Included Common Packages
# https://esphome.io/components/packages.html
##########################################################################################
#:########################################################################################:#
packages:
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
common_wifi: !include
@@ -64,6 +110,7 @@ packages:
vars:
local_device_name: "${device_name}"
local_static_ip_address: "${static_ip_address}"
local_current_ip_address: "${current_ip_address}"
local_ota_pass: "${ota_pass}"
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
@@ -78,10 +125,10 @@ packages:
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
@@ -91,10 +138,10 @@ packages:
#diag_debug: !include common/include_debug_diag_sensors.yaml
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
#########################################################################################
# ESPHome
#:########################################################################################:#
# ESPHOME:
# https://esphome.io/components/esphome.html
#########################################################################################
#:########################################################################################:#
esphome:
name: "${device_name}"
friendly_name: "${friendly_name}"
@@ -125,44 +172,44 @@ api:
level: WARN
format: "API disconnected: switching to manual/offline behavior"
#########################################################################################
# ESP Platform and Framework
# https://esphome.io/components/esp32.html
#########################################################################################
#:########################################################################################:#
# ESP PLATFORM AND FRAMEWORK:
# https://esphome.io/components/esp8266.html
#:########################################################################################:#
esp8266:
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
#########################################################################################
# ESPHome Logging Enable
#:########################################################################################:#
# 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)
#esp8266_store_log_strings_in_flash: false
#tx_buffer_size: 64
#########################################################################################
# STATUS LED
#:########################################################################################:#
# STATUS LED:
# https://esphome.io/components/status_led.html
#########################################################################################
#:########################################################################################:#
status_led:
pin:
number: GPIO02
inverted: yes
number: GPIO2
inverted: true
#########################################################################################
# BINARY SENSORS
#:########################################################################################:#
# BINARY SENSORS:
# https://esphome.io/components/binary_sensor/
#########################################################################################
#:########################################################################################:#
binary_sensor:
- platform: gpio
pin:
number: GPIO0
mode: INPUT
inverted: True
inverted: true
name: "Button 1: ${switch_1_name}"
on_multi_click:
@@ -183,7 +230,7 @@ binary_sensor:
scene_name: "Night Light"
- logger.log:
level: INFO
format: "BTN: Double click Scene Night Light"
format: "BTN: Double click -> Scene Night Light"
else:
- logger.log:
level: INFO
@@ -191,8 +238,8 @@ binary_sensor:
# --- Single short click ---
# Online (and override ON): use HA's last scene to decide.
# If last != "All Off" send "All Off"
# If last == "All Off" send "Bright"
# If last != "All Off" -> send "All Off"
# If last == "All Off" -> send "Bright"
# Offline (and override ON): toggle physical Relay_1
- timing:
- ON for at most 0.5s
@@ -218,7 +265,7 @@ binary_sensor:
scene_name: "All Off"
- logger.log:
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:
- homeassistant.service:
service: script.lounge_set_scene
@@ -226,7 +273,7 @@ binary_sensor:
scene_name: "Bright"
- logger.log:
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:
# OFFLINE path: only act if override ON; toggle physical relay
- if:
@@ -238,17 +285,18 @@ binary_sensor:
then:
- if:
condition:
lambda: 'return id(Relay_1).state;'
lambda: |-
return id(Relay_1).state;
then:
- switch.turn_off: Relay_1
- logger.log:
level: INFO
format: "BTN: Single click (offline) Relay_1 OFF"
format: "BTN: Single click (offline) -> Relay_1 OFF"
else:
- switch.turn_on: Relay_1
- logger.log:
level: INFO
format: "BTN: Single click (offline) Relay_1 ON"
format: "BTN: Single click (offline) -> Relay_1 ON"
else:
- logger.log:
level: INFO
@@ -272,33 +320,32 @@ binary_sensor:
action: "hold"
- logger.log:
level: INFO
format: "BTN: Long press Scene All Off + HA event (hold)"
format: "BTN: Long press -> Scene All Off + HA event (hold)"
else:
- logger.log:
level: INFO
format: "BTN: Long press ignored (no HA connection)"
#########################################################################################
# TEXT SENSOR COMPONENT
#
#########################################################################################
#:########################################################################################:#
# TEXT SENSOR COMPONENT:
# https://esphome.io/components/text_sensor/
#:########################################################################################:#
text_sensor:
- platform: homeassistant
id: ha_last_scene
entity_id: input_text.lounge_last_scene
# logging: helpful when testing
on_value:
- logger.log:
level: DEBUG
format: "HA last scene now: %s"
args: ["x.c_str()"]
#########################################################################################
# SWITCH COMPONENT
#:########################################################################################:#
# SWITCH COMPONENT:
# https://esphome.io/components/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
name: "Relay 1: ${switch_1_name}"
pin: GPIO12
@@ -310,6 +357,4 @@ switch:
name: "HA Loss manual override"
id: ha_loss_override
optimistic: true
restore_mode: RESTORE_DEFAULT_ON
restore_mode: RESTORE_DEFAULT_ON
+97 -51
View File
@@ -1,38 +1,81 @@
##########################################################################################
##########################################################################################
# MAIN BATHROOM LIGHTSWITCH 2 (OBK Converted, BK7231N)
#:########################################################################################:#
# TITLE: 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.0 2026-02-04 Reflash into new switch (old switch electrical failure, now a BK)
# V1.0 2025-11-23 Initial
##########################################################################################
# Zemismart KS-811 Triple push button
# pinout/schematic https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
#
# NOTES
# -
#
##########################################################################################
##########################################################################################
#:########################################################################################:#
# HARDWARE:
# - Zemismart KS-811 Triple 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 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)
##########################################################################################
#:########################################################################################:#
substitutions:
# Device Naming
device_name: "esp-mainbathroomlights"
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.
# Project Naming
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
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-garageentrylights2_ip
static_ip_address: !secret esp-mainbathroomlights_ip
mqtt_command_main_topic: !secret mqtt_command_main_topic
#mqtt_status_main_topic: !secret mqtt_status_main_topic
@@ -65,10 +108,10 @@ substitutions:
mqtt_remote_device1_command2: "20"
mqtt_remote_device1_command3: "30"
##########################################################################################
#:########################################################################################:#
# PACKAGES: Included Common Packages
# https://esphome.io/components/packages.html
##########################################################################################
#:########################################################################################:#
packages:
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
common_wifi: !include
@@ -94,28 +137,31 @@ packages:
#### 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
#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
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
#:########################################################################################:#
# PACKAGE ITEM REMOVALS / OVERRIDES:
#:########################################################################################:#
wifi:
min_auth_mode: !remove # The WPA2 only works on esp32/8266
reboot_timeout: 15min # override the selection from from the common package
fast_connect: false # (optional) force off, in case package vars change
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
#:########################################################################################:#
# ESPHOME:
# https://esphome.io/components/esphome.html
##########################################################################################
#:########################################################################################:#
esphome:
name: "${device_name}"
friendly_name: "${friendly_name}"
@@ -129,36 +175,36 @@ esphome:
# then:
# - switch.turn_on: Relay_3
##########################################################################################
# BUILD FOR BK CHIPSET
#:########################################################################################:#
# BUILD FOR BK CHIPSET:
# bk72xx
# https://devices.esphome.io/board/bk72xx/
##########################################################################################
#:########################################################################################:#
bk72xx:
board: generic-bk7231n-qfn32-tuya
##########################################################################################
# ESPHome Logging Enable
#:########################################################################################:#
# 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)
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
#:########################################################################################:#
# STATUS LED:
# https://esphome.io/components/status_led.html
##########################################################################################
#:########################################################################################:#
status_led:
pin:
number: P22 #GPIO22
inverted: true
##########################################################################################
# BINARY SENSORS
#:########################################################################################:#
# BINARY SENSORS:
# https://esphome.io/components/binary_sensor/
##########################################################################################
#:########################################################################################:#
binary_sensor:
- platform: gpio
pin:
@@ -235,10 +281,10 @@ binary_sensor:
topic: "${mqtt_remote_device1_command_topic}"
payload: "${mqtt_remote_device1_command3}"
##########################################################################################
# SWITCH COMPONENT
#:########################################################################################:#
# SWITCH COMPONENT:
# https://esphome.io/components/switch/
##########################################################################################
#:########################################################################################:#
switch:
- platform: gpio
name: "Relay 1: ${switch_1_name}"
@@ -261,10 +307,10 @@ switch:
id: Relay_3
restore_mode: ${relay_restore_mode}
##########################################################################################
# TEMPLATE COMPONENT
##########################################################################################
#:########################################################################################:#
# TEMPLATE COMPONENT:
# Virtual group switch for Home Assistant
#:########################################################################################:#
- platform: template
name: "All Main Bathroom Lights"
id: all_main_bathroom_lights
+100 -67
View File
@@ -1,34 +1,67 @@
##########################################################################################
##########################################################################################
# MAIN DISHWASHER POWER
# Controlled by a Athom Smart Plug V3
# package_import_url: github://athom-tech/athom-configs/athom-smart-plug.yaml
#
#:########################################################################################:#
# TITLE: MAIN DISHWASHER POWER
# zorruno.com layout v1.1 2026
#:########################################################################################:#
# 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
# V1.1 2025-06-12 package added for energy entities
# 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)
##########################################################################################
#:########################################################################################:#
substitutions:
# Device Naming
device_name: "esp-maindishwasherpower"
friendly_name: "Main Dishwasher Power"
description_comment: "Main Dishwasher Power Monitor :: Athom Smart Plug Power Monitor V3"
device_area: "Kitchen" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
description_comment: "Main Dishwasher Power Monitor :: Athom Smart Plug Power Monitor V3 (Layout V1.1)"
device_area: "Kitchen"
# Project Naming
project_name: "Athom Technology.Smart Plug V3" # Project Details
project_version: "v1.1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
project_name: "Athom Technology.Smart Plug V3"
project_version: "v3.5"
# Passwords
api_key: !secret esp-maindishwasherpower_api_key # unfortunately you can't use substitutions inside secrets names
ota_pass: !secret esp-maindishwasherpower_ota_pass # unfortunately you can't use substitutions inside secrets names
api_key: !secret esp-maindishwasherpower_api_key
ota_pass: !secret esp-maindishwasherpower_ota_pass
static_ip_address: !secret esp-maindishwasherpower_ip
# 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}
# 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
log_level: "INFO"
update_interval: "60s"
# Device Settings
# Relay / Load Settings
relay_icon: "mdi:dishwasher"
current_limit : "10" # Current Limit in Amps. AU Plug = 10. IL, BR, EU, UK, US Plug = 16.
##########################################################################################
# PACKAGES: Included Common Packages
current_limit: "10" # Current Limit in Amps. AU Plug = 10. IL, BR, EU, UK, US Plug = 16.
#:########################################################################################:#
# PACKAGES:
# Included Common Packages
# https://esphome.io/components/packages.html
##########################################################################################
#:########################################################################################:#
packages:
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
common_wifi: !include
@@ -54,8 +88,8 @@ packages:
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}"
local_ota_pass: "${ota_pass}"
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
common_api: !include
@@ -69,34 +103,35 @@ packages:
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
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
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
# Device Specific included packages
common_athompowermonV3: !include
#### DEVICE SPECIFIC INCLUDED PACKAGES ####
common_athompowermonv3: !include
file: common/athompowermonv3_common.yaml
vars:
local_current_limit: "${current_limit}"
##########################################################################################
# ESPHome
#:########################################################################################:#
# 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}"
name_add_mac_suffix: False
comment: "${description_comment}"
area: "${device_area}"
name_add_mac_suffix: false
min_version: 2024.6.0
project:
name: "${project_name}"
@@ -108,19 +143,19 @@ esphome:
on_boot:
priority: 200
then:
- switch.turn_on: "relay"
- switch.turn_on: relay
##########################################################################################
# ESP Platform and Framework
#:########################################################################################:#
# ESP PLATFORM AND FRAMEWORK:
# https://esphome.io/components/esp32.html
##########################################################################################
#:########################################################################################:#
esp32:
board: esp32-c3-devkitm-1
flash_size: 4MB
variant: ESP32C3
framework:
type: esp-idf # "esp-idf" OR "arduino". Suggested ESP-IDF Framework, or Plug Out the UART Cable Might Cause ESP32 Hang.
version: recommended # recommended, latest or dev
type: esp-idf
version: recommended
preferences:
flash_write_interval: 5min
@@ -128,24 +163,24 @@ preferences:
esp32_improv:
authorizer: none
##########################################################################################
# ESPHome LOGGING
#:########################################################################################:#
# LOGGER:
# https://esphome.io/components/logger.html
##########################################################################################
#:########################################################################################:#
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
##########################################################################################
# BINARY SENSORS
#:########################################################################################:#
# BINARY SENSORS:
# https://esphome.io/components/binary_sensor/
##########################################################################################
#:########################################################################################:#
binary_sensor:
- platform: gpio
pin:
number: GPIO03
number: GPIO3
mode: INPUT_PULLUP
inverted: true
name: "Power Button"
@@ -156,24 +191,22 @@ binary_sensor:
- min_length: 20ms
max_length: 500ms
then:
- switch.toggle:
id: relay
- switch.toggle: relay
- platform: template
name: "Relay Status"
lambda: |-
return id(relay).state;
#################################################################################################
# SWITCH COMPONENT
#:########################################################################################:#
# SWITCH COMPONENT:
# https://esphome.io/components/switch/
#################################################################################################
#:########################################################################################:#
switch:
- platform: gpio
name: "Power Output"
pin: GPIO05
pin: GPIO5
id: relay
restore_mode: RESTORE_DEFAULT_ON # Ensures the relay is restored (or off) at boot
#internal: true # Hides the switch from Home Assistant
icon: "${relay_icon}"
restore_mode: RESTORE_DEFAULT_ON
#internal: true
icon: "${relay_icon}"
+187
View File
@@ -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}
+193
View File
@@ -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}
+95 -92
View File
@@ -1,59 +1,77 @@
##########################################################################################
##########################################################################################
# Main Kitchen LIGHTSWITCH
# V3.7 2025-09-14 upload to this lightswitch from copy
#
##########################################################################################
# Zemismart KS-811 Double push button
# pinout/schematic https://community.home-assistant.io/t/zemismart-ks-811-working-with-esphome/
#
# NOTES
# - Light switch with 2 sets of lights
#
##########################################################################################
##########################################################################################
#:########################################################################################:#
# TITLE: MAIN KITCHEN LIGHTSWITCH
# zorruno.com layout v1.1 2026
#:########################################################################################:#
# REPO:
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-mainkitchenlights.yaml
#:########################################################################################:#
# VERSIONS:
# V3.8 2026-03-11 Updated yaml to zorruno layout V1.1
# V3.7 2025-09-14 Upload to this lightswitch from copy
#:########################################################################################:#
# 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)
##########################################################################################
#:########################################################################################:#
substitutions:
# Device Naming
# Device Naming
device_name: "esp-mainkitchenlights"
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)"
device_area: "Kitchen" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
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.
# Project Naming
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_name: "Zemismart Technologies.KS-811 Double" # Project Details
project_version: "v3.8" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
# 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-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
#relay_icon: "mdi:lightbulb-group"
log_level: "INFO" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
log_level: "INFO" # NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
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_1_name: "Main Lights"
switch_2_name: "Benchtop Lights"
#switch_3_name: "Nil"
#########################################################################################
#:########################################################################################:#
# PACKAGES: Included Common Packages
# https://esphome.io/components/packages.html
##########################################################################################
#:########################################################################################:#
packages:
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
common_wifi: !include
@@ -62,6 +80,7 @@ packages:
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
@@ -75,73 +94,74 @@ packages:
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
#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
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
#:########################################################################################:#
# 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
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_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:
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
#########################################################################################
# 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
#########################################################################################
#:########################################################################################:#
status_led:
pin:
number: GPIO2
inverted: yes
inverted: true
#########################################################################################
# BINARY SENSORS
#:########################################################################################:#
# BINARY SENSORS:
# https://esphome.io/components/binary_sensor/
#########################################################################################
#:########################################################################################:#
binary_sensor:
- platform: gpio
pin:
number: GPIO16
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}"
on_press:
- switch.toggle: Relay_1
@@ -150,25 +170,16 @@ binary_sensor:
pin:
number: GPIO05
mode: INPUT
inverted: True
inverted: true
name: "Button 2: ${switch_2_name}"
on_press:
- 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/
#########################################################################################
#:########################################################################################:#
switch:
- platform: gpio
name: "Relay 1: ${switch_1_name}"
@@ -178,12 +189,4 @@ switch:
- platform: gpio
name: "Relay 2: ${switch_2_name}"
pin: GPIO12
id: Relay_2
# KS-811-2 is a double only
# - platform: gpio
# name: "Relay 3: ${switch_3_name}"
# pin: GPIO14
# id: Relay_3
id: Relay_2
+20 -17
View File
@@ -1,8 +1,12 @@
#:########################################################################################:#
# 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:
# 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.1 2025-06-12 Added select and button to chose modes, added countdown & startup to boost
# V2.0 2025-06-05 YAML Tidyups
@@ -10,8 +14,8 @@
# V1.0 2025-02-14 Initial Version
#:########################################################################################:#
# HARDWARE:
# Controlled by a Sonoff Basic
# pinout/schematic: https://devices.esphome.io/devices/sonoff-basic-r4-v1.0/
# - Controlled by a Sonoff Basic
# - pinout/schematic: https://devices.esphome.io/devices/sonoff-basic-r4-v1.0/
#:########################################################################################:#
# OPERATION NOTES:
# - 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 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)
# - 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
# - 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
@@ -30,7 +34,7 @@
#:########################################################################################:#
# MQTT COMMANDS:
# 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-off/08:00 : Time device will go off
# 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/OFF : Device permanently off
# 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:
# 0 = OFF
@@ -50,15 +54,14 @@
# OFFLINE NOTES:
# a) Home Assistant OFFLINE, but Network and MQTT ONLINE
# - 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
# b) HA/MQTT OFFLINE
# 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.
# - 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.
# c) Internet/Wifi OFFLINE
# The HTR will still come on once or twice per day (depending on previous settings) however
# timing will likely shift. To make timing more accurate, it can be powered down then up at 12pm.
# Obviously this may drift again over time.
# - The HTR will still come on once or twice per day (depending on previous settings)
# - Timeclocks will drift without SNTP and can be reset by power cycling at 12pm (midday)
#:########################################################################################:#
#:########################################################################################:#
@@ -69,12 +72,12 @@ substitutions:
# Device Naming
device_name: "esp-masterbathtowelrail"
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.
# Project Naming
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
api_key: !secret esp-masterbathtowelrail_api_key # unfortunately you can't use substitutions inside secrets names
@@ -109,8 +112,8 @@ packages:
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}"
local_ota_pass: "${ota_pass}"
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
common_api: !include
@@ -606,7 +609,7 @@ sensor:
unit_of_measurement: "mins"
accuracy_decimals: "0"
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: |-
return id(current_mins);
@@ -787,4 +790,4 @@ interval:
//id(mqtt_client).publish("${mqtt_timer_topic}/operation", "TIMER");
}
}
- script.execute: evaluate_relay_state
- script.execute: evaluate_relay_state
+156 -130
View File
@@ -1,204 +1,222 @@
#############################################
#############################################
# OFFICE DUAL LIGHT CONTROL
# - Overhead cool white lights
# - Right hand warm bunker light
#:########################################################################################:#
# TITLE: OFFICE DUAL LIGHT CONTROL
# zorruno.com layout v1.1 2026
#:########################################################################################:#
# 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
# A sonoff dual uses serial data to turn the relays on/off
# MQTT COMMANDS:
# - 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)
# V2.3 - 2025-06-18 Added MQTT direct relay control
# b) MQTT offline (or HA and MQTT both offline):
# - Device continues to operate from local buttons only
# - No direct inter-ESP MQTT control available
# - No MQTT state feedback available
#
# NOTES:
# Command the lights on with MQTT
# ${mqtt_local_command_full_topic}/relay1/set ON or OFF
# ${mqtt_local_command_full_topic}/relay2/set ON or OFF
# ${mqtt_local_status_full_topic}/relay1/set ON or OFF
# ${mqtt_local_status_full_topic}/relay2/set ON or OFF
#
##########################################################################################
##########################################################################################
# c) Entire WiFi / Network offline:
# - Device continues to operate from local buttons only
# - No HA control or MQTT control/status available
# - Accurate time is not needed; SNTP is not required for operation
#:########################################################################################:#
##########################################################################################
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
##########################################################################################
#:########################################################################################:#
# SUBSTITUTIONS:
# Specific device variable substitutions
#:########################################################################################:#
substitutions:
# Device Naming
device_name: "esp-officeduallights"
friendly_name: "Office Dual Lights"
description_comment: "Dual Office Lights (Overhead and right hand Bunker) :: Sonoff Dual R1"
device_area: "Office" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
description_comment: "Dual Office Lights (Overhead and right hand Bunker) :: Sonoff Dual R1 (Layout V1.1)"
device_area: "Office"
# Project Naming
project_name: "Sonoff Technologies.Sonoff Dual R1" # Project Details
project_version: "v2.3" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
# Passwords & Secrets
project_name: "Sonoff Technologies.Sonoff Dual R1"
project_version: "v2.5"
# Passwords and Secrets
api_key: !secret esp-api_key
ota_pass: !secret esp-ota_pass
static_ip_address: !secret esp-officeduallights_ip # unfortunately you can't use substitutions inside secrets names
ota_pass: !secret esp-ota_pass
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_status_main_topic: !secret mqtt_status_main_topic
# Device Settings
relay_icon: "mdi:lightbulb-group"
log_level: "NONE" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
update_interval: "60s" # update time for for general sensors etc
log_level: "NONE"
update_interval: "60s"
# MQTT Controls
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_status_topic: "${mqtt_local_status_main_topic}/${mqtt_device_name}" # Topic we will use to view status 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}"
# Switch Naming
switch_1_name: "Dual L1 Relay"
relay_1_icon: "mdi:lightbulb"
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_1_name: "Dual L1 Relay"
relay_1_icon: "mdi:lightbulb"
light_1_name: "Light 1 (Right Hand Bunker Light)"
##########################################################################################
# PACKAGES: Included Common Packages
switch_2_name: "Dual L2 Relay"
relay_2_icon: "mdi:lightbulb"
light_2_name: "Light 2 (Cool White Overhead 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_current_ip_address: "${current_ip_address}"
local_ota_pass: "${ota_pass}"
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
common_api: !include
file: common/api_common.yaml
#file: common/api_common_noencryption.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
# common_webportal: !include common/webportal_common.yaml
# common_sntp: !include common/sntp_common.yaml
##########################################################################################
# ESPHome
diag_basic: !include common/include_basic_diag_sensors.yaml
diag_more: !include common/include_more_diag_sensors.yaml
# diag_debug: !include common/include_debug_diag_sensors.yaml
# diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
#:########################################################################################:#
# ESPHOME:
# https://esphome.io/components/esphome.html
##########################################################################################
#:########################################################################################:#
esphome:
name: "${device_name}"
friendly_name: "${friendly_name}"
comment: "${description_comment}" # Appears on the esphome page in HA
comment: "${description_comment}"
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
# https://esphome.io/components/esp32.html
##########################################################################################
#:########################################################################################:#
# ESP PLATFORM AND FRAMEWORK:
# https://esphome.io/components/esp8266.html
#:########################################################################################:#
esp8266:
board: esp01_1m # The original sonoff basic
restore_from_flash: False # restore some values on reboot
board: esp01_1m
restore_from_flash: false
preferences:
flash_write_interval: 5min
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
##########################################################################################
# NOTE: Sonoff Dual CANNOT send serial data to log
###############################################
#:########################################################################################:#
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, Serial control)
#esp8266_store_log_strings_in_flash: false
#tx_buffer_size: 64
level: "${log_level}"
baud_rate: 0
##########################################################################################
# UART Bus
#:########################################################################################:#
# UART BUS:
# https://esphome.io/components/uart.html
##########################################################################################
#:########################################################################################:#
uart:
tx_pin: GPIO01
rx_pin: GPIO03
baud_rate: 19200
#data_bits: 8
#stop_bits: 1
#parity: EVEN
##########################################################################################
# MQTT COMMANDS
# This adds device-specific MQTT command triggers to the common MQTT configuration.
##########################################################################################
#:########################################################################################:#
# MQTT:
# Device-specific MQTT command triggers
#:########################################################################################:#
mqtt:
# Direct MQTT control for relays via serial commands
on_message:
# Relay 1 control
- topic: "${mqtt_local_command_topic}/relay1/set"
payload: "ON"
then:
- switch.turn_on: relay_1
- light.turn_on: light_1
- topic: "${mqtt_local_command_topic}/relay1/set"
payload: "OFF"
then:
- 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"
payload: "ON"
then:
- switch.turn_on: relay_2
- light.turn_on: light_2
- topic: "${mqtt_local_command_topic}/relay2/set"
payload: "OFF"
then:
- switch.turn_off: relay_2
- light.turn_off: light_2
##########################################################################################
# STATUS LED
#:########################################################################################:#
# STATUS LED:
# Sonoff Dual LED is on GPIO13
# https://esphome.io/components/status_led.html
##########################################################################################
# Sonoff Dual LED is GPIO13
#############################################
#:########################################################################################:#
status_led:
pin:
number: GPIO13
inverted: yes
inverted: true
##########################################################################################
# BINARY SENSORS
#:########################################################################################:#
# BINARY SENSORS:
# Sonoff Dual R1 buttons are GPIO04 and GPIO14
# https://esphome.io/components/binary_sensor/
##########################################################################################
# Sonoff Dual R1 buttons are GPIO04, GPIO14
#############################################
#:########################################################################################:#
binary_sensor:
- platform: gpio
pin:
@@ -218,12 +236,11 @@ binary_sensor:
on_press:
- switch.toggle: relay_2
##########################################################################################
# SWITCH COMPONENT
#:########################################################################################:#
# SWITCH:
# Sonoff Dual R1 requires serial data packets to switch the relays
# https://esphome.io/components/switch/
##########################################################################################
# Sonoff Dual R1 requires serial data to switch
#############################################
#:########################################################################################:#
switch:
- platform: template
name: "${switch_1_name}"
@@ -234,7 +251,7 @@ switch:
turn_on_action:
- mqtt.publish:
topic: "${mqtt_local_status_topic}/relay1/state"
payload: "ON"
payload: "ON"
- if:
condition:
switch.is_off: relay_2
@@ -245,7 +262,7 @@ switch:
turn_off_action:
- mqtt.publish:
topic: "${mqtt_local_status_topic}/relay1/state"
payload: "OFF"
payload: "OFF"
- if:
condition:
switch.is_off: relay_2
@@ -253,6 +270,7 @@ switch:
- uart.write: [0xA0, 0x04, 0x00, 0xA1]
else:
- uart.write: [0xA0, 0x04, 0x02, 0xA1]
- platform: template
name: "${switch_2_name}"
id: relay_2
@@ -262,7 +280,7 @@ switch:
turn_on_action:
- mqtt.publish:
topic: "${mqtt_local_status_topic}/relay2/state"
payload: "ON"
payload: "ON"
- if:
condition:
switch.is_off: relay_1
@@ -273,7 +291,7 @@ switch:
turn_off_action:
- mqtt.publish:
topic: "${mqtt_local_status_topic}/relay2/state"
payload: "OFF"
payload: "OFF"
- if:
condition:
switch.is_off: relay_1
@@ -282,30 +300,38 @@ switch:
else:
- 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:
- platform: template
id: light_output_1
type: binary
write_action:
- lambda: |-
if (state) id(relay_1).turn_on();
else id(relay_1).turn_off();
if (state) {
id(relay_1).turn_on();
} else {
id(relay_1).turn_off();
}
- platform: template
id: light_output_2
type: binary
write_action:
- lambda: |-
if (state) id(relay_2).turn_on();
else id(relay_2).turn_off();
if (state) {
id(relay_2).turn_on();
} else {
id(relay_2).turn_off();
}
##########################################################################################
# LIGHT COMPONENT
#:########################################################################################:#
# LIGHT:
# https://esphome.io/components/light/
##########################################################################################
#:########################################################################################:#
light:
- platform: binary
name: "${light_1_name}"
@@ -313,6 +339,6 @@ light:
output: light_output_1
- platform: binary
name: "Light 2 (Cool White Overhead Lights)"
name: "${light_2_name}"
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
+469 -67
View File
@@ -1,144 +1,546 @@
###############################################################################
# PACKAGE: OpenHASP Thermostat (MQTT-only, all BUTTON objects)
# PACKAGE: OpenHASP Thermostat / Gas Heater Control
# 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:
lounge_setpoint:
name: Lounge Setpoint
min: 10
max: 30
step: 0.5
# How long Setpoint and Humidity are each shown before rotating
hasp_setpoint_humidity_cycle_seconds:
name: HASP Setpoint Humidity Cycle Seconds
min: 1
max: 60
step: 1
mode: box
unit_of_measurement: "℃"
initial: 21.5
unit_of_measurement: s
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
###############################################################################
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
alias: "HASP: update temp (p1b1.text)"
mode: queued
trigger:
- 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:
- service: mqtt.publish
data:
topic: "hasp/openhasp_1/command/p1b1.text"
payload: "{{ states('sensor.lounge_environment_lounge_environment_temperature')|float(0)|round(1) }} °C"
- id: hasp_setpoint_to_btn_text
alias: "HASP: update setpoint (p1b2.text)"
mode: queued
trigger:
- platform: state
entity_id: input_number.lounge_setpoint
action:
- service: mqtt.publish
data:
topic: "hasp/openhasp_1/command/p1b2.text"
payload: "Set: {{ states('input_number.lounge_setpoint')|float(0)|round(1) }} °C"
qos: 1
retain: true
payload: >
{% if is_state('switch.rinnai_neo_gas_heater_rinnai_neo_gas_heater_test_mode', 'on') %}
{% set raw = states('sensor.rinnai_neo_gas_heater_rinnai_neo_gas_heater_test_mode_temp') %}
{% else %}
{% set raw = states('sensor.lounge_environment_lounge_environment_temperature') %}
{% endif %}
{% set cleaned = raw
| replace('°C', '')
| replace('° C', '')
| replace('C', '')
| trim %}
{% if cleaned not in ['unknown', 'unavailable', '', 'none', 'None'] %}
{{ cleaned | float(0) | round(1) }} °C
{% else %}
-- °C
{% endif %}
# -------------------------------------------------------------------------
# Heater status text at bottom of screen
# -------------------------------------------------------------------------
- id: hasp_heater_status_to_btn_text
alias: "HASP: update heater status (p1b5.text)"
mode: queued
trigger:
- platform: state
entity_id: switch.lounge_heater
entity_id: sensor.rinnai_neo_gas_heater_rinnai_neo_gas_heater_status_text
action:
- service: mqtt.publish
data:
topic: "hasp/openhasp_1/command/p1b5.text"
payload: >
{% if is_state('sensor.gas_heater_operating','ON') %}
HEAT ON
{% else %}
HEAT OFF
{% endif %}
{% set s = states('sensor.rinnai_neo_gas_heater_rinnai_neo_gas_heater_status_text') %}
{{ s if s not in ['unknown', 'unavailable', ''] else 'HEATER --' }}
# --- BUTTON HANDLING FROM THE PLATE (listens on /state/) ------------------
- id: hasp_btn_up_increment
alias: "HASP: p1b3 up -> increment setpoint"
# -------------------------------------------------------------------------
# When setpoint changes:
# - 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
trigger:
- platform: mqtt
topic: "hasp/openhasp_1/state/p1b4"
condition:
- condition: template
value_template: "{{ trigger.payload_json.event|default('') == 'up' }}"
value_template: "{{ trigger.payload_json.event | default('') == 'up' }}"
action:
- service: input_number.increment
- service: button.press
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
alias: "HASP: p1b4 up -> decrement setpoint"
- id: hasp_btn_down_press
alias: "HASP: p1b3 up -> heater setpoint DOWN"
mode: queued
trigger:
- platform: mqtt
topic: "hasp/openhasp_1/state/p1b3"
condition:
- condition: template
value_template: "{{ trigger.payload_json.event|default('') == 'up' }}"
value_template: "{{ trigger.payload_json.event | default('') == 'up' }}"
action:
- service: input_number.decrement
- service: button.press
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
alias: "HASP: push texts on HA start"
# -------------------------------------------------------------------------
# Middle flame button
# - Tap toggles heater operation
# -------------------------------------------------------------------------
- id: hasp_btn_heat_toggle
alias: "HASP: p1b6 up -> heater operation toggle"
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:
- platform: homeassistant
event: start
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"
mode: queued
# -------------------------------------------------------------------------
# Re-push screen state when panel comes online
# -------------------------------------------------------------------------
- id: hasp_start_on_panel_online
alias: "HASP: start display loop when panel goes online"
trigger:
- platform: mqtt
topic: "hasp/openhasp_1/status"
topic: "hasp/openhasp_1/LWT"
condition:
- condition: template
value_template: "{{ trigger.payload == 'online' }}"
action:
- 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:
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
sequence:
- service: mqtt.publish
data:
topic: "hasp/openhasp_1/command/p1b1.text"
payload: "{{ states('sensor.lounge_environment_lounge_environment_temperature')|float(0)|round(1) }} °C"
- service: mqtt.publish
data:
topic: "hasp/openhasp_1/command/p1b2.text"
payload: "Set: {{ states('input_number.lounge_setpoint')|float(0)|round(1) }} °C"
qos: 1
retain: true
payload: >
{% if is_state('switch.rinnai_neo_gas_heater_rinnai_neo_gas_heater_test_mode', 'on') %}
{% set raw = states('sensor.rinnai_neo_gas_heater_rinnai_neo_gas_heater_test_mode_temp') %}
{% else %}
{% set raw = states('sensor.lounge_environment_lounge_environment_temperature') %}
{% endif %}
{% set cleaned = raw
| 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
data:
topic: "hasp/openhasp_1/command/p1b5.text"
payload: >
{% if is_state('sensor.gas_heater_operating','ON') %}
HEAT ON
{% else %}
HEAT OFF
{% endif %}
{% set s = states('sensor.rinnai_neo_gas_heater_rinnai_neo_gas_heater_status_text') %}
{{ s if s not in ['unknown', 'unavailable', ''] else 'HEATER --' }}
- 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 '--') }}
# 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"
-98
View File
@@ -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