I’d guess that your item is not number then, isn’t it? Or at least it is formated as a ‘Number:Dimensionless’ - in that case you have to do:
'=(items.HM_WZ_Heizung_Humidity.state > "50 %") ? "green" : "red"'
I’d guess that your item is not number then, isn’t it? Or at least it is formated as a ‘Number:Dimensionless’ - in that case you have to do:
'=(items.HM_WZ_Heizung_Humidity.state > "50 %") ? "green" : "red"'
Hi @Jeevs
In case of the ‘oh-label-card’ the background is a config parameter, which only applies to the content part - if this is enough for your scenario, just put your background expression in the config-part.
Any other background styles get overwritten by the standard widget itself.
That doesnt work, too. The item is formated just as number, but has a pattern at meta description (i think this doesnt matter?).
It shouldn’t as the .state just takes the raw item state. Could you try to create this custom widget please and tell me what’s happening with the background and whats the title label:
uid: test
component: f7-card
config:
title: =items.HM_WZ_Heizung_Humidity.state
style:
background: '=(items.HM_WZ_Heizung_Humidity.state > 50) ? "green" : "red"'
Oh, and maybe it would be better to create a new topic for your problem as we spam this thread a bit too much with specific problems that doesn’t belong here…
At the seperate widget it works fine. After i added “style:” to the card-yaml it works fine, too.
Many thanks for your help!
Hi @RGroll
Yes, I’m using the ‘oh-label-card’. Not sure I quite understand that content part? Do you mean with the standard widget I can only change the background color of the text itself? Rather than the whole box?
This is my YAML for the widget:
component: oh-label-card
config:
title: Presence
item: Presence
background: "=(items.Presence.state == ON) ? '#4cd964' : '#ff3b30'"
icon: oh:presence
Thank you!
Can’t find a way to access the label of an item in custom widget.
Sorry if this have been answered already somewhere …
In the props section, I’m going to ask for some items, e.g.:
props:
parameters:
- context: item
label: PowerState Item
name: powerstateItem
required: true
type: TEXT
...
Later in the widget’s components, I’d like to access the items states but also sometimes the label of the item what I trying to interact with, e.g.:
slots:
default:
- component: Label
config:
text: = items[props.powerstateItem].label
… which is not working that way
What’s the intended way to access the label of an item for use in a widget?
Fiddling around with the new possibilities like others here, I’m searching for a way to specify the column width of f7-col item.
The code for this is:
config:
style:
border-radius: 20px
background-color: rgba(6,25,36)
--text-color: rgba(255,255,255,1)
slots:
default:
- component: f7-block
config:
class:
- padding
slots:
default:
- component: f7-row
config:
class:
- padding-top
slots:
default:
- component: f7-block
slots:
default:
- component: f7-row
slots:
default:
- component: f7-col
slots:
default:
- component: oh-image
config:
url: /static/icons/tv.svg
style:
width: 25px
- component: f7-col
slots:
default:
- component: Label
config:
text: ="TVAV Zimmer"
style:
color: var(--text-color)
font-size: 18px
line-height: 30px
text-align: right
white-space: nowrap
overflow: hidden
text-overflow: ellipsis
The column containing the tv.svg image I like to justify in width
component: f7-col
slots:
default:
- component: oh-image
config:
url: /static/icons/tv.svg
style:
width: 25px
Any suggestion is welcome.
Generally you could set the width of each column with the config parameter width:
as described here
But I think in your case it would be more usefull to get rid of the columns at all and just use the row where you align your contents in - something like:
component: f7-card
config:
style:
border-radius: 20px
background-color: rgba(6,25,36)
--text-color: rgba(255,255,255,1)
slots:
default:
- component: f7-block
config:
class:
- padding
slots:
default:
- component: f7-row
config:
style:
flex-wrap: nowrap
slots:
default:
- component: f7-icon
config:
f7: tv
size: 30
color: white
class:
- padding-right
- component: Label
config:
text: ="TVAV Zimmer"
style:
color: var(--text-color)
font-size: 18px
line-height: 30px
text-align: left
white-space: nowrap
overflow: hidden
text-overflow: ellipsis
Thank you!
These widgets look great. But how do I have to use the source code provided at GitHub - rgrollfitz/oh3-widgets ? I added them on the developer page and now I have them under “Personal Widgets”.
But I only have sliders and switches on the widget. Now I want to use them for thermostats, displaying actual temperature history as a graph in the background and setting the desired temperature. Plus, I would like to show the humidity. This is shown in the images above for the dimmer control, but what are the required settings?
Sorry for posting so many questions, but for me, this widget topic is quite confusing and beyond any experience… Thanks!
Hey @Tobi77
this was one of my first experiments with the YAML structure and wasn’t updated since - so there might be some missing parts in documentation as well as in function.
It was more a first proof-of-concept how standard components of the MainUI would fit into a custom widget. So please be indulgent
You can enable/disable every control-element using the widget-configuration.
There’s no support for graphs in this widget. It could be added but wouldn’t fit the look & feel very well - The used oh-trend
component isn’t very flexible regarding styling atm.
Setting the desired temperature is possible with one of the control-elements (like slider, stepper buttons and so on) after you’ve defined the item you want to control (also in the widget-configuration setting)
If I got you right you want to show 2 values in the widget at the same time - like for example current temperature
and humidity
- this also isn’t supported as it was planned as a very simplistic approch to control & show a single item (yet?!).
Added an example with the integration of the oh-trend
component below
I updated the widget, that you don’t have to define the liquid-background anymore (as it’s implemented as an encoded inline-svg now)
You can set the path to the ‘hero-image’ (the one in the top-right corner) also inside the widget-configuration. The standard path would be /static/brightness_icon.svg
which corresponds to the path /etc/openhab/html/
in your OH-setup. But as said, you can set any url here.
What exactly you mean with ‘include’? Putting it inside the widget so you don’t need to load any images from another server? If you want to, you can customize the code so it loads the encoded svg as css-attirbute (this converter might help you with that)
But it remains - this widget still serves more a proof-of-concept approach (and maybe some small real-life usecases) as it’s not finished. Maybe I’ll find time to make it more configurable (and usable) in the future - but this isn’t my first priority right now tbh.
Nevertheless I updated the widget a bit to make it at least a bit more accessible and cleaned up the configuration section…
uid: darkLiquid_card
tags:
- small
- dark
- custom
- liquid
props:
parameters:
- context: item
description: Set an item which you want to control
label: Item
name: item
required: false
type: TEXT
groupName: general
- label: Value symbol
description: The value symbol shown after the item-value
name: valueSymbol
required: false
type: TEXT
groupName: general
- description: valueSymbol high or low
label: Value symbol position
name: valueSymbolPos
required: false
type: BOOLEAN
groupName: general
advanced: true
- description: Set the lowest value, that your item can have. (<b>default:</b> 0)
label: Items MIN value
name: minValue
required: false
type: TEXT
groupName: general
- description: Set the highest value, that your item can have. (<b>default:</b> 100)
label: Items MAX value
name: maxValue
required: false
type: TEXT
groupName: general
- description: Show trend graph instead of liquid background
label: Trend graph
name: showTrend
required: false
type: BOOLEAN
groupName: general
- label: Headline text
name: headline
required: false
type: TEXT
groupName: header
- label: Subheadline text
name: subheadline
required: false
type: TEXT
groupName: header
- label: Hero icon image url
name: heroIcon
required: false
type: TEXT
groupName: images
- description: Activating Stepper element to control item which you selected above
label: Show stepper buttons
name: showStepper
required: false
type: BOOLEAN
groupName: controls
- description: Activating Toggle element to control item which you selected above
label: Show toggle
name: showToggle
required: false
type: BOOLEAN
groupName: controls
- description: Activating Slider element to control item which you selected above
label: Show slider
name: showSlider
required: false
type: BOOLEAN
groupName: controls
parameterGroups:
- name: general
label: General settings
description: Most important widget settings
- name: header
label: Header area
- name: controls
label: Control settings
description: Controls to manipulate your item-state (only use one of them)
- name: images
label: Images
timestamp: Jan 9, 2021, 11:43:36 AM
component: f7-block
config:
style:
position: relative
-ms-user-select: None
-moz-user-select: None
-webkit-user-select: None
user-select: None
class:
- no-padding
- no-margin
slots:
default:
- component: oh-image
config:
url: "=props.heroIcon ? props.heroIcon : ''"
style:
position: absolute
top: -15px
right: -10px
width: 100%
max-width: min(max(50px, 15vw), 80px)
z-index: 99
- component: f7-card
config:
style:
max-height: 200px
background-color: rgb(57,60,76)
border-radius: 20px
overflow: hidden
position: relative
slots:
default:
- component: oh-repeater
config:
visible: "=props.showTrend ? false : true"
sourceType: range
for: liquid
rangeStart: "=!props.minValue ? 0 : Number(props.minValue)"
rangeStop: "=!props.maxValue ? 100 : Number(props.maxValue)"
slots:
default:
- component: f7-block
config:
visible: =items[props.item].state == loop.liquid_idx
style:
background-image: url('data:image/svg+xml,%3C%3Fxml version="1.0" encoding="UTF-8" standalone="no"%3F%3E%3C!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"%3E%3Csvg width="100%25" height="100%25" viewBox="0 0 100%25 100%25" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;"%3E%3Cg transform="matrix(1,0,0,1.16583,0,-41.4573)"%3E%3Cpath d="M2100,51C1877.85,82.213 1653.26,55.095 1427.19,70.645C1309.15,78.764 1091.86,41.538 882.9,59.37C605.267,83.062 300.648,21.379 0,51L0,250L2100,250L2100,51Z" style="fill:url(%23_Linear1);"/%3E%3C/g%3E%3Cdefs%3E%3ClinearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2,-214.44,250,-1.71552,1149,250)"%3E%3Cstop offset="0" style="stop-color:rgb(255,136,0);stop-opacity:1"/%3E%3Cstop offset="1" style="stop-color:rgb(255,197,28);stop-opacity:1"/%3E%3C/linearGradient%3E%3C/defs%3E%3C/svg%3E%0A')
position: absolute
height: 100%
width: 100%
left: 0
bottom: "=Math.fround((Number(loop.liquid) - (!props.maxValue ? 100 : Number(props.maxValue))) * (100 / (!props.maxValue ? 100 : Number(props.maxValue) - (!props.minValue ? 0 : Number(props.minValue))))) + '%'"
z-index: 1
- component: f7-card-content
config:
style:
height: 100%
display: flex
flex-direction: column
position: relative
z-index: 999
slots:
default:
- component: f7-row
config:
style:
z-index: 999
slots:
default:
- component: f7-col
slots:
default:
- component: Label
config:
propsParameterGroup: header
text: '=(props.headline) ? props.headline : "Headline"'
style:
white-space: nowrap
text-overflow: ellipsis
overflow: hidden
display: block
width: 100%
color: rgba(255,255,255,1)
letter-spacing: .75px
font-size: min(max(14px, 4vw), 21px)
font-weight: 600
- component: Label
config:
actionPropsParameterGroup: header
text: '=(props.subheadline) ? props.subheadline : "Subheadline"'
style:
white-space: nowrap
text-overflow: ellipsis
overflow: hidden
color: rgba(255,255,255,.7)
letter-spacing: .75px
font-size: min(max(9px, 2.5vw), 12px)
- component: f7-row
config:
style:
z-index: 999
slots:
default:
- component: f7-col
config:
class: '=props.valueSymbolPos ? props.valueSymbolPos : "align-items-flex-end"'
style:
display: flex
justify-content: flex-start
position: relative
slots:
default:
- component: Label
config:
text: =items[props.item].state
style:
color: rgba(255,255,255,1)
text-shadow: 2px 2px rgba(0,0,0,.25)
font-size: min(max(32px, 9vw), 51px)
font-weight: 600
- component: Label
config:
text: =props.valueSymbol
style:
color: rgba(255,255,255,1)
text-shadow: 2px 2px rgba(0,0,0,.25)
font-size: min(max(21px, 5.75vw), 32px)
font-weight: 600
- component: f7-col
config:
style:
display: flex
align-self: center
justify-content: flex-end
align-items: flex-end
flex-direction: column
slots:
default:
- component: oh-icon
config:
icon: power
visible: =items[props.item].state === "0"
action: command
actionOptions: COMMAND
actionItem: =props.item
actionPropsParameterGroup: action
actionCommand: ON
width: 20
height: 20
style:
cursor: pointer
filter: invert()
- component: oh-icon
config:
icon: power
visible: =items[props.item].state > "0"
action: command
actionOptions: COMMAND
actionItem: =props.item
actionCommand: OFF
width: 20
height: 20
style:
cursor: pointer
filter: invert(14%) sepia(99%) saturate(7416%) hue-rotate(0deg) brightness(94%) contrast(114%)
- component: f7-row
slots:
default:
- component: f7-col
config:
class: '=props.alignActionLeft ? props.alignActionLeft : "justify-content-flex-end"'
style:
height: 28px
max-height: 28px
display: flex
slots:
default:
- component: oh-stepper
config:
class: '=props.showStepper ? props.showStepper : "display-none"'
raised: true
buttonsOnly: true
small: true
autorepeat: true
min: =props.minValue
max: =props.maxValue
step: 1
color: white
style:
list-style-type: none
item: =props.item
- component: oh-toggle
config:
class: '=props.showToggle ? props.showToggle : "display-none"'
color: yellow
item: =props.item
style:
align-self: flex-end
- component: oh-slider
config:
class: '=props.showSlider ? props.showSlider : "display-none"'
step: "1"
min: =props.minValue
max: =props.maxValue
item: =props.item
style:
align-self: flex-end
font-color: yellow
- component: oh-trend
config:
visible: "=props.showTrend ? true : false"
trendItem: =props.item
trendGradient:
- "#FFE7DD"
- "#FFD1BD"
style:
position: absolute
bottom: 0
left: 0
width: 100%
height: 100%
@RGroll Thanks, this is close to what I thought about. But for thermostat control, I would be very happy to
If I get it right, I can only adress one value in the widget for control and trend, right? Can this be split in the widget without causing too much work for you?
Sorry for putting so much work for you, but up to now, these proof-of-concepts are all that beginners like me have. A library (for dimmer, for thermostat) would be of really great help.
This is how i show the room temperatures and the humidity:
(Background is getting red, when humidity rises avove 60%)
component: oh-label-cell
config:
header: Wohnzimmer
item: HM_WZ_Heizung_ActTemp
trendItem: HM_WZ_Heizung_ActTemp
action: group
actionGroupPopupItem: WZ_Klima
icon: f7:thermometer
subtitle: =items.HM_WZ_Heizung_ActProfile.displayState
footer: = "Luftfeuchtigkeit " + items.HM_WZ_Heizung_Humidity.displayState
expandable: false
style:
background: '=(items.HM_WZ_Heizung_Humidity.state > 60) ? "red" : ""'
I created a group item for the heating in every room, so profiles or set temperature can be changed by clicking on the cell:
I’ve been trying to work through you version of the Chromecast widget and make sure I totally understand what you’ve done and why. I think it makes sense so far. But I’m running into a problem.
I the 3rd row you defined a Label. But as far as I can tell, that doesn’t work with an Item. In this case, the app is a String held in a String Item. So I looked around and there is no oh-label
. And when I tried to use =props.prefix+"_App" for the text in the Label nothing shows up. I also tried an oh-label-card (out of desperation) but it doesn’t show anything either (because it’s a card?).
I appreciate any pointers. Everything else about the widget makes sense to me so far. I’m not sure how I would have figured out to do it that way on my own but at least now I’m starting to get it and may be able to start getting that part of the tutorial filled out more.
My current attempt is as follows.
uid: chromecast_widget
tags: []
props:
parameters:
- description: How all the Items associated with this chromecast starts
label: Item prefix
name: prefix
required: false
type: TEXT
- description: Title for the widget
label: Static Title
nameJS(secs2hours.js):%s: title
required: false
JS(secs2hours.js):%s type: TEXT
parameterGroups: []
timestamp: Dec 3, 2020, 8:57:58 PM
component: f7-card
config:
title: =props.title
slots:
default:
- component: f7-row
slots:
default:
- component: oh-image
config:
item: =props.prefix+"_Image"
style:
width: 100%
height: auto
- component: f7-row
slots:
default:
- component: f7-col
slots:
default:
- component: Label
text: =items[props.prefix+"__MediaArtist"].state
style:
font-size: 24px
- component: f7-col
slots:
default:
- component: Label
text: =items[props.prefix+"_MediaTitle"].state
style:
font-size: 24px
- component: f7-row
config:
class:
- padding-top
- padding-bottom
slots:
default:
- component: f7-col
slots:
default:
- component: oh-player-controls
config:
item: =props.prefix+"_MediaControl"
- component: f7-col
slots:
default:
- component: oh-slider
config:
item: =props.prefix+"_Volume"
min: 0
max: 100
step: 10
unit: %
label: true
- component: oh-button
config:
text: Stop
iconF7: stop
fill: true
color: red
action: command
actionCommand: ON
actionFeedback: Media Stopped
actionItem: =props.prefix+"_Stop"
class:
- margin-top
- component: f7-row
config:
class:
- padding-top
- justify-content-center
style:
border-top: 1px solid lightgray
border-bottom: 1px solid lightgray
slots:
default:
- component: Label
config:
text: =items[props.prefix+"_App"].state
Hey @rlkoshak
The Label
component is nothing documented I think (or at least I don’t know where) - I saw it in one of the Yannick’s widgets some time ago I think, so I just began to use it. It doesn’t have the oh-
prefix.
This should also work.
I tried your code and didn’t found the error at first until I see the very small (but decisive) faux-pas - the slots:
is not aligned with the config:
of the f7-row
component - the YAML structure is kinda evil.
So the last part would look like this:
- component: f7-row
config:
class:
- padding-top
- justify-content-center
style:
border-top: 1px solid lightgray
border-bottom: 1px solid lightgray
slots:
default:
- component: Label
config:
text: =items[props.prefix+"_App"].state
Yep, I just discovered that right before your reply. Now I’m just struggling with how to center justify the column. You showed how to do the row but that doesn’t appear to flow on down into the f7-cols. And justify-content-center doesn’t seem to do anything as a class under the config for the f7-col. But that’s more for my own knowledge and not something I’m trying to actively do.
The working widget (at least for now) is:
uid: chromecast_widget
tags: []
props:
parameters:
- description: How all the Items associated with this chromecast starts
label: Item prefix
name: prefix
required: false
type: TEXT
- description: Title for the widget
label: Static Title
name: title
required: false
parameterGroups: []
timestamp: Jan 12, 2021, 3:25:58 PM
component: f7-card
config:
title: =props.title
slots:
default:
- component: f7-row
slots:
default:
- component: oh-image
config:
item: =props.prefix+"_Image"
style:
width: 100%
height: auto
- component: f7-row
config:
class:
- justify-content-left
slots:
default:
- component: f7-col
slots:
default:
- component: Label
config:
text: =items[props.prefix+"_MediaArtist"].state
- component: f7-col
slots:
default:
- component: Label
config:
text: =items[props.prefix+"_MediaTitle"].state
- component: f7-row
config:
class:
- padding-top
- padding-bottom
slots:
default:
- component: f7-col
slots:
default:
- component: oh-player-controls
config:
item: =props.prefix+"_MediaControl"
- component: f7-col
slots:
default:
- component: oh-slider
config:
item: =props.prefix+"_Volume"
min: 0
max: 100
step: 10
unit: "%"
label: true
- component: oh-button
config:
text: Stop
iconF7: stop
fill: true
color: red
action: command
actionCommand: ON
actionFeedback: Media Stopped
actionItem: =props.prefix+"_Stop"
class:
- margin-top
- component: f7-row
config:
class:
- justify-content-center
slots:
default:
- component: Label
config:
text: =items[props.prefix+"_App"].state
though it would be nice to know how to left, right, and center justify those labels when there is more than one column.
I will probably still play around with the padding but over all I’m satisfied I know enough now to write up how I did this.
class:
- align-self-center
- align-self-flex-start
- align-self-flex-end
To align the text, use:
class:
- text-align-center
- text-align-left
- text-align-right
Yannick posted a nice source if you’re interested to dive a bit deeper into the handling of flex-box.