Using different icons/colors based on item state
config:
icon: ={ON:'if:mdi:lightbulb-on', OFF:'if:mdi:lightbulb-off'}
[@'LoungeRoom_Light2']
iconColor: ={ON:'green', OFF:'red'}[@'LoungeRoom_Light2']
- If you don’t have any spaces after
:
within the object i.e. ON:xx, yaml won’t complain about invalid syntax, without having to enclose the whole expression in quotes @'itemname'
is a shorthand foritems.itemname.state
. This is documented in Building Pages - Components & Widgets | openHAB- It isn’t that much different to using ternary operator, but when you have multiple possible states, this could be more easily readable.
Granular icon states
openHAB 4.2+:
config:
icon: |
=[
"if:tabler:battery",
"if:tabler:battery-1",
"if:tabler:battery-2",
"if:tabler:battery-3",
"if:tabler:battery-4"
][Math.min(~~(#"Back_Door_Battery" / 20), 4)]
Note |
tells yaml that you are going to specify the values in multiple lines. You can also use >
. The difference is |
keeps the newlines, >
converts the newlines into spaces. Either one would work.
openHAB 4.2 adds items['itemname'].numericState
so you don’t have to do Number.parseFloat(items['itemname'].state)
any more. Furthermore, a shorthand is added in mainUI for numericState: #'ItemName'
(this PR is not yet merged, but hopefully soon!) EDIT: This has now been merged and should be in 4.2M1
in openHAB 4.1 you’d have to write this as:
config:
icon: |
=[
"if:tabler:battery",
"if:tabler:battery-1",
"if:tabler:battery-2",
"if:tabler:battery-3",
"if:tabler:battery-4"
][Math.min(~~(Number.parseFloat(items.Back_Door_Battery.state) / 20), 4)]
Here I’m trying to show battery level (0-100) using the following icons:
- if:tabler:battery
- if:tabler:battery-1
- if:tabler:battery-2
- if:tabler:battery-3
- if:tabler:battery-4
We’ll put them in an array and use the array index to pick the icon based on the battery level
We need to map 0-100 into 0-4 using integer division
A trick to do “integer division without using Math.floor”: ~~(a / b)
. You could choose to use Math.floor if that’s easier to understand at a glance
Since there are 5 icons, we’ll divide by 20. This maps:
0 - 19 => 0
20 - 39 => 1
40 - 59 => 2
60 - 79 => 3
80 - 99 => 4
100 is a special case, since 100 / 5 = 5, we need to map this to 4 because our array only goes from 0-4. We do this using Math.min()
You could also write that more compactly like this:
config:
icon: ="if:tabler:battery" + ["", "-1", "-2", "-3", "-4"][Math.min(~~(#"Back_Door_Battery" / 20), 4)]