That’s really cool, thanks for pointing that out! I’m already looking forward for the first cool examples and probably something comes to my mind as well
By the way I stumbled upon the same problem a couple of days ago: the espmilight binding also uses a 0 - 100 range for the temperature. I still wanted the Kelvin value to be displayed and it can actually be done conpletely in the widget code: https://community.openhab.org/t/light-widget-with-temperature-control
You may of course stick with your version, I don’t see any disadvantages besides the additional item.
Thanks for sharing! I like having it all in the widget better, I just didn’t have the time to try and sort it out so I went with what I knew
I really like this widget.
Everything works fine, but when i press the color select button and the color wheel is displayed. It closes the color wheel card before I am able to chose a color…
Any suggestions or clues?
I’m not sure exactly what you mean. Would it be possible to post a gif file here?
Do you happen to use the miio binding? If so please try to set the profile of the color mode channel to “follow” and try if that works for you.
Brilliant!
I now realize my description was really poor.
But you solved it for me anyways. It was indeed MIIO binding. Changed to “follow”. Now it works. Many thanks
Great, so it was a good guess by me
I happen to control a light via the miio binding with this widget as well. The binding always sets the color mode back to white light after a second or so. I don’t know if this is a bug or not but it was easy enough to solve it via the profile so I did not bother to investigate any further.
Here is my Hue modification
uid: color_hue_light_v3
tags: []
props:
parameters:
- description: Header text
label: Header
name: header
required: false
type: TEXT
- context: item
description: Choose Lamp to control
label: Lamp
name: lamp
required: true
type: TEXT
- description: Choose if your Bulb has Color
label: Color
name: color
required: false
type: BOOLEAN
- context: item
description: Choose the Temperature Item if your Bulb has Temperature
label: Temperature
name: temperature
required: false
type: TEXT
- context: item
description: Timer
label: Shutdown Timer Item
name: shutdowntimer
required: false
type: TEXT
parameterGroups: []
timestamp: Apr 13, 2021, 12:00:22 AM
component: f7-card
slots:
default:
- component: f7-card-content
config:
class:
- display-flex
- flex-direction-column
- justify-content-flex-start
- align-items-center
style:
height: 175px
--f7-color-picker-slider-size: 18px
--f7-color-picker-slider-knob-size: 22px
slots:
default:
- component: f7-row
config:
style:
position: absolute
slots:
default:
- component: f7-block-header
slots:
default:
- component: Label
config:
text: =props.header
- component: f7-block
config:
class:
- no-padding
style:
width: 100%
height: 100%
margin-top: 2px
slots:
default:
- component: f7-block
config:
visible: "=vars.color != true ? true : false"
class:
- display-flex
- flex-direction-column
- justify-content-flex-end
style:
animation: f7-circle-circle-in 300ms
height: 60%
margin-top: 10px
slots:
default:
- component: f7-row
config:
visible: "=(props.temperature) ? true : false"
class:
- display-flex
- justify-content-space-between
- align-items-center
style:
width: calc(100% + 20px)
margin-left: -10px
slots:
default:
- component: f7-icon
config:
f7: thermometer
size: 20
style:
margin-left: 20px
color: var(--f7-block-header-text-color)
- component: Label
config:
text: '=items[props.temperature].state == "NULL" ? "-" : items[props.temperature].state + " %"'
style:
margin-right: 20px
color: var(--f7-block-header-text-color)
- component: f7-row
config:
visible: "=(props.temperature) ? true : false"
class:
- display-flex
- justify-content-center
- align-items-center
style:
width: 100%
slots:
default:
- component: oh-slider
config:
color: white
label: true
min: 0
max: 100
item: =props.temperature
style:
margin-top: 7px
--f7-range-bar-size: 18px
--f7-range-bar-border-radius: 10px
--f7-range-knob-size: 20px
--f7-range-bar-active-bg-color: transparent
--f7-range-bar-bg-color: linear-gradient(to right, rgba(215, 226, 255), rgba(255, 255, 255),rgba(255, 147, 44, 0.5),rgba(255, 147, 44, 0))
--f7-range-knob-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3)
--f7-range-label-text-color: black
width: 100%
z-index: 99 !important
- component: f7-row
config:
class:
- display-flex
- justify-content-space-between
- align-items-center
style:
width: calc(100% + 20px)
margin-left: -10px
margin-top: 20px
slots:
default:
- component: f7-icon
config:
f7: sun_min
size: 20
style:
margin-left: 20px
color: var(--f7-block-header-text-color)
- component: Label
config:
text: =items[props.lamp].state.split(",")[2] + " %"
style:
margin-right: 20px
color: var(--f7-block-header-text-color)
- component: f7-row
config:
class:
- display-flex
- justify-content-center
- align-items-center
style:
width: 100%
margin-top: 5px
slots:
default:
- component: oh-slider
config:
color: white
label: true
item: =props.lamp
style:
--f7-range-bar-size: 18px
--f7-range-bar-border-radius: 10px
--f7-range-knob-size: 20px
--f7-range-bar-active-bg-color: rgba(246,246,0,0.5)
--f7-range-bar-bg-color: linear-gradient(to right, rgba(169,169,169,0.8), rgba(246,158,81,0))
--f7-range-knob-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3)
--f7-range-label-text-color: black
width: 100%
z-index: 99 !important
- component: f7-block
config:
visible: "=vars.color != true ? false : true"
class:
- no-margin
style:
animation: f7-circle-circle-in 300ms
slots:
default:
- component: f7-row
config:
class:
- display-flex
- justify-content-center
slots:
default:
- component: f7-block
config:
style:
width: 100%
slots:
default:
- component: oh-colorpicker
config:
style:
margin-top: 7px
--f7-range-bar-size: 18px
--f7-range-bar-border-radius: 10px
--f7-range-knob-size: 20px
--f7-range-bar-active-bg-color: transparent
--f7-range-bar-bg-color: linear-gradient(to right, rgba(246,158,81,0.8), rgba(246,158,81,0))
--f7-range-knob-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3)
--f7-range-label-text-color: black
width: 100%
z-index: 99 !important
item: =props.lamp
modules:
- hsb-sliders
- component: f7-block
config:
class:
- display-flex
- justify-content-center
- align-items-center
- no-padding
- no-margin
style:
position: absolute
width: 40px
height: 40px
left: 30px
bottom: 20px
border-top: none
background: var(--f7-searchbar-search-icon-color)
box-shadow: var(--f7-actions-bg-color) 0px 0px 16px inset
border-radius: 50%
slots:
default:
- component: f7-block
config:
class:
- no-margin
style:
animation: '=items[props.shutdowntimer].state.split(" ")[0] > 0 ? "skeleton-effect-fade 0.2s linear infinite" : "none"'
position: absolute
width: 100%
height: 100%
box-shadow: '=items[props.lamp].state.split(",")[2] > 0 ? "0 0 7px #000, 0px 0px 7px rgba(0,255,0,0.5)" : "none"'
border-radius: 50%
transition: transform 0.2s
background: '=items[props.lamp].state.split(",")[2] > 0 ? "rgba(0, 255, 0, 0.9)" : "transparent"'
transform: '=items[props.lamp].state.split(",")[2] > 0 ? "scale(1)" : "scale(0,0)"'
- component: f7-block
config:
style:
position: absolute
width: calc(100% - 10px)
height: calc(100% - 10px)
border-radius: 50%
- component: oh-link
config:
iconOnly: true
iconF7: power
iconSize: 13
action: toggle
actionItem: =props.lamp
actionCommand: '=items[props.lamp].state.split(",")[2] > "0" ? "0" : "100"'
style:
border-radius: 50%
background-color: var(--f7-actions-bg-color)
color: "#a7a7a7"
width: calc(100% - 10px)
height: calc(100% - 10px)
text-align: center
backdrop-filter: opacity(88%)
z-index: 99 !important
box-shadow: 0px 0px 7px 2px var(--f7-actions-bg-color)
- component: oh-link
config:
text: Timer
visible: "=props.shutdowntimer ? true : false"
action: popover
popoverOpen: .timerpopover
style:
position: absolute
bottom: 10px
slots:
default:
- component: f7-popover
config:
class:
- timerpopover
slots:
default:
- component: oh-stepper-card
config:
item: =props.shutdowntimer
title: Ausschalten in Minuten
- component: f7-block
config:
visible: "=(props.color) == true ? true : false"
class:
- display-flex
- justify-content-center
- align-items-center
- no-padding
- no-margin
style:
position: absolute
bottom: 20px
right: 30px
width: 40px
height: 40px
border-top: none
background: var(--f7-searchbar-search-icon-color)
box-shadow: var(--f7-actions-bg-color) 0px 0px 16px inset
border-radius: 50%
slots:
default:
- component: f7-block
config:
class:
- no-margin
style:
position: absolute
width: 100%
height: 100%
box-shadow: '=vars.color == true ? "rgb(0 0 0) 0px 0px 4px, rgb(255 0 0 / 50%) -1px -1px 4px, rgb(255 255 0 / 50%) 1px -1px 4px, rgb(0 255 0 / 50%) 1px 1px 4px, rgb(0 0 255 / 50%) -1px 1px 4px" : "none"'
border-radius: 50%
transition: transform 0.5s
background: '=vars.color == true ? "linear-gradient(135deg, red, red, orange, yellow, green, blue, blue)" : "transparent"'
transform: '=vars.color == true ? "rotate(360deg) scale(1,1)" : "rotate(0deg) scale(0,0)"'
- component: f7-block
config:
style:
position: absolute
width: calc(100% - 10px)
height: calc(100% - 10px)
background: var(--f7-actions-bg-color)
border-radius: 50%
- component: oh-link
config:
iconOnly: true
iconF7: paintbrush
iconSize: 17
action: variable
actionVariable: color
actionVariableValue: true
style:
display: '=(vars.color == false || vars.color != true) ? "block" : "none"'
border: solid 2pt var(--f7-actions-bg-color)
border-radius: 50%
background-color: var(--f7-actions-bg-color)
background-image: "linear-gradient(135deg, #f7f7f7: none, #e7e7e7)"
color: "#a7a7a7"
width: calc(100% - 10px)
height: calc(100% - 10px)
text-align: center
box-shadow: 0px 0px 7px 2px var(--f7-actions-bg-color)
backdrop-filter: opacity(88%)
class:
- nextSlide
- component: oh-link
config:
iconOnly: true
iconF7: paintbrush_fill
iconSize: 17
action: variable
actionVariable: color
actionVariableValue: false
style:
display: '=(vars.color) ? "block" : "none"'
border: solid 2pt var(--f7-actions-bg-color)
border-radius: 50%
background-color: var(--f7-actions-bg-color)
color: "#a7a7a7"
width: calc(100% - 10px)
height: calc(100% - 10px)
text-align: center
backdrop-filter: opacity(88%)
class:
- previousSlide
- component: f7-card-footer
slots:
default:
- component: Label
config:
text: '=items[props.lamp].state.split(",")[2] > 0 ? "Licht an" : "Licht aus"'
I also made some other modifications. Should work with all Hue Lights (Color and non-color) and Groups
Awesome, your widget! As a beginner working with widgets and Jython rules, I try to understand how this stuff works. I have two issues to integrate the color light widget with my RGBW color lamp which basically works as an RGB lamp plus a separate tunable white lamp.
Issue #1: I do not have an item to select between color mode and white mode. I understand that I need to create a kind of virtual item without a counterpart outside OpenHAB. Upon toggling the color mode item between color and white, the respective other color channels should be turned off to avoid a parallel activation: If color mode = color then white switch = off. If color mode = white then RGB switch = off. However, I get lost whether I can implement this functionality inside the widget (and where to start) or whether I need to write a rule what I have never done before, at least not in Jython so that the rule does not depend on a particular item for exactly one lamp.
Issue #2: I do not have separate switch item, as I added the switch functionality to the respective color / dimmer type as specified in the things file:
Type color : RGBW "DG Dachraum Farbe" [ hsb="232.600:4/5/85+<4/5/100", switch="1.001:4/5/84+<4/5/99", position="5.001:4/5/89+<4/5/104", increaseDecrease="3.007:4/5/92" ]
Type dimmer : TWdim "DG Dachraum Weiß Helligkeit" [ switch="1.001:4/5/84+<4/5/99", position="5.001:4/5/95+<4/5/107", increaseDecrease="3.007:4/5/98" ]
Type number : TWcol "DG Dachraum Weiß Farbtemperatur" [ ga="7.600:4/5/94+<4/5/106" ]
Is there a way to switch on/off the color light in the widget on the basis of non-explicitly available switch items?
Best regards,
Peter
Hi Peter,
let me share my first thoughts on this:
Regarding issue #1: I think you are on the right track here. You are assuming correctly that you would need a rule to simultaneously switch color on/off while switching white off/on. I never used Jython rules so I can’t really help you with these. However I would recommend to simply create a rule from the UI. Since this is pretty basic stuff there is no real need to write a single line of code.
Regarding issue #2: I think I would go for the same solution as with issue #1 (slightly more complex): Create a virtual on/off switch and use a rule to switch off both channels when the switch is turned off. When it is turned on you would need to check what state your color mode switch from issue #1 has and only switch on the corresponding channel (color or dimmer).
Hi Thomas,
Thank you very much for pointing me to the rules to be created from the UI. In order to do so, I created a model first, assigned equipment (things) and points (items). However, I did not find a way to separate business logic from particular items by doing this way. The reason is that I have a number of lamps and would liketo avoid copy-paste the code with different items.
According to what I saw in the rules UI is that I may select a particular item and apply a script. It would be great if somebody could give me a hint as how to abstract the script so that I can re-use it for a number of different items, but following the same business logic.
Best regards,
Peter
Hi Thomas
I also really like your widget. I have made some minor changes to make it compatible with my Hue Hub (%Temperature for lights).
Can you clarify how the “Timer” works? I have created an Item for the shutdowntimer and when it is >0 I see the Power Icon “pulse”. However not clear how and where the countdown happens as I cannot see it in the widget. Does this has to be set externally somehow?
BTW I also see a delay on the Temperature slider when you power on the lights. The label can stay on UNDEF for quiet some time before changing to the correct %. Assuming this is a delay from the Hue Hub?
Thanks again
Mark
Hi Peter,
so far this has not been a big issue with regard to my own home setup. However this is of course a problem that many had before and Rich wrote a very comprehensive article about this topic here: Design Pattern: Working with Groups in Rules
It’s a bit lengthy but worth the read if you want to avoid duplication even though you might need to recreate some items to be able to use the techniques described there.
Regards,
Thomas
Oh yes the timer is probably something that would not work out of the box for a lot of users. I control a milight bulb with this widget that has a shutdown timer built into the device that can be controlled via a channel.
For devices that do not support this out of the box you would need to create your own timer Item and add a rule that gets triggered whenever the Item receives a command. The simplest approach would be in my opinion to create a rule that cancels any running timers, switches the light off when the Item received a 0 (0 minutes) or sets up a one minute timer when the Item is > 0 and sends a command to the same item with the Item value decreased by one. This will in turn trigger the rule again and starts a timer for the next minute and so on until you reached 0 and the rule will turn off the light.
Regarding the delays: The delay from the Hue Hub should really only matter if you set “autoupdate” to “false” in your Item config (this is the reason in my setup). If autoupdate is enabled I would guess that it is more likely a network delay between your device and the OpenHab Rest API.
I created a TripleToggle Python script which automatically creates and manages timers when needed. The timers are kept in an array, the key is the item name. This rule could serve as inspiration (see e.g. where the timers
array is initialised, how it is automatically created and how the timers are reset when needed):
Thanks for contributing to comminity!
Can you please help me to adopt my version for Yeelight color lamps? Code is:
uid: yeelight_color_light_v3
tags: []
props:
parameters:
- description: Header text
label: Header
name: header
required: false
type: TEXT
- description: Background image, located in static/ folder
label: Background image
name: bg_image_url
required: false
type: TEXT
- context: item
description: Toggle ON/OFF
label: Toggle
name: lampToggle
required: true
type: TEXT
- context: item
description: Brightness
label: Brightness
name: brightness
required: true
type: TEXT
- context: item
description: Temperature in K
label: Temperature
name: temperature
required: true
type: TEXT
- context: item
description: Color mode (1 = RGB, 2 = Temperature, 4 = Color flow)
label: Color Mode Item
name: colorMode
required: true
type: TEXT
- context: item
description: Color
label: Color Item
name: color
required: true
type: TEXT
- context: item
description: Timer
label: Shutdown Timer Item
name: shutdowntimer
required: false
type: TEXT
- context: item
label: Item_flow
name: item_flow
required: false
type: TEXT
parameterGroups: []
timestamp: Jul 13, 2021, 2:47:31 AM
component: f7-card
config:
style:
border-radius: var(--f7-card-expandable-border-radius)
box-shadow: 5px 5px 10px 1px rgba(0,0,0,0.1)
background-image: "=props.bg_image_url ? 'url(/static/' + props.bg_image_url + ')' : ''"
background-repeat: no-repeat;
background-size: cover
background-brightness: 60%
margin-left: 5px
margin-right: 5px
font-size: 15px
slots:
default:
- component: f7-card-content
config:
class:
- display-flex
- flex-direction-column
- justify-content-flex-start
- align-items-center
style:
height: 175px
slots:
default:
- component: f7-row
config:
style:
position: absolute
slots:
default:
- component: f7-block-header
slots:
default:
- component: Label
config:
text: =props.header
- component: f7-block
config:
class:
- no-padding
style:
width: 110%
height: 100%
margin-top: 20px
slots:
default:
- component: f7-block
config:
visible: '=items[props.colorMode].state == "2" ? true : false'
class:
- display-flex
- flex-direction-column
- justify-content-flex-end
style:
animation: f7-fade-in 300ms
height: 60%
margin-top: 10px
slots:
default:
- component: f7-row
config:
class:
- display-flex
- justify-content-space-between
- align-items-center
style:
width: calc(100% - 20px)
margin-left: 15px
slots:
default:
- component: f7-icon
config:
f7: thermometer
size: 20
style:
color: var(--f7-block-header-text-color)
- component: Label
config:
text: =items[props.temperature].state + "K"
style:
color: var(--f7-block-header-text-color)
- component: f7-row
config:
class:
- display-flex
- justify-content-center
- align-items-center
style:
width: 95%
margin-left: 10px
slots:
default:
- component: oh-slider
config:
color: white
label: true
min: 1700
max: 6500
item: =props.temperature
style:
--f7-range-bar-size: 18px
--f7-range-bar-border-radius: 10px
--f7-range-knob-size: 20px
--f7-range-bar-active-bg-color: transparent
--f7-range-bar-bg-color: linear-gradient(to right, rgba(255,121,0,1.8), rgba(50,249,255,1))
--f7-range-knob-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3)
--f7-range-label-text-color: black
width: 100%
z-index: 99 !important
- component: f7-row
config:
class:
- display-flex
- justify-content-space-between
- align-items-center
style:
width: calc(100% - 20px)
margin-left: 15px
slots:
default:
- component: f7-icon
config:
f7: sun_min
size: 20
style:
color: var(--f7-block-header-text-color)
- component: Label
config:
text: =items[props.brightness].state + "%"
style:
color: var(--f7-block-header-text-color)
- component: f7-row
config:
class:
- display-flex
- justify-content-center
- align-items-center
style:
margin-left: 10px
width: 95%
slots:
default:
- component: oh-slider
config:
color: white
label: true
item: =props.brightness
style:
--f7-range-bar-size: 18px
--f7-range-bar-border-radius: 10px
--f7-range-knob-size: 20px
--f7-range-bar-active-bg-color: rgba(100,100,0,0.5)
--f7-range-bar-bg-color: linear-gradient(to right, rgba(100,100,0,0.1), rgba(255,255,0,1))
--f7-range-knob-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3)
--f7-range-label-text-color: black
width: 100%
z-index: 99 !important
- component: f7-block
config:
visible: '=items[props.colorMode].state == "1" ? true : false'
class:
- display-flex
- justify-content-center
- align-items-center
style:
width: 107%
margin-left: -20px
animation: f7-fade-in 500ms
slots:
default:
- component: f7-row
config:
style:
width: 100%
class:
- display-flex
- justify-content-center
slots:
default:
- component: f7-block
config:
style:
width: 100%
heigth: 120%
slots:
default:
- component: oh-colorpicker
config:
item: =props.color
modules:
- hsb-sliders
- component: f7-block
config:
class:
- display-flex
- justify-content-center
- align-items-center
- no-padding
- no-margin
style:
position: absolute
width: 40px
height: 40px
left: 10px
bottom: 10px
border-top: '=items[props.lampToggle].state == "ON" ? "none" : "2px solid #ddd"'
box-shadow: "inset 0px 1px 2px #eee"
background: white
border-radius: 50%
slots:
default:
- component: f7-block
config:
class:
- no-margin
style:
animation: '=items[props.shutdowntimer].state.split(" ")[0] > 0 ? "skeleton-effect-fade 2s linear infinite" : "none"'
position: absolute
width: 100%
height: 100%
box-shadow: '=items[props.lampToggle].state == "ON" ? "0 0 20px #fff, 0px 0px 30px rgba(0,255,0,0.5)" : "none"'
border-radius: 50%
transition: transform 0.2s
background: '=items[props.lampToggle].state == "ON" ? "rgba(124, 252, 0, 0.5)" : "transparent"'
transform: '=items[props.lampToggle].state =="ON" ? "scale(1,1)" : "scale(0,0)"'
- component: f7-block
config:
style:
position: absolute
width: calc(100% - 10px)
height: calc(100% - 10px)
background: rgba(255,255,255,0.8)
border-radius: 50%
- component: oh-link
config:
iconOnly: true
iconF7: power
iconSize: 17
action: toggle
actionItem: =props.lampToggle
actionCommand: '=items[props.lampToggle].state == "ON" ? "OFF" : "ON"'
style:
border: solid 2pt white
border-radius: 50%
background-color: "#f7f7f7"
background-image: "linear-gradient(135deg, #f7f7f7, #e7e7e7)"
color: "#a7a7a7"
width: calc(100% - 10px)
height: calc(100% - 10px)
text-align: center
box-shadow: 0px 3px 8px
backdrop-filter: opacity(88%)
z-index: 99 !important
- component: oh-link
config:
text: =items[props.shutdowntimer].state
visible: "=props.shutdowntimer ? true : false"
action: popover
popoverOpen: .timerpopover
style:
position: absolute
bottom: 10px
slots:
default:
- component: f7-popover
config:
class:
- timerpopover
slots:
default:
- component: oh-stepper-card
config:
item: =props.shutdowntimer
title: Таймер в минутах
- component: f7-block
config:
class:
- display-flex
- justify-content-center
- align-items-center
- no-padding
- no-margin
style:
position: absolute
bottom: 10px
right: 10px
width: 40px
height: 40px
border-top: '=items[props.colorMode].state == 1 ? "none" : "2px solid #ddd"'
box-shadow: "inset 0px 1px 2px #eee"
background: white
border-radius: 50%
slots:
default:
- component: f7-block
config:
class:
- no-margin
style:
position: absolute
width: 100%
height: 100%
box-shadow: '=items[props.colorMode].state == 1 ? "0 0 15px #fff, -7px -7px 15px rgba(255,0,0,0.5), 7px -7px 15px rgba(255,255,0,0.5), 7px 7px 15px rgba(0,255,0,0.5), -7px 7px 15px rgba(255,255,0,0.5)" : "none"'
border-radius: 50%
transition: transform 0.2s
background: '=items[props.colorMode].state == 1 ? "linear-gradient(135deg, red, orange, yellow, green, blue)" : "transparent"'
transform: '=items[props.colorMode].state == 1 ? "rotate(360deg) scale(1,1)" : "rotate(0deg) scale(0,0)"'
- component: f7-block
config:
style:
position: absolute
width: calc(100% - 10px)
height: calc(100% - 10px)
background: rgba(255,255,255,0.8)
border-radius: 50%
- component: oh-link
config:
iconOnly: true
iconF7: paintbrush
iconSize: 17
action: command
actionItem: =props.colorMode
actionCommand: 1
style:
display: '=items[props.colorMode].state == 2 ? "block" : "none"'
border: solid 2pt white
border-radius: 50%
background-color: "#f7f7f7"
background-image: "linear-gradient(135deg, #f7f7f7, #e7e7e7)"
color: "#a7a7a7"
width: calc(100% - 10px)
height: calc(100% - 10px)
text-align: center
box-shadow: 0px 3px 8px
backdrop-filter: opacity(88%)
class:
- nextSlide
- component: oh-link
config:
iconOnly: true
iconF7: paintbrush_fill
iconSize: 17
action: command
actionItem: =props.colorMode
actionCommand: 2
style:
display: '=items[props.colorMode].state == 1 ? "block" : "none"'
border: solid 2pt white
border-radius: 50%
background-color: "#f7f7f7"
background-image: "linear-gradient(135deg, #f7f7f7, #e7e7e7)"
color: "#a7a7a7"
width: calc(100% - 10px)
height: calc(100% - 10px)
text-align: center
box-shadow: 0px 3px 8px
backdrop-filter: opacity(88%)
class:
- previousSlide
- component: f7-card-footer
slots:
default:
- component: Label
config:
text: '=items[props.lampToggle].state == "ON" ? "Включено" : "Выключено"'
Issues: changed colorwheel to hsb-sliders, which are better to control Yeelight, and can’t understand how to place them in a small cell on mobile phone - they become too small and hard to control.
Is there any way to design widgets other than Openhab`s web ui?
Hi @11194
As far as I know there is no out-of-the-box way to resize the color controls to your needs, I remember that I had a hard time trying to fit the wheel in there (had to absolutely position the buttons on top of the wheel due to space restrictions) and I think the sliders use a lot more space (at least if you want to have a reasonable size to be able to control them). I figured that for this use case (small screen, touch handling) the wheel works pretty well. So, sorry I don’t think there can be an easy solution unless you increase the size of the widget.
I always used the openHAB UI to develop the widgets. I don’t know of any other way to do this unless you can live without the preview panel.
Deleted absolute positions and condensed as much as i could.
uid: color_light_v2
tags: []
props:
parameters:
- description: Header text
label: Header
name: header
required: false
type: TEXT
- description: Background image, located in static/ folder
label: Background image
name: bg_image_url
required: false
type: TEXT
- context: item
description: Toggle ON/OFF
label: Toggle
name: lampToggle
required: true
type: TEXT
- context: item
description: Brightness
label: Brightness
name: brightness
required: true
type: TEXT
- context: item
description: Temperature in K
label: Temperature
name: temperature
required: true
type: TEXT
- context: item
description: Color mode (1 = RGB, 2 = Temperature, 4 = Color flow)
label: Color Mode Item
name: colorMode
required: true
type: TEXT
- context: item
description: Color
label: Color Item
name: color
required: true
type: TEXT
- context: item
description: Timer
label: Shutdown Timer Item
name: shutdowntimer
required: false
type: TEXT
- context: item
label: Item_flow
name: item_flow
required: false
type: TEXT
parameterGroups: []
timestamp: Aug 1, 2021, 3:06:38 PM
component: f7-card
config:
style:
border-radius: var(--f7-card-expandable-border-radius)
box-shadow: 5px 5px 10px 1px rgba(0,0,0,0.1)
background-image: "=props.bg_image_url ? 'url(/static/' + props.bg_image_url + ')' : ''"
background-repeat: no-repeat;
background-size: cover
background-brightness: 60%
margin: 5px
textColor: white
height: 150px
padding: 0
font-size: medium
line-height: 1
class:
- display-flex
- flex-direction-column
- align-items-center
slots:
default:
- component: f7-card-content
config:
style:
margin: 0px
margin-top: -10px
width: 100%
slots:
default:
- component: f7-block
config:
visible: "=props.header ? true : false"
style:
margin-top: -3px
margin-left: 0px
margin-bottom: 5px
width: 100%
class:
- display-flex
- flex-direction-column
- align-items-center
slots:
default:
- component: Label
config:
text: =props.header
style:
white-space: nowrap
- component: f7-block
config:
visible: '=items[props.colorMode].state == "2" ? true : false'
style:
animation: f7-fade-in 300ms
margin-top: 0px
margin-left: 0px
width: 100%
slots:
default:
- component: f7-row
config:
class:
- justify-content-space-between
style:
width: 100%
color: var(--f7-block-text-color)
slots:
default:
- component: f7-icon
config:
f7: thermometer
size: 20
- component: Label
config:
text: =items[props.temperature].state + "K"
- component: f7-row
slots:
default:
- component: oh-slider
config:
color: white
label: true
min: 1700
max: 6500
item: =props.temperature
style:
--f7-range-bar-size: 13px
--f7-range-bar-border-radius: 10px
--f7-range-knob-size: 15px
--f7-range-bar-active-bg-color: transparent
--f7-range-bar-bg-color: linear-gradient(to right, rgba(255,121,0,1.8), rgba(50,249,255,1))
--f7-range-knob-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3)
--f7-range-label-text-color: black
width: 100%
z-index: 99 !important
- component: f7-row
config:
class:
- justify-content-space-between
- align-items-center
style:
width: 100%
color: var(--f7-block-text-color)
slots:
default:
- component: f7-icon
config:
f7: sun_min
size: 20
- component: Label
config:
text: =items[props.brightness].state + "%"
- component: f7-row
slots:
default:
- component: oh-slider
config:
color: white
label: true
item: =props.brightness
style:
--f7-range-bar-size: 13px
--f7-range-bar-border-radius: 10px
--f7-range-knob-size: 15px
--f7-range-bar-active-bg-color: rgba(100,100,0,0.5)
--f7-range-bar-bg-color: linear-gradient(to right, rgba(100,100,0,0.1), rgba(255,255,0,1))
--f7-range-knob-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3)
--f7-range-label-text-color: black
width: 100%
z-index: 99 !important
- component: f7-block
config:
visible: '=items[props.colorMode].state == "1" ? true : false'
style:
margin-top: 0px
animation: f7-fade-in 500ms
slots:
default:
- component: oh-colorpicker
config:
item: =props.color
modules:
- hsb-sliders
- component: f7-card-footer
config:
class:
- display-flex
- justify-content-space-between
style:
width: 99%
padding: 7px
slots:
default:
- component: f7-block
config:
class:
- display-flex
- justify-content-center
- align-items-center
- no-padding
- no-margin
style:
width: 40px
height: 40px
border-top: '=items[props.lampToggle].state == "ON" ? "none" : "2px solid #ddd"'
box-shadow: "inset 0px 1px 2px #eee"
background: white
border-radius: 50%
slots:
default:
- component: f7-block
config:
class:
- no-margin
style:
animation: '=items[props.shutdowntimer].state.split(" ")[0] > 0 ? "skeleton-effect-fade 2s linear infinite" : "none"'
position: absolute
width: 100%
height: 100%
box-shadow: '=items[props.lampToggle].state == "ON" ? "0 0 20px #fff, 0px 0px 30px rgba(0,255,0,0.5)" : "none"'
border-radius: 50%
transition: transform 0.2s
background: '=items[props.lampToggle].state == "ON" ? "rgba(124, 252, 0, 0.5)" : "transparent"'
transform: '=items[props.lampToggle].state =="ON" ? "scale(1,1)" : "scale(0,0)"'
- component: oh-link
config:
iconOnly: true
iconF7: power
iconSize: 17
action: toggle
actionItem: =props.lampToggle
actionCommand: '=items[props.lampToggle].state == "ON" ? "OFF" : "ON"'
style:
border: solid 2pt white
border-radius: 50%
background-color: "#f7f7f7"
background-image: "linear-gradient(135deg, #f7f7f7, #e7e7e7)"
color: "#a7a7a7"
width: calc(100% - 10px)
height: calc(100% - 10px)
text-align: center
box-shadow: 0px 3px 8px
backdrop-filter: opacity(88%)
z-index: 99 !important
- component: oh-link
config:
text: "=items[props.shutdowntimer].state > 0 ? items[props.shutdowntimer].state : 'Timer'"
visible: "=props.shutdowntimer ? true : false"
action: popover
popoverOpen: .timerpopover
class:
- display-flex
- justify-content-center
- align-items-center
style:
margin-top: 16px
z-index: 98
slots:
default:
- component: f7-popover
config:
class:
- timerpopover
slots:
default:
- component: oh-stepper-card
config:
item: =props.shutdowntimer
title: Таймер
- component: f7-block
config:
class:
- display-flex
- justify-content-center
- align-items-center
- no-padding
- no-margin
style:
width: 40px
height: 40px
border-top: '=items[props.colorMode].state == 1 ? "none" : "2px solid #ddd"'
box-shadow: "inset 0px 1px 2px #eee"
background: white
border-radius: 50%
slots:
default:
- component: f7-block
config:
class:
- no-margin
style:
position: absolute
width: 100%
height: 100%
box-shadow: '=items[props.colorMode].state == 1 ? "0 0 15px #fff, -7px -7px 15px rgba(255,0,0,0.5), 7px -7px 15px rgba(255,255,0,0.5), 7px 7px 15px rgba(0,255,0,0.5), -7px 7px 15px rgba(255,255,0,0.5)" : "none"'
border-radius: 50%
transition: transform 0.2s
background: '=items[props.colorMode].state == 1 ? "linear-gradient(135deg, red, orange, yellow, green, blue)" : "transparent"'
transform: '=items[props.colorMode].state == 1 ? "rotate(360deg) scale(1,1)" : "rotate(0deg) scale(0,0)"'
- component: f7-block
config:
style:
position: absolute
width: calc(100% - 10px)
height: calc(100% - 10px)
background: rgba(255,255,255,0.8)
border-radius: 50%
- component: oh-link
config:
iconOnly: true
iconF7: paintbrush
iconSize: 19
action: command
actionItem: =props.colorMode
actionCommand: 1
style:
display: '=items[props.colorMode].state == 2 ? "block" : "none"'
border: solid 4pt white
border-radius: 50%
background-color: "#f7f7f7"
background-image: "linear-gradient(135deg, #f7f7f7, #e7e7e7)"
color: "#a7a7a7"
width: calc(100% - 10px)
height: calc(100% - 10px)
align-items: center
justify-content: center
box-shadow: 0px 3px 8px
backdrop-filter: opacity(88%)
class:
- nextSlide
- component: oh-link
config:
iconOnly: true
iconF7: paintbrush_fill
iconSize: 19
action: command
actionItem: =props.colorMode
actionCommand: 2
style:
display: '=items[props.colorMode].state == 1 ? "block" : "none"'
border: solid 4pt white
border-radius: 50%
background-color: "#f7f7f7"
background-image: "linear-gradient(135deg, #f7f7f7, #e7e7e7)"
color: "#a7a7a7"
width: calc(100% - 10px)
height: calc(100% - 10px)
box-shadow: 0px 3px 8px
backdrop-filter: opacity(88%)
class:
- previousSlide
Hi,
Thanks for sharing, it works perfectly to control my Hue lights.
Hello,
do you have any idea what I would have to modify in the YAML code to invert the color temperature setting?
The items of my Ikea lamps have a range from 0% (cold) to 100% (warm).
This is mapped “the wrong way around” in the configuration.