substitutions: device_name: rack-3 dn: rack_3 sn: R3 friendly_name: Rack 3 duct_fan_pin: GPIO13 duct_fan_name: ${sn} Duct Fan Spd duct_fan_tgt_spd_in_name: ${sn} DF Tgt Spd In duct_fan_tgt_spd_out_name: ${sn} DF Tgt Spd Out duct_fan_pwmfreq: 5000Hz duct_fan_off_spd: "0.0" duct_fan_lo_spd: "1.0" duct_fan_vent_spd: "50.0" duct_fan_amppwr_on_lo_spd: "20.0" duct_fan_hi_spd: "100.0" amppwr_pin: GPIO19 amppwr_name: "Denon Pwr" dallas_pin: GPIO32 dallas_in_addr: "0x7F0114328974D728" dallas_in_name: ${friendly_name} Temp In dallas_out_addr: "0xB801143296ED7B28" dallas_out_name: ${friendly_name} Temp Out dallas_update_interval: 30s globals: - id: duct_fan_off_spd_id type: float initial_value: ${duct_fan_off_spd} - id: duct_fan_lo_spd_id type: float initial_value: ${duct_fan_lo_spd} - id: duct_fan_amppwr_on_lo_spd_id type: float initial_value: ${duct_fan_amppwr_on_lo_spd} - id: duct_fan_vent_spd_id type: float initial_value: ${duct_fan_vent_spd} - id: duct_fan_hi_spd_id type: float initial_value: ${duct_fan_hi_spd} <<: !include .common.yaml <<: !include .wifi-oss.yaml esphome: name: ${dn} platform: ESP32 board: esp32doit-devkit-v1 on_boot: - priority: 200.0 then: - output.set_level: id: duct_fan_output_id level: ${duct_fan_vent_spd}% switch: - platform: template name: Thermostat On id: thermostat_on_id optimistic: true output: - platform: ledc pin: ${duct_fan_pin} id: duct_fan_output_id frequency: ${duct_fan_pwmfreq} fan: - platform: speed id: duct_fan_spd_id output: duct_fan_output_id name: ${duct_fan_name} dallas: - pin: number: ${dallas_pin} mode: INPUT_PULLUP update_interval: ${dallas_update_interval} sensor: - platform: dallas address: ${dallas_in_addr} name: ${dallas_in_name} - platform: dallas address: ${dallas_out_addr} name: ${dallas_out_name} id: dallas_out_id binary_sensor: - platform: gpio id: amppwr_id pin: ${amppwr_pin} name: ${amppwr_name} device_class: power - platform: homeassistant name: "Ventilate House" entity_id: input_boolean.ventilate_house id: ventilate_house number: - platform: template id: duct_fan_tgt_spd_in_id name: ${duct_fan_tgt_spd_in_name} optimistic: true min_value: ${duct_fan_lo_spd} max_value: ${duct_fan_hi_spd} step: 1 - platform: template id: duct_fan_tgt_spd_out_id name: ${duct_fan_tgt_spd_out_name} min_value: ${duct_fan_lo_spd} max_value: ${duct_fan_hi_spd} step: 1 set_action: then: lambda: |- float lo_temp; float hi_temp; float curtemp; float off_spd; float lo_spd; float vent_spd; float hi_spd; float newspd; lo_temp = id(thermostat_out_id).target_temperature_low; hi_temp = id(thermostat_out_id).target_temperature_high; curtemp = id(dallas_out_id).state; off_spd = id(duct_fan_off_spd_id); lo_spd = id(duct_fan_lo_spd_id); vent_spd = id(duct_fan_vent_spd_id); hi_spd = id(duct_fan_hi_spd_id); ESP_LOGD("fan_speed", "DEBUG Ventilate House: %d", id(ventilate_house).state); ESP_LOGD("fan_speed", "DEBUG Amp Power: %d", id(amppwr_id).state); ESP_LOGD("fan_speed", "DEBUG Current Temp: %f", curtemp); ESP_LOGD("fan_speed", "DEBUG Thermostat State: %d", id(thermostat_on_id).state); if (id(amppwr_id).state == true) { // Amp is on, use that lo speed. lo_spd = id(duct_fan_amppwr_on_lo_spd_id); } else if ((id(ventilate_house).state == false) && ((curtemp < lo_temp) || (id(thermostat_on_id).state == false))) { // Amp is off and temp is lo or thermostat is off. Turn the fan off. ESP_LOGD("fan_speed", "DEBUG turning off"); auto call = id(duct_fan_spd_id).turn_off(); call.perform(); return off_spd; } if (std::isnan(curtemp)) { ESP_LOGD("fan_speed", "DEBUG current temp unknown. Set spd to vent."); newspd = vent_spd; } else if (curtemp > hi_temp) { ESP_LOGD("fan_speed", "DEBUG curtemp > hi_temp"); newspd = hi_spd; } else if (curtemp < lo_temp) { newspd = lo_spd; } else { // Set newspd to same linear proportion of spd range as current temp is of temp range newspd = lo_spd + ((hi_spd - lo_spd) * (curtemp - lo_temp) / (hi_temp - lo_temp)); ESP_LOGD("fan_speed", "DEBUG New Speed set: %f", newspd); } if ((id(ventilate_house).state == true) && (newspd < vent_spd)) { newspd = vent_spd; ESP_LOGD("fan_speed", "DEBUG New Speed changed to Vent Speed: %f", newspd); } if (newspd < lo_spd) { ESP_LOGD("fan_speed", "DEBUG New Speed under lo_spd, turning off"); auto call = id(duct_fan_spd_id).turn_off(); call.perform(); return off_spd; } ESP_LOGD("fan_speed", "DEBUG Setting fan to newspd: %f", newspd); auto call = id(duct_fan_spd_id).turn_on(); call.set_speed(newspd); call.perform(); return newspd; # Dual-point thermostat climate: - platform: thermostat id: thermostat_out_id name: ${friendly_name} Out sensor: dallas_out_id visual: min_temperature: 60 °F max_temperature: 100 °F temperature_step: 1 default_mode: auto default_target_temperature_low: 75 °F default_target_temperature_high: 100 °F min_cooling_off_time: 60s min_cooling_run_time: 60s min_heating_off_time: 60s min_heating_run_time: 60s min_idle_time: 60s heat_action: - logger.log: "Turning off ${friendly_name} Thermostat" - switch.turn_off: thermostat_on_id idle_action: - logger.log: "Turning on ${friendly_name} Thermostat" - switch.turn_on: thermostat_on_id cool_action: - logger.log: "WARNING: ${friendly_name} Thermostat has hit high temp!" - switch.turn_on: thermostat_on_id #TODO - provide some kind of warning / action here