Beginner Looking for Pretty Basic (For Most of You) Code Editing Assistance

Good morning!

Relatively new to this whole HAOS experiment but things are going well so far a few weeks in with over 50 devices. A few speed bumps along the way (a couple I’m still working on) but so far, so good.

I’ve finally begun working on my mobile dashboard to have something more user friendly on mobile devices for the wife & I. Thanks to some online videos and articles I found I’ve got a very functional + aesthetically appealing UI foundation in place. So far, I dig it and she approves as well so that’s huge for adoption of this new interface as our old one (Vera) was very familiar for her but incredibly dated in terms of functionality and customization.

One thing I’m trying to do in terms of code is probably super basic for most reading this but I’m pretty new at this thing so I’m not sure what the steps look like to combine things for the cleanest and most simplistic code to perform the task.

My current dashboard has tiles for each subpage for rooms. Each one has a long press setting to turn the most used device on/off within that room. The icons are also all black/gray but light up (orange) when said device is in an on state. What I’m learning is that the long press on the dashboard isn’t as responsive as I’d like and I’m afraid this could lead to more frustration than user experience optimization. What I’m going to do is have each tile tap only to open the corresponding room.

What I need is help to merge the code I have to do this. An example for one of my tiles is my “Garage” tile that leads to a few garage door openers and locks. Each device tile individually behaves the way I want on that “Garage” sub-page. I’d like a way to have all of my rooms indicate anything that may need attention at a single glance. I’m wanting the tile to have a green icon when all devices are closed/locked and turn red if any one of them is open/unlocked.

These are the three devices and their code:

► Device #1: Double Garage Door state red/green ◄
{% if is_state(‘cover.garage_door_opener_double’, ‘closed’) %}
green
{% endif %}
{% if is_state(‘cover.garage_door_opener_double’, ‘open’) %}
red
{% endif %}

► Device #2: Single Garage Door state red/green ◄
{% if is_state(‘cover.garage_door_opener_single’, ‘closed’) %}
green
{% endif %}
{% if is_state(‘cover.garage_door_opener_single’, ‘open’) %}
red
{% endif %}

► Device #3: Back Garage Door Lock State ◄
{% if is_state(‘lock.garage_back_door_deadbolt’, ‘locked’) %}
green
{% if is_state(‘lock.garage_back_door_deadbolt’, ‘unlocked’) %}
red
{% endif %}

How do I combine those for one section of code so that if any one of them is open, the color of that main dashboard tile turns red? I’m sure there is an “else” in my future somewhere maybe. :joy: I think it would benefit from having a different color than the default (gray/black) like green. That would give me what I need so that I could use or remove that bit of code as necessary for each one.

With this, I can then modify for each room’s corresponding tile on an as-needed basis. I did some searching for similar code to modify but wasn’t successful finding something simple as most examples were very complex with things I didn’t need and I wasn’t quite sure how these could be modified for my specific and basic needs.

Thanks for the help as I start out on this journey!

ETA: the lines of code above have the colors indented properly but the forum is showing them as left justified same as the other lines. I was going to add something to indicate this but wanted to leave the code alone w/o any characters for human eyes that would affect functionality. Just use your imagination. :rofl:

To retain code formatting, use the Preformatted Text option in the composer (the icon looks like: </>).

It sounds like you want something like this:

{% 
    set entities = 
         ['cover.garage_door_opener_double',
          'cover.garage_door_opener_single',
          'lock.garage_back_door_deadbolt']
%}

{%
    set red_states =
         ['open', 
          'unlocked']  
%}

{% 
     if entities 
          | select('is_state', red_states) 
          | list 
          | length
          | bool
%}
     red
{% else %}
     green
{% endif %}
1 Like

That worked perfectly. Thanks!

Now to see if I can modify it to work on my other buttons.

I understand the first two sections well enough as that’s the list of entities as well as the states we’re looking for to make the icon red. That’s all simple enough but a different (and more efficient) layout than I was trying.

The third section is a but unclear though. What are those and would I need to make any modifications to those if I was to use this same code for another of my main dashboard cards/tiles?

Outside of that, I can easily just swap out the full entities name list as well as update any states that may or may not be different.

You can leave the {% if %} . . . {% else %} . . . {% endif %} part alone if all you are doing is changing the list of entities or the list of states. That’s the part that figures out if any of the entites in the entities list are in one of the states in the red_states list.

1 Like

Ah, okay cool. Makes sense. Thank you so much!

What do |list |length and |bool do in this case?

The select identifies the entities that have one of those states. The list converts the output (a Jinja “generator”) into a regular list. The length tells you how many items are in the list. The bool, strictly speaking, is not necessary; it returns true if the result of the length is 1 or more, and false otherwise. If you didn’t have the bool, it would work just the same, but I like to be careful about data types, even in a language like Jinja.

For future reference, you can use an Immediate If, and fewer filters, to achieve the same result.

{% set entities = 
     ['cover.garage_door_opener_double',
      'cover.garage_door_opener_single',
      'lock.garage_back_door_deadbolt'] %}
{% set red_states = ['open', 'unlocked'] %}

{{ iif(entities | select('is_state', red_states) | list, 'red', 'green') }}
1 Like

Thanks for the tip!

I used this one too in addition to the one provided previously and both worked great for anyone else who finds this thread searching for something similar.

I find the immediate-if to be highly unintuitive, personally. I avoid it for the sake of conserving neurons when I have to go back and figure out what my code is supposed to be doing.

Thanks for this lesson! :wink:

It’s a less verbose version of if-else-endif.

iif(something is true, then this, else this)

However, it behaves a bit differently. It always evaluates any expressions in the “then” and “else” positions.

For example, if x is not zero then divide 5 by x, otherwise report x.

iif(x!=0, 5/x, x)

It will fail because it will evaluate both expressions and report a “divide by zero” error (when x is zero).

Regardless of whether one uses if or iif, the test it performs simply needs to return a value that can be interpreted as being “truthy” or “falsey”. For example, an empty list is understood to be false and a list with at least one element is true. Knowing that, we need fewer filters to determine if any entities are open/unlocked.

entities | select('is_state', red_states) | list