Thermostat with PID controller

Apparently PID usually includes P, I, and D. That’s what I mean by standard.

@axax i set it now for 22 constantly, will see. I do agree that bit of sun can easily participate in overshoot, and as I said, I am mostly concerned about heating when temp is over the set temp, and maybe not have to heat constantly for 4 hours, rather than few shorter cycles.

I think there is an issue with the derivative part, it always returns to 0 between steps as the temperature is really slow to change. The gains seems to be quite OK when looking at the amplitudes, maybe Kp is a little bit high, keeping Kd as is and reducing Kp by 10% steps may help on the overshoot but I’m afraid the integral may then become dominant and force the heating with negative error.
I think that the main issue is that you generate a very small step in the morning while the temperature is already close to the set-point.
Maybe the solution would be to return to lower Kp and Kd gain and use the new outdoor temperature compensation available in the v2021.12.5-beta versions, to have a kind of higher speed compensation that may help with small set point steps, and smaller Kp and Kd will then help for fine regulation around set points. It also embeds a system to automatically increase the PWM period when on time is lower than the minimum cycle duration, to avoid overheating ; maybe it can help you too.

Willing to give it a try. Would it be to move to beta only (for starters, i would keep kp kd ki as they are now)? Or is there some additional parameter to configure?

Install the beta, yes, stop HA, specify the outdoor_sensor entity in the configuration file with a temperature sensor, and restart HA.
Then fix the Ke gain (you can do it live in HA using the set_pid_gain service) : Ke = 10 / (22 - outside temperature during these days).
Finally, clear the integral using the clear_integral service.
The PID will then start using outdoor temperature.

OK, here is my configuration now:

  outdoor_sensor: sensor.espaltherma_outside
  min_cycle_duration: 00:20:00
  kp : 100
  ki : 0.0032
  kd : 220000
  ke: 0.588
  pwm : 02:00:00
  sampling_period: 00:10:00

Cleared the integral. This is current state:

control_output: 6.7
Kp: 77
Ki: 0.0032
Kd: 110000
Ke: 0.588
pid_mode: auto
pid_p: -15.4
pid_i: 0
pid_d: -0.0
pid_e: 0
pid_dt: 12.511824131011963

I also did return to previous 0,5degree less during nights

I see you’re still adjusting the gains using the configuration file: the gains in the state of the device are different from gains in the file.
Please note the gains in configuration file are only taken into account when:

  • Starting the thermostat for the very first time
  • In case of HA database crash or deletion

In all other cases, the gains are restored from the database, and should be adjusted using the set_pid_gain service

I did change all of them now using service too. I like to keep my yaml in line.
I also noticed that I had Ki value as 0.0032 however only 0.003 is acceptable.

While using outdoor temperature compensation you could decrease the kp and kd gains.
You should first keep the set point steady, without night/day steps, and adjust the gains to see how it behaves.

When doing set point steps, the overshoot will depend on the gains, but also on the amplitude of the step. The bigger the step, the higher the overshoot. Example :

On the smaller step, when the temperature starts to rise, the D is still too small to stop the heating due to large kp gain, and when D start to increase and cut the P, the temperature is already high Vs the step level. When the heater is switched off with set point decrease, the temperature is still increasing and overshoots by 0.5°C the requested temperature step.

Open Chrome developer tools and its Network tab. Go to your Locelace Dashboard containing the Thermostat Card for which you would like the data. Go to the history graph of the thermostat card, which causes JSON-data to be loaded to your browser for display on the graph in the Thermostat Card. The JSON data is accessible in one of the requests in the Network tab ov the Developer tools - look in the Response section of the request. Copy paste the JSON-data to JSON to CSV Converter | Online Tool
And from there copy-paste to Excel. In Excel, Reformat the data series, for example creating a column with seconds elapsed from the first time stamp of interest. I believe you can just cerate a column with ‘1’ for heater on, and ‘0’ for heater off, as the Input column which you then use in the export to pidtuner.

This is last 24 hours, with beta version and constant setpoint:

Shortly to setting the gains via service. It is OK, however at some point, I would like these to be reflected in the yaml, just in case, like you said, if database is corrupted, or simply when I want to move other rooms from generic to smart thermostat, I would like to be able just to copy those from yaml, and not have to explore if this is the last state. That’s why I like modifying yaml, but I will also keep using service. Maybe that could be a feature request? :slight_smile:
Also, since those PIDE values only accept 3 decimals, what happens if yaml has 4 or more, while service allows to set only 3? Does it take only first 3? It does not throw any validation error.

It’s recommended in the readme to save the PID gain values in the YAML after tuning, to ensure the values are backed up in case of database crash.

Regarding the decimals, the UI only accepts .001 precision, but using the YAML editor in services panel you can use the full float precision (same for YAML configuration file).

It is way way better in last 2 days, getting +0,1-0,2 degrees, while still doing steps in temperatures day/night (21,5 vs 22)

@adrien.b I have switched all my rooms over to your thermostat, I have in total 7 of them. I was thinking of how to manage switching of main heater better. As you may remember, with thermostat, I am only switching valves for zones, and I have automation running every minute outside of that to decide if heater needs to be switched on/off. However each zone works on its own, so it can happen that none will need heat, heater will turn off, and minute later, it will turn on because other zone will need heat, which isn’t really ideal for main heater to cycle that often.
I could run automation every 15 minutes, but that would, on the other hand, prolong heating when it might not be needed.
So I was thinking if there could be some additional logic, like to predict if any zone is about to heat in certain time, so that heating could start a little earlier, or would that defeat the whole purpose of this thermostat? Also, it could only be a small step towards incorporating that logic into your thermostats and create a master switch for heater?

There is the Multizone Thermostat that is working like that. I may look as how it is done, but it looks much more complex than the Smart Thermostat.

Hello i heave problem witch My thermostat config.
My temperature still is Over hot or to cold

On screen looks how works i think not correct or my config is bad

My Config

platform: smart_thermostat
name: Termostat Grzejniki.smart
heater: group.grupa_piec_grzejniki
target_sensor: sensor.najnizsza_temperatura_na_grzejniki
outdoor_sensor: sensor.openweathermap_temperature
min_temp: 18
max_temp: 23
precision: 0.1
comfort_temp: 21.6
target_temp: 21.6
target_temp_step: 0.1
kp: 10
ki: 0.01
kd: 1000
ke: 0.588
keep_alive: 00:05:00
away_temp: 21
pwm : 600
min_cycle_duration: 300
min_off_cycle_duration: 120
sampling_period: 300

And Developer screen

hvac_modes: heat, off
min_temp: 18
max_temp: 23
target_temp_step: 0.1
preset_modes: none, away, comfort
current_temperature: 21
temperature: 21.5
hvac_action: heating
preset_mode: none
away_temp: 21
eco_temp: null
boost_temp: null
comfort_temp: 21.6
home_temp: null
sleep_temp: null
activity_temp: null
control_output: 18.8
Kp: 10
Ki: 0.01
Kd: 1000
Ke: 0.588
pid_mode: auto
pid_p: 5
pid_i: 0
pid_d: 0
pid_e: 13.8
pid_dt: 300.00096583366394
autotune_status: off
autotune_sample_time: 0
autotune_tuning_rule: none
autotune_set_point: 0
autotune_peak_count: 0
autotune_buffer_full: 0
autotune_buffer_length: 0
friendly_name: Termostat Grzejniki.smart
supported_features: 17
Please help I wanna used PID controller :slight_smile:

Hello, you need to check the pid_p, pid_i p, pid_d and pid_e attributes over time to see which one is making the control output switch the heater on. Then decrease the corresponding gain.

1 Like

Thank you for your understanding
And how can I save the Pide statistics chart?

Adjustment by changing parameters K?

@adrien.b since I moved all my rooms to using smart thermostat, temperatures are relatively OK, but ocasionally I see cases where heating was turned on despite setpoint being lower than actual temperature. For instance today, one of rooms was set at 6 PM from 22 to 21,5 degrees, started to heat hour later, despite measured temp was 21,9. Heating was on for 2,5 hours, then turned off and almost 30 minutes later, turned on again. All this time, set point was lower than actual temperature in room.

Other than that, I am pretty happy with how it is controlling the temperature, I just don’t get it why would it kick off heating, and why would that heating cycle take 2,5 hours when temp is higher all that time.

  min_cycle_duration: 00:20:00
  kp : 100
  ki : 0.003
  kd : 220000
  ke: 0.588
  pwm : 02:00:00
  sampling_period: 00:10:00

How you collect PIDE data on Right screen ?