Control heating: PV surplus with ESP32 & Home Assistant
After about 20 years, I was able to take control of my heat pump with Home Assistant and an ESP32. In order to make better use of the electricity generated by my PV system during the day, I came up with the idea of activating the heating when the PV system is currently supplying the most electricity. After I already had the electricity consumption and temperature values available in Home Assistant, the only thing missing was the ability to actively intervene in the heating.
Probably works with any heater: fake temperature ...
My heating system is responsible for hot water preparation as well as for the actual heating. The heating is controlled purely via the outside temperature, the boiler via its water temperature. In addition to an outdoor sensor, temperature sensors are used for the boiler and the buffer tank. While my heat pump already provides a serial interface, unfortunately it is not documented and so I started thinking about alternative options. A look at the documentation for the heating control system told me that the temperature sensors for the boiler and buffer tank are PTC resistors. This gave me the idea to change the resistor value if needed. Changing the temperature values allows me to fake the buffer tank and boiler temperature, which causes the heater to heat the boiler or buffer when the temperature is low, or do nothing when the temperature is faked high. It was important to me that the heating continues to work even without Home Assistant. Therefore, I continue to use the installed PTC temperature sensor and replace it with a low resistance value for switching on and a high resistance value for switching off, if necessary. My first attempts with a digital potentiometer were not successful, so I resorted to simple relays and fixed resistors.
For monitoring the temperature values of the boiler and buffer tank in Home Assistant I already have an ESP32 in use. By an extension with a 4-Channel Relay Board I can use 2 relays for controlling the hot water and 2 relays for controlling the buffer tank. As resistors I have 1kOhm available, which corresponds to a temperature value of 25°C with the installed PTC temperature sensor. A value of 1.25 kOhm would already mean over 50°C: similar to a heated boiler. No 250 Ohm resistor at hand, I used 4 pieces of 1kOhm in a parallel circuit. Here is the schematic diagram using the boiler as an example.
Explanation: When the two relays are not active, the original PTC temperature sensor is used. When the first relay is activated, the PTC is interrupted and replaced by the installed resistors, which corresponds to a temperature above 50°C and deactivates the heating. If I switch on the 2nd relay, the resistors for the 250Ohm value are bypassed and the remaining 1kOhm resistor fools the heating into thinking it is 25°C: Time for hot water preparation. So the circuit allows 3 states for each boiler and buffer tank:
- previous automatic operation with the PTC of the heater (relay 1 off + relay 2 off).
- deactivate heating (relay 1 on + relay 2 off)
- activate heating (relay 1 on + relay 2 on)
Relay 1 and 2 is used for the boiler and relay 3 and 4 for the buffer tank. The three-pole cables: yellow-green, blue and brown lead to the existing PTC connection cable.
CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22PTC%2010%20k%26lt%3Bbr%26gt%3Bt%20(%C2%B0C)%20R%20(%E2%84%A6)%26lt%3Bbr%26gt%3B-%2030%20623%26lt%3Bbr%26gt%3B-%2025%20652%26lt%3Bbr%26gt%3B-%2020%20682%26lt%3Bbr%26gt%3B-%2015%20713%26lt%3Bbr%26gt%3B-%2010%20745%26lt%3Bbr%26gt%3B-%205%20779%26lt%3Bbr%26gt%3B%200%20813%26lt%3Bbr%26gt%3B%2B%205%20848%26lt%3Bbr%26gt%3B%2B10%20885%26lt%3Bbr%26gt%3B%2B15%20922%26lt%3Bbr%26gt%3B%2B20%20961%26lt%3Bbr%26gt%3B%2B25%201000%26lt%3Bbr%26gt%3B%2B30%201040%26lt%3Bbr%26gt%3B%2B35%201082%26lt%3Bbr%26gt%3B%2B40%201124%26lt%3Bbr%26gt%3B%2B50%201211%26lt%3Bbr%26gt%3B%2B60%201302%26lt%3Bbr%26gt%3B%2B70%201397%26lt%3Bbr%26gt%3B%2B80%201496%26lt%3Bbr%26gt%3B%2B90%201599%26lt%3Bbr%26gt%3B100%201706%26lt%3Bbr%26gt%3B110%201817%26lt%3Bbr%26gt%3B120%201932%22%20style%3D%22text%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Balign%3Dright%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22580%22%20y%3D%2230%22%20width%3D%2290%22%20height%3D%22370%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3Integration in ESP-Home, see: Relay Board ESP32 - ESP Home
In addition to the already existing temperature sensors and a water flow meter, I added the relay board to ESP-Home as follows:
# Relais
switch:
- platform: gpio
pin: GPIO32
name: Relay-heating-water-fake
id: relay1
inverted: true
- platform: gpio
pin: GPIO33
name: Relay-heating-water-cold
id: relay2
inverted: true
- platform: gpio
pin: GPIO25
name: Relay-heating-buffer-fake
id: relay3
inverted: true
- platform: gpio
pin: GPIO26
name: Relay-heating-buffer-cold
id: relay4
inverted: true
Home Assistant Automation
To ensure that my heater is activated whenever possible when the PV plant is supplying power, I put together an automation in Home Assistant:
The three-phase compressor installed in my heater is only capable of two operating states: on and off. When the heat pump is activated, the pressure gradually builds up and the power consumption increases to a maximum of 4.5KW. In order to have some reserve, the heater should be activated only after a 10-minute surplus of about 5.5kW: "When meter_power is below -5500 for 20:00".
The aim of this automation is to use the most ideal time for the start of the water heating:
Legend: Red: Electricity consumption, Green: PV production, Yellow: Heating (hot water preparation).
To make it easier to address the switching operations of the relays, I created scripts for the individual states:
Script | Sequence |
---|---|
![]() |
|
![]() |
|
![]() |
|
![]() |
|
... | ... |
- water automatically: turns Relay heating water fake off (Relay1) and Relay water cold off (Relay2)
- water on: turns Relay heating water fake on (Relay1) and Relay water cold on (Relay2)
- water off: turns Relay heating water fake on (Relay1) and Relay water cold off (Relay2)
I then used the scripts in the automation:
The following triggers start the automation for water heating:
Trigger | Description |
---|---|
![]() |
meter_power reflects the data from the smart meter: negative values (-) mean a power surplus ID: PV surplus |
![]() |
ID: Water=cold |
![]() |
ID: Water=hot |
Actions | Description |
---|---|
![]() |
Turn on hotwater when water is cold (trigger hot water is below 40) |
![]() |
Switch on water heating when: a PV-surplus or Peak Time has been triggered. |
|
Disable hot water preparation when water iswarm (trigger hot water is above 50). |
description: ""
mode: single
trigger:
- platform: numeric_state
entity_id: sensor.meter_power
for:
hours: 0
minutes: 10
seconds: 0
id: PVsurplus
below: -5500
- platform: numeric_state
entity_id: sensor.heating_water
below: 40
id: water=cold
- platform: numeric_state
entity_id: sensor.heating_water
above: 50
id: water=hot
condition: []
action:
- if:
- condition: trigger
id:
- water=cold
then:
- service: script.water_on
data: {}
- if:
- condition: trigger
id:
- PVsurplus
then:
- service: script.water_on
data: {}
- if:
- condition: trigger
id:
- water=hot
- condition: device
type: is_on
device_id: ??
entity_id: ??
domain: switch
then:
- service: script.water_off
data: {}
The automation is currently still in a test phase and has been simplified in this version somewhat: any improvements that result from practical operation will be included in this article. For more information on automations, see: Home Assistant Automation - Possibilities & Basics.
Control heating
Sunrise | The battery is charged until a charge level of 100% is reached. |
---|---|
Noon | Battery is fully charged: Start of water heating, followed by heating until the room temperature is one degree higher than necessary. (Depending on the weather, the battery could be somewhat discharged at this point: But doesn't matter, as long as enough power is collected until the evening). |
late afternoon |
The house is warm and currently so is the buffer tank, so the circulating pumps can be stopped so that the available energy can be drawn from the buffer tank during the night. |
Before sunset |
The accumulator is charged again to 100% and is ready to cover the household electricity during the night. Again as a reminder, the boiler is hot, so is the buffer tank and the house is heated 1 °C higher than necessary. |
In the evening and at night |
The heating remains deactivated, the house cools down very slightly (By the 1 °C we heated more before). The power for the house comes from the battery. |
In the early morning hours | The circulating pumps are activated to retrieve the stored heat from the buffer tank ... |
In practice, my first tests on this look like this:
Solar production in mid-October on these days was about 30-45 kWh, heat pump electricity consumption about 12-14 kWh per day and household electricity consumption about 15 kWh, average outdoor temperature over 24h about 5.5 °C and room temperature about 22-23°C. If the solar radiation is not sufficient for this sequence, additional triggers can be built into the automation: As an example, the circulation pumps could be started when the room temperature cools down by more than 1 °C. If this measure is not sufficient, the heating can also be activated at night. Nevertheless, the more electricity consumed during the day directly from the yield of the PV system, the higher the self-sufficiency rate and the more money can be saved with automation. I am currently testing different variations of automations for heating. Started with one automation for the different triggers and actions, I had later used several template sensors as triggers. In the meantime I tested numerous automations for the different actions and last again an automation with a time pattern trigger and if-then queries in the actions, see also: Home Assistant Automation - Possibilities & Basics.
Conclusion
Controlling the heating is a simple and inexpensive measure to increase the self-consumption of the PV plant. If the boiler or buffer storage is heated during the day, the energy does not have to be purchased again at night: Not only PV systems without electricity storage benefit from this, but also when using an accumulator, this can be relieved and possibly even be dimensioned somewhat smaller.

{{percentage}} % positive
