This was already discussed and answered here - this isn’t possible (yet)
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 https://github.com/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?
- How to include the nice graph in the widget background?
- Where should I put the images provided in the github archive?
- How can I include those images?
- How can I add the humidity information?
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…
Widget YAML
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
- see and change the desired temperature
- see vaule and trend of the current temperature.
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.
Thanks! For clarity that is put under the config for the Label.
Hey @ysc
are there any news on that? Just asking, to be sure that I don’t miss anything while creating a widget where this feature would be usefull.
And one more questions on the same topic - you’ve introduced a feature some time ago, to set parameters for a selected widget within the action configuration.
Is there a way to use that function in custom widgets?
Thanks!
Yes you define a parameterGroup with a context: action
in your props (this will replace the group props with the standard dynamic action form), and then instead of the action*
propertes in widgets, you specify actionPropsParameterGroup
instead and it will normally take all the action parameters from that group.
uid: widget_281d436ead
props:
parameterGroups:
- name: myaction
context: action
label: My Action
parameters:
...
component: oh-link
config:
actionPropsParameterGroup: myaction
actionModalConfig:
prop1: abc
item: Item1
or am I misunderstanding something?
Thanks for your quick answer - this is exactly what I’m looking for! Awesome, will start right away to implement this.
To be honest, I haven’t thought about, that this context:action
could already include the external component configuration (which makes sense) and thought every action configuration setting has its own context parameter. The soloution like this is even better (and much easier to implement)
So, thank you, again!
After searching a number of posts, I am still unable to determine if it is possible to change the default grid spacing and element size in the overview page, or any other pages such as location and equipment. For example if I want the standard element size to be only half as tall as the default, is this possible to do on a global or eleven element by element basis. Any help here is appreciated.
Only one more thing here…
Can I access the groupParameter like a normal parameter to hide the link-component if nothing is specified as action? (you seems to do that in all the standard widgets)
The obvious at least won’t work
props.widgetAction
For the Overview page, it’s a layout so you can do a lot with CSS variables. For the other pages, you can only customize the order, grouping, header, but not the layout.
They are regular props with a little bit of logic to deal with prefixes etc. It’s a little complex to explain accurately.
Use something like this temporarily to inspect the props
object:
component: f7-card
config:
content: =JSON.stringify(props)
This is enough explanation for now - got it working! TY
Maybe we both misunderstood something here - I can set the ‘actionModal’ parameters on the widget YAML manually, to open the widget with them, yes.
My naive expectation was, that the available parameters of the widget to open, would be loaded automatically after setting the widget/page - but it looks like this on my side…
This was my last question for today, I swear!