ESPHome Underflooor heating Pump Switch – ET-PS01
Table of Contents
Introduction
As electricity is so damn expensive in Europe now and my (2) underfloor heating pumps are constantly consuming more than 40 Watt each, I wanted to find a smarter solution for that. While browsing the internet of course it turned out there are existing solutions to the problem that will simply switch of electricity to the pump when the measured temperature of the heating supply pipe falls below a certain temperature. The cost of such devices varies between €25,00 and €55,00 and these things have some serious disadvantages. For instance you won’t be able to connect them to Home Assistant. Well, that did it for me… I needed to come up with a smarter solution. 😉
Design parameters
My requirements were:
- Wemos D1 mini ESP8266 controlled (due to smaller size)
- Operating at 230V AC, so I can install it in-line with the pump.
- Temperature measurement and historic graphs.
- Must fit in a custom 3D-printable enclosure.
- Parts should be available at AliExpress or Amazon for affordable prices, making it as cheap as possible to build
- Firmware should be ESPhome (for use with Home Assistant)
Practical design
I talked to Paul and we agreed the design should be reliable but simple and cheap to build. After some measuring and testing he came up with this PCB design:
It’s all fairly simple: You cut the power-supply cable of your underfloor heating pump in half. One end of the cable goes to ‘AC-in’, the other and to ‘Pump-out’. The PCB is powered by a small 230V AC to 5V DC power supply.
The internal Dallas temperature sensor on the bottom of the PCB will measure the heating supply pipe temperature and switch on/off the power to your underfloor heating pump using the on-board 10A relay.
There is also an option to connect a (primary or secondary) external Dallas temperature sensor at JP2. For safety reasons we added a fuse. That’s about it.
We did not even bother building a prototype but ordered the PCB’s at PCBway. Waiting for the postman Paul designed a 3d-printable enclosure to go with the PCB. The Dallas temperature sensor sticks out the back, you simply fold it in the cavity and your done.
Finally we threw the ESPHome firmware on it. and the thing worked right away 🙂
Circuit diagram
Build it!
Bill of materials
See below the list with the components you will need to build the ET-PS01 controller. A number of these items will not be sold in smaller quantities at AliExpress. We will try to use the same components as much as possible in future projects.
We would really appreciate it if you will use the links below to buy the components, since it will give a little bit of commission to us without any additional cost for yourself. These commissions will be used to cover some of the costs involved in the development of the design.
Reference | Qty | Description | Link |
WEMOS1 | 1 | Wemos Mini D1 ESP8266* | AliExpress |
D1 | 1 | 1N4148 | AliExpress |
C1 | 1 | 470µF / 16V 6mm diameter, 2.54mm pitch | AliExpress |
T1 | 1 | S8050 TO-92 Triode Transistor | Aliexpress |
R1 | 1 | Resistor 220 ohm | AliExpress |
R2 | 1 | Resistor 3k3 | AliExpress |
R3 | 1 | Resistor 4k7 | Aliexpress |
X1, X2 | 2 | 9 pole terminal, or 3x 2 pole + 1x 3 pole. 5.00mm pitch | Aliexpress |
SENSOR | 1 | DS18b20 Dallas temperature sensor | Aliexpress |
F1 | 1 | 0,2-0,5A self resetting fuse 230V | Aliexpress |
K1 | 5V relay 230V/10A (5VDC SRD-05VDC-SL-C) | Aliexpress | |
X3 | 1 | AC-DC 5V 700mA power supply (Vertical-5V 700MA) | Aliexpress |
LED | 1 | 5mm Red LED | Aliexpress |
Enclosure | 1 | 3d-print | Thingiverse |
PCB | 1 | A 5-pack is the smallest order at PCBway, enough for you and your friends 😉 | PCBway |
Putting it together
Like with all other projects, it is the easiest to start with identifying the components purchased as discussed in the blog post. After sorting the components and cleaning the PCB, start with the lowest components first. For this project, we advise to work in this order:
- Resistors
- Transistor
- Fuse
- Screw terminals
- ESP module headers (Use the hints in the soldering blog post!)
- Electrolytic capacitor
- Relay
- Power supply
- Dallas sensor
- Led
Once all components are soldered in place, perform a good visual check of all joints, and pay particular attention to possible solder bridges (unwanted solder connections between pins). Do not forget to clean the excess solder flux from the PCB using alcohol!
Software configuration
# Underfloor Heating Pump Controller # ESPHome - with Dallas temperature sensor # # Controls a underfloor heating-pump. When warm water is received from the # central heater, warm water is entering the pump via its pipes. This is # detected by the temperature sensor and the pump will be switched on. # When the heater stops (requested temperature is reached) the flow of water # will cool down. The temperature sensor will detect this and will shut # down the pump. # # The RED LED light indicates the mode. In automatic mode (default) flashes # slowly. # # In case the controller is unable to connect with Home Assistant for 5 minutes, # the controller switches over to automatic mode. # # Manny thanks to Martin for the initial configuration! # https://github.com/Martinvdm/underfloor_heating_pump_controller substitutions: devicename: "espthings-et-ps01-002" upper_devicename: "Vloerverwarming boven" esphome: name: "$devicename" platform: ESP8266 board: d1_mini esp8266_restore_from_flash: yes comment: "$upper_devicename" on_boot: then: - script.execute: led_signaling - script.execute: controller wifi: ssid: !secret esphome_wifi_ssid password: !secret esphome_wifi_password ap: ssid: "$devicename" password: "qwe12345" logger: web_server: port: 80 ota: password: !secret esphome_ota_password api: encryption: key: !secret esphome_api_key services: - service: threshold_off variables: value: float then: - lambda: |- if (value < 0.0f){ return; } if (value > 48.0f){ value = 48.0; } id(g_threshold_temp_off) = value; auto d = id(g_threshold_temp_on) - id(g_threshold_temp_off); if (d < 2.0){ id(g_threshold_temp_on) = value + 2.0; } - script.execute: controller - service: threshold_on variables: value: float then: - lambda: |- if (value > 50.0f){ return; } if (value < 2.0) { value = 2.0; } id(g_threshold_temp_on) = value; auto d = id(g_threshold_temp_on) - id(g_threshold_temp_off); if (d < 2.0){ id(g_threshold_temp_off) = value - 2.0; } - script.execute: controller globals: # true when in automatic mode # false when in manual mode - id: g_automatic_mode type: bool restore_value: no initial_value: "true" # if water temperature below this threshold # pump demand automatic will be 'off' (false) - id: g_threshold_temp_off type: float restore_value: no initial_value: "34.0" # if water temperature above this threshold # pump demand automatic will be 'on' (true) - id: g_threshold_temp_on type: float restore_value: no initial_value: "36.0" # manual demand pump - id: g_pump_demand_manual type: bool restore_value: no initial_value: "false" # demand based on water temperature - id: g_pump_demand_automatic type: boolean restore_value: no initial_value: "false" dallas: - pin: D5 update_interval: 60s sensor: - platform: dallas id: sensor_water_temperature name: "$upper_devicename temperature" address: 0x803c01d075271728 unit_of_measurement: "°C" device_class: temperature accuracy_decimals: 1 filters: - delta: 0.1 on_value: then: # the controller is notified when the water temperature crosses # one of the thresholds - lambda: |- /* only useful when in automatic mode */ if(!id(g_automatic_mode)){ return; } /* only submit when something has changed */ auto water_temperature = id(sensor_water_temperature).state; if ( water_temperature < id(g_threshold_temp_off) && id(g_pump_demand_automatic)){ id(g_pump_demand_automatic) = false; id(controller).execute(); } else if ( water_temperature > id(g_threshold_temp_on) && !id(g_pump_demand_automatic)){ id(g_pump_demand_automatic) = true; id(controller).execute(); } - platform: template name: "$upper_devicename Threshold off" id: sensor_threshold_temp_off unit_of_measurement: "°C" accuracy_decimals: 1 lambda: return id(g_threshold_temp_off); update_interval: 1ms filters: - delta: 0.1 - platform: template id: sensor_threshold_temp_on name: "$upper_devicename Threshold on" unit_of_measurement: "°C" accuracy_decimals: 1 lambda: return id(g_threshold_temp_on); update_interval: 1ms filters: - delta: 0.1 - platform: wifi_signal name: "$upper_devicename WiFi Signal" update_interval: 60s - platform: uptime name: "$upper_devicename Uptime" 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 ? to_string(days) + "d " : "") + (hours ? to_string(hours) + "h " : "") + (minutes ? to_string(minutes) + "m " : "") + (to_string(seconds) + "s") ).c_str(); text_sensor: - platform: template name: "$upper_devicename Uptime Human Readable" id: uptime_human icon: mdi:clock-start binary_sensor: # In case the API connection is lost, the controller will change # to automatic mode. - platform: template id: sensor_api_connected lambda: return global_api_server->is_connected(); filters: - delayed_off: 5min on_release: then: - logger.log: Lost API connection, selecting automatic mode - switch.turn_on: sw_automatic_mode # template sensor to publish pump state - platform: template name: "$upper_devicename Pump" id: sensor_pump_state lambda: return id(ps01_relay).state; switch: # relay, switches pump on and off - platform: gpio pin: number: GPIO12 inverted: true id: ps01_relay # Boolean input to toggle between manual or automatic mode - platform: template name: "$upper_devicename Manual/Automatic" id: sw_automatic_mode lambda: return id(g_automatic_mode); turn_on_action: - globals.set: id: g_automatic_mode value: "true" - script.execute: controller - script.execute: led_signaling turn_off_action: - globals.set: id: g_automatic_mode value: "false" - script.execute: controller - script.execute: led_signaling # Boolean input to control manual demand - platform: template name: "$upper_devicename On/Off" id: sw_on_off lambda: return id(g_pump_demand_manual); turn_on_action: - globals.set: id: g_pump_demand_manual value: "true" - script.execute: controller turn_off_action: - globals.set: id: g_pump_demand_manual value: "false" - script.execute: controller script: # script for calculating the demand for the pump. Should # it run or not. Applies the changes to the relay. - id: controller then: - lambda: |- /* calculate if pump should be on or not */ bool demand = false; if (!id(g_automatic_mode)){ /* manual mode */ demand = id(g_pump_demand_manual); } else{ /* automatic mode */ demand = id(g_pump_demand_automatic); } /* only send commands when needed */ if (demand && !id(ps01_relay).state) { id(ps01_relay).turn_on(); } else if (!demand && id(ps01_relay).state){ id(ps01_relay).turn_off(); } - id: led_signaling then: # The green led is used to show the mode of operation: # - manual mode, led is on # - automatic mode, led blinks - lambda: |- if (id(g_automatic_mode)){ auto call = id(ps01_led_light).turn_on(); call.set_effect("auto_effect"); call.perform(); } else { auto call = id(ps01_led_light).turn_on(); call.set_effect("none"); call.perform(); } output: - platform: esp8266_pwm id: ps01_led pin: number: GPIO13 inverted: True light: - platform: monochromatic output: ps01_led id: ps01_led_light effects: - strobe: name: auto_effect colors: - brightness: 100% duration: 1s - brightness: 0% duration: 2s
Home Assistant
This is what it looks like in Home Assistant:
Final thoughts
We have this running for about 3 months now and it works great. On stand-by the pump (including the ET-PS01) consumes about 0.6w, which is 39,4 Watt less than before 😉
If you want to save some electricity and monitor your underfloor heating supply temperature in Home Assistant, then build this thing yourself! If you do, please let us know in the comments 🙂
If you run into issues during the construction, or you have any question regarding this controller, please leave a comment below. We will try to reply as soon as possible!
Make sure to subscribe to our YouTube channel so you won’t miss any of our upcoming project videos!
Please subscribe to our newsletter!
Next month, I am going to install floor heating in my home. As a Home Assistant/esphome user, this project might just be exactly what I am looking for. Pretty sure I will built this, if I get some confirmation the pump that will be installed can handle the frequent on/off switching.
Thanks!