Heating control by using PID controller

Platform Information:
Hardware: Raspberry Pi 4
Operating system: openhabian
openHAB Version: openHAB 3.2.0 - Release Build
Temperature sensors: Shelly H&T
Actuator: Möhlenhoff Alpha 5, controlled with Shelly 2.5

Problem of the topic:
In my house with underfloor heating, I would like to be able to monitor and adjust the temperature of each room individually using Main UI. For this purpose I would like to use a PID controller.

Since the PID controller rule integrated in OpenHAB is still relatively new, I haven’t found any beginner-friendly examples yet. I have tried to fill everything in as good as possible, but am failing and I don’t know why. I hope someone can put me on the right track.

The actuator is normally closed.so if the PID Controller triggers, the command ON should be sent to the Shelly and the valve should open.
But no matter what setpoint I enter, the actuator is always open.
image

Any ideas, hints, help or further ideas on how I could program the underfloor heating are greatly appreciated.

Hi D00mi,

issue is caused by the output of the PID-Controller. This is a numeric value and not an ON/OFF state. If you have a heating valve which just supports ON/OFF state you need to combine the PID-Controller with a PWM output (Pulse Width Modulation (PWM) Automation - Automation | openHAB). Do not forget to limit the PID-Controller output to a range of [0-100%].

Regards,
Matthias

hi Matthias,
one question… is it enough to set the output (the send command in the first picture) to the valve dimmer item of a heating regulator?

Hello,
I´m quite new to OH and just found this thread. I´d also like to control my underfloor heating using the PID module together with the PWM module. My actuator can only be switched ON and OFF and has a deadtime of ~2min.
Can anyone of you help me with this?

Another question:
How can the Cell from the first post be created? (Büro 23.9°C with target temp. setting arrows)

I´d be glad to get any hint of how I can proceed with these topics.
Many thanks in advance!
Cheers, Andre

Hello Matthias

Thank you for your answer. Unfortunately, I still haven’t managed it (I gave up in frustration and now want to try again).
I understand why it didn’t work, but I don’t know how to combine the PID controller with the PWM output.
What I have currently tried:
I have set the current temperature (Number:Temperature) and the setpoint (Number:Temperature). So far I think the part “PID Controller Trigger” is understood.
But now I am failing with the PID output.
What and how exactly do I have to set here?
If I understand correctly, I need a PID output item, which is written in the “Then” part with either “Update an Item State” or “Send a command” (neither seems to work for me).
This PID output item is then read back into the PWM as a DutyCycleItem and then sent as an output directly to the actuator with the Command On.
However, this does not work either.
Can you possibly give me another hint? As you can see, I am not a very good programmer. I hope for a beginner-friendly hint :wink:

Thank you in advance and kind regards

I didn’t write the widget myself and unfortunately I can’t find the source after a year. That’s why I can’t give the right credits to the author.
Nevertheless, the widget looks like this:

uid: Heizungssteuerung
tags: []
props:
  parameters:
    - description: Small title on top of the card
      label: Title
      name: title
      required: false
      type: TEXT
    - description: Icon on top of the card (only f7 icons (without f7:))
      label: Icon
      name: icon
      required: false
      type: TEXT
    - description: in rgba() or HEX or empty
      label: Background Color
      name: bgcolor
      required: false
      type: TEXT
    - context: item
      label: Current Temperature
      name: temp_item
      required: false
      type: TEXT
    - context: item
      label: Set Temperature
      name: set_temp_item
      required: false
      type: TEXT
    - context: item
      label: Current Humidity
      name: humidity_item
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Apr 20, 2022, 2:03:32 PM
component: f7-card
config:
  style:
    background-color: "=props.bgcolor ? props.bgcolor : ''"
    border-radius: var(--f7-card-expandable-border-radius)
    box-shadow: 5px 5px 10px 1px rgba(0,0,0,0.1)
    height: 120px
    margin-left: 5px
    margin-right: 5px
    noShadow: false
    padding: 0px
slots:
  content:
    - component: f7-block
      config:
        style:
          display: flex
          flex-direction: row
          left: 16px
          position: absolute
          top: -5px
      slots:
        default:
          - component: f7-icon
            config:
              f7: =props.icon
              size: 18
              style:
                margin-right: 10px
              visible: "=props.icon ? true : false"
          - component: Label
            config:
              style:
                font-size: 12px
                margin-top: 0px
              text: "=props.title ? props.title : ''"
    - component: f7-block
      config:
        style:
          bottom: -20px
          flex-direction: row
          left: 16px
          position: absolute
      slots:
        default:
          - component: Label
            config:
              style:
                font-size: 22px
                font-weight: 400
                margin-left: 0px
                margin-top: 0px
              text: "=items[props.temp_item].displayState ? items[props.temp_item].displayState : items[props.temp_item].state"
    - component: f7-block
      config:
        style:
          bottom: -40px
          display: flex
          flex-direction: row
          left: 12px
          position: absolute
      slots:
        default:
          - component: f7-icon
            config:
              f7: drop
              size: 18
              visible: "=props.humidity_item ? true : false"
          - component: Label
            config:
              style:
                font-size: 12px
                margin-left: 5px
                margin-top: 0px
              text: =items[props.humidity_item].displayState
              visible: "=props.humidity_item ? true : false"
    - component: oh-button
      config:
        action: command
        actionCommand: =Number(items[props.set_temp_item].state.split(' ')[0]) + 0.5
        actionItem: =props.set_temp_item
        iconColor: red
        iconF7: arrow_up_circle
        iconSize: 35
        style:
          background: transparent
          height: 35px
          position: absolute
          right: 10px
          top: 12px
        visible: "=props.set_temp_item ? true : false"
    - component: oh-button
      config:
        action: command
        actionCommand: =Number(items[props.set_temp_item].state.split(' ')[0]) - 0.5
        actionItem: =props.set_temp_item
        iconColor: red
        iconF7: arrow_down_circle
        iconSize: 35
        style:
          background: transparent
          height: 35px
          position: absolute
          right: 10px
          top: 74px
        visible: "=props.set_temp_item ? true : false"
    - component: Label
      config:
        style:
          font-size: 12px
          position: absolute
          right: 15px
          top: 50px
        text: =items[props.set_temp_item].state
        visible: "=props.set_temp_item ? true : false"
    - component: f7-block
      config:
        style:
          height: 120px
          left: 15px
          position: absolute
          top: 15px
          width: "=props.set_temp_item ? 'calc(100% - 55px)' : '100%' "
      slots:
        default:
          - component: oh-trend
            config:
              style:
                --f7-theme-color-bg-color: transparent
                background: var(--f7-theme-color-bg-color)
                filter: opacity(30%)
                height: 100%
                left: 0px
                position: absolute
                top: 0px
                width: 100%
                z-index: 1
              trendGradient:
                - "#aa2b1d"
                - "#cc561e"
                - "#ef8d32"
                - "#beca5c"
              trendItem: =props.temp_item
    - component: oh-link
      config:
        action: analyzer
        actionAnalyzerChartType: day
        actionAnalyzerCoordSystem: time
        actionAnalyzerItems: "=props.set_temp_item ? [props.temp_item, props.humidity_item, props.set_temp_item, props.heating_item] : (props.humidity_item ? [props.temp_item, props.humidity_item] : [props.temp_item])"
        style:
          height: 120px
          left: 0px
          position: absolute
          top: 0px
          width: "=props.set_temp_item ? 'calc(100% - 55px)' : '100%' "

I hope this helps :slight_smile:

1 Like