Files
esphome-config/switch-exhaust.yaml
T
Brian Hanifin d46eb271e4 switch-exhaust: refactor
* Allow humidity to warm room when shower begins:
    * Turn fan off when delta between upper/lower deltas (and HUMIDITY is not the last trigger).
    * Turn fan back on when upper delta is met.
* Only start the turn off timer when humidity delta is below the lower trigger.
* Remove globals.
2023-02-13 08:52:03 -08:00

369 lines
10 KiB
YAML

---
# Device: Shelly 1 PM
# Location: Upstairs bathroom in wall
#
substitutions:
project: Upstairs bathroom exhaust
id: switch_exhaust
hostname: switch-exhaust
ip: 10.0.20.50
#humidity_reference_sensor: "sensor.upstairs_bathroom_humidity_average_last_24_hours"
humidity_reference_sensor: "sensor.upstairs_humidity_average"
remaining_time_duration: "600" # 600 seconds = 10 minutes
max_temp: "70.0" # Max power measurement board temperature in °C.
<<: !include common/substitutions/gpio/shelly1pm.yaml
esphome:
name: $hostname
on_boot:
- sensor.template.publish:
id: remaining_time
state: 0
esp8266:
board: esp01_1m
framework:
version: recommended
restore_from_flash: true
<<: !include common/common.yaml
interval:
- interval: 5s
then:
- script.execute: humidity_delta_calculate
- if:
condition:
- switch.is_on: relay
then:
# When the humidity is not the trigger, and the humidity is between the lower and upper trigger values.
- if:
condition:
and:
- lambda: return id(diagnostic_last_trigger).state != "HUMIDITY";
- lambda: return id(humidity_delta).state >= id(delta_lower_trigger).state;
- lambda: return id(humidity_delta).state < id(delta_upper_trigger).state;
then:
# Allow humidity to warm up the room.
- switch.turn_off: relay
# Clear remaining time.
- script.execute: remaining_time_clear
# When the humidity is less than or equal to the lower trigger.
- if:
condition:
- lambda: return id(humidity_delta).state <= id(delta_lower_trigger).state;
then:
# Start the remaining time countdown.
- if:
condition:
- lambda: return id(remaining_time).state == 0;
then:
- script.execute: remaining_time_start
else:
# Decrement the remaing time.
- script.execute: remaining_time_decrement
script:
- id: humidity_delta_calculate
then:
# Recalculate the difference between the bathroom humidity and the reference humidity.
- sensor.template.publish:
id: humidity_delta
state: !lambda return id(humidity_now).state - id(humidity_reference).state;
- id: humidity_trigger_check
then:
# Turn the fan on when the humidity delta reaches the upper trigger.
- if:
condition:
and:
- switch.is_off: relay
- lambda: return id(humidity_delta).state >= id(delta_upper_trigger).state;
then:
- switch.turn_on: relay
- if:
condition:
- lambda: return id(diagnostic_last_trigger).state != "HUMIDITY";
then:
- text_sensor.template.publish:
id: diagnostic_last_trigger
state: HUMIDITY
- id: remaining_time_clear
then:
- if:
condition:
- lambda: return id(remaining_time).state > 0;
then:
- sensor.template.publish:
id: remaining_time
state: "0"
- id: remaining_time_decrement
then:
# Decrement the timer.
- if:
condition:
and:
- lambda: return id(remaining_time).state > 0;
- switch.is_on: relay
then:
- sensor.template.publish:
id: remaining_time
state: !lambda return id(remaining_time).state -= 5;
# Turn off the relay when the remaining time reaches zero.
- if:
condition:
and:
- lambda: return id(remaining_time).state == 0;
- switch.is_on: relay
then:
- switch.turn_off: relay
- id: remaining_time_start
then:
- sensor.template.publish:
id: remaining_time
state: !lambda return $remaining_time_duration;
binary_sensor:
# Physical Toggle Switch. Monitor for switch position changes internally. Do not expose to Home Assistant.
- platform: gpio
pin:
number: $button_gpio
id: button_toggle
internal: true
filters:
- delayed_on_off: 50ms
on_state:
- switch.toggle: relay
- if:
condition:
- lambda: return id(diagnostic_last_trigger).state != "PHYSICAL";
then:
- text_sensor.template.publish:
id: diagnostic_last_trigger
state: PHYSICAL
# Use motion detection to keep fan running.
- platform: homeassistant
id: motion
entity_id: binary_sensor.upstairs_bathroom_motion
on_state:
- if:
# When motion is detected.
condition:
and:
- binary_sensor.is_on: motion
then:
- if:
condition:
- switch.is_off: relay
then:
- switch.turn_on: relay
- if:
condition:
- lambda: return id(diagnostic_last_trigger).state != "MOTION";
then:
- text_sensor.template.publish:
id: diagnostic_last_trigger
state: MOTION
# Start the countdown when: motion ends, the fan is on, the countdown has not already started, and humidity is below the lower trigger.
- if:
condition:
and:
- binary_sensor.is_off: motion
- switch.is_on: relay
- lambda: return id(remaining_time).state == 0;
- lambda: return id(humidity_delta).state <= id(delta_lower_trigger).state;
then:
- script.execute: remaining_time_start
number:
- platform: template
name: "$project humidity delta upper trigger"
id: delta_upper_trigger
icon: "mdi:timer-play"
entity_category: config
unit_of_measurement: "%"
optimistic: true
restore_value: true
min_value: 0.5
max_value: 30.0
step: 0.5
- platform: template
name: "$project humidity delta lower trigger"
id: delta_lower_trigger
icon: "mdi:timer-stop"
entity_category: config
unit_of_measurement: "%"
optimistic: true
restore_value: true
min_value: 0.5
max_value: 15.0
step: 0.5
sensor:
- platform: template
id: humidity_delta
name: "$project humidity delta"
accuracy_decimals: 1
icon: "mdi:delta"
entity_category: diagnostic
unit_of_measurement: "%"
on_value:
then:
- script.execute: humidity_trigger_check
- platform: homeassistant
id: humidity_now
internal: true
accuracy_decimals: 1
entity_id: sensor.upstairs_bathroom_humidity
unit_of_measurement: "%"
- platform: homeassistant
id: humidity_reference
internal: true
accuracy_decimals: 1
entity_id: $humidity_reference_sensor
unit_of_measurement: "%"
- platform: template
id: remaining_time
name: "$project remaining time"
icon: "mdi:sort-clock-ascending"
accuracy_decimals: 0
entity_category: diagnostic
unit_of_measurement: "seconds"
## Power monitoring
- platform: adc
id: temp_analog_reading
pin: A0
- platform: hlw8012
cf_pin: GPIO05
cf1_pin: GPIO13 # not used because it is not available on the 1PM but it is needed to compile
sel_pin: GPIO14 # not used because it is not available on the 1PM but it is needed to compile
power:
name: "$project power"
id: "shelly1pm_power"
device_class: power
state_class: measurement
unit_of_measurement: W
accuracy_decimals: 0
filters:
# Map from sensor -> measured value
- calibrate_linear:
- 0.0 -> 1.0
- 110.33186 -> 20.62
- 131.01909 -> 24.32
- 341.33920 -> 62.08
- 5561.41553 -> 1000.0
- 2975.51221 -> 535.7
- 9612.66309 -> 1720.0
- 14891.35352 -> 2679.0
# Make everything below 2W appear as just 0W.
- lambda: if (x < 2) return 0; else return x;
update_interval: 60s
- platform: total_daily_energy
name: "$project daily energy"
power_id: "shelly1pm_power"
device_class: energy
state_class: total_increasing
unit_of_measurement: kWh
filters:
- multiply: 0.001
# Temperature overheat monitoring.
- platform: ntc
sensor: temp_resistance_reading
name: "$project temperature"
accuracy_decimals: 1
device_class: temperature
unit_of_measurement: "°C"
disabled_by_default: true
entity_category: diagnostic
calibration:
b_constant: 3350
reference_resistance: 10kOhm
reference_temperature: 298.15K
on_value_range:
- above: $max_temp
then:
- homeassistant.event:
event: esphome.overheat
data:
title: "$project has overheated."
- platform: resistance
id: temp_resistance_reading
sensor: temp_analog_reading
configuration: DOWNSTREAM
resistor: 32kOhm
switch:
- platform: gpio
id: relay
pin: $relay_gpio
on_turn_on:
- if:
condition:
- lambda: return id(humidity_delta).state <= id(delta_lower_trigger).state;
then:
- script.execute: remaining_time_start
on_turn_off:
- script.execute: remaining_time_clear
- platform: template
id: virtual_switch
name: $project
optimistic: no
lambda: return (id(relay).state);
turn_off_action:
- if:
condition:
- switch.is_on: relay
then:
- switch.turn_off: relay
turn_on_action:
- if:
condition:
- switch.is_off: relay
then:
- switch.turn_on: relay
- if:
condition:
- lambda: return id(diagnostic_last_trigger).state != "VIRTUAL";
then:
- text_sensor.template.publish:
id: diagnostic_last_trigger
state: VIRTUAL
text_sensor:
# Trigger states: PHYSICAL, VIRTUAL (UI or voice assistant), MOTION, HUMIDITY
- platform: template
id: diagnostic_last_trigger
name: "$project last trigger"
disabled_by_default: true
entity_category: diagnostic
time:
- platform: homeassistant
id: homeassistant_time
timezone: America/Los_Angeles