RTR plug-in

Providing a room temperature regulator

plugin.yaml

rtr:
    class_name: RTR
    class_path: plugins.rtr
    # default_Kp: 10 # Proportional gain
    # default_Ki: 15 # Integral gain

Description of the attributes:

  • default_Kp: change default value for Kp (optional, default: 10)

  • default_Ki: change default value for Ki (optional, default: 15)

  • cycle_time: (optional, default: 60)

  • defaultBoostTime: (optional, default: 240)

  • defaultOnExpiredTimer: (optional, default: True)

items.yaml

Three items need to be assigned rtr_current, rtr_setpoint and rtr_actuator. The attributes each are assigned an integer index. The same index shows that the items belong to the same controller.

But we have now a lot of optional attributes to custumize our controller from global defaults, read below.

Required attributes:

rtr_current

This attribute marks the item with an integer index as a provider for the current value (e.g. measured temperature) In the example below it is the item gf.floor.temp

rtr_setpoint

This attribute marks the item as a provider for the setpoint value (e.g. the wanted temperature in a room). In the example below it is the item gf.floor.temp.set

rtr_actuator

This attribute marks the item as a receiving one for the value to be sent to the actuator. In the example below it is the item gf.floor.temp.state

Optional attributes

rtr_Kp, rtr_Ki

With those you can define different Kp and/or Ki values to your controller, which override the global default from default_Kp/default_Ki.

The attributes are only valid on the same item, where rtr_current is defined and belongs to that controller.

rtr_stops

This attribute can be used to define a item as a stop/pause trigger of the given controller(s). When the value of the Item changes to on/true the controller(s) stops execution and set the item of rtr_actuator to 0, till the value changes back to off/false.

The attributes can only be set on a Item of type Bool. You can add muliple Items to one controller and also one Item to multiple controllers

rtr_temp_default, rtr_temp_boost, rtr_temp_boost_time, rtr_temp_drop

They are for a new way, to handle 3 different temperature modes:

First we have a default room temperature, lets say 21 °C

This is set with rtr_temp_default = 21

Now when we want to boost the temperature for a special event or what ever you can imagine, you can set the temperature manually to a higher value and hope you dont forget to set it back.

Or u use the boost function of this plugin, to set the temperature to your predefinied value of 23 °C. The Boost function will also handle for you a timer, when the temperature will be set back (lets say in 3 hours) to the predefinied default temperature.

For this set rtr_temp_boost = 23. The end time, where the value will be set back to Default is defined in minutes. We can use the global attribute defaultBoostTime or you set a individual time with rtr_temp_boost_time.

For those finding this is not flexible enough: The function boost() can also be called with a individual end time. So you can as an example create multiple logics with individual times and bind them to extra items to trigger them.

Now at least we have the third temperature mode drop. With it you can build as example a away mode or night reduction where you want to set the reduced temperature to maybe 19 °C.

So u set rtr_temp_drop = 19

The drop() function has not per default a timer, like the boost() function. But you can also pass a datetime value to the drop()-function, to set the time, when the temperature should be set back to default.

The importent thing is, that a created scheduler will survice a restart of smarthome, that the temperature will also be set back to default, when your computer reboots.

To achieve this, the plugins stores the unix timestamp of the timers end in a file under base_dir + ‚/var/rtr/timer/‘, to restore it at startup.

The attributes are only valid on the same item, where rtr_setpoint is defined and belongs to that controller.

For more info about the functions contine reading.

rtr_hvac_mode

The rtr_hvac_mode can be connected to a item, to trigger/read the 3 new modes (default/boost/drop) and get the currently mode set. It implements the KNX DPT 20.102.

Set the item value to

  • 1 to trigger the boost function of the controller

  • 2 to trigger the default function of the controller

  • 3 to trigger the drop function of the controller

  • 4 is currently not implemented and sets the controller back to default

Example

The following shows an simple example for a working.

gf:

    floor:

        temp:
            name: Temp
            type: num
            knx_dpt: 9
            knx_send: 4/2/120
            knx_reply: 4/2/120
            ow_addr: 28.52734A030000
            ow_sensor: T
            rtr_current: 1

            set:
                type: num
                visu: 'yes'
                cache: 'On' # this can be importent, or your defined setpoint get lost after restarts
                knx_dpt: 9
                knx_send: 4/3/120
                knx_listen: 4/3/120
                rtr_setpoint: 1

            state:
                type: num
                visu: 'yes'
                knx_dpt: 9
                knx_send: 4/1/120
                knx_listen: 4/1/120
                rtr_actuator: 1

        door:
            name: Frontdoor
            open:
                rtr_stops:
                  - '1'
                  - '2'

    room1:
        temp:
            name: Temp
            type: num
            knx_dpt: 9
            knx_send: 4/2/130
            knx_reply: 4/2/130
            ow_addr: 28.52432A030000
            ow_sensor: T
            rtr_current: 2

            set:
                type: num
                visu: 'yes'
                cache: 'On' # this can be importent, or your defined setpoint get lost after restarts
                knx_dpt: 9
                knx_send: 4/3/130
                knx_listen: 4/3/130
                rtr_setpoint: 2

            state:
                type: num
                visu: 'yes'
                knx_dpt: 9
                knx_send: 4/1/130
                knx_listen: 4/1/130
                rtr_actuator: 2

        window:
            name: Window
            open:
                rtr_stops:
                  - '2'

logic

To define items which trigger the default(), boost() or drop() function, you can use the item attribute rtr_hvac_mode or you can start to use a logic and bind the watch item(s) to that logic.

For that I made the following logic, which you can take as an example:

src = trigger['source']
logger.info("triggerd by {}".format(src))
src_item = sh.return_item(src)

if src_item is not None and src_item():
    parent_item = src_item.return_parent()
    src_item_name = src_item.id().replace("{}.".format(parent_item.id()), "")
    logger.debug("extracted item name {}".format(src_item_name))

    src_item_parts = src_item_name.split('_')
    if len(src_item_parts) == 3:
        m = 0
        st = src_item_parts[2]
        if st.find("h") > 0:
            num = st.replace("h", "")
            if num.isnumeric():
                m = int(num) * 60
        elif st.find("m") > 0:
            num = st.replace("m", "")
            if num.isnumeric():
                m = int(num)
        else:
            logger.error("time is invalid for this logic!")

        if m > 0 or src_item_parts[0] == "default":

            items = []
            if src_item_parts[1] == "all":
                for item in sh.find_items('rtr_current'):
                    items.append(item)
            else:
                for item in sh.match_items('*.'+src_item_parts[1]+'.*:rtr_current'):
                    items.append(item)

            edt = sh.now() + datetime.timedelta(minutes=m)
            if src_item_parts[0] == "default":
                for item in items:
                    sh.rtr.default(item.conf["rtr_current"])
            elif src_item_parts[0] == "boost":
                for item in items:
                    sh.rtr.boost(item.conf["rtr_current"], edt)
            elif src_item_parts[0] == "drop":
                for item in items:
                    sh.rtr.drop(item.conf["rtr_current"], edt)
        else:
            logger.error("time of 0 is invalid for this logic!")
    else:
        logger.error("item name is invalid for this logic!")

Than I created the follow items:

central:

    heater:
        sv_page: overview
        sv_img: sani_heating.svg
        sv_overview: heater

        sv_heading_left: "Boost for <span data-role='controlgroup' data-type='horizontal'>{{ basic.stateswitch('bz1', '.boost_all_3h', '', 1, 'sani_heating_temp', '3h', '', 'icon1') }}{{ basic.stateswitch('bz2', '.boost_all_5h', '', 1, 'sani_heating_temp', '5h', '', 'icon1') }}</span>"
        sv_heading_center: "{{ basic.stateswitch('nz1', '.default_all_0h', '', 1, 'sani_heating_temp', 'Normal', '', 'icon1') }}"
        sv_heading_right: "Drop for <span data-role='controlgroup' data-type='horizontal'>{{ basic.stateswitch('dz1', '.drop_all_3h', '', 1, 'sani_heating_temp', '3h', '', 'icon1') }}{{ basic.stateswitch('dz2', '.drop_all_5h', '', 1, 'sani_heating_temp', '5h', '', 'icon1') }}</span>"

        default_all_0h:
            type: bool
            visu_acl: rw
            enforce_updates: 'yes'

        boost_all_3h:
            type: bool
            visu_acl: rw
            enforce_updates: 'yes'

        boost_all_5h:
            type: bool
            visu_acl: rw
            enforce_updates: 'yes'

        drop_all_3h:
            type: bool
            visu_acl: rw
            enforce_updates: 'yes'

        drop_all_5h:
            type: bool
            visu_acl: rw
            enforce_updates: 'yes'

The logic extract the function name (default/boost/drop), destination items and runtime from the triggering item name. Because rtr->default() can’t have a datetime set, you must define 0d/0m in the name. Everything elso should be self explained and can/should be modified to your needs.