Is there a CASE statement (or equivalent) when using templates?

Hi All,

I’m overengineering again!
What I want to do is convert my Weather Alerting system which provides its output as words … “Green”, “Yellow”, “Orange”, “Red”
I want to change this to a numeric value 0-3 or 1-4 so that I can use a gauge card to present this info.

Is there an equivalent of a CASE statement for templates … something like

CASE
  "Green"
     set alertvariable to 0
  "Yellow"
     set alertvariable to 1
  "Orange"
     set alertvariable to 2
  "Red"
     set alertvariable to 3
END CASE

Thanks in advance

1 Like

Use a dictionary and get()

{% set d = {
  'Green': 0,
  'Yellow': 1,
  'Orange': 2,
  'Red': 3 } %}
{{ d.get( states('sensor.weather_alerting') ) }}
2 Likes

Thank you. That’s perfect!

Another alternative, using a list:

{{ ['Green', 'Yellow', 'Orange', 'Red'].index(states('sensor.weather_alerting')) }}

Note that this will raise an error if the sensor does not match one of the four colours, unlike the get() version which returns null.

Just to show that there are lots of ways of achieving the result, here are some options for trying out in the Template Editor, where c is your sensor, including a stupid code golf one. All four options cope with an offline sensor (unknown or unavailable) in differing ways:

{% set c = "Green" %}

# Drew's get() solution: returns None if offline
{{ {'Green': 0, 'Yellow': 1, 'Orange': 2, 'Red': 3}.get(c) }}

# List lookup: returns 4 or 5 if offline
{{ ['Green', 'Yellow', 'Orange', 'Red', 'unknown', 'unavailable'].index(c) }}

# String lookup of first character: returns 4 if offline
{{ 'GYORu'.index(c.0) }}

# Playing games with character codes: returns 1 if offline
{{ c.0|ord%14//4 }}
1 Like

If you eventually find yourself looking for the equivalent of ‘case else’, the get method allows for a default value.

For example, if ‘case else’ should report blue then do this:

{{ d.get(states('sensor.weather_alerting'), 'blue') }}

Reference: python dictionary get method

1 Like

Thank you!