I’m trying to figure out how to simplify my YAML code for a couple Main UI widgets.
Widgets are configured by means of props
. There’s also a vars
collection that holds variables.
Does somebody know when the vars collection is updated?
For instance, if an entry in vars
depends on the state of an item, is it safe to assume that state changes will be picked up?
Here’s a naive example. Consider a weather widget which also renders info about wind and gust speed:
- Wind speed and gust speed are rendered in km/h and on the Beaufort scale
- On occasions, the gust speed is not set. E.g., when the weather is not gusty
- The Beaufort reading will be rendered as “min - max Bf” if min < max and as “val Bf” if val = min = max.
- The wind and gust speed ranges will be rendered with a linear gradient depending on the Beaufort values
I know that I can define new Items that “follow” the original weather forecast items, e.g. through a SCALE transform. Unfortunately, this pollutes persistence.
What if I could compute the Beaufort values for wind and gust speeds and store them as vars
in the widget, so I can use them in the YAML definitions to simplify the code (and to reduce errors)?
If I can assume that vars
are updated when their dependent item states change, this could work, as in:
vars:
currentWindSpeedBf: >
= (
items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_WindSpeed' ].state === '-'
|| ! Number.isFinite(
Number.parseFloat(
(props.itemPrefix ? props.itemPrefix : '') + 'Current_WindSpeed' ].state
)
)
) ?
'-' :
Number.parseFloat( items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_WindSpeed' ].state ) >= 118 ? '12' :
Number.parseFloat( items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_WindSpeed' ].state ) >= 103 ? '11' :
Number.parseFloat( items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_WindSpeed' ].state ) >= 89 ? '10' :
Number.parseFloat( items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_WindSpeed' ].state ) >= 75 ? '9' :
Number.parseFloat( items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_WindSpeed' ].state ) >= 62 ? '8' :
Number.parseFloat( items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_WindSpeed' ].state ) >= 50 ? '7' :
Number.parseFloat( items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_WindSpeed' ].state ) >= 39 ? '6' :
Number.parseFloat( items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_WindSpeed' ].state ) >= 29 ? '5' :
Number.parseFloat( items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_WindSpeed' ].state ) >= 20 ? '4' :
Number.parseFloat( items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_WindSpeed' ].state ) >= 12 ? '3' :
Number.parseFloat( items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_WindSpeed' ].state ) >= 6 ? '2' :
Number.parseFloat( items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_WindSpeed' ].state ) >= 2 ? '1' : '0'
currentGustSpeedBf: >
= (
items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_GustSpeed' ].state === '-'
|| ! Number.isFinite(
Number.parseFloat(
(props.itemPrefix ? props.itemPrefix : '') + 'Current_GustSpeed' ].state
)
)
) ?
'-' :
Number.parseFloat( items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_GustSpeed' ].state ) >= 118 ? '12' :
Number.parseFloat( items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_GustSpeed' ].state ) >= 103 ? '11' :
Number.parseFloat( items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_GustSpeed' ].state ) >= 89 ? '10' :
Number.parseFloat( items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_GustSpeed' ].state ) >= 75 ? '9' :
Number.parseFloat( items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_GustSpeed' ].state ) >= 62 ? '8' :
Number.parseFloat( items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_GustSpeed' ].state ) >= 50 ? '7' :
Number.parseFloat( items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_GustSpeed' ].state ) >= 39 ? '6' :
Number.parseFloat( items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_GustSpeed' ].state ) >= 29 ? '5' :
Number.parseFloat( items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_GustSpeed' ].state ) >= 20 ? '4' :
Number.parseFloat( items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_GustSpeed' ].state ) >= 12 ? '3' :
Number.parseFloat( items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_GustSpeed' ].state ) >= 6 ? '2' :
Number.parseFloat( items[ (props.itemPrefix ? props.itemPrefix : '') + 'Current_GustSpeed' ].state ) >= 2 ? '1' : '0'
One big ‘hidden’ benefit of this approach (if it works), is that I can dramatically simplify my Item state validation by checking if vars.currentWindSpeedBf
differs from '-'
in case of valid current wind speed item state. That’s because of the way vars.currentWindSpeedBf
has been defined…
Further on, I could then write:
- component: Label
config:
text: >
=
vars.currentWindSpeedBf === '-' ?
'-' :
(
Math.round(
Number.parseFloat(
items[ (props.itemPrefix ? props.itemPrefix : '') + 'ForecastToday_WindSpeed' ].state
)
)
+ (
(
vars.currentGustSpeedBf === '-'
|| Number.parseFloat(
items[ (props.itemPrefix ? props.itemPrefix : '') + 'ForecastToday_GustSpeed' ].state
)
<= Number.parseFloat(
items[ (props.itemPrefix ? props.itemPrefix : '') + 'ForecastToday_WindSpeed' ].state
)
) ?
'' :
(
' - '
+ Math.round(
Number.parseFloat(
items[ (props.itemPrefix ? props.itemPrefix : '') + 'ForecastToday_GustSpeed' ].state
)
)
)
)
+ ' km/h'
)
and so forth.
Likewise, checking if the Beaufort values of wind speed and gust speed differ, is now trivial:
- component: Label
config:
text: >
=
vars.currentWindSpeedBf === '-' ?
'-' :
vars.currentWindSpeedBf
+ (
(
vars.currentGustSpeedBf === '-'
|| vars.Current_GustSpeedBf <= vars.currentWindSpeedBf
) ?
'' :
(
' - '
+ vars.Current_GustSpeedBf
)
)
+ ' Bf'
)
This is far from obvious without using vars
(if it works), as whenever you see vars.currentWindSpeedBf
or vars.currentGustSpeedBf
you would otherwise have to replace them with their respective (lengthy) definitions…
Finally, getting the colors for the gradient label text could easily be inferred from the computed Beaufort values in an array with 13 entries (0→12 Bf) containing the color definitions and stored as a custom variable in vars
(without depending on item states), as in:
vars:
windBfColor: >
= [ 'white',
'#AEF1F9',
'#96F7DC',
'#96F7B4',
'#6FF46F',
'#73ED12',
'#A4ED12',
'#DAED12',
'#EDC212',
'#ED8F12',
'#ED6312',
'#ED2912',
'#D5102D'
]
. . .
style:
text-align: center
padding-top: 5px
font-size: var(--weather-normal-font-size)
background-image: >
= vars.currentWindSpeedBf === '-' ?
'gray' :
(
vars.currentGustSpeedBf === '-'
|| vars.currentWindSpeedBf == vars.currentGustSpeedBf
) ?
vars.windBfColor[ vars.currentWindSpeedBf ] :
(
'linear-gradient(90deg, '
+ vars.windBfColor[ vars.currentWindSpeedBf ]
+ ','
+ vars.windBfColor[ vars.currentGustSpeedBf ]
+ ')'
)
background-size: 100%
background-clip: text
--webkit-background-clip: text
--moz-background-clip: text
text-fill-color: transparent
--webkit-text-fill-color: transparent
--moz-text-fill-color: transparent
white-space: nowrap
overflow: hidden
text-overflow: ellipsis
z-index: 100
Can somebody tell me whether this might possibly work? My main issue right now, is to know if state changes are adequately picked up in dependent vars
…