New Automation: PID Controller

This introduces a PID controller for openHAB.

It is based on the work of @george.erhan and @hilbrand.

A PID controller can be used for closed-loop controls. For example:

  • Heating: A sensor measures the room temperature.
    The PID controller calculates the heater’s valve opening, so that the room temperature is kept at the setpoint.
  • Lighting: A light sensor measures the room’s illuminance.
    The PID controller controls the dimmer of the room’s lighting, so that the illuminance in the room is kept at a constant level.
  • PV zero export: A meter measures the power at the grid point of the building.
    The PID controller calculates the amount of power the battery storage system needs to feed-in or charge the battery, so that the building’s grid power consumption is around zero,
    i.e. PV generation, battery storage output power and the building’s power consumption are at balance.

Here is a step response of a PV zero export system, realized with this controller. It shows an increase of the power supply setpoint from the grid by 1kW. The P, I and D parts are summed to form the output of the controller, i.e. the charging power of the battery system. The actual value is the power flow from/into the grid.

You see that the grid power consumption is held at a constant level, although the PV generated power is fluctuating (orange line in the upper chart).

The controller can be used via Rules:

The JAR file can be dropped into the addons folder to make the PID trigger and action module available in the rule engine.

EDIT: As of openHAB 3.1, the PID controller is part of the official release.

The documentation is available here. There’s also a guidance on how to tune your PID controller.

Here is a tutorial using the PID controller for heating valves: Set up house heating using Eurotronic Spirit actuators with PID control and "manual" control

The PID controller can be used with the PWM automation module for actuators which support only ON/OFF: New Automation: Pulse Width Modulation (PWM)


Yay this looks really promising. Thanks @fwolter.
There are many usecases where a PID may improve things.
I was following the work of goerge and hilbrand in the past already.
Nice to see that we getting some progress again.

It looks quite interesting to see it implemented as rule module. The initial issues George pointed were delays introduced by rule dsl which made controller misfiring.
Looking forward to see how this one goes.

I had some basic rules such as cycle calculator/cycle cost, heat exchanger efficiency and energy efficiency of HVAC implemented as bindings. I think using your code as a blueprint I will be able to make it in proper way.

Great job! This is a useful project, please keep going! I love the informative documentation, too!
I installed the add-on and working on implementing a PID controlled floor heating.

One theoretical question: Should not the integral part accumulate the deviation upon every loopTime, rather than the currect 1 sec? My system is very slow (like other floor heaters), it takes an hour to reach the setpoint for a 2°C change. So I will set very slow loop time like 5 min. But the integral part is shooting out in my slow system to the thousand range currently with a 0.5 Ki. Of course I can manage this by a very low Ki… I am not a control loop expert, but it looks somewhat logical to calculate the integral based on the loop time. What do you think?

Another observation: The output limits are not just limiting the output, but also the individual components separately. Not sure if this is intentional. It would probably be better to fix this or make it clear in the docs.

Thanks for your feedback and test!

I changed the Ki time base several times during development from loop time to a fixed value and back. My intention making it based on a fixed duration was to have a Ki value which is independent from the loop time setting. Otherwise the Ki value needs to be adjusted when you change the loop time, which I found counterintuitive. But from a detached perspective I find the current implementation counterintuitive, tough. I could imagine that commercially available controller’s Ki values are also based on the loop time. I think I’m gonna change it back as I hadn’t such really slow control loops in mind when implementing it.

The “output limit” in fact is only limiting the I-part and not the output. I think the configuration parameter needs to be renamed. I’m not a control expert either. Should the output get a limitation, too?

Does anyone know whether this addon can be used in the Rules DSL (text-based) system? Or can it only be used via the new GUI Rules? Can I mix DSL & GUI Rules?

1 Like

Can I mix DSL & GUI Rules?

You can use mixed rules. I have text based DSLs defined by .rules file, I have the PID controller rule set on UI and I have Scheduling rules All appearing under Rules setting on OH3 UI.

(I would also like to know if it is possible to define PID contoller rules by text)

My intention making it based on a fixed duration was to have a Ki value which is independent from the loop time setting.

I think you are right, the integral should be calculated on a fix, definite cadence independent from the loop time. Maybe it would make sense to be able to set the cadence.

The “output limit” in fact is only limiting the I-part and not the output. I think the configuration parameter needs to be renamed. I’m not a control expert either. Should the output get a limitation, too?

Currently the limits are limiting both the output and the I-part, this is not good for me now in my test. Limiting the I-part seem to be vital in my use case. A separately configurable limit for the output might make sense, but not critical as you always put some code that translates the PID output to the actuator’s input value, it is quite easy to add the limit there if needed.

I peeked into the manuals of some commercial controllers and I didn’t find any with a dedicated time base setting for the I-part. As far as I understood they use all the loop time. Maybe @george.erhan has some thoughts to that topic?

You’re right, the “output limit” setting limits not only the I-part but also the output. That was a last minute change. I think I change this behavior that only the I-part is limited as this gives max flexibility to the user as you said.

It really depends on what one would like to achieve. Normally the increase/decrease of the integral part should be done exclusively by the loop time duration.

The problem occurred only on relatively small loop times (less than 500 ms). For slow processes DSL rules work just fine. When dealing with fast processes (e.g. brightness control of ambient lighting) you need small loop times. For these I needed a better closed control loop response time.

The different cadence time should not be used in the integral part, the loop time is the standard time to use in a standard PID. It defies the concept of a standard PID, you would have two controller: one I Controller, the other a PD controller.

1 Like

Fabian, I have another suggestion… It would make sense to implement a configurable low pass filter for the input signal. I have standard digital thermometers on my system with a resolution of about 0.1°C. On my system the D gain is quite big now (10) due to the slow loop. The D part making quite big jumps due to the discrete steps of the thermometer, which sometimes confuses the control. I think it would make the control loop more stable if a slight smoothing could be set for the input signal.

See example graph below…

Thanks for you input @george.erhan! I will make the Ki part dependent on the loop time.

@rgabo74 I see. But that should be implemented in a separate automation module, which won’t be a big deal.

When you have slow systems, don’t use the Derivative part, it has no meaningful input, set Kd to 0.
All the controllers used for ambient climate control, only have a PI controller (no derivative part) because the process is too slow,

Hm… Interesting… I found the opposite to be a working setup. The Integral did not work for me. It accumulates in one direction in the long loop (even with very low Gain) and it does not compensate back as my system tend to make bigger overruns than under-runs, so the I component was just kept growing. The derivative part did what it should do, it pulling the break in time and minimized oscillation effectively.

See this example at the marked point. The D part nicely stops heating far ahead the STP reached due to the fast increasing temperature.

Well, tuning a PID controller is definitely not easy.
The integral should decrease when set point is reached and in time (depending on the K/h capability of the system), things will work smoothly.
Be patient and you will find the right working Ki for your system.

The documentation link is bad ?

The link is working again, thanks!

@rgabo74 I’m wondering how you convert the PID output to the “HeatingOnOff” signal. I don’t see any much relationship between the two.

I implemented PWM control with 10 minutes cycle. PID Output value 0.3 - 1.0 doing a heating period from 3 to 10 minutes in every 10 minutes cycle. I excluded the <0.3 range to save the heater from short term operation.