Skip to content

Instantly share code, notes, and snippets.

@patrickdk77
Last active January 28, 2022 06:32
Show Gist options
  • Save patrickdk77/c8ede78a8345ae17c5931053d6de7110 to your computer and use it in GitHub Desktop.
Save patrickdk77/c8ede78a8345ae17c5931053d6de7110 to your computer and use it in GitHub Desktop.
#0 boot (not used)
#1 tx (not used)
#2 led status (not used)
#3 rx (not used)
#4 status neopixel
#5 dallas
#16 thermostat O
#17 thermostat Y
#18 (not used)
#19 outdoor W
#21 i2c sda
#22 i2c scl
#23 water overflow
#25 thermostat G
#26 (not used)
#27 thermostat W
#32 adc4 (not used)
#33 adc5 (not used)
#34 adc6 (not used)
#35 adc7 (not used)
substitutions:
display_name: "Upstairs HVAC"
name: upstairs_hvac
heartbeat: 900s
tempature_delta: "0.1"
humidity_delta: "0.1"
pressure_diff_delta: "5"
pressure_hpa_delta: "0.2"
tempature_diff_delta: "0.5"
btu_delta: "100"
defaulttxrssi: "-72"
maxdistance: "5.0"
room: "guest room"
channel: "room_presence"
tele: "presense_nodes/${name}/tele"
availability: "presense_nodes/${room}"
#old
# dallas_gpio: "23"
#new
status_bright: "35"
dallas_gpio: "5"
neopixel: "GPIO4"
thermostat_y: "GPIO17"
thermostat_o: "GPIO16"
thermostat_w: "GPIO27"
thermostat_g: "GPIO25"
outdoor_w: "GPIO19"
overflow: "GPIO23"
heatpump_fanspeed: "fan_high"
constant_fanspeed: "fan_low"
dry_fanspeed: "fan_med"
low_temp: "20"
high_temp: "25"
low_away: "12"
high_away: "35"
min_temp: "10"
max_temp: "35"
esphome:
name: "${name}"
platform: ESP32
board: mhetesp32minikit
#arduino_version: latest
platformio_options:
board_build.flash_mode: qout
board_build.f_flash: 80000000L
build_flags:
# - -DCONFIG_ARDUINO_LOOP_STACK_SIZE=32768
# - -DCONFIG_ARDUINO_LOOP_STACK_SIZE=16384
- -DCONFIG_ARDUINO_LOOP_STACK_SIZE=49152
on_boot:
- priority: 300
then:
- binary_sensor.template.publish:
id: overflow_lockout
state: OFF
- binary_sensor.template.publish:
id: freeze_lockout
state: OFF
- binary_sensor.template.publish:
id: freeze_warn
state: OFF
- priority: -100
then:
- climate.control:
id: hvac
fan_mode: AUTO
mode: HEAT_COOL
on_shutdown:
then:
- switch.turn_off: outside_y
- switch.turn_off: electric_heat
- switch.turn_off: fan_low
- switch.turn_off: fan_med
- switch.turn_off: fan_high
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_pass
fast_connect: off
#power_save_mode: none
manual_ip:
static_ip: !secret ip_upstairs_hvac
gateway: !secret ip_gateway
subnet: !secret ip_subnet
dns1: !secret ip_dns1
dns2: !secret ip_dns2
logger:
# baud_rate: 0
# level: VERY_VERBOSE
web_server:
port: 80
#api:
# reboot_timeout: 0s
ota:
mqtt:
id: mqttid
reboot_timeout: 2000s
log_topic:
broker: !secret mqtt_broker
port: !secret mqtt_port
username: !secret mqtt_user
password: !secret mqtt_pass
discovery: true
discovery_retain: true
topic_prefix: "${tele}"
birth_message:
topic: "${availability}"
payload: "CONNECTED"
will_message:
topic: "${availability}"
payload: "DISCONNECTED"
shutdown_message:
topic: "${availability}"
payload: "DISCONNECTED"
on_json_message:
# topic: zigbee2mqtt/Upstairs
# then:
# if:
# condition:
# - lambda: |-
# return (x.containsKey("temperature"));
# then:
# - sensor.template.publish:
# id: thermastat_temperature
# state: !lambda |-
# return (x["temperature"]);
topic: tele/tasmota_blerry/upstairs_atc
then:
if:
condition:
- lambda: |-
return (x.containsKey("Temperature"));
then:
- sensor.template.publish:
id: thermastat_temperature
state: !lambda |-
return (x["Temperature"]);
- sensor.template.publish:
id: thermastat_humidity
state: !lambda |-
return (x["Humidity"]);
globals:
- id: schedule_disabled
type: bool
restore_value: true
initial_value: 'false'
#sun:
# latitude: !secret latitude
# longitude: !secret longitude
time:
- platform: sntp
timezone: !secret timezone
servers:
- !secret ip_ntp1
- !secret ip_ntp2
id: ntp_time
on_time:
- seconds: 0
minutes: 0
hours: 21
then:
- if:
condition:
- switch.is_off: schedule_override
then:
- climate.control:
id: hvac
preset: HOME
- seconds: 0
minutes: 0
hours: 9
days_of_week: MON-FRI
then:
- if:
condition:
- switch.is_off: schedule_override
then:
- climate.control:
id: hvac
preset: AWAY
- seconds: 0
minutes: 0
hours: 10
days_of_week: SAT,SUN
then:
- if:
condition:
- switch.is_off: schedule_override
then:
- climate.control:
id: hvac
preset: AWAY
i2c:
- id: bmei2c
sda: 21
scl: 22
scan: true
# frequency: 50000
# frequency: 400000
pcf8574:
- id: 'gpiohub'
pcf8575: false
address: 0x20
i2c_id: bmei2c
dallas:
- pin: ${dallas_gpio}
update_interval: 16s
id: dallas_bus_01
status_led:
id: statusled
pin:
number: GPIO2
inverted: true
#esp32_ble_tracker:
sensor:
- platform: template
name: "${display_name} Thermastat Temperature"
id: thermastat_temperature
accuracy_decimals: 1
unit_of_measurement: "°C"
filters:
- or:
- heartbeat: ${heartbeat}
- delta: ${tempature_delta}
- platform: template
name: "${display_name} Thermastat Humidity"
id: thermastat_humidity
accuracy_decimals: 1
unit_of_measurement: "%"
filters:
- or:
- heartbeat: ${heartbeat}
- delta: ${tempature_delta}
# - platform: pvvx_mithermometer
# mac_address: "A4:C1:38:0E:CC:CF"
# temperature:
# id: xiaomi_upstairs_temperature
# name: "LYWSD03MMC Temperature"
# accuracy_decimals: 1
# humidity:
# id: xiaomi_upstairs_humidity
# name: "LYWSD03MMC Humidity"
# accuracy_decimals: 0
# battery_level:
# name: "Xiaomi Upstairs Battery Level"
# battery_voltage:
# name: "Xiaomi Upstairs Battery Voltage"
- platform: uptime
name: ${display_name} Uptime Sensor
id: uptime_sensor
update_interval: 60s
on_raw_value:
then:
- text_sensor.template.publish:
id: uptime_human
state: !lambda |-
int seconds = round(id(uptime_sensor).raw_state);
int days = seconds / (24 * 3600);
seconds = seconds % (24 * 3600);
int hours = seconds / 3600;
seconds = seconds % 3600;
int minutes = seconds / 60;
seconds = seconds % 60;
return (
(days ? String(days) + "d " : "") +
(hours ? String(hours) + "h " : "") +
(minutes ? String(minutes) + "m " : "") +
(String(seconds) + "s")
).c_str();
- platform: dallas
dallas_id: dallas_bus_01
address: 0x2E3C01B5562F1C28
id: lineset_vapor_temperature
name: "${display_name} Lineset Vapor Temperature"
accuracy_decimals: 1
filters:
- or:
- heartbeat: ${heartbeat}
- delta: ${tempature_delta}
- platform: dallas
dallas_id: dallas_bus_01
address: 0xE53C01B556296628
id: lineset_liquid_temperature
name: "${display_name} Lineset Liquid Temperature"
accuracy_decimals: 1
filters:
- or:
- heartbeat: ${heartbeat}
- delta: ${humidity_delta}
# - platform: dallas
# dallas_id: dallas_bus_01
# address: 0x7E3C01B5561C7F28
# id: duct_supply_temperature
# name: "${display_name} Duct Supply Temperature"
# accuracy_decimals: 1
# filters:
# - or:
# - heartbeat: ${heartbeat}
# - delta: ${tempature_delta}
# - platform: dallas
# dallas_id: dallas_bus_01
# address: 0x8E3C01B556795828
# id: duct_return_temperature
# name: "${display_name} Duct Return Temperature"
# accuracy_decimals: 1
# filters:
# - or:
# - heartbeat: ${heartbeat}
# - delta: ${tempature_delta}
- platform: dallas
dallas_id: dallas_bus_01
address: 0x063C01B5568B3A28
id: coil_temperature
name: "${display_name} Evaporator Coil Temperature"
accuracy_decimals: 1
filters:
- or:
- heartbeat: ${heartbeat}
- delta: ${tempature_delta}
on_value_range:
- below: -5
then:
if:
condition:
switch.is_on: outside_o
then:
- switch.turn_off: outside_y
- binary_sensor.template.publish:
id: freeze_lockout
state: ON
- switch.turn_on: fan_high
- below: 1
above: -1
then:
if:
condition:
switch.is_on: outside_o
then:
- binary_sensor.template.publish:
id: freeze_warn
state: ON
# - if:
# condition:
# switch.is_on: fan_high
# then:
# - switch.turn_off: outside_y
# - binary_sensor.template.publish:
# id: freeze_lockout
# state: ON
- if:
condition:
- switch.is_on: fan_med
then:
- switch.turn_on: fan_high
- if:
condition:
- switch.is_on: fan_low
then:
- switch.turn_on: fan_high
- if:
condition:
- switch.is_on: outside_y
- switch.is_off: fan_high
- switch.is_off: fan_med
- switch.is_off: fan_low
then:
- script.execute: fan_heatpump
- above: 10
then:
- if:
condition:
- binary_sensor.is_on: freeze_lockout
then:
- binary_sensor.template.publish:
id: freeze_lockout
state: OFF
- if:
condition:
- switch.is_off: outside_y
- switch.is_off: electric_heat
then:
- script.execute: fan_ramp_off
- delay: 900s
- switch.turn_on: outside_y
- above: 3
below: 10
then:
- if:
condition:
- binary_sensor.is_on: freeze_warn
then:
- binary_sensor.template.publish:
id: freeze_warn
state: OFF
- above: 40
then:
- if:
condition:
- switch.is_on: outside_y
- switch.is_off: outside_o
- switch.is_off: ${heatpump_fanspeed}
then:
- script.execute: fan_heatpump
- platform: bme280
i2c_id: bmei2c
address: 0x76
update_interval: 13s
temperature:
name: "${display_name} Supply Temperature"
oversampling: 4x
unit_of_measurement: "°C"
id: bme280_supply_temperature
accuracy_decimals: 1
filters:
- or:
- heartbeat: ${heartbeat}
- delta: ${tempature_delta}
pressure:
name: "${display_name} Supply Pressure"
oversampling: 16x
unit_of_measurement: "hPa"
id: bme280_supply_pressure
accuracy_decimals: 2
filters:
- or:
- heartbeat: ${heartbeat}
- delta: ${pressure_hpa_delta}
humidity:
name: "${display_name} Supply Humidity"
oversampling: 16x
unit_of_measurement: "%"
id: bme280_supply_humidity
accuracy_decimals: 1
filters:
- or:
- heartbeat: ${heartbeat}
- delta: ${humidity_delta}
# - offset: -5.0
#on_value_range:
# - above: 80
# then:
# - if:
# condition:
# - lambda: 'return id(ntp_time).now().hour < 23;'
# - lambda: 'return id(ntp_time).now().hour > 06;'
# then:
# - switch.turn_on: fan
# - below: 75
# then:
# - switch.turn_off: fan
- platform: template
name: "${display_name} Supply Wetbulb"
id: bme280_supply_wetbulb
lambda: |-
return (-5.806+0.672*id(bme280_supply_temperature).state-0.006*id(bme280_supply_temperature).state*id(bme280_supply_temperature).state+
(0.061+0.004*id(bme280_supply_temperature).state+0.000099*id(bme280_supply_temperature).state*id(bme280_supply_temperature).state)*id(bme280_supply_temperature).state+
(-0.000033-0.000005*id(bme280_supply_temperature).state-0.0000001*id(bme280_supply_temperature).state*id(bme280_supply_temperature).state)*id(bme280_supply_humidity).state*id(bme280_supply_humidity).state);
accuracy_decimals: 1
update_interval: 15s
unit_of_measurement: "°C"
filters:
- or:
- heartbeat: ${heartbeat}
- delta: ${tempature_delta}
- platform: template
name: "${display_name} Supply Dewpoint"
id: bme280_supply_dewpoint
lambda: |-
const float temp = id(bme280_supply_temperature).state;
const float logRH = log(id(bme280_supply_humidity).state /100.0);
const float alpha = 6.112;
const float beta = 17.62;
const float theta = 243.12;
return (theta * (logRH + ((beta * temp) /(243.04 + temp)) ) ) / (beta - (logRH - ((beta * temp)/(theta + temp)) ) );
accuracy_decimals: 1
update_interval: 18s
unit_of_measurement: "°C"
filters:
- or:
- heartbeat: ${heartbeat}
- delta: ${tempature_delta}
- platform: template
name: "${display_name} Supply Absolute Humidity"
id: bme280_supply_abs_hum
lambda: |-
const float mw = 18.01534; // molar mass of water g/mol
const float r = 8.31447215; // Universal gas constant J/mol/K
return (6.112 * powf(2.718281828, (17.67 * id(bme280_supply_temperature).state) /
(id(bme280_supply_temperature).state + 243.5)) * id(bme280_supply_humidity).state * mw) /
((273.15 + id(bme280_supply_temperature).state) * r); // in grams/m^3
accuracy_decimals: 2
update_interval: 22s
filters:
- or:
- heartbeat: ${heartbeat}
- delta: 0.1
- platform: template
name: "${display_name} Supply Enthalpy"
id: bme280_supply_enthalpy
lambda: |-
const float tempf = (id(bme280_supply_temperature).state *9.0/5.0) +32.0;
const float psi = id(bme280_supply_pressure).state * 0.0145037738;
const float kelvinf = tempf + 459.67;
const float logkelvinf = log(kelvinf);
const float l = -10440.4/kelvinf - 11.29465-0.02702235 * kelvinf +1.289036E-005 * pow(kelvinf,2) -2.478068E-009 * pow(kelvinf,3) +6.545967 * logkelvinf;
const float s = exp(l);
const float p = id(bme280_supply_humidity).state / 100.0 * s;
const float w = 0.62198 * p / (psi - p);
return 0.24 * tempf + w * (1061.0+0.444 * kelvinf);
accuracy_decimals: 3
update_interval: 24s
unit_of_measurement: "btu/lb"
filters:
- or:
- heartbeat: ${heartbeat}
- delta: 0.001
- platform: bme280
i2c_id: bmei2c
address: 0x77
update_interval: 13s
temperature:
name: "${display_name} Return Temperature"
oversampling: 4x
unit_of_measurement: "°C"
id: bme280_return_temperature
accuracy_decimals: 1
filters:
- or:
- heartbeat: ${heartbeat}
- delta: ${tempature_delta}
pressure:
name: "${display_name} Return Pressure"
oversampling: 16x
unit_of_measurement: "hPa"
id: bme280_return_pressure
accuracy_decimals: 2
filters:
- or:
- heartbeat: ${heartbeat}
- delta: ${pressure_hpa_delta}
humidity:
name: "${display_name} Return Humidity"
oversampling: 16x
unit_of_measurement: "%"
id: bme280_return_humidity
accuracy_decimals: 1
filters:
- or:
- heartbeat: ${heartbeat}
- delta: ${humidity_delta}
# - offset: +2.0
#on_value_range:
# - above: 80
# then:
# - if:
# condition:
# - lambda: 'return id(ntp_time).now().hour < 23;'
# - lambda: 'return id(ntp_time).now().hour > 06;'
# then:
# - switch.turn_on: fan
# - below: 75
# then:
# - switch.turn_off: fan
- platform: template
name: "${display_name} Return Wetbulb"
id: bme280_return_wetbulb
lambda: |-
return (-5.806+0.672*id(bme280_return_temperature).state-0.006*id(bme280_return_temperature).state*id(bme280_return_temperature).state+
(0.061+0.004*id(bme280_return_temperature).state+0.000099*id(bme280_return_temperature).state*id(bme280_return_temperature).state)*id(bme280_return_temperature).state+
(-0.000033-0.000005*id(bme280_return_temperature).state-0.0000001*id(bme280_return_temperature).state*id(bme280_return_temperature).state)*id(bme280_return_humidity).state*id(bme280_return_humidity).state);
accuracy_decimals: 1
update_interval: 16s
unit_of_measurement: "°C"
filters:
- or:
- heartbeat: ${heartbeat}
- delta: ${tempature_delta}
- platform: template
name: "${display_name} Return Dewpoint"
id: bme280_return_dewpoint
lambda: |-
const float temp = id(bme280_return_temperature).state;
const float logRH = log(id(bme280_return_humidity).state /100.0);
const float alpha = 6.112;
const float beta = 17.62;
const float theta = 243.12;
return (theta * (logRH + ((beta * temp) /(243.04 + temp)) ) ) / (beta - (logRH - ((beta * temp)/(theta + temp)) ) );
accuracy_decimals: 1
update_interval: 21s
unit_of_measurement: "°C"
filters:
- or:
- heartbeat: ${heartbeat}
- delta: ${tempature_delta}
- platform: template
name: "${display_name} Return Absolute Humidity"
id: bme280_return_abs_hum
lambda: |-
const float mw = 18.01534; // molar mass of water g/mol
const float r = 8.31447215; // Universal gas constant J/mol/K
return (6.112 * powf(2.718281828, (17.67 * id(bme280_return_temperature).state) /
(id(bme280_return_temperature).state + 243.5)) * id(bme280_return_humidity).state * mw) /
((273.15 + id(bme280_return_temperature).state) * r); // in grams/m^3
accuracy_decimals: 2
update_interval: 24s
filters:
- or:
- heartbeat: ${heartbeat}
- delta: ${tempature_delta}
- platform: template
name: "${display_name} Return Enthalpy"
id: bme280_return_enthalpy
lambda: |-
const float tempf = (id(bme280_return_temperature).state *9.0/5.0) +32.0;
const float psi = id(bme280_return_pressure).state * 0.0145037738;
const float kelvinf = tempf + 459.67;
const float logkelvinf = log(kelvinf);
const float l = -10440.4/kelvinf - 11.29465-0.02702235 * kelvinf +1.289036E-005 * pow(kelvinf,2) -2.478068E-009 * pow(kelvinf,3) +6.545967 * logkelvinf;
const float s = exp(l);
const float p = id(bme280_return_humidity).state / 100.0 * s;
const float w = 0.62198 * p / (psi - p);
return 0.24 * tempf + w * (1061.0+0.444 * kelvinf);
accuracy_decimals: 3
update_interval: 26s
unit_of_measurement: "btu/lb"
filters:
- or:
- heartbeat: ${heartbeat}
- delta: 0.001
- platform: template
name: "${display_name} Total BTU/h"
id: total_btu_hour
# Black (Hi) 165pa difference, 21.4td 1 bank electric, 644.5cfm
# Blue (Med) 150pa difference, 22.8td 1 bank electric, 605cfm
# Red (Low) 130pa difference, 23.5td 1 bank electric, 586cfm
lambda: |-
const float cfm = 644.0;
if(id(bme280_supply_pressure).state - id(bme280_return_pressure).state < 0.8) {
return 0;
} else {
return cfm * 4.5 * (id(bme280_return_enthalpy).state - id(bme280_supply_enthalpy).state);
}
accuracy_decimals: 0
update_interval: 13s
unit_of_measurement: "btu/h"
filters:
- or:
- heartbeat: ${heartbeat}
- delta: ${btu_delta}
- platform: template
name: "${display_name} Sensible BTU/h"
id: sensible_btu_hour
lambda: |-
const float cfm = 644.0;
if(id(bme280_supply_pressure).state - id(bme280_return_pressure).state < 0.8) {
return 0;
} else {
return cfm * (id(bme280_return_temperature).state - id(bme280_supply_temperature).state) *9.0/5.0 * 1.08;
}
accuracy_decimals: 0
update_interval: 14s
unit_of_measurement: "btu/h"
filters:
- or:
- heartbeat: ${heartbeat}
- delta: ${btu_delta}
- platform: template
name: "${display_name} Latent BTU/h"
id: latent_btu_hour
lambda: |-
const float cfm = 644.0;
if(id(bme280_supply_pressure).state - id(bme280_return_pressure).state < 0.8) {
return 0;
} else {
return cfm * 0.68 * (id(bme280_return_enthalpy).state - id(bme280_supply_enthalpy).state);
}
accuracy_decimals: 0
update_interval: 12s
unit_of_measurement: "btu/h"
filters:
- or:
- heartbeat: ${heartbeat}
- delta: ${btu_delta}
# - platform: template
# name: "${display_name} Duct Temperature Difference"
# id: duct_difference_temperature
# lambda: |-
# return abs((id(duct_return_temperature).state-id(duct_supply_temperature).state)*90.0/5.0)/10.0;
# accuracy_decimals: 1
# update_interval: 12s
# unit_of_measurement: "°F"
# filters:
# - or:
# - heartbeat: ${heartbeat}
# - delta: ${tempature_diff_delta}
- platform: template
name: "${display_name} Temperature Difference"
id: bme280_difference_temperature
lambda: |-
return abs((id(bme280_return_temperature).state-id(bme280_supply_temperature).state)*90.0/5.0)/10.0;
accuracy_decimals: 1
update_interval: 20s
unit_of_measurement: "°F"
filters:
- or:
- heartbeat: ${heartbeat}
- delta: ${tempature_diff_delta}
- platform: template
name: "${display_name} Pressure Difference"
id: bme280_difference_pressure
lambda: |-
return abs((id(bme280_supply_pressure).state-id(bme280_return_pressure).state)*1000.0)/10.0;
accuracy_decimals: 1
update_interval: 20s
unit_of_measurement: "Pa"
filters:
- or:
- heartbeat: ${heartbeat}
- delta: ${pressure_diff_delta}
- platform: template
name: "${display_name} Filter Pressure"
id: filter_pressure
accuracy_decimals: 0
unit_of_measurement: "Pa"
- platform: template
name: "${display_name} Ambiant Pressure"
id: ambiant_pressure
accuracy_decimals: 0
unit_of_measurement: "Pa"
# - platform: template
# name: "${display_name} Supply Spped of Sound"
# id: bme280_supply_sos
# lambda: |-
# return 64202.43439*(pow((id(bme280_supply_temperature).state+273.16)/273.15,0.5));
# accuracy_decimals: 1
# update_interval: 20s
# unit_of_measurement: ft/m
# filters:
# - or:
# - heartbeat: ${heartbeat}
# - delta: 10
# - platform: template
# name: "${display_name} Return Spped of Sound"
# id: bme280_return_sos
# lambda: |-
# return 64202.43439*(pow((id(bme280_return_temperature).state+273.16)/273.15,0.5));
# accuracy_decimals: 1
# update_interval: 20s
# unit_of_measurement: ft/m
# filters:
# - or:
# - heartbeat: ${heartbeat}
# - delta: 10
- platform: wifi_signal
id: wifi_sig
name: "${display_name} RSSI"
unit_of_measurement: "dBm"
update_interval: 122s
filters:
- median:
window_size: 7
send_every: 5
send_first_at: 5
- or:
- heartbeat: ${heartbeat}
- delta: 3
# const float den = 0.075 * (530 / (460 / tempf ) * ( (id(bme280_return_pressure).state/1000) / 29.92 );
# CFM = (AMPS*VOLTS*3.41214) / (1.08 * (SupplyTemp - ReturnTemp))
# BTU Sensible Heat Removed = CFM * (1.08 * (SupplyTemp - ReturnTemp))
# BTU Latent Heat Removed = 0.68 * CFM *
# BTU Heat Removed = BTU Sensible + BTU Latent, aka, 4.5 * CFM
binary_sensor:
- platform: template
id: overflow_lockout
name: "${display_name} Overflow Lockout"
- platform: template
id: freeze_lockout
name: "${display_name} Freeze Lockout"
- platform: template
id: freeze_warn
name: "${display_name} Freeze Warning"
- platform: gpio
id: thermostat_y
name: "${display_name} Thermostat Y"
pin:
number: ${thermostat_y}
mode: INPUT_PULLUP
inverted: true
filters:
- delayed_on: 50ms
- delayed_off: 50ms
- platform: gpio
id: thermostat_o
name: "${display_name} Thermostat O"
pin:
number: ${thermostat_o}
mode: INPUT_PULLUP
inverted: true
filters:
- delayed_on: 20ms
- delayed_off: 20ms
- platform: gpio
id: thermostat_w
name: "${display_name} Thermostat W"
pin:
number: ${thermostat_w}
mode: INPUT_PULLUP
inverted: true
filters:
- delayed_on: 30ms
- delayed_off: 30ms
- platform: gpio
id: thermostat_g
name: "${display_name} Thermostat G"
pin:
number: ${thermostat_g}
mode: INPUT_PULLUP
inverted: true
filters:
- delayed_on: 20ms
- delayed_off: 20ms
- platform: gpio
id: outdoor_w
name: "${display_name} Outdoor Defrost"
pin:
number: ${outdoor_w}
mode: INPUT_PULLUP
inverted: true
filters:
- delayed_on: 30ms
- delayed_off: 30ms
- platform: gpio
id: overflow
name: "${display_name} Water Overflow"
pin:
number: ${overflow}
mode: INPUT_PULLUP
inverted: false #off on overflow, on for normal
filters:
- delayed_on: 50ms
- delayed_off: 50ms
on_press:
then:
- switch.turn_off: outside_y
- binary_sensor.template.publish:
id: overflow_lockout
state: ON
on_release:
then:
- binary_sensor.template.publish:
id: overflow_lockout
state: OFF
switch:
- platform: template
id: schedule_override
name: "${display_name} Disable Schedule"
restore_state: false
optimistic: true
turn_on_action:
- globals.set:
id: schedule_disabled
value: 'true'
turn_off_action:
- globals.set:
id: schedule_disabled
value: 'false'
lambda: |-
return id(schedule_disabled);
- platform: gpio
id: fan_high
name: "${display_name} Fan High"
restore_mode: ALWAYS_OFF
pin:
pcf8574: gpiohub
number: 7
mode: OUTPUT
inverted: false
interlock: &fanspeed_group [fan_high, fan_med, fan_low]
interlock_wait_time: 1s
- platform: gpio
id: fan_med
name: "${display_name} Fan Med"
restore_mode: ALWAYS_OFF
pin:
pcf8574: gpiohub
number: 6
mode: OUTPUT
inverted: false
interlock: *fanspeed_group
interlock_wait_time: 1s
- platform: gpio
id: fan_low
name: "${display_name} Fan Low"
restore_mode: ALWAYS_OFF
pin:
pcf8574: gpiohub
number: 5
mode: OUTPUT
inverted: false
interlock: *fanspeed_group
interlock_wait_time: 1s
# - platform: gpio
# name: "${display_name} Extra3"
# restore_mode: ALWAYS_OFF
# pin:
# pcf8574: gpiohub
# number: 4
# mode: OUTPUT
# inverted: false
# - platform: gpio
# name: "${display_name} Extra4"
# restore_mode: ALWAYS_OFF
# pin:
# pcf8574: gpiohub
# number: 3
# mode: OUTPUT
# inverted: false
- platform: gpio
id: electric_heat
name: "${display_name} Em Heat"
restore_mode: ALWAYS_OFF
pin:
pcf8574: gpiohub
number: 2
mode: OUTPUT
inverted: false
on_turn_on:
then:
if:
condition:
- switch.is_off: fan_high
- switch.is_off: fan_med
- switch.is_off: fan_low
then:
- script.execute: fan_heatpump
- platform: gpio
id: outside_y
internal: false
name: "${display_name} Outdoor Y"
restore_mode: ALWAYS_OFF
pin:
pcf8574: gpiohub
number: 1
mode: OUTPUT
inverted: false
on_turn_on:
then:
- if:
condition:
or:
- binary_sensor.is_on: overflow_lockout
- binary_sensor.is_on: freeze_warn
- binary_sensor.is_on: freeze_lockout
then:
- switch.turn_off: outside_y
# else:
# - if:
# condition:
# - switch.is_off: ${heatpump_fanspeed}
# then:
# - script.execute: fan_heatpump
- platform: gpio
id: outside_o
internal: false
name: "${display_name} Outdoor O"
restore_mode: ALWAYS_ON
pin:
pcf8574: gpiohub
number: 0
mode: OUTPUT
inverted: false
text_sensor:
- platform: wifi_info
bssid:
id: wifi_bssid
name: "${display_name} BSSID"
# - platform: ble_scanner
# name: "${display_name} BLE"
- platform: template
name: ${display_name} Uptime Readable
id: uptime_human
icon: mdi:clock-start
#light:
# - platform: neopixelbus
# type: GRB
# pin: ${neopixel}
# num_leds: 1
# name: "NeoPixel Lights"
# id: statusrgb
# internal: true
# variant: WS2812
# effects:
# - strobe:
# name: "Cooling"
# colors:
# - state: true
# duration: 500ms
# brightness: ${status_bright}%
# red: 0%
# green: 0%
# blue: 100%
# - state: false
# duration: 500ms
# - strobe:
# name: "Heating"
# colors:
# - state: true
# duration: 500ms
# brightness: ${status_bright}%
# red: 100%
# green: 0%
# blue: 0%
# - state: false
# duration: 500ms
# - strobe:
# name: "Fan On"
# colors:
# - state: true
# duration: 500ms
# brightness: ${status_bright}%
# red: 0%
# green: 100%
# blue: 0%
# - state: false
# duration: 500ms
# - strobe:
# name: "Dehumidifing"
# colors:
# - state: true
# duration: 500ms
# brightness: ${status_bright}%
# red: 40%
# green: 0%
# blue: 100%
# - state: false
# duration: 500ms
# - strobe:
# name: "Cool"
# colors:
# - state: true
# duration: 500ms
# brightness: ${status_bright}%
# red: 0%
# green: 0%
# blue: 100%
# - state: true
# duration: 500ms
# brightness: ${status_bright}%
# red: 0%
# green: 0%
# blue: 100%
# - strobe:
# name: "Heat"
# colors:
# - state: true
# duration: 500ms
# brightness: ${status_bright}%
# red: 100%
# green: 0%
# blue: 0%
# - state: true
# duration: 500ms
# brightness: ${status_bright}%
# red: 100%
# green: 0%
# blue: 0%
# - strobe:
# name: "Fan"
# colors:
# - state: true
# duration: 500ms
# brightness: ${status_bright}%
# red: 0%
# green: 100%
# blue: 0%
# - state: true
# duration: 500ms
# brightness: ${status_bright}%
# red: 0%
# green: 100%
# blue: 0%
# - strobe:
# name: "Dry"
# colors:
# - state: true
# duration: 500ms
# brightness: ${status_bright}%
# red: 40%
# green: 0%
# blue: 100%
# - state: true
# duration: 500ms
# brightness: ${status_bright}%
# red: 40%
# green: 0%
# blue: 100%
# - strobe:
# name: "Auto"
# colors:
# - state: true
# duration: 500ms
# brightness: ${status_bright}%
# red: 100%
# green: 100%
# blue: 100%
# - state: true
# duration: 500ms
# brightness: ${status_bright}%
# red: 100%
# green: 100%
# blue: 100%
climate:
- platform: thermostat
id: hvac
name: "${display_name} Thermostat"
visual:
min_temperature: ${min_temp} °C
max_temperature: ${max_temp} °C
temperature_step: 1.0 °C
sensor: thermastat_temperature
# sensor: xiaomi_upstairs_temperature
default_mode: heat_cool
default_target_temperature_low: ${low_temp} °C
default_target_temperature_high: ${high_temp} °C
set_point_minimum_differential: 3 °C
cool_deadband: 1 °C
cool_overrun: 0.5 °C
heat_deadband: 1 °C
heat_overrun: 0.5 °C
# supplemental_cooling_delta: 2 °C
# max_cooling_run_time: 1000s
# supplemental_heating_delta: 2 °C
# max_heating_run_time: 1000s
away_config:
default_target_temperature_low: ${low_away} °C
default_target_temperature_high: ${high_away} °C
startup_delay: true
min_cooling_off_time: 600s
min_cooling_run_time: 800s
min_heating_off_time: 600s
min_heating_run_time: 800s
min_idle_time: 30s
# min_fanning_off_time: 30s
# min_fanning_run_time: 60s
min_fan_mode_switching_time: 30s
# fan_only_action_uses_fan_mode_timer: true
# fan_only_cooling: false
fan_with_cooling: false
fan_with_heating: false
cool_action:
- switch.turn_on: outside_o
- switch.turn_on: outside_y
- delay: 30s
- script.execute: fan_heatpump
# supplemental_cooling_action:
dry_action:
- switch.turn_on: outside_o
- switch.turn_on: outside_y
- delay: 30s
- switch.turn_on: ${dry_fanspeed}
heat_action:
- switch.turn_off: outside_o
- switch.turn_on: outside_y
- delay: 200s
- script.execute: fan_heatpump
# supplemental_heating_action:
# - switch.turn_on: electric_head
# fan_only_action:
# if:
# condition:
# or:
# - switch.is_on: outside_y
# - switch.is_on: electric_heat
# then:
# - switch.turn_on: ${heatpump_fanspeed}
# else:
# - switch.turn_on: ${constant_fanspeed}
idle_action:
- switch.turn_off: outside_y
- switch.turn_off: electric_heat
- script.execute: fan_ramp_off
# To set led
# auto_mode:
# - light.turn_on:
# id: statusrgb
# effect: Auto
# off_mode:
# - light.turn_off:
# id: statusrgb
# heat_mode:
# - light.turn_on:
# id: statusrgb
# effect: Heat
# cool_mode:
# - light.turn_on:
# id: statusrgb
# effect: Cool
# dry_mode:
# - light.turn_on:
# id: statusrgb
# effect: Dry
# fan_only_mode:
# - light.turn_on:
# id: statusrgb
# effect: Fan
fan_mode_auto_action:
then:
if:
condition:
or:
- switch.is_on: outside_y
- switch.is_on: electric_heat
then:
- script.execute: fan_heatpump
else:
- script.execute: fan_ramp_off
fan_mode_low_action:
then:
if:
condition:
or:
- switch.is_on: outside_y
- switch.is_on: electric_heat
then:
- script.execute: fan_heatpump
else:
- switch.turn_on: fan_low
fan_mode_medium_action:
then:
if:
condition:
or:
- switch.is_on: outside_y
- switch.is_on: electric_heat
then:
- script.execute: fan_heatpump
else:
- switch.turn_on: fan_med
fan_mode_high_action:
then:
if:
condition:
or:
- switch.is_on: outside_y
- switch.is_on: electric_heat
then:
- script.execute: fan_heatpump
else:
- switch.turn_on: fan_high
# fan_mode_off_action:
# - script.execute: fan_ramp_off
fan_mode_on_action:
then:
if:
condition:
or:
- switch.is_on: outside_y
- switch.is_on: electric_heat
then:
- switch.turn_on: ${heatpump_fanspeed}
else:
if:
condition:
- switch.is_off: fan_high
- switch.is_off: fan_med
- switch.is_off: fan_low
then:
- switch.turn_on: ${constant_fanspeed}
script:
- id: fan_heatpump
mode: single
then:
if:
condition:
- switch.is_off: fan_high
- switch.is_off: fan_med
- switch.is_off: fan_low
then:
- lambda: |-
id(ambiant_pressure).publish_state(id(bme280_return_pressure).raw_state*100.0);
- switch.turn_on: ${heatpump_fanspeed}
- delay: 40s
- lambda: |-
id(filter_pressure).publish_state(id(ambiant_pressure).raw_state-(id(bme280_return_pressure).raw_state*100.0));
else:
- switch.turn_on: ${heatpump_fanspeed}
- id: fan_ramp_off
mode: restart
then:
if:
condition:
lambda: |-
return abs(id(bme280_return_temperature).state - id(coil_temperature).state)>5.0;
then: #was cooling or heating
- switch.turn_off: fan_med
- switch.turn_off: fan_high
- switch.turn_off: fan_low
- if:
condition:
lambda: |-
switch(id(hvac).fan_mode.value()) {
case esphome::climate::CLIMATE_FAN_LOW:
case esphome::climate::CLIMATE_FAN_MEDIUM:
case esphome::climate::CLIMATE_FAN_HIGH:
case esphome::climate::CLIMATE_FAN_ON:
return false;
case esphome::climate::CLIMATE_FAN_OFF:
case esphome::climate::CLIMATE_FAN_AUTO:
default:
return true;
}
then:
- switch.turn_on: ${constant_fanspeed}
- wait_until:
lambda: |-
return abs(id(bme280_return_temperature).state - id(coil_temperature).state)<4.0
|| id(outside_y).state
|| id(electric_heat).state;
- switch.turn_off: ${constant_fanspeed}
- if:
condition:
or:
- switch.is_on: outside_y
- switch.is_on: electric_heat
then:
- switch.turn_on: ${heatpump_fanspeed}
else:
if:
condition:
lambda: |-
switch(id(hvac).fan_mode.value()) {
case esphome::climate::CLIMATE_FAN_LOW:
return true;
default:
return false;
}
then:
switch.turn_on: fan_low
else:
if:
condition:
lambda: |-
switch(id(hvac).fan_mode.value()) {
case esphome::climate::CLIMATE_FAN_MEDIUM:
return true;
default:
return false;
}
then:
switch.turn_on: fan_med
else:
if:
condition:
lambda: |-
switch(id(hvac).fan_mode.value()) {
case esphome::climate::CLIMATE_FAN_HIGH:
return true;
default:
return false;
}
then:
switch.turn_on: fan_high
else:
if:
condition:
lambda: |-
switch(id(hvac).fan_mode.value()) {
case esphome::climate::CLIMATE_FAN_ON:
return true;
default:
return false;
}
then:
switch.turn_on: ${constant_fanspeed}
else:
- switch.turn_off: fan_low
- switch.turn_off: fan_med
- switch.turn_off: fan_high
- if:
condition:
or:
- switch.is_on: outside_y
- switch.is_on: electric_heat
then:
- switch.turn_on: ${heatpump_fanspeed}
else:
if:
condition:
lambda: |-
switch(id(hvac).fan_mode.value()) {
case esphome::climate::CLIMATE_FAN_LOW:
return true;
default:
return false;
}
then:
switch.turn_on: fan_low
else:
if:
condition:
lambda: |-
switch(id(hvac).fan_mode.value()) {
case esphome::climate::CLIMATE_FAN_MEDIUM:
return true;
default:
return false;
}
then:
switch.turn_on: fan_med
else:
if:
condition:
lambda: |-
switch(id(hvac).fan_mode.value()) {
case esphome::climate::CLIMATE_FAN_HIGH:
return true;
default:
return false;
}
then:
switch.turn_on: fan_high
else:
if:
condition:
lambda: |-
switch(id(hvac).fan_mode.value()) {
case esphome::climate::CLIMATE_FAN_ON:
return true;
default:
return false;
}
then:
switch.turn_on: ${constant_fanspeed}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment