ESPHome new device, DIN power mon PMB

This commit is contained in:
root
2025-08-27 00:11:56 +12:00
parent 8adb0a63ba
commit c547bd8cb9
6 changed files with 776 additions and 16 deletions

View File

@@ -36,8 +36,8 @@ substitutions:
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
static_ip_address: !secret esp-bedrm2fanswitch_ip static_ip_address: !secret esp-bedrm2fanswitch_ip
mqtt_local_command_main_topic: !secret mqtt_local_command_main_topic mqtt_command_main_topic: !secret mqtt_command_main_topic
mqtt_local_status_main_topic: !secret mqtt_local_status_main_topic mqtt_status_main_topic: !secret mqtt_status_main_topic
# Device Settings # Device Settings
#relay_icon: "mdi:heating-coil" #relay_icon: "mdi:heating-coil"
@@ -51,11 +51,11 @@ substitutions:
# MQTT REMOTE Controls # MQTT REMOTE Controls
mqtt_remote_device_name: "bedroom2-ceilingfan" mqtt_remote_device_name: "bedroom2-ceilingfan"
mqtt_remote_device_command_topic: "${mqtt_local_command_main_topic}/${mqtt_remote_device_name}/speed/set" mqtt_remote_device_command_topic: "${mqtt_command_main_topic}/${mqtt_remote_device_name}/speed/set"
mqtt_remote_device_command1: "+" mqtt_remote_device_command1: "+"
mqtt_remote_device_command2: "-" mqtt_remote_device_command2: "-"
mqtt_remote_device_command3: "0" mqtt_remote_device_command3: "0"
mqtt_local_status_topic: "${mqtt_local_status_main_topic}/${mqtt_remote_device_name}/speed/state" # Topic we will use to view status locally without HA mqtt_local_status_topic: "${mqtt_status_main_topic}/${mqtt_remote_device_name}/speed/state" # Topic we will use to view status locally without HA
# Button Naming & Icons # Button Naming & Icons

View File

@@ -0,0 +1,755 @@
##########################################################################################
##########################################################################################
# SMART DIN POWER MONITOR AND RELAY (Originally CBU)
# V1.0 2025-08-26 Initial Version
##########################################################################################
# Ex Tuya Smart Relay
# Uses this chip for power monitoring BL0942
# Replacement https://templates.blakadder.com/ESP8685-WROOM-06.html
#
# NOTES
# - DIN rail power monitor and relay
# - Relay is a pulse to latch ON (GPIO04) and pulse to latch OFF (GPIO05)
# - Has an "is it running" template sensor with a minimum wattage value of ${min_power_to_state_running_default}
# - The relay opens on over-current at ${max_current_trip_default} (Trip Active sensor set). Trip is latched
# (relay stays OFF) until manually reset via the "Clear Trip" button or you toggle the relay ON again.
# - The status_led flashes with a speed depending on current (faster near limit).
# - The status_led is ON when the relay has tripped
# - Inrush debounce: current must remain above the trip threshold for ${overcurrent_debounce_ms} ms
# before the trip occurs (helps ignore short inrush spikes).
# - Energy totals calculated on-device:
# * Last Hour Energy (kWh) snapshot of the previous completed hour
# * Today / Yesterday (kWh) resets at local midnight, survives reboots
# * This Week / Last Week (kWh) resets at Monday 00:00 local time, survives reboots
# * This Month / Last Month (kWh) resets at 1st of month 00:00 local time, survives reboots
# - For rolling 24h Min/Max Power, use HA "Statistics" helper instead of on-device buffers.
#
##########################################################################################
##########################################################################################
##########################################################################################
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
##########################################################################################
substitutions:
# Device Naming
device_name: "dinpowermonitor-pmb"
friendly_name: "Din Power"
description_comment: "DIN Rail mounted current monitor and relay, with current based (software) trip"
device_area: "Hallway" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
# Project Naming
project_name: "Generic ESP32.ESP8685-WROOM-06" # Project details, a dot separates the HA columns
project_version: "v1.0" # Project version allows checking of deployed vs latest version
# Passwords
api_key: !secret esp-api_key # unfortunately you cannot use substitutions inside secrets names
ota_pass: !secret esp-ota_pass
static_ip_address: !secret esp-dinpowermonitor-pmb_ip
# Device General Settings
log_level: "ERROR" # NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
update_interval: "60s" # update time for general sensors etc
# Device Specific Defaults (used to seed HA-tunable numbers)
relay_1_name: "Relay"
button_1_name: "Toggle Button"
status_led_name: "Power Active"
min_power_to_state_running_default: 4 # Watts, initial value only
max_current_trip_default: 6 # Amps, initial value only
led_flash_slow_ms: 1000 # slow flash period when just running
led_flash_fast_ms: 100 # very fast flash period near trip
overcurrent_debounce_ms: 300 # Over-current inrush debounce (ms)
##########################################################################################
# PACKAGES: Included Common Packages
# https://esphome.io/components/packages.html
##########################################################################################
packages:
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}"
common_api: !include
file: common/api_common.yaml
vars:
local_api_key: "${api_key}"
common_webportal: !include
file: common/webportal_common.yaml
common_mqtt: !include
file: common/mqtt_common.yaml
vars:
local_device_name: "${device_name}"
common_sntp: !include
file: common/sntp_common.yaml
common_general_sensors: !include
file: common/sensors_common.yaml
vars:
local_friendly_name: "${friendly_name}"
local_update_interval: "${update_interval}"
##########################################################################################
# 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: -100
then:
# Restore "Last Trip" text from persisted epoch (if any)
- lambda: |-
if (id(last_trip_epoch) > 0) {
auto t = time::ESPTime::from_epoch_local(id(last_trip_epoch));
char buf[24];
t.strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S");
id(ts_last_trip).publish_state(buf);
} else {
id(ts_last_trip).publish_state("Never");
}
# Apply Power Restore Mode selector (Always ON / Always OFF / Previous State)
- lambda: |-
std::string mode = id(sel_restore_mode).state;
if (mode == "Always ON") {
id(relay_virtual).turn_on();
} else if (mode == "Always OFF") {
id(relay_virtual).turn_off();
} else {
// "Previous State" -> do nothing (template switch will keep last or default OFF)
}
##########################################################################################
# ESP Platform and Framework
# https://esphome.io/components/esp32.html
##########################################################################################
esp32:
board: esp32-c3-devkitm-1
variant: esp32c3
framework:
type: esp-idf
##########################################################################################
# ESPHome Logging Enable
# https://esphome.io/components/logger.html
##########################################################################################
logger:
level: ${log_level}
##########################################################################################
# STATUS LED (BLUE) - low = ON per mapping
# https://esphome.io/components/status_led.html
##########################################################################################
status_led:
pin:
number: GPIO8
inverted: true
##########################################################################################
# UART BUS
# https://esphome.io/components/uart/
##########################################################################################
uart:
# for BL0942
id: bl_uart
rx_pin: GPIO19 # BL0942 TXD -> MCU RX
tx_pin: GPIO18 # BL0942 RXD -> MCU TX
baud_rate: 4800
parity: NONE
stop_bits: 1
##########################################################################################
# GLOBALS
# https://esphome.io/components/globals.html
##########################################################################################
globals:
# Used for LED blink period calculation (in milliseconds)
- id: _blink_period_ms
type: int
restore_value: no
initial_value: "500"
# Last trip time, saved across reboots.
- id: last_trip_epoch
type: uint32_t
restore_value: yes
initial_value: "0"
# Debounce start timestamp (ms since boot) for over-current detection
- id: _oc_start_ms
type: uint32_t
restore_value: no
initial_value: "0"
# ---- ENERGY ACCUMULATION & PERIOD SNAPSHOTS ----
- id: g_last_ms # millis() timestamp of last integration step
type: uint32_t
restore_value: no
initial_value: "0"
# Current-period totals (persisted)
- id: g_hour_kwh
type: float
restore_value: yes
initial_value: "0.0"
- id: g_today_kwh
type: float
restore_value: yes
initial_value: "0.0"
- id: g_week_kwh
type: float
restore_value: yes
initial_value: "0.0"
- id: g_month_kwh
type: float
restore_value: yes
initial_value: "0.0"
# Last-period snapshots (persisted)
- id: g_last_hour_kwh
type: float
restore_value: yes
initial_value: "0.0"
- id: g_yesterday_kwh
type: float
restore_value: yes
initial_value: "0.0"
- id: g_last_week_kwh
type: float
restore_value: yes
initial_value: "0.0"
- id: g_last_month_kwh
type: float
restore_value: yes
initial_value: "0.0"
# Boundary trackers (dont persist)
- id: g_last_hour_seen
type: int
restore_value: no
initial_value: "-1"
- id: g_last_doy_seen
type: int
restore_value: no
initial_value: "-1"
- id: g_last_wday_seen
type: int
restore_value: no
initial_value: "-1"
- id: g_last_month_seen
type: int
restore_value: no
initial_value: "-1"
##########################################################################################
# SENSORS
# https://esphome.io/components/sensor/
##########################################################################################
sensor:
- platform: bl0942
uart_id: bl_uart
update_interval: 250ms
voltage:
name: "${friendly_name} Voltage"
id: pm_voltage
accuracy_decimals: 1
unit_of_measurement: "V"
device_class: voltage
state_class: measurement
current:
name: "${friendly_name} Current"
id: pm_current
accuracy_decimals: 3
unit_of_measurement: "A"
device_class: current
state_class: measurement
on_value:
then:
- lambda: |-
// OVER-CURRENT TRIP HANDLER with inrush debounce
// Trip when current > n_max_trip and relay is ON, but only if it stays above
// for ${overcurrent_debounce_ms} ms (to ignore short inrush spikes).
if (id(bs_tripped).state) {
// Already tripped: reset debounce tracker and do nothing
id(_oc_start_ms) = 0;
} else if (id(relay_virtual).state && x > id(n_max_trip).state) {
// Over threshold while relay is ON
if (id(_oc_start_ms) == 0) {
id(_oc_start_ms) = millis(); // start debounce window
}
uint32_t elapsed = millis() - id(_oc_start_ms);
if (elapsed >= ${overcurrent_debounce_ms}) {
ESP_LOGI("trip",
"Overcurrent trip: %.3f A > %.3f A for %u ms (>= %u ms), opening relay",
x, id(n_max_trip).state, (unsigned) elapsed, (unsigned) ${overcurrent_debounce_ms});
// Mark trip, stop blinker FIRST
id(bs_tripped).publish_state(true);
id(led_blinker).stop();
// Open latching relay (template handles OFF coil pulse)
id(relay_virtual).turn_off();
// Force LED solid ON to indicate trip
auto call = id(led).turn_on();
call.perform();
// Time-stamp "Last Trip" using SNTP time (YYYY-MM-DD HH:MM:SS) and persist
auto now_clk = id(sntp_time).now();
if (now_clk.is_valid()) {
char buf[24];
now_clk.strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S");
id(ts_last_trip).publish_state(buf);
id(last_trip_epoch) = (uint32_t) now_clk.timestamp;
} else {
id(ts_last_trip).publish_state("unknown");
}
// Reset debounce tracker
id(_oc_start_ms) = 0;
}
} else {
// Below threshold or relay OFF: reset debounce tracker
id(_oc_start_ms) = 0;
}
// ------------------------------------------------------------------
// ENERGY ACCUMULATION (kWh) + PERIOD ROLLOVERS (hour/day/week/month)
// ------------------------------------------------------------------
// Integrate W over time using millis() -> kWh
uint32_t now_ms = millis();
if (id(g_last_ms) == 0) {
id(g_last_ms) = now_ms; // first sample since boot
} else {
uint32_t dt_ms = now_ms - id(g_last_ms);
id(g_last_ms) = now_ms;
float p_w = (isnan(x) || x < 0.0f) ? 0.0f : x; // sanitize power
float inc_kwh = p_w * (dt_ms / 3600000.0f); // W * hours -> kWh
id(g_hour_kwh) += inc_kwh;
id(g_today_kwh) += inc_kwh;
id(g_week_kwh) += inc_kwh; // Week rolls at Monday 00:00 local time
id(g_month_kwh) += inc_kwh;
}
// Use SNTP time for clean boundary changes
auto now = id(sntp_time).now();
if (now.is_valid()) {
// Hour rollover: when hour changes
if (id(g_last_hour_seen) != now.hour) {
if (id(g_last_hour_seen) != -1) {
id(g_last_hour_kwh) = id(g_hour_kwh);
id(s_last_hour_kwh).publish_state(id(g_last_hour_kwh));
}
id(g_hour_kwh) = 0.0f;
id(g_last_hour_seen) = now.hour;
}
// Day rollover (midnight local)
if (id(g_last_doy_seen) != now.day_of_year) {
if (id(g_last_doy_seen) != -1) {
id(g_yesterday_kwh) = id(g_today_kwh);
id(s_yesterday_kwh).publish_state(id(g_yesterday_kwh));
}
id(g_today_kwh) = 0.0f;
id(g_last_doy_seen) = now.day_of_year;
}
// Week rollover: Monday 00:00 local time (i.e., after Sunday)
// ESPHome day_of_week: Monday=1 ... Sunday=7
if (now.day_of_week == 1 && now.hour == 0 && id(g_last_wday_seen) != 1) {
id(g_last_week_kwh) = id(g_week_kwh);
id(s_last_week_kwh).publish_state(id(g_last_week_kwh));
id(g_week_kwh) = 0.0f;
}
id(g_last_wday_seen) = now.day_of_week;
// Month rollover: first day of month at 00:00
if (id(g_last_month_seen) != now.month) {
if (id(g_last_month_seen) != -1 && now.day_of_month == 1 && now.hour == 0) {
id(g_last_month_kwh) = id(g_month_kwh);
id(s_last_month_kwh).publish_state(id(g_last_month_kwh));
id(g_month_kwh) = 0.0f;
}
id(g_last_month_seen) = now.month;
}
}
power:
name: "${friendly_name} Power"
id: pm_power
accuracy_decimals: 1
unit_of_measurement: "W"
device_class: power
state_class: measurement
energy:
name: "${friendly_name} Energy"
id: pm_energy
unit_of_measurement: "Wh"
device_class: energy
state_class: total_increasing
frequency:
name: "${friendly_name} Frequency"
id: pm_freq
unit_of_measurement: "Hz"
device_class: frequency
state_class: measurement
# Optional calibration references (uncomment and tune if needed)
# voltage_reference: 15968
# current_reference: 124180
# power_reference: 309.1
# energy_reference: 2653
##########################################################################
# ENERGY TOTALS (kWh) EXPOSED TO HA
# These read the persisted globals; they update periodically.
##########################################################################
- platform: template
name: "${friendly_name} Last Hour Energy"
id: s_last_hour_kwh
unit_of_measurement: "kWh"
device_class: energy
state_class: total
accuracy_decimals: 3
update_interval: 30s
lambda: |-
return id(g_last_hour_kwh);
- platform: template
name: "${friendly_name} Today Energy"
id: s_today_kwh
unit_of_measurement: "kWh"
device_class: energy
state_class: total
accuracy_decimals: 3
update_interval: 30s
lambda: |-
return id(g_today_kwh);
- platform: template
name: "${friendly_name} Yesterday Energy"
id: s_yesterday_kwh
unit_of_measurement: "kWh"
device_class: energy
state_class: total
accuracy_decimals: 3
update_interval: 30s
lambda: |-
return id(g_yesterday_kwh);
- platform: template
name: "${friendly_name} This Week Energy"
id: s_week_kwh
unit_of_measurement: "kWh"
device_class: energy
state_class: total
accuracy_decimals: 3
update_interval: 30s
lambda: |-
return id(g_week_kwh);
- platform: template
name: "${friendly_name} Last Week Energy"
id: s_last_week_kwh
unit_of_measurement: "kWh"
device_class: energy
state_class: total
accuracy_decimals: 3
update_interval: 30s
lambda: |-
return id(g_last_week_kwh);
- platform: template
name: "${friendly_name} This Month Energy"
id: s_month_kwh
unit_of_measurement: "kWh"
device_class: energy
state_class: total
accuracy_decimals: 3
update_interval: 30s
lambda: |-
return id(g_month_kwh);
- platform: template
name: "${friendly_name} Last Month Energy"
id: s_last_month_kwh
unit_of_measurement: "kWh"
device_class: energy
state_class: total
accuracy_decimals: 3
update_interval: 30s
lambda: |-
return id(g_last_month_kwh);
##########################################################################################
# TEXT SENSOR COMPONENT
# https://esphome.io/components/text_sensor/
##########################################################################################
text_sensor:
# Holds the date/time of last trip (string with seconds)
- platform: template
name: "${friendly_name} Last Trip"
id: ts_last_trip
icon: "mdi:clock-alert"
entity_category: diagnostic
##########################################################################################
# BINARY SENSORS
# https://esphome.io/components/binary_sensor/
# https://esphome.io/components/binary_sensor/template.html
##########################################################################################
binary_sensor:
# "Is Running" template sensor
- platform: template
id: bs_running
name: "${friendly_name} Running"
lambda: |-
if (isnan(id(pm_power).state)) {
return false;
} else if (id(pm_power).state > id(n_min_power).state) {
return true;
} else {
return false;
}
filters:
- delayed_off: 15s
on_press:
then:
- if:
condition:
and:
- switch.is_on: relay_virtual
- lambda: 'return !id(bs_tripped).state;'
then:
- script.execute: led_blinker
on_release:
then:
- script.stop: led_blinker
- if:
condition:
lambda: 'return !id(bs_tripped).state;'
then:
- light.turn_off: led
# Trip flag exposed to HA; set true on over-current. Cleared when relay is turned ON or via Reset button.
- platform: template
id: bs_tripped
name: "${friendly_name} Trip Active"
device_class: problem
# On-board button (P17 -> IO9) pulls low when pressed
- platform: gpio
pin:
number: GPIO9
mode: INPUT_PULLUP
inverted: true
name: "${button_1_name}"
on_press:
- switch.toggle: relay_virtual
##########################################################################################
# NUMBER COMPONENT
# https://esphome.io/components/number/
##########################################################################################
# HA-TUNABLE THRESHOLDS (NUMBER ENTITIES)
# https://esphome.io/components/number/template.html
##########################################################################################
number:
- platform: template
name: "${friendly_name} Min Power Running"
id: n_min_power
optimistic: true
restore_value: true
initial_value: ${min_power_to_state_running_default}
min_value: 1
max_value: 100
step: 1
unit_of_measurement: "W"
icon: "mdi:flash-outline"
- platform: template
name: "${friendly_name} Max Current Trip"
id: n_max_trip
optimistic: true
restore_value: true
initial_value: ${max_current_trip_default}
min_value: 0
max_value: 10
step: 0.2
unit_of_measurement: "A"
icon: "mdi:current-ac"
##########################################################################################
# BUTTON COMPONENT
# Reset the trip latch from HA (does not close the relay automatically)
# https://esphome.io/components/button/
##########################################################################################
button:
- platform: template
name: "${friendly_name} Clear Trip"
id: btn_clear_trip
icon: "mdi:alert-remove-outline"
on_press:
- logger.log: "Trip reset requested (clearing Trip Active and LED state)"
- binary_sensor.template.publish:
id: bs_tripped
state: false
- lambda: |-
// Clear any pending debounce
id(_oc_start_ms) = 0;
- if:
condition:
and:
- switch.is_on: relay_virtual
- binary_sensor.is_on: bs_running
then:
- script.execute: led_blinker
else:
- light.turn_off: led
##########################################################################################
# SWITCH COMPONENT
# https://esphome.io/components/switch/
##########################################################################################
# LATCHING RELAY CONTROL (two coils: ON and OFF)
# P24 -> IO5 (close), P26 -> IO4 (open) per mapping.
# Two hidden GPIO pulse switches to drive the coils.
# User-facing switch sends a short pulse to the appropriate coil.
##########################################################################################
switch:
# Hidden coil driver: ON pulse (GPIO5)
- platform: gpio
id: relay_on_coil
pin:
number: GPIO5
inverted: false
restore_mode: ALWAYS_OFF
# Hidden coil driver: OFF pulse (GPIO4)
- platform: gpio
id: relay_off_coil
pin:
number: GPIO4
inverted: false
restore_mode: ALWAYS_OFF
# User-facing virtual switch
- platform: template
id: relay_virtual
name: "${relay_1_name}"
optimistic: true
# Use default restore behavior; "Previous State" is honored by doing nothing in on_boot.
# Set a safe baseline here (default off if no previous state).
restore_mode: RESTORE_DEFAULT_OFF
turn_on_action:
- logger.log: "Relay ON: pulsing ON coil"
- binary_sensor.template.publish:
id: bs_tripped
state: false # clear trip on manual ON
- switch.turn_on: relay_on_coil
- delay: 200ms
- switch.turn_off: relay_on_coil
- if:
condition:
and:
- binary_sensor.is_on: bs_running
- lambda: 'return !id(bs_tripped).state;'
then:
- script.execute: led_blinker
turn_off_action:
- logger.log: "Relay OFF: pulsing OFF coil"
- switch.turn_on: relay_off_coil
- delay: 200ms
- switch.turn_off: relay_off_coil
- script.stop: led_blinker
- if:
condition:
lambda: 'return !id(bs_tripped).state;'
then:
- light.turn_off: led
##########################################################################################
# OUTPUT COMPONENT
# https://esphome.io/components/output/ledc.html
##########################################################################################
# RED LED AS LIGHT (P9 -> IO10, low = ON)
##########################################################################################
output:
- platform: ledc
id: pow_red_led_pwm
pin:
number: GPIO10
inverted: true
##########################################################################################
# LIGHT COMPONENT
# https://esphome.io/components/light/monochromatic.html
##########################################################################################
# Hidden from HA; still used internally by scripts/logic
light:
- platform: monochromatic
id: led
output: pow_red_led_pwm
internal: true
##########################################################################################
# SELECT COMPONENT
# Choose how the relay state should be restored after boot
# https://esphome.io/components/select/template.html
##########################################################################################
select:
- platform: template
name: "${friendly_name} Power Restore Mode"
id: sel_restore_mode
optimistic: true
restore_value: true
options:
- "Always ON"
- "Always OFF"
- "Previous State"
initial_option: "Previous State"
icon: "mdi:power-settings"
##########################################################################################
# SCRIPTS
# https://esphome.io/components/script.html
##########################################################################################
script:
# LED blinker: variable-speed based on current vs n_max_trip; runs only when running, relay ON, not tripped
- id: led_blinker
mode: restart
then:
- while:
condition:
and:
- switch.is_on: relay_virtual
- binary_sensor.is_on: bs_running
- lambda: 'return !id(bs_tripped).state;'
then:
# Compute and store current-period ms in _blink_period_ms
- lambda: |-
float i = isnan(id(pm_current).state) ? 0.0f : id(pm_current).state;
float maxA = id(n_max_trip).state;
if (maxA < 0.1f) maxA = 0.1f;
float f = i / maxA; // 0.0 .. 1.0
if (f < 0.0f) f = 0.0f;
if (f > 1.0f) f = 1.0f;
int slow_ms = ${led_flash_slow_ms};
int fast_ms = ${led_flash_fast_ms};
if (slow_ms < fast_ms) { int t = slow_ms; slow_ms = fast_ms; fast_ms = t; } # ensure slow >= fast
int period = slow_ms - (int)((slow_ms - fast_ms) * f);
id(_blink_period_ms) = period;
# Blink with 50% duty cycle at the computed period
- light.turn_on:
id: led
brightness: 100%
- delay: !lambda 'return (uint32_t)(id(_blink_period_ms) / 2);'
- light.turn_off: led
- delay: !lambda 'return (uint32_t)(id(_blink_period_ms) / 2);'

View File

@@ -1,6 +1,7 @@
############################################# #############################################
############################################# #############################################
# MAIN BATHROOM FAN/HEAT COMBO SWITCH # MAIN BATHROOM FAN/HEAT COMBO SWITCH
# V1.1 2025-08-26 Minor Changes (MQTT)
# V1.0 2025-06-01 Initial Version # V1.0 2025-06-01 Initial Version
############################################# #############################################
# Zemismart KS-811 Triple push button # Zemismart KS-811 Triple push button
@@ -25,7 +26,7 @@ substitutions:
# Project Naming # Project Naming
project_name: "Zemismart Technologies.KS-811-2 (Double)" # Project Details project_name: "Zemismart Technologies.KS-811-2 (Double)" # Project Details
project_version: "v1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version project_version: "v1.1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
entity_prefix: "Main Bathroom" # Simple device name where we want to prefix a sensor or switch, eg "Load" Current. entity_prefix: "Main Bathroom" # Simple device name where we want to prefix a sensor or switch, eg "Load" Current.
@@ -33,16 +34,17 @@ substitutions:
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
static_ip_address: !secret esp-mainbathfancombo_ip static_ip_address: !secret esp-mainbathfancombo_ip
mqtt_command_main_topic: !secret mqtt_command_main_topic
#mqtt_status_main_topic: !secret mqtt_status_main_topic
# Device Settings # Device Settings
#relay_icon: "mdi:heating-coil" #relay_icon: "mdi:heating-coil"
log_level: "INFO" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE log_level: "INFO" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
update_interval: "60s" # update time for for general sensors etc update_interval: "60s" # update time for for general sensors etc
# MQTT Controls # MQTT REMOTE Controls
mqtt_main_command_topic: !secret mqtt_main_command_topic mqtt_remote_device1_name: "masterbath-towelrail"
#mqtt_main_status_topic: !secret mqtt_main_status_topic mqtt_remote_device1_command_topic: "${mqtt_command_main_topic}/${mqtt_remote_device1_name}/operation"
mqtt_remote_device1_command_topic: "${mqtt_main_command_topic}/masterbath-towelrail/operation"
mqtt_remote_device1_command1: "BOOST" mqtt_remote_device1_command1: "BOOST"
########################################################################################## ##########################################################################################

View File

@@ -27,7 +27,8 @@ substitutions:
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
static_ip_address: !secret esp-officeelvcontrol_ip static_ip_address: !secret esp-officeelvcontrol_ip
mqtt_main_command_topic: !secret mqtt_main_command_topic mqtt_command_main_topic: !secret mqtt_command_main_topic
#mqtt_status_main_topic: !secret mqtt_status_main_topic
# Device Settings # Device Settings
relay_icon: "mdi:generator-portable" relay_icon: "mdi:generator-portable"
@@ -40,7 +41,7 @@ substitutions:
# MQTT Controls # MQTT Controls
mqtt_device_name: "office-elv-control" mqtt_device_name: "office-elv-control"
mqtt_main_topic: "${mqtt_main_command_topic}/${mqtt_device_name}" # Topic we will use to command stuff from external without HA mqtt_main_topic: "${mqtt_command_main_topic}/${mqtt_device_name}" # Topic we will use to command stuff from external without HA
########################################################################################## ##########################################################################################
# PACKAGES: Included Common Packages # PACKAGES: Included Common Packages

View File

@@ -27,7 +27,8 @@ substitutions:
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
static_ip_address: !secret esp-officeusbhubpower_ip static_ip_address: !secret esp-officeusbhubpower_ip
mqtt_main_command_topic: !secret mqtt_main_command_topic mqtt_command_main_topic: !secret mqtt_command_main_topic
mqtt_status_main_topic: !secret mqtt_status_main_topic
# Device Settings # Device Settings
relay_icon: "mdi:generator-portable" relay_icon: "mdi:generator-portable"
@@ -40,7 +41,7 @@ substitutions:
# MQTT Controls # MQTT Controls
mqtt_device_name: "office-usbhub-power" mqtt_device_name: "office-usbhub-power"
mqtt_main_topic: "${mqtt_main_command_topic}/${mqtt_device_name}" # Topic we will use to command stuff from external without HA mqtt_main_topic: "${mqtt_command_main_topic}/${mqtt_device_name}" # Topic we will use to command stuff from external without HA
########################################################################################## ##########################################################################################
# PACKAGES: Included Common Packages # PACKAGES: Included Common Packages

View File

@@ -2,13 +2,14 @@ group:
simulation_lights_all: simulation_lights_all:
name: Simulation Lights (All) name: Simulation Lights (All)
entities: entities:
- switch.esp_centralstairs_top_relay_2_stair_footer_lights
- switch.esp_centralstairs_bottom_relay_1_main_stair_lights_lower
- switch.esp_entrancebathrmlights_relay_1_main_lights
- group.downstairs_flat_lights # ← now valid here
- switch.tasmo_ks811d_1242_entrance_a - switch.tasmo_ks811d_1242_entrance_a
- switch.tasmo_ks811d_6110_kitchen_a - switch.tasmo_ks811d_6110_kitchen_a
- switch.tasmo_ks811d_6110_kitchen_b - switch.tasmo_ks811d_6110_kitchen_b
- switch.main_hallway_lightswitch_tasmo_ks811s_2940_hallway_1a - switch.main_hallway_lightswitch_tasmo_ks811s_2940_hallway_1a
- switch.tasmo_ks811d_1701_stairs_2a
- switch.tasmo_ks811t_0702_lounge_3a - switch.tasmo_ks811t_0702_lounge_3a
- switch.tasmo_ks811t_0702_lounge_3b - switch.tasmo_ks811t_0702_lounge_3b
- switch.tasmo_ks811t_0702_lounge_3c - switch.tasmo_ks811t_0702_lounge_3c
- switch.esp_entrancebathrmlights_relay_1_main_lights
- group.downstairs_flat_lights # ← now valid here