The room card widget provides a quick overview for many states in one room and is fully configurable.
You can use a background image and you may use a header.
Color scheme and opacity is fully configurable for the columns.
This widget is part of my personal custom developed widget set, which is available on GitHub: openhab-conf/UI/widgets at main · florian-h05/openhab-conf · GitHub .
Data displayed
The widget can display up to three columns of data, each data field can and has to be configured:
Humidity and illumination
Current temperature, target temperature (in braces), heating & cooling state
Lights state (on/off + number of lights on), windows/doors (for each open/closed + number of open), one or two blinds position, speaker state
The widget was inspired by the cards of the location tab and credits for the basic concept go to @Integer at [OH3] Main UI Examples - #22 by Integer .
Screenshots
Changelog
The git history can be seen as a changelog: History for UI/widgets/florianh-widgetset/roomCard.yaml - florian-h05/openhab-conf · GitHub .
Resources
https://github.com/florian-h05/openhab-conf/raw/main/UI/widgets/florianh-widgetset/roomCard.yaml
4 Likes
Line 254 (actual temperature) should be
“=(items[props.temp].displayState ? items[props.temp].displayState : items[props.temp].state) + (props.settemp ? ’ (’ + items[props.settemp].state + ‘)’ : ‘’)”
instead of
“=(items[props.temp].displayState) + (props.settemp ? ’ (’ + items[props.settemp].displayState + ‘)’ : ‘’)”
in case of using innogy thermostat, but maybe on all other thermostats as well
@Andy_Eichhorst
Thanks for that tip.
I had no problems only using displayState
, but yeah, sometimes displayState
is not available, so I updated the whole widget to always fall back to state
when displayState
is not available.
1 Like
bkumio
(Mario)
January 2, 2023, 6:40pm
4
Hi Florian, all
I like your widget. Interesting for me to learn yaml code.
I do have a question on your last lines of code. Instead of opening a new “page” (which I could do of course) I would like to use the semantic model functionality like the one form the the standard “label cell” to open a group popup Item (actionGroupPopupItem) instead.
what I did was to replace your last lines of code se below.
Your stuff :
- component: oh-link
config:
action: navigate
actionPage: ='page:' + props.page
style:
height: 125px
left: 0px
position: absolute
top: 0px
width: 100%
visible: "=props.page ? true : false"
with my idea of using your “page” property to show the group as popup
- component: oh-link
config:
action: group
actionGroupPopupItem: props.page
expandable: false
item: props.page
stateAsHeader: true
title: props.page
But when I hover over the room card unfortunately the mouse pointer is not changing to a “hand” indicating that you can even “click the card”. despite the fact the nothing is happening
I am not a developer just an advanced OH user currently migrating from OH2.5 to v3.4 and learning on how to use the new pages concept…,If you have an idea let me know
bkumio
(Mario)
January 3, 2023, 10:28am
5
I think I found an example from AndrasU : Widgets
which does the trick.
If I understand correctly in addition to the props: parameters: he added a props: parameterGroups function which allows in the UI config to select the “group” function and then from the sematic model you select the group you want to have displayed as button popup (without the need to create an additional page) .
parameterGroups:
- name: buttonAction
context: action
label: Action
description: Action to start
with a subsequent oh-button action
- component: oh-button
config:
actionPropsParameterGroup: buttonAction
fill: false
style:
width: 100%
height: 100%
no-border: true
background: '=(props.backgroundImageUrl) ? "url(" + props.backgroundImageUrl + ")" : (props.colorCodeTop_d) ? (props.colorCodeTop_d) : "#AFDFFF"'
background-size: cover
class:
- no-padding
The design of the card itself is as everyone wants to configure but I quite like it…
So thanks Andras, I am learning ervery day
bkumio
Yes, thats quite practical. Most of my widgets actually use the action configuration via the parameter group in the UI, but my room card doesn‘t as I only use pages with it‘s action.
I would do it as following, but I guess it does the same as your modification:
- name: widgetAction
context: action
label: Action settings
description: Action to perform when the widget is clicked
- component: oh-link
config:
actionPropsParameterGroup: widgetAction
style:
height: 125px
left: 0px
position: absolute
top: 0px
width: 100%
@bkumio BTW: I have a full custom widgetset, you can find it on GitHub: openhab-conf/UI/widgets at main · florian-h05/openhab-conf · GitHub .
Dom_KS
(Dom KS)
January 28, 2023, 4:40pm
7
Hello!
Great widget! Is there a chance that you add custom items ex. item one … /icon off … / icon on ?
I would add TV/PS4/AV or NestHub.
Unfortunately I‘ve no idea how to do that: dynamically adding custom items with custom icons. If you have an idea, please let me know.
Note that you can install from the marketplace and then modify the widget to your needs.
Dom_KS
(Dom KS)
January 28, 2023, 8:26pm
9
Yes! I mod it!
I added:
TV
Settop box (android/sattelite etc.)
Changed speaker icon to hifi speaker ( home cinema)
Console
Google speaker
Should or can I post it here?
1 Like
Feel free to post here if you want to, I will see if I add those to the widget. (Note that I cannot add all icons/Items that people use, because then the widget would end up getting huge. I mean, everyone can add anything he wants to to the widget and further customize it.)
My „problem“ with the hifispeaker icon is, that there is no icon version to display the off state. How do you handle that state? Hide the icon?
Same goes for the console icon.
Dom_KS
(Dom KS)
February 1, 2023, 10:28am
11
I just add next items and icons. I don’t have binds so it isn’t displayed.
For ON state i use filled (black) icons for OFF white ones.
uid: roomCard_max
tags:
- community.openhab.org
- florianh-widgetset
props:
parameters:
- description: Title to display in upper right corner
label: Header
name: text_header
required: false
type: TEXT
- description: web address of background image
label: Background image
name: image
required: false
type: TEXT
- default: black
description: HEX, rgba or name, e.g. white or black
label: Background color
name: bgcolor
required: true
type: TEXT
- default: "0.6"
description: decimal, e.g. 0.6
label: Background opacity
name: bgopacity
required: true
type: TEXT
- default: white
description: icon & text color, e.g. black or white
label: Icon & text color
name: color
required: true
type: TEXT
- description: Page which will be navigated to
label: Page ID
name: page
required: false
- context: item
description: item/group for light(s)
label: Light(s) item
name: light
required: false
type: TEXT
- context: item
description: Group:Number:COUNT(ON) item for numbers of lights on
label: Number of lights on
name: lights_number
required: false
type: TEXT
- context: item
description: item for windows(s)
label: Window(s) item
name: window
required: false
type: TEXT
- context: item
description: Group:Number:COUNT(CLOSED) item for numbers of windows open
label: Number of windows open
name: windows_number
required: false
type: TEXT
- context: item
description: item for temperature
label: Temperature item
name: temp
required: false
type: TEXT
- context: item
description: item for set temperature
label: Set temperature item
name: settemp
required: false
type: TEXT
- context: item
description: item for blinds
label: Blind(s) item
name: blinds
required: false
type: TEXT
- context: item
description: item for blinds
label: Blind 2 item
name: blinds2
required: false
type: TEXT
- context: item
description: item for heating state
label: Heating state item
name: heating
required: false
type: TEXT
- context: item
description: item for cooling state
label: Cooling state item
name: cooling
required: false
type: TEXT
- context: item
description: item for humidity
label: Humidity item
name: humidity
required: false
type: TEXT
- context: item
description: item for illuminance
label: Illuminance item
name: illuminance
required: false
type: TEXT
- context: item
description: item for door state(s)
label: Door state(s)
name: door_state
required: false
type: TEXT
- context: item
description: item for door lock(s)
label: Door lock(s)
name: door_lock
required: false
type: TEXT
- context: item
description: Item for garagedoor state(s)
label: Garagedoor state(s)
name: garagedoor_state
required: false
type: TEXT
- context: item
description: item for TV
label: TV(s) item
name: tv
required: false
type: TEXT
- context: item
description: item for TV Box
label: TV Box item
name: tvbox
required: false
type: TEXT
- context: item
description: item for speaker(s)
label: Speaker(s) item
name: speaker
required: false
type: TEXT
- context: item
description: item for gaming console
label: Gaming console
name: console
required: false
type: TEXT
- context: item
description: item for Google speaker
label: Google speaker
name: google_speaker
required: false
type: TEXT
timestamp: Jan 28, 2023, 9:14:40 PM
component: f7-card
config:
style:
--f7-chip-bg-color: rgba(255, 255, 255, 0.0)
--f7-chip-height: 22px
--f7-chip-padding-horizontal: 10px
--f7-chip-text-color: =props.color
background-image: ='url(' + props.image + ')'
background-position: center
background-size: cover
border-radius: var(--f7-card-expandable-border-radius)
box-shadow: 5px 5px 10px 1px rgba(0,0,0,0.1)
class:
- padding: 0px
height: 130px
margin-left: 5px
margin-right: 5px
noShadow: false
slots:
content:
- component: f7-block
config:
style:
background: =props.bgcolor
border-radius: 7px
opacity: =props.bgopacity
position: absolute
right: 16px
top: -5px
visible: "=props.text_header ? true : false"
slots:
default:
- component: Label
config:
style:
color: =props.color
font-size: 20px
font-weight: 600
margin-left: 0px
margin-top: 0px
text: =props.text_header
- component: f7-block
config:
style:
background: =props.bgcolor
border-radius: 7px
bottom: -75px
left: 16px
opacity: =props.bgopacity
position: absolute
slots:
default:
- component: f7-chip
config:
iconColor: =props.color
iconF7: "=items[props.light].state == 'ON' ? 'lightbulb_fill' : 'lightbulb_slash'"
iconSize: 18
text: "=props.lights_number ? ((items[props.light].state == 'ON') ? items[props.lights_number].state : '') : ''"
visible: "=props.light ? true : false"
- component: f7-chip
config:
visible: "=props.garagedoor_state ? true : false"
slots:
media:
- component: oh-icon
config:
icon: "=items[props.garagedoor_state].state === 'CLOSED' ? 'mygaragedoor-closed' : 'mygaragedoor-open'"
iconSize: 24
style:
height: 24px
- component: f7-chip
config:
visible: "=props.door_state ? true : false"
slots:
media:
- component: oh-icon
config:
icon: "=items[props.door_state].state === 'CLOSED' ? 'door-closed' : 'door-open'"
iconSize: 24
style:
height: 24px
- component: f7-chip
config:
text: "=(items[props.window].state == 'OPEN') ? (props.windows_number ? items[props.windows_number].state : '') : ''"
visible: "=props.window ? true : false"
slots:
media:
- component: oh-icon
config:
icon: "=items[props.window].state === 'CLOSED' ? 'window-closed' : 'window-open'"
iconSize: 24
style:
height: 24px
- component: f7-chip
config:
iconColor: =props.color
iconF7: "=items[props.door_lock].state === 'ON' ? 'lock_open' : 'lock'"
iconSize: 18
visible: "=props.door_lock ? true : false"
- component: f7-chip
config:
iconColor: =props.color
iconF7: arrow_up_arrow_down
iconSize: 18
text: "=props.blinds2 ? items[props.blinds].state + ' | ' + items[props.blinds2].displayState : items[props.blinds].displayState"
visible: "=props.blinds ? true : false"
- component: f7-chip
config:
iconColor: =props.color
iconF7: "=items[props.tv].state === 'ON' ? 'tv_fill' : 'tv'"
iconSize: 18
visible: "=props.tv ? true : false"
- component: f7-chip
config:
iconColor: =props.color
iconF7: "=items[props.tvbox].state === 'ON' ? 'ticket_fill' : 'ticket'"
iconSize: 18
visible: "=props.tvbox ? true : false"
- component: f7-chip
config:
iconColor: =props.color
iconF7: "=items[props.speaker].state === 'ON' ? 'hifispeaker_fill' : 'hifispeaker'"
iconSize: 18
visible: "=props.speaker ? true : false"
- component: f7-chip
config:
iconColor: =props.color
iconF7: "=items[props.console].state === 'ON' ? 'gamecontroller_fill' : 'gamecontroller'"
iconSize: 18
visible: "=props.console ? true : false"
- component: f7-chip
config:
iconColor: =props.color
iconF7: "=items[props.google_speaker].state === 'ON' ? 'logo_google' : 'nosign'"
iconSize: 18
visible: "=props.google_speaker ? true : false"
- component: f7-block
config:
style:
background: =props.bgcolor
border-radius: 7px
bottom: -45px
left: 16px
opacity: =props.bgopacity
position: absolute
slots:
default:
- component: f7-chip
config:
iconColor: =props.color
iconF7: thermometer
iconSize: 18
text: "=(items[props.temp].displayState ? items[props.temp].displayState : items[props.temp].state) + (props.settemp ? ' (' + (items[props.settemp].displayState ? items[props.settemp].displayState : items[props.settemp].state) + ')' : '')"
visible: "=props.temp ? true : false"
- component: f7-chip
config:
iconColor: =props.color
iconF7: flame
iconSize: 18
visible: "=props.heating ? items[props.heating].state === 'ON' : false"
- component: f7-chip
config:
iconColor: =props.color
iconF7: circle_grid_hex
iconSize: 18
visible: "=props.cooling ? items[props.cooling].state === 'ON' : false"
- component: f7-block
config:
style:
background: =props.bgcolor
border-radius: 7px
bottom: -15px
left: 16px
opacity: =props.bgopacity
position: absolute
slots:
default:
- component: f7-chip
config:
iconColor: =props.color
iconF7: drop
iconSize: 18
text: "=items[props.humidity].displayState ? items[props.humidity].displayState : items[props.humidity].state"
visible: "=props.humidity ? true : false"
- component: f7-chip
config:
iconColor: =props.color
iconF7: sun_min
iconSize: 18
text: "=items[props.illuminance].displayState ? items[props.illuminance].displayState : items[props.illuminance].state"
visible: "=props.illuminance ? true : false"
- component: oh-link
config:
action: navigate
actionPage: ='page:' + props.page
style:
height: 125px
left: 0px
position: absolute
top: 0px
width: 100%
visible: "=props.page ? true : false"
Dom_KS
(Dom KS)
February 1, 2023, 10:49am
12
Do you know how I can hide icons? It could be interesting.
Dom_KS
(Dom KS)
February 4, 2023, 9:02pm
13
Is there a possibility that click on the widget navigates to location ex. Livingroom ?
IMO the other way (black for off, on for white) makes more sense, but that’s up to you You can modify the widget in any way you want.
Yes, the widget actually already does this for all icons if the corresponding Item is not set.
Just set the visible
parameter of the f7-chip
to an expression like:
"=items[props.someitem].state === 'ON' ? true : false"
This will display the icon if the Item defined in the someitem property has the state ON
and hide the icon for all other Item states. Note that for the existing f7-chip
s you need to extend the expression because it already covers the case that an Item property is not set.
AFAIK no, there is no way to navigate to the auto-generated page of a semantic location (if you mean that).