fan coil thermostat with ESP32 and Home Assistant

Published at : 23 Dec 2025

#fan_coil #thermostat #home_assistant

Learn how to build a fan coil thermostat to control 4 pipe with 3 speed fan coils with ESP32 development boards integrated with Home Assistant.

Invitation Link to join my Exclusive membership:
https://www.youtube.com/channel/UCXRNO_06vrZ7MGvQvWZPQ3Q/join

1:10 Start Programming
2:00 Describing Lines
7:32 Reconfiguring integration
8:58 Describing Board and Wiring while Testing the project

Thermostat Climate Controller:
t.ly/xW8B

BUY ME A COFFEE:
https://www.buymeacoffee.com/kian.smarthome

Lines:
sensor:
- platform: adc
id: source_sensor
attenuation: 11db
pin: 36
update_interval: never

- platform: resistance
sensor: source_sensor
configuration: DOWNSTREAM
resistor: 14kOhm
id: resistance_sensor

- platform: ntc
sensor: resistance_sensor
calibration:
b_constant: 3550
reference_temperature: 25°C
reference_resistance: 15kOhm
name: Temperature
id: temperature1

fan:
- platform: speed
id: ventilate
output: custom_fan
name: "Fan"
speed_count: 3

output:
- platform: template
id: custom_fan
type: float
write_action:
- if:
condition:
lambda: return ((state ==0));
then:
#action for off
- switch.turn_off: relay1
- switch.turn_off: relay2
- switch.turn_off: relay3
- if:
condition:
lambda: return ((state (GREATER SYMBOL) .16) && (state (LOWER SYMBOL) .34));
then:
# action for low
- switch.turn_on: relay1
- if:
condition:
lambda: return ((state (GREATER SYMBOL) .35) && (state (LOWER SYMBOL) .7));
then:
# action for medium
- switch.turn_on: relay2
- if:
condition:
lambda: return ((state ==1));
then:
# action for high
- switch.turn_on: relay3

switch:
- platform: gpio
pin: 16
name: "Relay 1"
id: relay1
interlock: &interlock_group [relay1, relay2, relay3]
interlock_wait_time: 300ms
internal: true

- platform: gpio
pin: 17
name: "Relay 2"
id: relay2
interlock: *interlock_group
interlock_wait_time: 300ms
internal: true

- platform: gpio
pin: 5
name: "Relay 3"
id: relay3
interlock: *interlock_group
interlock_wait_time: 300ms
internal: true

- platform: gpio
pin: 27
id: heater

- platform: gpio
pin: 25
id: cooler

- platform: gpio
pin: 32
id: ntc_vcc

interval:
- interval: 30s
then:
- switch.turn_on: ntc_vcc
- component.update: source_sensor
- switch.turn_off: ntc_vcc

climate:
- platform: thermostat
visual:
min_temperature: 0 °C
max_temperature: 80°C
temperature_step: 0.5 °C
name: "Thermostat"
sensor: temperature1

default_target_temperature_low: 20 °C
default_target_temperature_high: 22 °C
min_cooling_off_time: 5s
min_cooling_run_time: 5s
min_heating_off_time: 5s
min_heating_run_time: 5s
min_fanning_run_time: 5s
min_fanning_off_time: 5s
min_fan_mode_switching_time: 5s
min_idle_time: 5s

away_config:
default_target_temperature_low: 20
default_target_temperature_high: 25

cool_action:
- switch.turn_on: cooler
- fan.turn_on: ventilate

heat_action:
- switch.turn_on: heater
- fan.turn_on: ventilate

idle_action:
- switch.turn_off: heater
- switch.turn_off: cooler
- fan.turn_off: ventilate

fan_mode_on_action:
- fan.turn_on: ventilate

fan_only_action:
- switch.turn_off: heater
- switch.turn_off: cooler
- fan.turn_on: ventilate

fan_mode_low_action:
lambda: !lambda |-
auto call = id(ventilate).turn_on();
call.set_speed(1);
call.perform();

fan_mode_medium_action:
lambda: !lambda |-
auto call = id(ventilate).turn_on();
call.set_speed(2);
call.perform();

fan_mode_high_action:
lambda: !lambda |-
auto call = id(ventilate).turn_on();
call.set_speed(3);
call.perform();

fan_mode_off_action:
- fan.turn_off: ventilate



#esp32 #esp8266 #esp #esphome #integration #smart_thermostat #smart_home #home_automation #automation #wifi #zigbee #zwave #z-wave #philio #ezlo #fibaro #heltun #tuya #mcohome #peace #comfort #energy_saving #smart_fan_coil_thermostat #iot #development_board