ScratMan / HASmartThermostat

Smart Thermostat with PID controller for HomeAssistant
365 stars 55 forks source link

PID_I not decreasing when target temp is much lower than current temp (night) #137

Closed HermesHonshappo closed 1 year ago

HermesHonshappo commented 1 year ago

Describe the bug I have a target temperature that changes twice a day. It does to sleep temp at 6PM, and then back to day temp at 3AM During the dat shift, PID_II increases and decreases as it should. However, at night, when the target temp suddenly drops, PID_I doesn't decrease anymore. Which means that the next heat cycle starts with a very high value of PID_I

Tested both in latest version, and I did a rollback in 2022.2.1 yesterday This night the sqystem ran with version 2022.2.1, and this behavior didn't show up

In 2023.2.1 (yesterday)

This is the graph with the target temp (purple line).

Screenshot 2023-03-03 at 08 48 20

If I superpose the PID_I graph, you can see that PID_I doesn't move at all (flat line) during the low target temp period. When the target temp goes back up, then PID-I starts to increase again, but starting on the value it had hours ago.

Screenshot 2023-03-03 at 08 47 51

So yesterday evening I did a downgrade to 2022.2.1, and here are the same graphs for last night:

Screenshot 2023-03-03 at 08 46 50 Screenshot 2023-03-03 at 08 47 03

As you can see PID_I dropped back during the night. Not down to zero, but it did decrease steadily during the whole period

One thing important: when I restarted in 2022.2.1 last evening, it restarted with the old gain values (that were in climate.yaml). So that may or may not have affected the results. I have now put the correct values and am keeping 2022.2.1 for one more cycle, to see if the cause is the version, or it it was the values used I am not sure if this is linked to the version, or if this is a behavior that shows up when the PID output is zero because of highly negative PID-P values

Important EDIT: this does not seem linked to the version, but to the value of "control_output". See update in post below

To Reproduce Steps to reproduce the behavior: Set a scheduler to have 12 hours at a high temp, then 12 hours at a low temp Monitor PID_I values

Expected behavior A clear and concise description of what you expected to happen.

Desktop (please complete the following information):

Additional context

Keep in mind that I have multiple smart_thermostats. I remember it was a key element in previous issue identified and solved (#121)

Here is the smart_thermostat config

- platform: smart_thermostat
  name: Thermostat Salon
  unique_id: dfa26e22-f6f3-4b7d-9c3d-0b1cfef1a3a3
  heater: input_boolean.commande_chauffage_salon
  target_sensor: sensor.temperature_salon_temperature
  ac_mode: False
  target_temp_step: 0.1
  keep_alive:
    seconds: 60
  pwm: 00:15:00
  min_cycle_duration: 00:03:00
  cold_tolerance: 0
  hot_tolerance: 0
  min_temp: 10
  max_temp: 24
  away_temp: 12
  sleep_temp: 15.5
  comfort_temp: 18
  preset_sync_mode: sync
  kp : 50
  ki : 0.004
  kd : 25000
  outdoor_sensor: sensor.temperature_exterieur_temperature
  ke: 2
#  debug: true

- platform: smart_thermostat
  name: Thermostat SdB M2
  unique_id: 580e04e0-9da4-4da4-9eae-c48d047bd002
  heater: input_boolean.commande_chauffage_salle_de_bain_m2
  target_sensor: sensor.temperature_salle_de_bain_temperature
  ac_mode: False
  target_temp_step: 0.1
  keep_alive:
    seconds: 60
  pwm: 00:15:00
  sampling_period: 00:30:00
  min_cycle_duration: 00:03:00
  cold_tolerance: 0
  hot_tolerance: 0
  min_temp: 10
  max_temp: 24
  away_temp: 12
  sleep_temp: 15.5
  comfort_temp: 18
  preset_sync_mode: sync
  kp : 50
  ki : 0.004
  kd : 25000
  outdoor_sensor: sensor.temperature_exterieur_temperature
  ke: 2
#  debug: true

- platform: smart_thermostat
  name: Thermostat Ch. Parents
  unique_id: d28ba05c-63f4-4893-8df3-48594e3fe77d
  heater: input_boolean.commande_chauffage_ch_parents
  target_sensor: sensor.temperature_chambre_parents_temperature
  ac_mode: False
  target_temp_step: 0.1
  keep_alive:
    seconds: 60
  pwm: 00:15:00
  min_cycle_duration: 00:03:00
  cold_tolerance: 0
  hot_tolerance: 0
  min_temp: 10
  max_temp: 24
  away_temp: 12
  sleep_temp: 15.5
  comfort_temp: 18
  preset_sync_mode: sync
  kp : 50
  ki : 0.004
  kd : 25000
  outdoor_sensor: sensor.temperature_exterieur_temperature
  ke: 2
#  debug: true

- platform: smart_thermostat
  name: Thermostat Ch. Mômes
  unique_id: 15263b8f-e428-4872-8cb6-d263b8c3b9d8
  heater: input_boolean.commande_chauffage_ch_momes
  target_sensor: sensor.temperature_chambre_momes_temperature
  ac_mode: False
  target_temp_step: 0.1
  keep_alive:
    seconds: 60
  pwm: 00:15:00
  min_cycle_duration: 00:03:00
  cold_tolerance: 0
  hot_tolerance: 0
  min_temp: 10
  max_temp: 24
  away_temp: 12
  sleep_temp: 15.5
  comfort_temp: 18
  preset_sync_mode: sync
  kp : 50
  ki : 0.004
  kd : 25000
  outdoor_sensor: sensor.temperature_exterieur_temperature
  ke: 2
#  debug: true

- platform: smart_thermostat
  name: Thermostat Ch. Ian PID
  unique_id: 59045b01-811b-47da-91da-194dcff41fee
  heater: input_boolean.commande_pompe_1
  target_sensor: sensor.temperature_ch_ian_temperature
  target_temp_step: 0.1
  ac_mode: False
  keep_alive:
    seconds: 60
  pwm: 00:30:00
  sampling_period: 00:05:00
  min_cycle_duration: 00:03:00
  cold_tolerance: 0.1
  hot_tolerance: 0.1
  min_temp: 10
  max_temp: 24
  away_temp: 12
  sleep_temp: 16
  comfort_temp: 18
  preset_sync_mode: sync
#autotune results
#  kp : 7.23432
#  ki : 0.00184
#  kd : 2032.44078
  kp : 30
  ki : 0.0008
  kd : 25000
  outdoor_sensor: sensor.temperature_exterieur_temperature
  ke: 1
#  debug: true

- platform: smart_thermostat
  name: Thermostat Ch. Ian PID Dalle
  unique_id: c8d8a872-84ac-41dd-9cf5-7e3a28868de5
  heater: input_boolean.commande_pompe_2
  target_sensor: sensor.temp_dalle_ch_ian_average_temperature_hacs_1h
  ac_mode: False
  keep_alive:
    seconds: 60
  pwm : 1800                  #30 minutes
  sampling_period: 00:05:00
  min_cycle_duration: 180     #3 minutes
  cold_tolerance: 0
  hot_tolerance: 0.1
  min_temp: 10
  max_temp: 27
  away_temp: 15
  sleep_temp: 22
  comfort_temp: 25
  preset_sync_mode: sync
  kp : 40
  ki : 0.0009
  kd : 25000
  outdoor_sensor: sensor.temperature_exterieur_temperature
  ke: 1.5
#  debug: true
HermesHonshappo commented 1 year ago

With better screenshots, showing both the heating cycles and the PID outputs:

Yesterday, with 2023.2.1 and my regular PID gains (so a high Kp, resulting in a very negative PID_p during night) PID_i does not decrease during the night

Screenshot 2023-03-03 at 10 14 38

This night, with 2022.1.1 and the PID gains that were in the climate.yaml (so a much lower Kp, and a higher Ki). PID_i does decrease during the night

Screenshot 2023-03-03 at 10 14 54

It seems PID_i is only updated when control_output is > 0%. Last night, each time PID_i decreased was when control-output went slightly above zero (probably because of a temp sensor update, and PID_d slightly overpowering the negative value of PID_p)

This means that it's not related to a specific version, but to the value of control_output. If control_output=0, then PID_i doesn't decrease. But if control_output = 0.1%, then PID_i decreases

The 2 days summarized in the graph below:

Screenshot 2023-03-03 at 11 42 02

I'm not sure if this is normal or not...

ScratMan commented 1 year ago

That's normal behaviour, see here: https://github.com/ScratMan/HASmartThermostat/issues/130#issuecomment-1436010137

HermesHonshappo commented 1 year ago

Mmmk, I read the wikipedia about integral windup. It sounds a bit strange to me, as it seems to create the behavior that this measure is trying to avoid.

What I am observing is that when I have Kp high enough for a quick system response, then the control_output is zero during the night. Slowly over a few days, PID_i increases more than it decreases. This happens for a few days, until the system overshoots seriously one day when it starts the day with a PID_i that is already at 50% at the beginning of the heat cycle.

This is what happened on march 2nd, when the cycle started with a PID_i still at 47% from the day before. PID_i rose to 60% while the temp was still below target, and then it overshot badly, until temp was high enough for PID_p to negate PID_i. What's bad imho is that when PID_p was low enough to stop the heating completely, PID_i stopped decreasing. So it stayed stuck at 52.7% (flat period around noon in the graph)

Screenshot 2023-03-03 at 17 28 18

But I admit I know zilch about PID controllers, so why not, I guess. Not having this measure might result in even worse integral windups. It could be worse.

Would you have any suggestion on how to mitigate this behavior? From the top of my head, here's what I could think about:

ScratMan commented 1 year ago

You could increase ke so that the ke * (target_temp - outdoor_temp) is half of the expected integral value. Then clear the integral and wait for the system to be stabilized.