New Automation: PID Controller

Thanks for the tip! I installed the PID controller addon from the GUI and there are no error messages now.

I am still having an issue with the PID reset though - I am not sure if this is working correctly, or if its behaviour is different to the prototype.

I have a scene that I can trigger manually to reset the PID. This sends the RESET string to the command item:

2021-10-26 10:25:29.923 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'BedroomTrvPidCommandItem' received command RESET

2021-10-26 10:25:29.924 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'BedroomTrvPidCommandItem' changed from NULL to RESET

2021-10-26 10:25:29.925 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'BedroomTrvPidCommandItem' changed from RESET to NULL

I can see that the PID Controller has received the reset command because it gets set back to NULL immediately afterwards.

However, in the past I would expect this to set the ‘I’ value to zero and then change on the next PID trigger. I am seeing a non-zero value in the ‘I’ Inspector immediately.

Is that what you would expect now?

The integral and derivative part are internally reset to 0, but the inspector Items are only updated on the next trigger. In the meantime, the I part could be risen again. So, this should be only a cosmetic issue.

Yes, that would make sense - it does appear to be internally resetting, just the behaviour is slightly different as you say.

Can this be used using text rule (non gui)?

Yes - that is how I am using it. You have to create each PID controller instance in the GUI Rules configuration but the Setpoint, Input, and Output Items can be ones created as Text Items. Therefore it is also possible to use the Text Rules engine to process the PID output.

Hi @fwolter - I’m seeking some advice.

I’m facing a problem when PID controller is not setting up the PID_Control item to Null value post sending RESET.

In my case it works in a way that whenever a new SetPoint value is set on heaters I’m sending RESET command. PID controller seems to pick it up but the value remains instead of being clearead.

Is there any log somewhere to track any error/exception?

Thank you @fwolter for this amazing Add-on! :+1: :mechanical_arm:

In technical environments it is common to limit the I part, so the whole PID controller produces an output in a predetermined area. Otherwise the PID controller gets to a point with no return. (eg. The I part is growing continuously to values which are way out of the possible values of the plant)

How can I limit the I part with upper and lower bounds?

I added a min and a max configuration parameter to limit the I-Part. The linked JAR file in the original post has been updated.

The I-part can be limited via `integralMinValue`/`integralMaxValue`.
This is useful if the regulation cannot meet its setpoint from time to time.
E.g. a heating controller in the summer, which can not cool (min limit) or when the heating valve is already at 100% and the room is only slowly heating up (max limit).
When controlling a heating valve, reasonable values are 0% (min limit) and 100% (max limit).

@Dominik_Jeziorski Maybe you can use these limit parameters, too. IMHO it’s cleaner instead of resetting the I-Part on every setpoint change.

1 Like

Thank you really much!
I will test it and give you feedback.

To apply this new functionality I have to manually transfer the JAR file to my openhab instance instead of installing it via the Main UI Binding installation option?

Can I discuss with you another possible feature for your PID?
I try to control a heating ventilation via analog signals. These signals can be in the range of 0 to 10000 mV. So I need to keep my output of the PID in this range and also as an integer. Currently I do this with a second rule which takes the output of the PID as an input and limits the number.
What do you think about adding also limits to the output and define the data type (eg.: integer, decimal). If the limits are overs hooted, the algorithm chooses the nearest limit.

I’m currently not using the D-part, but from the mathematical point of view this D-part could also increase or decrease to numbers, where the PID will not get back. Would it be useful to limit the D-part as well?

You can simply drop the JAR into your addons folder. It should be loaded without restarting OH. You can uninstall the PID controller beforehand via MainUI, but you don’t need to. The snapshot version will take precedence.

Most devices, which are fed by the PID output limit their values internally. E.g. your 0-10V output probably won’t become negative or way above 10V, although if the PID output exceeds this range. So, I don’t think it’s a common use case, that the output needs to be limited.

Limiting the I-part is some special thing as it can run away over time. In contrast to the D-part, which will tend to 0, if the regulation is stable. The D-part can take extreme values on sudden changes, but it also decreases again on its own.

The decimal data type should be casted to integer by the binding controlling your 0-10V actuator. What 0-10V actuator are you using?

@fwolter thanks for thinking about my case! It really sounds like better solution and less maitananace of needed variables.

Not to mention that visualising data on grafana will become simpler.

Hello and thanks @fwolter for your work on the PID controller, including the latest update that restores the integrator limits. I have only recently discovered it and I’m running now 2 humidifiers and 3 floor heating zones using the PID+PWM setup. The humidiers are switched by IKEA smart plugs through zigbee2mqtt and the floor heating zones are switched by a relay module controlled by a Tasmota module over MQTT. It works brilliantly so far.

I’ve routed the PID controller output to individual XYZ_dutycycle items in openhab that is picked up by the PWM module and those items are also logged to influxdb and graphed using Grafana.

While the PWM module is happy to accept inputs such as -250 or 125 by coercing them into the range of 0…100 before processing, then these values are not exactly representative of a duty cycle percentage. Viewing that output on the graph gets a little weird too.

I would put another vote in favor of adding output min/max config options to guarantee that the output value is inside the input range of whatever is being controlled. Also for example some other automation might not be so happy to accept values outside the input range. I’d be willing to contribute code as well if that would help.

I absolutely welcome code contributions! But I wouldn’t use an output limit, because I cannot see how much above or below the limit the actual value is, anymore. This is useful to see how long it might take that the output value reaches the valid range again, i.e. when the regulation starts working again.

In the rare case your input struggles with out-of-range values, you could add a rule to limit the value.

I understand your case as well. However, would you consider merging such output limits code as long as the limits are optional? Your module already provides the inspector items for the components and maybe we could provide an inspector item for the unbounded output value as well?

Yeah, go ahead.

I was able to install the addon as you suggested and it is working now as expected.
One thing I observed is, that although the error is positive, the I part stays at my negative min bound of -2000.

I have setpoint of 6°C and the current input ist 4.4°C and the error is 1.6°C, but the I part keeps to stay at -2000. When I reset the PID controller it immediately starts increasing the I part after every calculation cycle. It increases slowly to my maximum limit.

I use Wolf heating ventilators and these devices accept a signal from 0V to 10V. I now managed it by setting up a rule which limits the overall output to 0 and 10000.

Here is a log from the I-inspector item. It stays at the minimum level and don’t change. Only after I did the reset of the PID it startet to act normal again.

Log
2022-01-25 21:21:40.392 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from -2000.0 to 1.6001599999999996
2022-01-25 21:21:50.396 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 1.6001599999999996 to 3.2004799999999993
2022-01-25 21:22:00.394 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 3.2004799999999993 to 4.800799999999999
2022-01-25 21:22:10.448 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 4.800799999999999 to 6.400959999999999
2022-01-25 21:22:20.437 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 6.400959999999999 to 8.001279999999998
2022-01-25 21:22:30.412 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 8.001279999999998 to 9.601599999999998
2022-01-25 21:22:40.406 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 9.601599999999998 to 11.201759999999997
2022-01-25 21:22:50.422 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 11.201759999999997 to 12.802079999999997
2022-01-25 21:23:00.419 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 12.802079999999997 to 14.402719999999997
2022-01-25 21:23:10.429 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 14.402719999999997 to 16.003039999999995
2022-01-25 21:23:20.417 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 16.003039999999995 to 17.603199999999994
2022-01-25 21:23:30.408 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 17.603199999999994 to 19.203519999999994
2022-01-25 21:23:40.472 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 19.203519999999994 to 20.803999999999995
2022-01-25 21:23:50.452 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 20.803999999999995 to 22.404159999999994
2022-01-25 21:23:55.548 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 22.404159999999994 to 23.173659999999995
2022-01-25 21:24:00.422 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 23.173659999999995 to 23.904459999999993
2022-01-25 21:24:10.426 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 23.904459999999993 to 25.404759999999992
2022-01-25 21:24:19.868 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 25.404759999999992 to 26.91691999999999
2022-01-25 21:24:20.412 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 26.91691999999999 to 27.00491999999999
2022-01-25 21:24:28.028 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 27.00491999999999 to 28.14701999999999
2022-01-25 21:24:30.443 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 28.14701999999999 to 28.50521999999999
2022-01-25 21:24:40.441 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 28.50521999999999 to 30.00551999999999
2022-01-25 21:24:50.432 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 30.00551999999999 to 31.50581999999999
2022-01-25 21:25:00.505 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 31.50581999999999 to 33.00611999999999
2022-01-25 21:25:10.430 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 33.00611999999999 to 34.50641999999999
2022-01-25 21:25:20.434 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 34.50641999999999 to 36.00656999999999
2022-01-25 21:25:30.438 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 36.00656999999999 to 37.50686999999999
2022-01-25 21:25:40.429 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 37.50686999999999 to 39.00701999999999
2022-01-25 21:25:49.253 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 39.00701999999999 to 40.24279999999999
2022-01-25 21:25:50.430 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 40.24279999999999 to 40.407299999999985
2022-01-25 21:26:00.442 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 40.407299999999985 to 41.807439999999986
2022-01-25 21:26:10.433 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 41.807439999999986 to 43.207579999999986
2022-01-25 21:26:13.579 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 43.207579999999986 to 43.67872999999999
2022-01-25 21:26:20.501 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 43.67872999999999 to 44.70787999999999
2022-01-25 21:26:21.803 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 44.70787999999999 to 44.89785999999999
2022-01-25 21:26:30.483 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 44.89785999999999 to 46.10899999999999
2022-01-25 21:26:40.444 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 46.10899999999999 to 47.50927999999999
2022-01-25 21:26:50.487 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 47.50927999999999 to 48.90955999999999
2022-01-25 21:27:00.508 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 48.90955999999999 to 50.30969999999999
2022-01-25 21:27:10.457 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 50.30969999999999 to 51.709979999999995
2022-01-25 21:27:20.454 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'hvacregister_PID_IINSPECTOR' changed from 51.709979999999995 to 53.11026

I created additionally some screenshots from the data diagrams. As in the diagrams shown the error was positive since 17:07, so the I-part should increase since then, but it stayed at -2000 till I did the manual RESET.
As I understand it correctly, the I part should increase when the error is positive:

Lines 56 and 57:

// integral calculation
integralResult += error * lastInvocationMs / loopTimeMs;

I-Inspector Item:

Error-Inspector Item:

@fwolter
I have a problem with the PID controller regarding the RESET function.

I am using several instances of the PID controller, each controlling a TRV. One of the instances is no longer responding to RESET commands on the CommandItem. This is causing a large negative I value to accumulate. I can see the RESET being sent correctly in the log, but the I value does not reset (I know it doesn’t normally show in the inspector item until the next cycle, but it is not resetting at all now.

I suspect there may be an intermittent bug in the part of code that handles RESET requests, that can cause it to become unresponsive over time. It has been working fine for several weeks since last OH restart and has only just started to show the issue.

I am using the latest OH3 Release version (not the recent one you have made).

@fwolter /@Morgano - I thought I have bug in my rules but apparently I see same issue.

I was restarting OH some time ago and I thought it has solve it.

The value “RESET” stays there and is not picked Up.

The behaviour I am getting is slightly different - I’m seeing the command item RESET get set back to NULL by the PID controller instance as expected, but the internal ‘I’ value does not get reset.

This started happening on one of the five PID controller instances in my system. Restarting OH fixes the problem but I suspect it will happen again.

Actually, looking at this again, what I am seeing is that my PID controller command items are getting stuck at “RESET” like yours @Dominik_Jeziorski. I can imagine a scenario where, if the PID controller misses a RESET command for whatever reason, it will never get set back to NULL. From that point onwards, even if my rules set the command item to RESET, the PID controller will not see it. I presume the PID controller is looking for a change in the command item string before it processes it.

As a workaround I have created a regular task that sets my PID command items to “”. This way when I later set it to RESET, the PID controller will see it.