Thermostat with PID controller

@axax with a kd that high, are you not saturating your output? I recognise the python program and i think it clips the output. If you have 0.5°c difference between measurements and then multiply by 150000 you get 75000 which is huge. From experience programming control systems kd is usally small because you get something called derivative kick (https://apmonitor.com/pdc/index.php/Main/ProportionalIntegralDerivative).

Hi Matthew,

Thanx for your feedback. Yes the Kd was on the high side. I’m now running it without Kd to see it’s behaviour. The Kd is however not that high as your would expect. I changed the PID code to include a smoothing average for the Kd part, I think about 15 to 60 min for that Kd value.

I use a xiaomi sensor for the temperature which updated irregularly, sometimes within a minute up to 1-2 hours when temp is constant. This would result with a PID update in a very unstable behaviour. The reason I wanted to try to use the Kd part too compensate abrupt temp changes .

But I will read your links soon when I got some time!

Hello,

Will this thermostat work with thermal actuator like this one: https://www.salus-controls.eu/products/online-control-smart-home-system/underfloor-heating/t30nc-m30x1-5-230v-thermal-actuators

In a nut shell it’s on/off with ~2min cycle. I would like to attach it to a radiaotr connected to central heating in my flat.

Hi all, as a first beginning of a PID regulator in the standard HA I have posted a pull request for a binary-switch to PWM-analog convertor. This can be used as a PID output, but for other purposes and controllers as well. You can find it here: https://github.com/home-assistant/core/pull/33427. I don’t know exactly what the requirements are for an archtectural change to be accepted, but maybe it helps if you give the architectural change proposal some thumbs: https://github.com/home-assistant/architecture/issues/358. Once we have this analog output it will be much easier to implement PID regulators and thermostats, as well as other smart regulators.

Hello all,

I was wondering if any has had this issue when the climate hvac_action is in heating mode and you attempt to execute a climate.turn_off:

2020-04-30 19:24:47 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection.140525538636992] 'SmartThermostat' object has no attribute '_async_async_heater_turn_off'
Traceback (most recent call last):
  File "/home/homeassistant/std/lib/python3.8/site-packages/homeassistant/components/websocket_api/commands.py", line 129, in handle_call_service
    await hass.services.async_call(
  File "/home/homeassistant/std/lib/python3.8/site-packages/homeassistant/core.py", line 1232, in async_call
    await asyncio.shield(self._execute_service(handler, service_call))
  File "/home/homeassistant/std/lib/python3.8/site-packages/homeassistant/core.py", line 1255, in _execute_service
    await handler.func(service_call)
  File "/home/homeassistant/std/lib/python3.8/site-packages/homeassistant/components/script/__init__.py", line 179, in toggle_service
    await script.async_toggle(context=service.context)
  File "/home/homeassistant/std/lib/python3.8/site-packages/homeassistant/helpers/entity.py", line 647, in async_toggle
    await self.async_turn_on(**kwargs)
  File "/home/homeassistant/std/lib/python3.8/site-packages/homeassistant/components/script/__init__.py", line 284, in async_turn_on
    await self.script.async_run(kwargs.get(ATTR_VARIABLES), context)
  File "/home/homeassistant/std/lib/python3.8/site-packages/homeassistant/helpers/script.py", line 802, in async_run
    await run.async_run()
  File "/home/homeassistant/std/lib/python3.8/site-packages/homeassistant/helpers/script.py", line 523, in async_run
    await self._async_run()
  File "/home/homeassistant/std/lib/python3.8/site-packages/homeassistant/helpers/script.py", line 540, in _async_run
    await self._async_step(log_exceptions=not propagate_exceptions)
  File "/home/homeassistant/std/lib/python3.8/site-packages/homeassistant/helpers/script.py", line 153, in _async_step
    await getattr(
  File "/home/homeassistant/std/lib/python3.8/site-packages/homeassistant/helpers/script.py", line 623, in _async_call_service_step
    await self._hass.services.async_call(
  File "/home/homeassistant/std/lib/python3.8/site-packages/homeassistant/core.py", line 1232, in async_call
    await asyncio.shield(self._execute_service(handler, service_call))
  File "/home/homeassistant/std/lib/python3.8/site-packages/homeassistant/core.py", line 1255, in _execute_service
    await handler.func(service_call)
  File "/home/homeassistant/std/lib/python3.8/site-packages/homeassistant/helpers/entity_component.py", line 212, in handle_service
    await self.hass.helpers.service.entity_service_call(
  File "/home/homeassistant/std/lib/python3.8/site-packages/homeassistant/helpers/service.py", line 412, in entity_service_call
    future.result()  # pop exception if have
  File "/home/homeassistant/std/lib/python3.8/site-packages/homeassistant/helpers/entity.py", line 600, in async_request_call
    await coro
  File "/home/homeassistant/std/lib/python3.8/site-packages/homeassistant/helpers/service.py", line 443, in _handle_entity_call
    await result
  File "/home/homeassistant/std/lib/python3.8/site-packages/homeassistant/components/climate/__init__.py", line 479, in async_turn_off
    await self.async_set_hvac_mode(HVAC_MODE_OFF)
  File "/home/homeassistant/std/homeassistant/custom_components/smart_thermostat/climate.py", line 335, in async_set_hvac_mode
    await self._async_async_heater_turn_off()
AttributeError: 'SmartThermostat' object has no attribute '_async_async_heater_turn_off'

The above issue does not occur when the climate hvac_action is in idle mode. I extracted the faulty code:

async def async_set_hvac_mode(self, hvac_mode):
    """Set hvac mode."""
    if hvac_mode == HVAC_MODE_HEAT:
        self._hvac_mode = HVAC_MODE_HEAT
        await self._async_control_heating(force=True)
    elif hvac_mode == HVAC_MODE_COOL:
        self._hvac_mode = HVAC_MODE_COOL
        await self._async_control_heating(force=True)
    elif hvac_mode == HVAC_MODE_OFF:
        self._hvac_mode = HVAC_MODE_OFF
        if self._is_device_active:
            await self._async_async_heater_turn_off()
    else:
        _LOGGER.error("Unrecognized hvac mode: %s", hvac_mode)
        return
    # Ensure we update the current operation after changing the mode
    self.schedule_update_ha_state()

The line that it fails on is: await self._async_async_heater_turn_off() I believe it to be a function that does not exist anymore. But not sure what to do about it?

Update:
I tried to make a new version that’s “better”. supporting a working autotune for different heating systems.
+200 hours later my conclusion about this is fairly disappointing.

First of all most heating systems are already automated. What worked 40 years ago still works perfectly fine.

If you plan on automating your heating system further necessary hardware already includes the software. Having your additional software is overkill and near to useless or even bad depending on how skilled you are.

PID controllers only work in a none changing environment such as the heating system itself but not the room heating (e.g. radiator). Basically you’re not allowed to open windows or doors, which would be controllable but most people have apartments or normal family houses.

  • Apartments are controlled by a central heating system which makes it impossible to keep things constant also they are influenced by surrounding apartments and their heating.

  • Family houses on the other hand are usually already automated with components tuned by professionals. For old or cheap houses that still have radiators simply buy new smart valves and give a fuck on Tuning and maintaining yourself. average cost 40$/valve

So there are just a very few cases it actually works significantly enough to consider implementing a own PID tuned thermostat. For all others you don’t need this.

Guide:
For those that actually look into making the generic thermostat smarter.

  • Don’t use PID controllers on heat elements. (You can but it’s usually senseless)

  • Buy sensors for windows and maybe even your doors. I recommend aqara.

  • Buy smart Valves if you can.

  • Automate your heating system if not already (pumps, flow temperature etc.) but only if you know what you’re doing, else buy something like a NEST

Actually safe energy by:

  • Setting up a generic thermostat and an automation that turns it off when you open a window.

  • Lower the set-point when leaving the house for longer.

Features:
A nice little feature you might want to add to rooms that get to hot when you close the door and are inside of them is a door sensor. Turn the heating off when you close the door.

Also safe a lot of energy buy closing your curtains in summer and open them in winter whenever you can. For those who invested in smart curtains automate it!

Lower the set-point when away even further and still feel comfortable when coming home by applying a timer or geofencing to your home as well as workplace

Comment:
I’m sad my work led my to a dead end.
I’ll make a full guide on automation for heating systems instead.

1 Like

Hi Fabian,

Sorry to hear you are disappointed with your PID implementation and the limited added value. In my case, I think, it would still be a good option and a really nice feature.

In my home there is floor heating on two floors and 5-6 rooms. I cannot control the rooms individually, only from the thermostat in the living room. Buying a commercial system would cost around €1000-2000.

At the moment I have your system running for more than 1.5 year an performing quite well. Up to now only as a replacement for the living room thermostat. It does perform similar as the Honeywel chronotherm. In general the sun radiation gives the most disturbance.

My idea-goal was to use a HA thermostat with PID+PWM per room and control the thermal actuators. The PID+PWM would control the opening/flow per actuator. I already have xiaomi temperature sensors in all rooms and the relays for the actuators ready. I was waiting for next iteration (maybe with db-cl generic thermostat update) to see the progress before implementing zone heating.

At least thanx for your work.

I want use a PID for cold system
I have split daikin into each room with temperature sensor xiaomi.

what is the better system to regulation temperature?
I want use split daikin with 4 command

  • off
  • 1 fan and 20°
  • 3 fan and 20°
  • 5 fan and 20°

I am very thankful for the PID controller. I am currently setting it up and I need some help and recommendation for the initial PID settings.
I’m trying to control underfloor heating and every room has it’s own temperature sensor and wax actuator. All I have is controlling the actuator to set the temperature. The system is very slow and needs constant pulsing so the floors don’t’ get too cold or too hot. The concrete floors hold so much temperature that if I’m not careful close to the set point then I overshoots by 2°c or so and the temperature in the room is rising for hours after I have turned off the vax actuators.

I have xiaomi temperature sensors that send update every 50 minutes if the temperature change is within 0.5°c but if more than that they send the new value right away.
The vax actuators (17 in total) take 3 minutes from 0 to 100% (open and close).

What settings should is start out with? Am I doing anything wrong?

  • platform: smart_thermostat
    name: termostat_bedroom
    heater: switch.heater_bedroom
    target_sensor: sensor.temperature_bedroom
    min_temp: 15
    max_temp: 24
    ac_mode: False
    target_temp: 21.5
    keep_alive:
    seconds: 300 #5 mintues? Should I have this value higher? lower? considdering how slow everything happens in a under floor system.
    #initial_operation_mode: “off”
    away_temp: 18
    kp : 30 #how is the p related to everything else? low number slow? high number fast? Should I start with a low number and work my way up? Is this number a proportion of any other number?
    ki : 3 #is this time? 300 x 3=900 seconds? Is the difference calculated every 900 seconds?
    kd : 0
    pwm : 30 #30 minutes or 30 seconds? Can I see somehow in the logs that this is 10 minutes on and 20 minutes off for a zone? I only see on or off.
    autotune : ziegler-nichols
    difference : 100 #in the logs I only see 0 (zero) or 100 nothing in between…
    noiseband : 0.1

Thanks,
Sincerely, Stefán

Hello Fabian,
I share your point, I’m from a relevant OEM company in the HVAC segment, PID control in residential applications potentially can cause few headaches due to the “D” part of the control. This happens especially in the occasion of big free heating supply as a sunny day, cooking activity, people presence or sporadic supply of auxiliary heating devices (e.g. fireplace, ecc…). The Derivative part get tricked.
But I would kindly encourage you to go on by simplifying the control versus a PI solution. All the climate controllers in the product portfolio are using PI control with effectiveness.

My Br
Stefano S.

2 Likes

@Fabian Thank you for working on this. I have been working on my own thermostat for few years now and based on the experience, for thermostat to give expected results it has to calculate energy added or removed from the house in addition to the boiler. I.E. it has to track outside temperature, insolation, wind speed, and rain. Better yet it should anticipate future energy addition/removal due to weather ahead of time.

In some circumstances, another complication might be that for On-OFF heat sources that cannot modulate their output, dumb thermostat may cause unnecessary and wasteful short ON cycles so smart thermostat should track heat cycle of the heat source as well.

Hi, I got fascinated with the PID thermostat but I am using battery operated Z-Wave TRV heads on my radiators. The current solution of PID thermostat to issue only ON/OFF commands is a bit crude for me and it will create problems with battery life of the valves.
I can control the exact valve position on my TRV. Is there any chance to transform the thermostat to suggest discreet values in the range of 0-100 instead of on/off commands only?

Hello,

I agree, the D part can sometimes kick the whole system into an unstable state.
There’s also integral windup that can cause all sorts of issues.
Control theory can be really interesting, in uni we would use matlab to estimate the values for the PID parts. One of the harder aspects is integrating heatloss into the block diagram, should it be removed from the input as an error, added to the system output as a disturbance or even noise to the sensor feedback. All have their merits and their implications when doing stability calculations. I always found it easier using state space.
Anyway good luck.

Hi Fabian,

I also wanted to give you feedback to your PID controller.
I’m very satisfied using it for my floor heating in three rooms.
Since the winter started it worked very smooth with the Aqara Smart Air Pressure Temperature Humidity Sensors.
With an automation and the “keep alive of 180s” I added a minimum heating.
So if the floor heating was not set to heat for 45mins (automation on the actuator relay), it will trigger the relays to on. After maximal 180 seconds the pid recognizes this and turns the relay back to off. In the worst case the valve will not open at all if the relay is set back to off after 5s or so.
For me it works fine and the floor doesn’t get too cold.

Could you maybe update your code that the temperature, which was set, is saved after a restart?
It always falls back to the target_temp in the config.

Here my settings:
min_temp: 15
max_temp: 30
ac_mode: False
target_temp: 23
keep_alive:
seconds: 180
away_temp: 16
kp : 150
ki : 0.01
kd : 200
pwm : 900
difference : 100
noiseband : 0.1

I have a similar use case (although output needs to be between 10 and 90)…

Hi @fabian.n,
this is my first post here and I’m going to thank you for your work.

I’m going to setup a system with at least 12 rooms with floor heating.

Until now, in my previous house I used Tado as central controller: it uses PID for sure. This is one of his graph (an I can hear the frequent click from his internal relè):

If you want, I can help you. Some consideration:

  • I’m a software engineer (no python, but java) and I know how to debug, read log, grep, investigate traceback, etc.
  • I’m passionate about FPV racing drones: home made drones require a lot of experience in PID tuning (we use a software called betaflight which implements PID controller to keep everything steady)
  • In racing drones, the D term can go crazy if the frame is unbalanced or you have a lot vibrations
  • To avoid this, both input data (from a gyro, but in heating is a term sensor) and D “fluctuations” are filtered: there is a lot of literature about filtering before PID chain calculation
  • External perturbations are wind, gravity and random noise: the equivalent in heating of window opened, sun, people, cooking, etc.

In my opinion, PID is the right solution but cannot be left alone: filtering is required and, as per FPV drones, a “runaway” protection must be set to prevent huge values in PID term calculations.

For example, Tado introduced a “open window detector” which, in my opinion, it’s only a windup detector on P term.

Bye
Vincenzo

Hi Vincenzo,

I’m trying to create the same for a 6 room house with distric heating. At the moment I’m rewriting the latest generic thermostat with the following options:

  • on-off
  • PID
  • weather compensating
  • master mode (using ohter thermostats as input)

The last three can be used in any form together.

Still some debugging an fine tuning to be done but the above works already quite well. I hope to do my first in house tests somewhere next week and will share the code then as well.

Great! I plan to test in my house, but I must wait at least 6 months.

I got some time on my hands right now. I’ll try to build some addons around the PID to make it more stable.

finished a new version. Can someone test it?

New:

  • service to set PID values and PWM
  • removed some stuff that i think is not working
  • fixed some things that were not working
1 Like