Thermostat with PID controller

Your curves are good, you may add more D to get more anticipation and reduce overshoot and undershoot.
However, it’s not recommended using daily schedule to decrease the setpoint overnight on a floor heating. The inertia makes the system much too slow and the energy required to heat up in the morning will compensate the benefits durin the night.

I would say, try with the same configuration as @sciorty , it seems to work pretty well. And it should be really good if you don’t do setpoint steps.

Hi everyone, I’m using this smart thermostat for a while now but I continue to have a problem.

Since HA is running in our vacation home, in winter the temperature of the various rooms drops and stabilizes on a low value (safe from icing). The problem arises when I attempt to raise the thermostat’s temperature setting to heat the rooms. Although the PID control output is set to 100 by the algorithm, the thermostat control remains idle. This issue eventually resolves itself after an indeterminate amount of time, sometimes measured in hours, and then the thermostat begins heating and functions normally with perfect behavior.

What can cause this?

Below you can see:

  • my configuration
  • the control output set to 100
  • the thermostat set to 17°C and, while the temperature of the room is 6.3°C and the control output is 100, the thermostat remains on “idle”.

Thank you very much for your help!

It may be due to PWM stretching. Your min cycle duration being high vs the PWM, if the current temperature is high vs your setpoint the PWM duration may be stretched and multiplied by 2, 3, or 10.
To check this you may enable debugging for the integration in your configuration.yaml file:

logger:
  logs:
    custom_components.smart_thermostat: debug

And then look in the HA logs to see the duration indicated in the lines stating "Time until <your thermostat> turns <ON/OFF>: xx sec"

Thank you for your response, I enabled the debug mode and I recreated the problem.
The logs are below.

2023-12-15 10:57:31.565 INFO (MainThread) [custom_components.smart_thermostat.climate] climate.termostatogarage: Turning OFF switch.garage
2023-12-15 10:57:31.566 DEBUG (MainThread) [custom_components.smart_thermostat.climate] climate.termostatogarage: New PID control output: 100.00 (error = 13.20, dt = 8.71, p=528.00, i=0.00, d=-0.00, e=10.10)
2023-12-15 10:57:31.567 INFO (MainThread) [custom_components.smart_thermostat.climate] climate.termostatogarage: Output is 100.0. Request turning ON switch.garage
2023-12-15 10:57:31.567 INFO (MainThread) [custom_components.smart_thermostat.climate] climate.termostatogarage: Reject request turning ON switch.garage: Cycle is too short

Based on these logs I set a “min off cycle duration” to 10 seconds and now it seems to be working, but I have to test it more thoroughly to be sure. This doesn’t explain why before it would take hours to start working, since the “min off cycle duration” should default to “min cycle duration” which is 5 minutes.

I have a question. PID control setup as follows:

{code}
    initial_hvac_mode: "heat"
    ac_mode: False
#     $$$  Generic Parameter Configuration  $$$
    sampling_period: 00:01:00
    target_temp_step: 0.1
    noiseband: 0.2
#    $$$  Temperature definitions  $$$
    min_temp: 17
    max_temp: 27
    keep_alive:
      seconds: 60
    min_cycle_duration: 00:20:00
#    $$$  Mods definition  $$$
    away_temp: 18
    sleep_temp: 21.4
    comfort_temp: 22
    kp: 15
    ki: 0
    kd: 0
    ke: 0.6
    pwm: 00:20:00
{code}

Question: thermostat only works in slices of 20min…but even if a need to raise the temp with 2 degrees …it runs 20min…waits say 40 min…than goes again
I was expecting to trigger 2 or 3 slices of 20 min one after the other consecutively
Does anyone know how it works internally and detail a bit please

Apologies if this is a dumb question, but how is the output (raw P+I+D) converted to a %age? The output range is more or less unbounded, so 100% can not easily be calculated. If it is truncated, so anything > X is allocated 100%, how is X calculated?

I think the issue is due to the fact the PWM is stretched, so the on duration will be 5 minutes, but the thermostat considers it should still remain OFF for xx minutes. Theoretically I made a fix in the past so that the PWM is ignored when setpoint is changed. So this should not happen since a while. I’ll have to dig into that in a near future.

It’s using pulse width modulation. Let’s say the thermostat computes that you need 25% of the heating power to maintain the room temperature. Your PWM duration being 20 minutes, it will request heating during 20 * 0.25 = 5 minutes. But as you specified a minimum cycle duration of 20 minutes, it can’t stop after 5 minutes, so to keep the 25% it will stretch the PWM to 20 / 0.25 = 80 minutes, so will heat during 20 minutes and remains idle during 60 minutes.

the P+I+D output is directly percents and clamped on 0 to 100% range. If the sum is 180%, it means you need 180% of the heating power. But as there is only 100% available, we clamp the value to 100%.
The role of the kp, ki and kd gains is to match the computation of the thermostat with the available heating power and losses on your system.

1 Like

Hi! I have a big mess in my heating system in my house. All my life I have lived in apartment flats with central heating. But this time I am living in an apartment flat which is heated by combi boiler. I renovated the house knowing that the heater system’s piping was new allready, so I did not change it. A huge mistake… It is BAD! :smiley: After the boiler the heated water gets devided into two. One is for 5 bedrooms, 3 bathrooms. The other one is for kitchen and living room. The problem is, one is three times longer then the other. So, most of the water is circulated in my livingroom area, which makes rest of the house hard to heat. The plumber did not add any valves and pipes are hidden in bricket walls (cement apartment). I found the pipe behind the dishwasher, break the wall just enough to work and add a valve there. Then made myself a step motor controller driven by ESPHOME and connected it to the valve. Now I can reduce the water circulation in living room, which makes the rest of the house much easier to heat.

Now, what I need is to pid control this valve (which has allready a step motor working on it) to control my living room temperature. In week days only between 18.30 and 01.00 we are using the living room. Rest of the time either we are at work, or sleeping. So, I want to let it cool down up to 16-17C. And on 17.30 it will start to heat the room back up to 21C. In my tests, I saw that, if I completely shutoff livingroom, rest of the rooms heats up way better. I allready have a high power pump in my system. So, I beleive the plumbing is seriously bad. Probably at some point when joining pipes, they overheated pvc pipe and caused it to melt inside and reduce the inside area. This happens in pvc plumbing if an amateur does it. But for now, there is nothing I can do about it.

So I need a thermostat that controls the stepper motor.

I allready use an ESP8266 + DHT22 based temperature sensor in living room; but I don’t know where to start. My heater is not electric. PWM is not for me. How can I get the pid output and change it to drive a stepper motor? I have no clue. Can anybody help me?

In my country floor heating elements also work with heated water. So in discussion above, I could not be sure either you are talking about an electric floor heater or water based floor heater.

If anybody can get me started, I will appriciate much.

Thank you for the cool feature!
I have electric underfloor heating set up in 6 zones, in each zone there is a floor temperature sensor and a room temperature sensor.
How can I set up the PID controller to take both into account? I guess I would need to cascade 2 PID controllers, first the floor one (with a max_temp limit), and the room one on top of that?

1 Like

heater (Required): entity_id for heater control, should be a toggle device or a valve accepting direct input between 0% and 100%. If a valve is used, pwm parameter should be set to 0.

Hello, what kind of heating system is it ? If floor heating, I don’t recommend changing the temperature with such big steps during the night, as you will consume a lot of energy in the morning to heat up the room.

If you only have water radiators and rooms are in parallel, I think the best would be to use some connected thermostatic valves like Netatmo or Tado. Each room can then request the boiler to heat and regulate rooms independently.

@adrien.b I’ve sent a pull request adding support for cascading PIDs.
It works really well.

1 Like

Hi @Huseyin_Ozsut .
Take a look at https://community.home-assistant.io/t/zigbee-based-climate-solution/630920/4?u=guff666. In this, I explained how I control our CH in multiple rooms. It’s not directly comparable, but may give you some ideas.
Gareth

I’m looking a software thermostat for my HA , I’m not able to get this working

I have installed via HACS but the hvac_action is always idle, I cannot see any action on switch what go wrong with my configuration?

I’m looking for a simple ON/OFF thermostat, any ide?

- platform: smart_thermostat
  name: Smart Thermostat
  heater: switch.fancoil_1
  cooler: switch.fancoil_1
  target_sensor: sensor.lumi_temperature
  outdoor_sensor: sensor.temperatura_esterna
  min_temp: 7
  max_temp: 30
  ac_mode: True
  target_temp: 19
  target_temp_step: 0.1
  hot_tolerance: 0.3
  cold_tolerance: 0.3
  precision: 0.1
  keep_alive:
    seconds: 60
  kp: 5
  ki: 0.01
  kd: 500
  pwm: 00:15:00
  min_cycle_duration: 00:05:00
  force_off_state: True
  sampling_period: 00:10:00

I’m using this smart thermostat for a warm water underfloor heating system with 7 zones. The system is pretty slow to warm a zone/room up (say 0.5 degrees celsius per hour), and has a lot of inertia, and I’m struggling to work out how best to configure things to avoid a big overshoot and get each room warm for the hours of day that are most useful and allow it to cool off at night, say.

Here you can see a room with a 20.5 degrees target between about 8am and 7pm, and otherwise effectively off.

It would make sense for the heating to kick in at 6am or so, and then to stop heating far before it does to avoid the overshoot. As things stand the room is on average warming during the evening+night than it is during the day, which is the opposite of what’s needed!

- platform: smart_thermostat
  name: Study
  unique_id: thermo_study
  heater: switch.upperheating_zone5_study
  target_sensor: sensor.study_t_h_sensor_temperature
  outdoor_sensor: sensor.tesla_wall_connector_handle_temperature
  min_temp: 8
  max_temp: 24
  ac_mode: False
  target_temp: 20.5
  keep_alive:
    seconds: 300
  away_temp: 14
  sleep_temp: 18
  home_temp: 20.5
  eco_temp: 9
  kp: 30
  ki: 0.005
  kd: -24000
  pwm: 00:15:00
  min_cycle_duration: 180
  min_off_cycle_duration: 180
  target_temp_step: 0.1
  precision: 0.1

Any advice for how to configure this more helpfully?

The only advice is to stop changing the setpoint of underfloor heating systems. Inertia is much too big.
I tried with 1°C decrease in my living room during night, and it never recovered before the end of the morning, even with a commercial thermostat with PID and predictive heating.
So now I keep it steady, and it doesn’t consume more gas than before.

3 Likes

Hi,

I would like to control my underfloor heating via HA.

Insulation (U-value): 0.21 to 0.24 W/m²K
Outdoor sensor: Available
Actuator: on:off
Room thermostat wall: Available

This is underfloor heating from JOCO, which is not as sluggish as classic underfloor heating systems.

Parts of the heating system:

  • 3 cm XPS insulation
  • Pipe spacing 12.5 cm
  • Pipe diameter: 16x2 mm
  • Full surface also in the curves: 2.5 mm aluminum
  • 5 mm reinforcement mat (plastic honeycomb mat filled with tile adhesive)
  • 7 mm tile adhesive
  • 7 mm tile

Ergo the distance from the heating surface to the Feet is just 19 mm. At the end of the article a few pictures for those interested :wink:

Since you have a lot of parameters to choose from here:

I wanted to ask what basic configuration is best to start with.

  • Are there parameters I should leave out?
  • Are there parameters I should add?
  • Which values are useful for the start?

Here is an initial situation:

climate:
  - platform: smart_thermostat
    name: Smart Thermostat Example
    unique_id: smart_thermostat_example
    heater: switch.on_off_heater
    target_sensor: sensor.MyWallThermostat_temperature
    outdoor_sensor: sensor.MyOutdoor_temperature
    min_temp: 7
    max_temp: 28
    ac_mode: False
    target_temp: 22
    keep_alive:
      seconds: 60
    away_temp: 14
    kp: 5
    ki: 0.01
    kd: 500
    ke: 0.5
    pwm: 00:15:00



Thanks for your tips.

########################################’

My Solution

I can now explain it to myself. I took this setting as a basis and let it run for several days. You just have to wait until some temperature oscillations have been recorded. Preferably without windows or door openings.:

climate:
  # DG - Fußbodenheizung
  - platform: smart_thermostat
    name: DG - Fußbodenheizung - HASmartThermostat
    unique_id: DG-Fussbodenheizung-HASmartThermostat
    heater: switch.eltako_gw1_00_00_00_50
    target_sensor: sensor.hm_tc_it_wm_w_eu_oeq1668843_temperatur
    outdoor_sensor: sensor.heizgeraet1_aussentemperatur
    min_temp: 5
    max_temp: 24
    ac_mode: False
    target_temp: 21.0
    keep_alive:
      seconds: 300
    away_temp: 20.0
    sleep_temp: 19
    home_temp: 21.0
    eco_temp: 5
    kp: 100
    ki: 0.0
    kd: 0.0
    ke: 0.5
    pwm: 00:15:00
    min_cycle_duration: 180
    min_off_cycle_duration: 180
    target_temp_step: 0.1
    precision: 0.1

Change the parameters via the services so that something happens !!!

It is important to know that the PID values etc. After initialization, you do not have to change them in the Config but via the services for anything to happen. The same applies to (away_temp, sleep_temp, home_temp, eco_temp etc.) !

My Calculation example PID Source:

I became aware of this through this link: Smart Thermostat - le chauffage contrôlé par PID - #186 par Toniob - Intégration - Home Assistant Communauté Francophone

Solution found in this link: Autotune feature usage. · ScratMan/HASmartThermostat · Discussion #21 · GitHub

Quote from the second link:

#####################START######################
Hello,

If autotune fails (it really depends on the regularity of the oscillation), you can extract the required information from the temperature history manually (and you can do it as soon as you have a full period of oscillation, while the autotune often needs to wait several cycles) :
Measure the amplitude of the oscillation Yosc (in degrees) and the oscillation period tosc (in seconds).

Screenshot

This will allow computing the ultimate gain Ku:
Ku = 8.0 * difference / (Yosc * pi)
(difference = 100 by default)

Next, depending on the autotune rule you prefer (it provides different results) you can compute the gains Kp, Ki and Kd using the divisors of the selected rule :

ruler divisor1 divisor2 divisor3
“ziegler-nichols” 34 40 160
“tyreus-luyben” 44 9 126
“ciancone-marlin” 66 88 162
“pessen-integral” 28 50 133
“some-overshoot” 60 40 60
“no-overshoot” 100 40 60
“brewing” 2.5 6 380

using the formulas below :

Kp = Ku / divisor1
Ki = Kp / (tosc / divisor2)
Kd = Kp * (tosc / divisor3)

Example with some measures made on the chart above :
Oscillation amplitude Yosc = 2.1°C, oscillation period tosc = 10200 seconds.
According to Ziegler-Nichols the gains will be :

Ku = 8 * 100 / (2.1 * pi) = 121.261
Kp = 121.261 / 34 = 3.567
Ki = 3.567 / (10200 / 40) = 0.01499
Kd = 3.567 * (10200 / 160) = 227.396

The resulting gains are a good starting point, you should then tune them to match your requirements, if you need more reactivity or stability, or to decrease an overshoot.
#####################ENDE######################

My setting based on the calculation with ziegler-nichols:

climate:
  # DG - Fußbodenheizung
  - platform: smart_thermostat
    name: DG - Fußbodenheizung - HASmartThermostat
    unique_id: DG-Fussbodenheizung-HASmartThermostat
    heater: switch.eltako_gw1_00_00_00_50
    target_sensor: sensor.hm_tc_it_wm_w_eu_oeq1668843_temperatur
    outdoor_sensor: sensor.heizgeraet1_aussentemperatur
    min_temp: 5
    max_temp: 24
    ac_mode: False
    target_temp: 21.0
    keep_alive:
      seconds: 300
    away_temp: 20.0
    sleep_temp: 20
    home_temp: 21.0
    eco_temp: 5
    kp: 18.724
    ki: 0.01510
    kd: 5802.451
    ke: 0.5
    pwm: 00:15:00
    min_cycle_duration: 180
    min_off_cycle_duration: 180
    target_temp_step: 0.1
    precision: 0.1

First long-term result after the first calculation.
Previously, 25°C was reached in some cases. With a setpoint of 20.5°C.

I hope this helps some of you.
Sorry for the english :wink: