New Automation: PID Controller

@fwolter Thank you for your feedback.
I have replaced in all rules type: pidcontroller.action with core.ItemCommandAction.

Now the rule is active again.

triggers:
  - id: "1"
    configuration:
      input: KnxEGWohnzimmerIstTemp
      setpoint: KnxEGWohnzimmerSollTemp
      kp: 65
      kd: 0
      kdTimeConstant: 1
      commandItem: cInspectorLivingRoom
      ki: 0.2
      loopTime: 600000
    type: pidcontroller.trigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      output: outputLivingRoom
      pInspector: pInspectorLivingRoom
      iInspector: iInspectorLivingRoom
      dInspector: dInspectorLivingRoom
      eInspector: eInspectorLivingRoom
    type: core.ItemCommandAction
1 Like

@george.erhan There’s a use case for battery powered heating valve actuators to update the output less frequently, when the setpoint is reached to save battery. Maybe there are other use cases where minor changes to the output should be avoided. Are there any PID mechanisms we can implement in this PID controller to support this use case? It seems I’m missing the correct search terms to find anything useful on this topic concerning control theory. Can you point me in the right direction?

Hi, I was just upgrading my whole solution to new instance of OH 3.1 - I saw that PID is now added to default plugin list but there seem to be changes compared to previous implementation.

It took me some time to figure it out - AFAIK:

  • output changed to itemName
  • pidcontroller.action → core.ItemCommandAction

Where there any other changes?

PS. Next time it would be nice to add it somewhere to the official documentation. Probably rule sample (as text would also be a nice starting point)

PS2. Addon is not throwing any error if items for debugging are not existing but are placed in the rule (at least I think the rule was not executed at all)

Sample:

triggers:
  - id: "1"
    configuration:
      input: Filip_Virtual_Temperature
      setpoint: Filip_Desired_SetPoint
      kp: 65
      kd: 0
      kdTimeConstant: 1
      ki: 0.1
      loopTime: 60000
    type: pidcontroller.trigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      output: Filip_Desired_Dimmer
    type: pidcontroller.action

Would become

triggers:
  - id: "1"
    configuration:
      input: Filip_Virtual_Temperature
      setpoint: Filip_Desired_SetPoint
      kp: 65
      kd: 0
      kdTimeConstant: 1
      ki: 0.1
      loopTime: 60000
    type: pidcontroller.trigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      itemName: Filip_Desired_Dimmer
    type: core.ItemCommandAction
1 Like

The change was done to a milestone release. It was mentioned here: New Automation: PID Controller - #91 by fwolter. Breaking changes to milestone releases are not announced separately, since it’s prototype code.

Would be awesome if you could add an example to the documentation!

I added a pull request logging an error message if an inspector Item doesn’t exist.

1 Like

Thanks I didn’t spotted it.

Regarding documentation - I’m planning to write a tutorial on how I have set up my heaters using your PID controller. I hope it would be enough documentation on possible approach. I was just surprised that my rules stopped working all of a sudden and tracking down the issue was hard as I couldn’t figure out what is wrong.

You (and possibly others) might take a look here → Set up house heating using Eurotronic Spirit actuators with PID control and "manual" control

Any suggestions are welcome.

1 Like

@fwolter
I’m having some trouble with the new version of PID controller after upgrading to openHAB Stable 3.1.0.

I have removed the 3.1.0-SNAPSHOT jar from the addons folder.

I don’t see any error messages in the log but the PID controller rule no longer responds to a ‘RESET’ command.

Here is one of my PID controller configs:

triggers:
  - id: "1"
    configuration:
      input: BedroomMultisensorSensorTemperature
      setpoint: BedroomTrvPidSetpoint
      kp: 100
      kd: 0
      kdTimeConstant: 1
      commandItem: BedroomTrvPidCommandItem
      ki: 0.5
      loopTime: 480000
    type: pidcontroller.trigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      output: BedroomTrvPidValvePosition
      pInspector: BedroomTrvPidPInspectorItem
      iInspector: BedroomTrvPidIInspectorItem
      dInspector: BedroomTrvPidDInspectorItem
      eInspector: BedroomTrvPidErrorInspectorItem
    type: pidcontroller.action

My ‘Reset’ rule looks like this:

rule "Bedroom TRV PID controller reset"
when
    Item BedroomTrvPidControllerResetScene changed to ON
then
    // reset PID controller
    logInfo("Bedroom", "Manual request, resetting Bedroom TRV PID controller")
   
    BedroomTrvPidCommandItem.sendCommand("RESET")
    BedroomTrvPidCommandItem.sendCommand("")
end

When it was working before I found I had to send an empty string after the ‘RESET’ otherwise it sticks on ‘RESET’ and the PID controller cannot see the change the next time it is run.

It seems you run a pre-3.1.0 version, if your posted config is working. You are using the action type pidcontroller.action which should be core.ItemCommandAction, now. Also, the inspector items must be configured within the trigger module. Your config before the edit looked better.

The issue with the self-resetting RESET command should have been fixed in 3.1.0.

@fwolter
Thanks for the info. I think I am closer, but it is still not working.

Part of the problem is that I had renamed the prototype JAR

org.openhab.automation.pidcontroller-3.1.0-SNAPSHOT.jar

to

org.openhab.automation.pidcontroller-3.1.0-SNAPSHOT.jar.old

in my

/usr/share/openhab/addons

directory but it was still loading it. I could see this by checking in the openHAB cli:

openhab-cli console

then running

bundle:list

The old PID controller add-on was still showing at the bottom of the list:

255 ? Active ?  75 ? 3.1.0                 ? openHAB Add-ons :: Bundles :: Transformation Service :: Map
256 ? Active ?  80 ? 3.1.0                 ? openHAB UI :: Bundles :: Basic UI
257 ? Active ?  80 ? 3.1.0                 ? openHAB UI :: Bundles :: HABPanel UI
258 ? Active ?  80 ? 3.1.0                 ? openHAB UI :: Bundles :: Icon Set :: Classic
259 ? Active ?  80 ? 3.1.0.202101141550    ? openHAB Add-ons :: Bundles :: Automation :: PID Controller

So I removed the JAR completely and restarted openHAB. I also modified my PID rules as below:

triggers:
  - id: "1"
    configuration:
      setpoint: BedroomTrvPidSetpoint
      iInspector: BedroomTrvPidIInspectorItem
      kp: 100
      pInspector: BedroomTrvPidPInspectorItem
      kdTimeConstant: 1
      dInspector: BedroomTrvPidDInspectorItem
      input: BedroomMultisensorSensorTemperature
      eInspector: BedroomTrvPidErrorInspectorItem
      kd: 0
      commandItem: BedroomTrvPidCommandItem
      ki: 0.5
      loopTime: 480000
    type: pidcontroller.trigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      itemName: BedroomTrvPidValvePosition
    type: core.ItemCommandAction

I now get the following error in the Rule:

HANDLER_INITIALIZING_ERROR
Missing handler 'pidcontroller.trigger' for module '1' 

It seems that the PID Controller add-on is not installed and I couldn’t see anywhere to install it in the GUI.

I tried clearing the cache:

sudo systemctl stop openhab
sudo rm -rf /var/lib/openhab/cache/*
sudo rm -rf /var/lib/openhab/tmp/*
sudo systemctl start openhab

but this has not helped.

You can install it under Settings/Automation, click on the plus symbol:

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?