Universal Radiator Control Card

Hello community! I’m trying to build a universal Radiator Control widget for every Radiator model.
This is the first release, so there could be some bugs or options to be fine tuned, so feel free to tell me what are issues you will find.
This widget looks into “Model” scheme, find some defined tags (described below) and automatically show/hide widget options.

First thing to be done is to configure a Group and set it as “RadiatorControl” in Semantic Class.

Then, you have to set:

Mode item as “Type” (String), “Semantic Class” (Control) and “Semantic Property” (Temperature);
Setpoint item, “Type” (Number:Temperature), “Semantic Class” (Setpoint) and “Semantic Property” (Temperature);
Temperature item as “Type” (Number:Temperature), “Semantic Class” (Measurement) and “Semantic Property” (Temperature);
Humidity item as “Type” (Number:Intensity), “Semantic Class” (Measurement) and “Semantic Property” (Humidity);

Maybe nothing too much different from the setup you already have.

Screenshots



Changelog

  • Added Humidity support for who have Nest Radiators device
  • Added displayState for temperature and setpoint items

Version 0.2

  • Added Humidity Graph and value label

Version 0.1

  • initial release

Resources

uid: Universal_Radiator_Card
tags: []
props:
  parameters:
    - context: text
      description: Temperature Equipment Group Name
      label: Temperature Equipment Group Name
      name: tempTitle
      required: false
      type: TEXT
    - context: item
      description: Temperature Equipment Group
      label: Temperature Equipment Group
      name: groupItem
      required: true
      type: TEXT
timestamp: Oct 5, 2022, 3:11:57 PM
component: f7-card
config:
  noShadow: false
  padding: false
  style:
    background: rgb(240, 240, 240)
    border-radius: var(--f7-card-expandable-border-radius)
    box-shadow: 5px 5px 15px 1px rgba(0,0,0,0.3)
    height: auto
    margin-left: 5px
    margin-right: 5px
    padding: 0px
slots:
  default:
    - component: f7-card-content
      config:
        style:
          height: auto
      slots:
        default:
          - component: oh-icon
            config:
              icon: iconify:ph:flame-duotone
              style:
                color: red
                position: absolute
                top: 25px
              width: 40px
          - component: f7-row
            config:
              style:
                margin-left: 50px
                margin-top: 0px
            slots:
              default:
                - component: Label
                  config:
                    style:
                      color: black
                      font-size: 15px
                      font-weight: 500
                    text: =props.tempTitle
          - component: f7-block
            config:
              style:
                display: flex
                justify-content: space-between
                margin-top: 0px
                margin-left: 35px
                width: 150px
            slots:
              default:
                - component: oh-repeater
                  config:
                    fetchMetadata: semantics,metadata,listWidget
                    filter: "(loop.tempItem.groupNames.indexOf(props.groupItem) >= 0) ? true : false"
                    for: tempItem
                    itemTags: Measurement,Temperature
                    sourceType: itemsWithTags
                  slots:
                    default:
                      - component: f7-chip
                        config:
                          style:
                            color: '=items[loop.tempItem.name].state >= "21" ? "red" : items[loop.tempItem.name].state >= "19" ? "black" : "blue"'
                            background: rgb(200,200,200)
                            font-weight: 500
                          text: "=items[loop.tempItem.name].displayState ? items[loop.tempItem.name].displayState : items[loop.tempItem.name].state"
                - component: oh-repeater
                  config:
                    filter: "(loop.setpointItem.groupNames.indexOf(props.groupItem) >= 0) ? true : false"
                    fetchMetadata: semantics,metadata,listWidget
                    sourceType: itemsWithTags
                    itemTags: Setpoint,Temperature
                    for: setpointItem
                  slots:
                    default:
                      - component: f7-chip
                        config:
                          style:
                            background: transparent
                            color: red
                            font-weight: 500
                          text: '=items[loop.setpointItem.name].displayState ? items[loop.setpointItem.name].displayState : items[loop.setpointItem.name].state == "UNDEF" ? "Not set" : items[loop.setpointItem.name].state'
                - component: oh-repeater
                  config:
                    filter: '(loop.humidityItem.groupNames.indexOf(props.groupItem) >= 0) ? true : false'
                    fetchMetadata: semantics,metadata,listWidget
                    sourceType: itemsWithTags
                    itemTags: Measurement,Humidity
                    for: humidityItem
                  slots:
                    default:
                      - component: f7-chip
                        config:
                          style:
                            background: transparent
                            color: blue
                            font-weight: 500
                          text: '=items[loop.humidityItem.name].displayState ? items[loop.humidityItem.name].displayState : items[loop.humidityItem.name].state ? items[loop.humidityItem.name].state : ""'
          - component: f7-row
            config:
              style:
                margin-top: 3%
            slots:
              default:
                - component: f7-col
                  config:
                    style:
                      width: 73%
                  slots:
                    default:
                      - component: oh-repeater
                        config:
                          fetchMetadata: semantics,metadata,listWidget
                          filter: "(loop.tempItem.groupNames.indexOf(props.groupItem) >= 0) ? true : false"
                          for: tempItem
                          itemTags: Measurement,Temperature
                          sourceType: itemsWithTags
                        slots:
                          default:
                            - component: oh-trend
                              config:
                                style:
                                  --f7-theme-color-bg-color: transparent
                                  background: var(--f7-theme-color-bg-color)
                                  filter: opacity(100%)
                                  margin-left: 40px
                                  margin-top: 5px
                                  z-index: 98
                                trendGradient:
                                  - red
                                  - black
                                trendItem: =loop.tempItem.name
                      - component: oh-repeater
                        config:
                          fetchMetadata: semantics,metadata,listWidget
                          filter: "(loop.humidityItem.groupNames.indexOf(props.groupItem) >= 0) ? true : false"
                          for: humidityItem
                          itemTags: Measurement,Humidity
                          sourceType: itemsWithTags
                        slots:
                          default:
                            - component: oh-trend
                              config:
                                style:
                                  --f7-theme-color-bg-color: transparent
                                  background: var(--f7-theme-color-bg-color)
                                  filter: opacity(100%)
                                  margin-left: 40px
                                  margin-top: 5px
                                  z-index: 98
                                trendGradient:
                                  - blue
                                  - black
                                trendItem: =loop.humidityItem.name
                - component: f7-col
                  config:
                    style:
                      width: 20px
                  slots:
                    default:
                      - component: oh-repeater
                        config:
                          filter: '((loop.modeItem.groupNames.indexOf(props.groupItem) >= 0) && (loop.modeItem.type=="String")) ? true : false'
                          fetchMetadata: semantics,metadata,listWidget
                          sourceType: itemsWithTags
                          itemTags: Control,Temperature
                          for: modeItem
                        slots:
                          default:
                            - component: oh-repeater
                              config:
                                filter: '((loop.setpointItem.groupNames.indexOf(props.groupItem) >= 0) && (loop.setpointItem.type=="Number:Temperature")) ? true : false'
                                fetchMetadata: semantics,metadata,listWidget
                                sourceType: itemsWithTags
                                itemTags: Setpoint,Temperature
                                for: setpointItem
                              slots:
                                default:
                                  - component: oh-button
                                    config:
                                      action: command
                                      actionCommand: =Number(items[loop.setpointItem.name].state.split(' ')[0]) + 0.5
                                      actionItem: =loop.setpointItem.name
                                      iconColor: red
                                      iconF7: arrow_up_circle
                                      iconSize: 30
                                      style:
                                        background: transparent
                                        height: 35px
                                        display: flex
                                        position: absolute
                                        right: 1%
                                        z-index: 98
                                      visible: '=items[loop.modeItem.name].state != "OFF" ? true : false'
                                  - component: oh-button
                                    config:
                                      action: command
                                      actionCommand: =Number(items[loop.setpointItem.name].state.split(' ')[0]) - 0.5
                                      actionItem: =loop.setpointItem.name
                                      iconColor: red
                                      iconF7: arrow_down_circle
                                      iconSize: 30
                                      style:
                                        background: transparent
                                        bottom: 5%
                                        height: 35px
                                        position: absolute
                                        right: 1%
                                        z-index: 98
                                      visible: '=items[loop.modeItem.name].state != "OFF" ? true : false'
    - component: oh-repeater
      config:
        filter: '((loop.modeItem.groupNames.indexOf(props.groupItem) >= 0) && (loop.modeItem.type=="String")) ? true : false'
        fetchMetadata: semantics,metadata,listWidget
        sourceType: itemsWithTags
        itemTags: Control,Temperature
        for: modeItem
      slots:
        default:
          - component: f7-card-footer
            config:
              style:
                background: rgb(255, 204, 204)
                border-radius: 0 0 var(--f7-card-expandable-border-radius) var(--f7-card-expandable-border-radius)
                height: auto
            slots:
              default:
                - component: f7-block
                  config:
                    style:
                      display: flex
                      justify-content: space-between
                      margin-top: 0px
                      padding: 0
                      width: 100px
                  slots:
                    default:
                      - component: oh-link
                        config:
                          action: options
                          actionItem: =loop.modeItem.name
                        slots:
                          default:
                            - component: f7-chip
                              config:
                                text: =loop.modeItem.label
                                style:
                                  color: white
                                  background: red

2 Likes

Hi @rubenfuser,

Firstly thanks very much for this cool widget!

I’ve got it set up and showing the following:

image

Now, I’m based in the UK using a Nest thermostat and this does not have a ‘Switch’ as such just an option to switch the heating on/off based on a ‘Mode’. Secondly, the ‘Setpoint’ and ‘Temperature’ do not seem to be using stateDescription that I’ve set as the metadata e.g.

%.1f %unit%

Any help would be greatly appreciated!

Many thanks,

hi! thank you for your opinion!
ok, try to post the setpoint and the temperature items when in “edit” mode from items list. i will have a look.

just use


text: =loop.tempItem.displayState ? loop.tempItem.displayState : loop.tempItem.state

1 Like

Again thank you for your help!
Tomorrow i will update the YAML with this :blush:
I have so much to learn,bit i’ll keep fighting :blush:

:+1:

Hi both,

@hmerk I tried your suggestion and in the editor I’m getting the following error:

Nested mappings are not allowed in compact mappings at line 82, column 33:

                          text: =loop.tempItem.displayState ? loop.tempItem.dis…
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^…

Thanks as always :slight_smile:

p.s. I ensured that the indentation was correct :slight_smile:

yes i’ve seen, add an ’ before = and one ’ at the end of the line…
or just replace the code with the one above (already updated) :slight_smile:

1 Like

@rubenfuser thanks for the update, I’ve done this and there is no longer an error but still seeing the same :frowning:

can you try this?

text: =loop.tempItem.displayState

If I just do that, I get the following from the widget editor:

image

yes i’m facing the same. seems that won’t recognize the .displayState but only .state

i’m checking

edit: ok got it. gimme some minutes to post new yaml.

1 Like

ok new YAML posted. can you try now?

1 Like

Perfecto - you’ve nailed it there!

The only thing remaining is from my original post; I do not have a ‘Switch’ item as such instead a ‘Mode’ that determines in the heating is on/off…I know this is specific to my nest application, would you have any thoughts on this matter?

Many thanks :slight_smile:

My first idea was to remove toggle and keep mode label always visible.
Maybe i can try to keep toggle but also keep visible mode label. After lunch i will try something different to be tried…

1 Like

Amazing - thank you so much @rubenfuser :slight_smile:

ok i’ve decided to keep footer visible always, and setpoint arrows visible only when radiator is NOT OFF.
Also setpoint value now is visible only when radiator is NOT OFF.
Already updated the YAML. let me know if it’s better now.

Last thing, if you want, you can try other Universal Widgets (Rollershutter and Conditioner)?
Just search in marktplace for “Universal” :slight_smile:
soon i will publish universal lights widget, Scene widget and maybe security widget…

1 Like

@rubenfuser you are a genius! That works perfectly fine for me! :smiley:

Thanks so much for amending so quickly - it is most appreciated!

I’ll be sure to check out the Rollershutter and Conditoner widget :slight_smile: Great work as always!

edit: just another thought; would it be possible to add another line on the graph to maybe show humidity?

1 Like

i’m happy to help who find interesting my things :wink:
yes it is possible, but let me think about it, because is not a technical issue, but not all thermostats have hiumidity sensor. and 'cause this should be “Universal”…
in the meanwhile i’ve update the YAML adding some color ideas for temperature color…

1 Like

Completely understand - if you choose to keep it without, I may pick your brains to add this into mine :smiley:

p.s. liking the new colours :slight_smile: