Can anyone suggest a simple way to change the color of a colorpicker widget, using the actual color of a RGB stripe.
I tried using this YAML code, but the widget is alwais white
component: oh-colorpicker-cell
config:
action: toggle
actionCommand: ON
actionCommandAlt: OFF
actionItem: Led_Switch
color: =(items.LEDRGB_Color.state)
icon: colorpicker
item: LEDRGB_Color
on: =(items.Led_Switch.state == ‘ON’)
stateAsHeader: true
title: Color
slots: null
I think I should do some sort of “translation” from the LEDRGB_Color.state.
Can I use a JS function into the YAML code? Has anyone some example to start with?
Platform information:
Hardware: Raspberry 2B
OS: _OpenHabian
openHAB version: 3.2.0
JustinG
(JustinG)
February 11, 2022, 5:46pm
2
Welcome to the forums.
Unfortunately, particularly with a cell widget, this is going to be very difficult. I won’t say “impossible”, but off the top of my head, I can’t see a way to make it work.
The real issue here is that the way the cells are built, color
is not a direct conduit to the background of the element. The value of color
gets concatenated into a class name that is applied to the cell (e.g., bg-color-green
) which then gets styled via some default f7 styling from there. So color
only accepts the colors names that are listed in the f7 theme docs .
You could inject css directly into the widget via the stylesheet property to override the f7 class stylings, but I believe the stylesheet property only accepts static text so you couldn’t import the item state into that css.
I haven’t spent a lot of time working with color states, so there may be a workaround. I’m just not aware of one.
MartOs
(MartOs)
February 17, 2022, 11:54pm
3
I want to do this too.
My best guess was something like
component: f7-card
config:
title: =items[props.item].state.split(",")[0]
content: test
style:
background: hsl(items[props.item].state.split(",")[0], 100%, 50%)
items[props.item].state.split(",")[0] extracts the correct number from the color item,
and hsl(0.0,100%,50%) works,
but the above yaml doesn’t work.
MartOs
(MartOs)
February 18, 2022, 12:13am
4
This works as a very coarse approximation
background: '=(items[props.item].state.split(",")[0] >= 360-30) ? "hsl(0,100%,50%)" :
(items[props.item].state.split(",")[0] >= 300-30) ? "hsl(300,100%,50%)" :
(items[props.item].state.split(",")[0] >= 240-30) ? "hsl(270,100%,50%)" :
(items[props.item].state.split(",")[0] >= 180-30) ? "hsl(180,100%,50%)" :
(items[props.item].state.split(",")[0] >= 120-30) ? "hsl(120,100%,50%)" :
(items[props.item].state.split(",")[0] >= 60-30) ? "hsl(60,100%,50%)" :
(items[props.item].state.split(",")[0] >= 0) ? "hsl(0,100%,50%)" :
"white"'
JustinG
(JustinG)
February 18, 2022, 2:13am
5
MartOs:
component: f7-card
The original request was about an oh-cell
where the background style won’t get applied properly, so unfortunately this won’t work for the original poster.
You’re close to getting this to work, there are just a few pieces to tweak. If you’re going to call an item state, then the property has to be an expression (the parses has to know to evaluate it instead of just keeping it as a string), so it has to start with an =
. Then you just have to remember that you are trying to build a string with the item’s value inserted in the middle of it. So the rest of the expression has to be made up of string literals (must be in quotes). So the final form should look something like this:
background: ='hsl(' + items[props.item].state.split(",")[0] + ', 100%, 50%)'
1 Like
MartOs
(MartOs)
February 18, 2022, 10:13am
6
Wow! Thank you!
Yes that works as expected.
Sorry for hijacking the thread.
I’m actually trying to put this into an IF expression, and I can’t seem to apply the above learning.
I’m doing something wrong with ’ and ". I have tried a few variations without success.
I get as far as -
color: '=((items[props.bright].state > 0 || items[props.bright].state == "ON") && items[props.colorMode].state != "ON") ? "yellow":
((items[props.bright].state > 0 || items[props.bright].state == "ON") && items[props.colorMode].state == "ON") ? "hsl(" + items[props.colorSel].state.split(",")[0] + ", 100%, 50%)" :
"gray"'
Can you see where my mistake is?
MartOs
(MartOs)
February 18, 2022, 10:46am
7
ok. This seems to work
component: f7-card
config:
title: =items[props.colorSel].state.split(",")[0]
content: test
style:
background: '=((items[props.bright].state > 0 || items[props.bright].state == "ON") && items[props.colorMode].state != "ON") ? "yellow":
((items[props.bright].state > 0 || items[props.bright].state == "ON") && items[props.colorMode].state == "ON") ? "hsl(" + items[props.colorSel].state.split(",")[0] + ", 100%, 50%)" :
"gray"'
But the same code doesn’t work when trying to apply it to the color of an f7 icon burried in a more complex widget.
The relevant lines start at line 100.
component: f7-card
config:
backdrop: true
class:
- card-expandable-animate-width
expandable: true
style:
background: '=(items[props.bright].state > 0 || items[props.bright].state == "ON") ? "linear-gradient(to bottom, hsla(48, 90%, 54%, 1), hsla(48, 90%, 95%, 1), 10% , hsla(0, 0%, 100%, 1) )": "white"'
height: 170px
margin: 5px
margin-top: 10px
swipeToClose: true
slots:
default:
- component: oh-button
config:
class:
- cell-open-button
- card-opened-fade-out
color: gray
iconF7: ellipsis
iconSize: 30px
style:
padding-bottom: 40px
padding-right: 15px
padding-top: 10px
position: absolute
right: 0
top: 0
z-index: 999
- component: f7-card-content
config:
style:
padding-top: 30px
width: 100%
slots:
default:
- component: f7-icon
config:
color: '=((items[props.bright].state > 0 || items[props.bright].state == "ON") && items[props.colorMode].state != "ON") ? "yellow":
((items[props.bright].state > 0 || items[props.bright].state == "ON") && items[props.colorMode].state == "ON") ? "hsl(" + items[props.colorSel].state.split(",")[0] + ", 100%, 50%)" :
"gray"'
material: lightbulb
size: '=(items[props.bright].state > 0 || items[props.bright].state == "ON") ? "110px": "90px"'
style:
opacity: '=(items[props.bright].state > 0 || items[props.bright].state == "ON") ? "100%": "10%"'
position: absolute
right: '=(items[props.bright].state > 0 || items[props.bright].state == "ON") ? "-5px": "0px"'
top: '=(items[props.bright].state > 0 || items[props.bright].state == "ON") ? "45px": "60px"'
- component: oh-button
config:
class:
- card-opened-fade-in
- cell-close-button
- card-close
color: black
iconF7: xmark_circle_fill
iconSize: 30px
style:
padding-bottom: 35px
padding-top: 10px
position: absolute
right: 0
top: 0
z-index: 999
- component: oh-link
config:
action: toggle
actionCommand: '=(props.sbright) ? items[props.sbright].state: "ON"'
actionCommandAlt: OFF
actionItem: =props.bright
class:
- card-prevent-open
style:
height: 100%
left: 0
position: absolute
top: 0
width: 100%
z-index: 0
- component: f7-block
config:
class:
- no-padding
style:
height: 200px
margin: 0px
slots:
default:
- component: f7-row
config:
style:
flex-wrap: nowrap
height: 65px
white-space: nowrap
width: auto
slots:
default:
- component: f7-col
slots:
default:
- component: Label
config:
style:
font-weight: 600
overflow: hidden
text-overflow: ellipsis
white-space: nowrap
text: =props.location
- component: f7-chip
config:
color: '=(items[props.bright].state > 0) ? "yellow": (items[props.bright].state == "ON") ? "yellow": "gray"'
text: '=(items[props.bright].state > 0) ? items[props.bright].state + " %": (items[props.bright].state == "ON") ? "ON": "OFF"'
- component: f7-row
config:
class:
- justify-content-flex-start
style:
flex-wrap: nowrap
height: auto
white-space: nowrap
slots:
default:
- component: f7-icon
config:
color: '=(items[props.motion].state == "OFF" && items[props.motionOnOff].state == "ON") ? "blue" : (items[props.motion].state == "ON") ? "red" : (items[props.motionOnOff].state == "OFF") ? "gray" : "gray"'
f7: dot_radiowaves_right
size: 20px
style:
margin-right: 5px
visible: '=(props.motionOnOff) ? "true": "false"'
- component: f7-icon
config:
color: '=(items[props.oTtimer].state > 0 && (items[props.bright].state == 0 || items[props.bright].state == "OFF")) ? "blue": (items[props.oTtimer].state > 0 && (items[props.bright].state > 0 || items[props.bright].state != "OFF")) ? "red": "gray"'
f7: timer
size: 20px
style:
margin-right: 5px
visible: '=(props.oTtimer) ? "true": "false"'
- component: f7-row
config:
style:
height: auto
overflow: hidden
width: 100%
visible: '=(props.illum) ? "true": "false"'
slots:
default:
- component: f7-col
config:
style:
align-self: flex-end
flex-wrap: nowrap
slots:
default:
- component: f7-row
config:
class:
- justify-content-flex-start
style:
flex-wrap: nowrap
margin-top: 5px
slots:
default:
- component: f7-icon
config:
color: yellow
f7: light_max
size: 18px
style:
margin-left: 0px
margin-top: 0px
- component: Label
config:
style:
color: gray
font-size: 12px
margin-left: 8px
overflow: hidden
text-overflow: ellipsis
white-space: nowrap
text: =items[props.illum].state
- component: f7-row
config:
style:
height: 20px
overflow: hidden
width: 100%
visible: '=(props.illumt) ? "true": "false"'
slots:
default:
- component: f7-col
config:
style:
align-self: flex-end
flex-wrap: nowrap
slots:
default:
- component: f7-row
config:
class:
- justify-content-flex-start
style:
flex-wrap: nowrap
margin-top: 5px
slots:
default:
- component: f7-icon
config:
color: '=((Number.parseFloat(items[props.illumt].state.split(" ")[0])) < (Number.parseFloat(items[props.illum].state.split(" ")[0]))) ? "gray": (items[props.motionOnOff].state == "OFF") ? "gray": "green"'
f7: increase_indent
size: 18px
style:
margin-left: 0px
margin-top: 0px
- component: Label
config:
style:
color: gray
font-size: 12px
margin-left: 8px
overflow: hidden
text-overflow: ellipsis
white-space: nowrap
text: =items[props.illumt].state
- component: f7-block
config:
class:
- card-prevent-open
- card-content-padding
slots:
default:
- component: oh-list
config:
class:
- padding
slots:
default:
- component: oh-toggle-item
config:
actionCommand: '=(props.sbright) ? items[props.sbright].state: "ON"'
actionCommandAlt: OFF
color: yellow
icon: f7:power
item: =props.bright
title: On/Off
- component: oh-stepper-item
config:
autorepeat: true
autorepeatDynamic: true
color: '=(items[props.bright].state > 0) ? "yellow" : "gray"'
fill: true
icon: oh:slider
iconUseState: true
item: =props.bright
max: 100
min: 0
round: true
small: true
title: Brightness
visible: '=(props.sbright) ? "true": "false"'
- component: oh-stepper-item
config:
autorepeat: true
autorepeatDynamic: true
color: blue
fill: true
icon: oh:slider
iconUseState: true
item: =props.sbright
max: 100
min: 0
round: true
small: true
title: Scene Brightness
visible: '=(props.sbright) ? "true": "false"'
- component: oh-list-item
config:
action: toggle
actionCommand: ON
actionCommandAlt: OFF
actionItem: =props.motionOnOff
badge: '=(items[props.motionOnOff].state == "ON" && (Number.parseFloat(items[props.illumt].state.split(" ")[0])) >= (Number.parseFloat(items[props.illum].state.split(" ")[0]))) ? "AUTO": (items[props.motionOnOff].state == "OFF") ? "OFF": (items[props.motionOnOff].state == "ON" && (Number.parseFloat(items[props.illumt].state.split(" ")[0])) < (Number.parseFloat(items[props.illum].state.split(" ")[0]))) ? "TOO BRIGHT": (items[props.motionOnOff].state == "ON") ? "AUTO": items[props.motionOnOff].displayState'
badge-color: '=(items[props.motionOnOff].state == "ON" && (Number.parseFloat(items[props.illumt].state.split(" ")[0])) >= (Number.parseFloat(items[props.illum].state.split(" ")[0])) && items[props.motion].state == "OFF") ? "blue": (items[props.motionOnOff].state == "OFF") ? "black": (items[props.motionOnOff].state == "ON" && (Number.parseFloat(items[props.illumt].state.split(" ")[0])) < (Number.parseFloat(items[props.illum].state.split(" ")[0]))) ? "yellow": (items[props.motion].state == "ON" && items[props.motionOnOff].state == "ON" && (Number.parseFloat(items[props.illumt].state.split(" ")[0])) < (Number.parseFloat(items[props.illum].state.split(" ")[0]))) ? "green": "red"'
icon: f7:dot_radiowaves_right
title: Motion detection
visible: '=(props.motionOnOff) ? "true": "false"'
- component: oh-stepper-item
config:
autorepeat: true
autorepeatDynamic: true
color: '=(items[props.motionOnOff].state == "ON") ? "blue": "gray"'
fill: true
footer: in Minutes
icon: f7:timer
item: =props.mtimer
max: 600
min: 1
round: true
small: true
title: Motion Timer
visible: "=(props.mtimer) ? true: false"
- component: oh-stepper-item
config:
autorepeat: true
autorepeatDynamic: true
color: '=(Number.parseFloat(items[props.illumt].state.split(" ")[0])) < (Number.parseFloat(items[props.illum].state.split(" ")[0])) ? "gray": (items[props.motionOnOff].state == "OFF") ? "gray": "green"'
fill: true
footer: '=(Number.parseFloat(items[props.illumt].state.split(" ")[0])) < (Number.parseFloat(items[props.illum].state.split(" ")[0])) ? "Currently " + items[props.illum].state + " - Too bright" : "Currently " + items[props.illum].state'
icon: f7:light_max
item: =props.illumt
max: 600
round: true
small: true
title: lux Threshold
visible: "=(props.illumt) ? true: false"
- component: oh-stepper-item
config:
autorepeat: true
autorepeatDynamic: true
color: '=(items[props.oTtimer].state == "0") ? "gray": "blue"'
fill: true
footer: in Minutes
icon: f7:timer
item: =props.oTtimer
max: 600
min: 0
round: true
small: true
title: Auto Off
visible: "=(props.oTtimer) ? true: false"
- component: oh-list-item
config:
action: toggle
actionCommand: ON
actionCommandAlt: OFF
actionItem: =props.colorMode
badge: =items[props.colorMode].displayState
badge-color: blue
footer: RGB or White
icon: oh:colorwheel
title: Colour Mode
visible: "=(props.colorMode) ? true: false"
- component: oh-colorpicker-item
config:
icon: oh:colorwheel
item: =props.colorSel
modules:
- hue-slider
title: Color Select
visible: '=(items[props.colorMode].state == "ON") ? "true": "false"'
MartOs
(MartOs)
February 18, 2022, 11:12am
8
On further experimenting, it seems I can’t apply hsl, rgb, or web# colors to the f7-icon component, only word colors eg red, blue etc
The expression wasn’t the problem.
*Update
Got it.
For the f7-icon component, the color:
line has to be in style:
, not config:
JustinG
(JustinG)
February 18, 2022, 2:13pm
9
When using the widget editor, remember that you can always press ctrl + space to get a list of all the config options for a component when you’re on an options line.
One other small note:
MartOs:
background: '=((items[props.bright].state > 0 || items[props.bright].state == "ON") && items[props.colorMode].state != "ON") ? "yellow":
((items[props.bright].state > 0 || items[props.bright].state == "ON") && items[props.colorMode].state == "ON") ? "hsl(" + items[props.colorSel].state.split(",")[0] + ", 100%, 50%)" :
"gray"'
Works only because you are comparing the brightness state to 0
. The items object always returns a string, which can often lead to unexpected results when using >
or <
. For the best results you should convert that to a number for numerical comparisons:
Number(items[props.bright].state) > 0
1 Like
MartOs
(MartOs)
February 18, 2022, 3:30pm
10
Thanks for all that. It’s working well now.