Useful template examples relating to lights that I wish I had known earlier:

Present’s, [director’s cut]:

A [Cheat-Sheet/Crash-Guide] List of Light related Template Examples or, How To’s:

Starring :point_right:YOU :point_left: in the leading role,
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
Once upon a time, not so long ago; in a land not so far away there was A Emperor, & they had a HAss type domain. (Big long winded blurb like at the beginning of Star Wars, leading into the Emperor saying)
“For all Lights in my HAss Domain, will Hence be called ‘light’, & the State of them will be called ‘states.light’.” - “Sir, Please. DefenestrateIT!”

states.light function

[Greenhorn’s copy & paste the code bellow into your “Developer Tools > TEMPLATE > Template editor”:
& play with it as your :heart: desires, ( but you might want to Bookmark this page first ).]

Their are {{states.light|map(attribute='entity_id')|list|count}}{#
#} loyal 'light's in your vast HAss Domain, good sir.
{{states.light|selectattr('state','eq','on')|rejectattr('attributes.entity_id',
'defined')|list|count}} of them are 'on' gard right now, & {{states.light
|selectattr('state','eq','off')|list|count}} of them 'off' dutie.
"Does that add up? Are any of my 'light' subjects 'unavailable'?"
{{ states.light|selectattr('state','eq','unavailable')|list|count
>0}}, sir {{states.light|selectattr('state','eq','unavailable')|
list|count}}; of your subjects can't be accounted for.
"I'm still not sure that adds up, I'll show you how to make {#
#}some Templates so you can 'knight' your loyal subjects & expel {#
#}the pesky "group/s:"
A——————————————————————————————
List all lights including groups:
{{ states.light 
              | map ( attribute = 'entity_id' ) 
              | list 
}}
B——————————————————————————————
List all lights that are 'on' including groups:
{{ states.light 
              | selectattr( 'state' , 'eq' , 'on' ) 
              | map ( attribute = 'entity_id' ) 
              | list 
}}
C——————————————————————————————
List all lights with out ‘helper’ groups: Method One
{{ states.light 
              | rejectattr ( 'attributes.entity_id' , 'defined' )
              | map ( attribute = 'entity_id' ) 
              | list 
}} {#Thank you @Petro for this method#}
D——————————————————————————————
List all lights, with out ‘helper’ groups: Method Two
{{ states.light 
              | rejectattr ('entity_id', 'in', integration_entities('group')) 
              | map ( attribute = 'entity_id' ) 
              | list 
}} {#Thank you @CentralCommand for this method#}
E——————————————————————————————
List all lights, with out ‘helper’ groups: Method Three (This expands existing groups & lists the entitiies)
{{ states.light
              | selectattr ( 'attributes.entity_id' , 'defined' )
              | expand 
              | map ( attribute = 'entity_id' ) 
              | list
}}{#Thank you @123 Taras for this method#}
F——————————————————————————————
List all lights that are ‘on’ with out ‘helper’ groups:
{{ states.light 
              | rejectattr ( 'attributes.entity_id' , 'defined' )
              | selectattr ( 'state' , '==' , 'on' ) 
              | map ( attribute = 'entity_id' ) 
              | list 
}} 
G——————————————————————————————
List all lights that are ‘on’ with out ‘hue’ or ‘deconz’ & ‘helper’ groups:
{{ states.light
              | rejectattr ( 'attributes.is_deconz_group' , 'true' )
              | rejectattr ( 'attributes.is_hue_group' , 'true' )
              | rejectattr ( 'attributes.entity_id' , 'defined' )
              | selectattr ( 'state' , 'eq' , 'on' )
              | map ( attribute = 'entity_id' )
              | list 
}}
H——————————————————————————————
List all lights that are ‘off’ with out ‘helper’ groups:
{{ states.light 
              | rejectattr ( 'attributes.entity_id' , 'defined' )
              | selectattr ('state' , '==' , 'off' ) 
              | map ( attribute = 'entity_id' ) 
              | list 
}}
I——————————————————————————————
List all lights that are ‘off’ or 'unavailable' with out ‘helper’ groups:
{{ states.light 
              | rejectattr ( 'attributes.entity_id' , 'defined' )
              | selectattr ('state' , '!=' , 'on' ) 
              | map ( attribute = 'entity_id' ) 
              | list 
}}
J——————————————————————————————
List all lights that are 'unavailable' with out ‘helper’ groups:
{{ states.light 
              | rejectattr ( 'attributes.entity_id' , 'defined' )
              | selectattr ('state' , '==' , 'unavailable' ) 
              | map ( attribute = 'entity_id' ) 
              | list 
}}
K——————————————————————————————
Count lights that are 'on' with out ‘hue’ or ‘deconz’ & ‘helper’ groups:
{{ states.light 
              | rejectattr ( 'attributes.is_deconz_group' , 'true' )
              | rejectattr ( 'attributes.is_hue_group' , 'true' )
              | rejectattr ( 'attributes.entity_id' , 'defined' )
              | selectattr ('state' , 'eq' , 'on' )  
              | list  
              | count 
}}
L——————————————————————————————
Count total lights with out ‘hue’ or ‘deconz’ & ‘helper’ groups:
{{ states.light  
              | rejectattr ( 'attributes.is_deconz_group' , 'true' )
              | rejectattr ( 'attributes.is_hue_group' , 'true' )
              | rejectattr ( 'attributes.entity_id' , 'defined' )
              | list  
              | count 
}}
N——————————————————————————————
List Lights ‘on’ in the area_id: 'bathroom'
{{ states.light 
              | selectattr ( 'entity_id' , 'in' , area_entities( 'bathroom' ))
              | selectattr ( 'state' , '==' , 'on' ) 
              | map ( attribute = 'entity_id' )
              | list
}}
M——————————————————————————————
'True' or 'False' are any of the lights 'on' in the area_id: 'bedroom'
{{ states.light 
              | selectattr ( 'entity_id' , 'in' , area_entities( 'bedroom' ))
              | selectattr ( 'state' , 'eq' , 'on' ) 
              | list
              | count > 0
}}
O——————————————————————————————
'True' or 'False' are any of the lights 'on':
{{ states.light 
              | selectattr ( 'state' , '==' , 'on' ) 
              | list
              | count > 0
}}
P——————————————————————————————
'True' or 'False' are any of the lights 'unavailable':
{{ states.light 
              | selectattr ( 'state' , 'eq' , 'unavailable' ) 
              | list
              | count > 0
}}
Q——————————————————————————————
But how would you write a Template that only lists Light Groups using the states.light command?
R——————————————————————————————
List All lights & there state:
{% for state in states.light -%}
  {%- if loop.first %}The {% elif loop.last %} and {{-'\n'-}} The {% else %},{{-'\n'-}}The {% endif -%}
  {{ state.name | lower }} is '{{state.state_with_unit}}'
{%- endfor %} {#Just for 123 Taras: This one WAS copied from the 'Demo Template' & tweaked for states.light #}

“But my light knights skills need more training on Variable Scripted missions, with Target/Selector style themes; so for now my ‘light’ knights will be called ‘lights’” - “Sir, No-More. DefenestrateIT!”.

Target orientated extentions

[Once again Grasshopper’s copy the code below & replace all the code in your Template Editor. Change:
“office”, “light.office_lights_group” & “0123456789abcdef0123456789abcdef”.
To your appropriate parameters for your setup. :speak_no_evil: :hear_no_evil: :see_no_evil: ]

{#For newbies in setting variables to test blueprints with [Template Editor]:#}
{% set lights = { 
                  "area_id" :  "office" ,
                "entity_id" : "light.office_lights_group"  ,
                "device_id" :  "0123456789abcdef0123456789abcdef" 
                }
%}{#
-------------------------------------------------------------------
Above change the 'lights' Variable settings: 
'office', 'light.office_lights_group' & '0123456789abcdef0123456789abcdef'.
To A 'device_id', 'entity_id' & 'area_id' in your HAss Domain.
-------------------------------------------------------------------
#}|{{lights.area_id}}|><|{{lights.entity_id}}|><|{{lights.device_id}}|
=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓==↓=↓
  What is my Light area_id: '{{ area_name ( lights.area_id ) }}'
What is my Light entity_id: '{{ state_attr( lights.entity_id , 'friendly_name') }}'
What is my Light device_id: '{{ device_attr ( lights.device_id , 'name' ) }}'{#
-------------------------------------------------------------------
                           #}{% if area_name ( lights.area_id ) != none %}
Area-----------------------------------------------lights.area_id
{#                       #}The {{ area_name ( lights.area_id ) }} has {#
                             #}{{ expand ( area_entities ( lights.area_id )) | selectattr ( 'domain' , 'eq' , 'light' ) | list | count }} Lights.
Are any of the Lights On? {# #}{{ expand ( area_entities ( lights.area_id )) | selectattr ( 'domain' , 'eq' , 'light' ) | selectattr ( 'state' , '==' , 'on' ) | list | count > 0 }}{#
                             #}{%if expand ( area_entities ( lights.area_id )) | selectattr ( 'domain' , 'eq' , 'light' ) | list | count != expand ( area_entities ( lights.area_id )) | selectattr ( 'domain' , 'eq' , 'light' ) | selectattr ( 'state' , '==' , 'on' ) | list | count %}{#
                               #}{% for state in expand ( area_entities ( lights.area_id ))| selectattr ( 'domain' , 'eq' , 'light' ) -%}{#
                               #}{%- if loop.first %}
{#                         #}The {% elif loop.last %} and {{-'\n'-}} The {#
                               #}{% else %},{{-'\n'-}}The {#
                               #}{% endif -%}{#
                               #}{{ state.name | lower }} is '{#
                               #}{{ state.state_with_unit }}'{#
                               #}{%- endfor %}{#
                             #}{% endif %}{#
                           #}{% endif %}{#
----------------------------------------------------------------
                            #}{%if state_attr( lights.entity_id , 'friendly_name') != none %}
Entity------------------------------------------lights.entity_id
{#                       #}Is '{{ state_attr ( lights.entity_id , 'friendly_name') }}' on? '{#
                             #}{{ is_state ( lights.entity_id , 'on' ) }}' 
Does the bulb have brightness controls?{#
                             #}{% if is_state_attr ( lights.entity_id , "brightness" , none ) %} "False" {#
                             #}{% else %} "True"
Is the light A colour bulb?{#  #}{% if is_state_attr ( lights.entity_id , 'rgb_color' , none ) %} "False"{#
                               #}{% else %} "True"{#   
#}                               {% endif %}
What are it's native efects features? {#
                               #}{{ state_attr ( lights.entity_id , 'effect_list') }}
What are it's min-max mirids: {#
                               #}{% if is_state_attr ( lights.entity_id , 'color_temp', none ) %} "None"{#
                               #}{% else %} {#
                            #}Min '{{ state_attr ( lights.entity_id , 'min_mireds') }}' - {#
                            #}Max '{{ state_attr ( lights.entity_id , 'max_mireds') }}'{#
                                 #}{% endif %}{#   
#}                               {% endif %}{#   
#}Show me all of it Properties?
{#                           #}{{ expand ( lights.entity_id ) }}{#
                           #}{% endif %}{#
--------------------------------------------------------------------
                           #}{% if device_attr ( lights.device_id , 'name' ) != none %}
Device------------------------------------------lights.device_id
{#                      #}The '{{ device_attr ( lights.device_id , 'name' ) }}' Device, curently in the Area {#
                            #}'{{ device_attr ( lights.device_id , 'area_id' ) }}':
{#                     #}Is A '{{ device_attr ( lights.device_id , 'manufacturer' ) }}' - {#
                            #}'{{ device_attr ( lights.device_id , 'model' ) }}' - Firmware Version: {#
                            #}'{{ device_attr ( lights.device_id , 'sw_version' ) }}'
                    entity_id: {{ device_entities ( lights.device_id ) }}{#
                           #}{% endif %}{#
----------------------------------------------------------------
                           #}{% if area_name ( lights.area_id ) != none or device_attr ( lights.device_id , 'name' ) != none or state_attr( lights.entity_id , 'friendly_name') != none %}
-----------------------------------------------------------------
Are any of the Lights On? {# #}{% if device_attr ( lights.device_id , 'name' ) != none %}{#
                               #}{{ is_state ( lights.device_id , 'on' ) }}{#
                             #}{% elif state_attr( lights.entity_id , 'friendly_name') != none %}{#
                               #}{{ is_state ( lights.entity_id , 'on' ) }}{#
                             #}{% elif area_name ( lights.area_id ) != none %}{#
                               #}{{ expand ( area_entities ( lights.area_id )) | selectattr ( 'domain' , 'eq' , 'light' ) | list | count > 0 }}{#
                             #}{% endif %}{#
                           #}{% endif %}{#
----------------------------------------------------------------
                           #}

“So now my light-saber coding skills have been honed, I need more advanced training on Blueprint automation style missions, with A ‘Target’ - ‘Selector’ in mind…” - “Sir, I will. DefenestrateIT!”.

Blueprint Academy, still under construction:

{Padawan’s, again copy & replace the code with the bellow code into your Template Editor:

Now this code is because “expand” does not work for a “selector:” >< “target” when creating “Blueprints”.
Please Vote for the “expand” function to work for: Use expand on a value set from a target selector

{# Note the Code runs slightly different from "template editor" & when run from a "Blueprint". #}
{% set lights = { 
                  "area_id" :  [ "office" , "kitchen" ] ,
                "entity_id" :  [ "light.office_lights_group" , "light.kitchen_lights_group" ] ,
                "device_id" :  [ "0123456789abcdef0123456789abcdef" , "fedcba9876543210fedcba9876543210" ]
                }
%}
|{{lights.area_id}}|><|{{lights.entity_id}}|><|{{lights.device_id}}|

{%- set entities -%}
  {%- set ns = namespace(ret=[]) -%}
  {%- for key in ['device_id', 'area_id', 'entity_id'] -%}
    {%- set items = lights.get(key, [] ) -%}
    {%- if items %} {#@petroUlegend#}
      {%- set items = [ items ] if items is string else items -%}
      {%- set filt = key.split('_') | first -%}
      {%- set items = items if filt == 'entity' else items | map(filt ~ '_entities') | sum ( start = [] ) -%}
      {%- set ns.ret = ns.ret + [ items ] -%}
    {%- endif %}
  {%- endfor %}
  {{- ns.ret | sum(start=[]) -}}
{%- endset -%}
{%- set expanded = lights.entity_id | expand | map ( attribute = 'entity_id' ) | list %}
{%- set filtered = entities | select ( 'search' , '^light' ) | list %}

=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓=↓==↓=↓
---------------filter down to only light entities---------------------
{{ filtered }}
--------expanded for when lights.entity_id is a group---------
{{ expanded }}
--All referenced entities before "expand" & being filtered--
{{ entities }}
---------------------------------------------------------

For an example of a useless Blueprint Script:
Create A file called “test.yaml” in the directory: “/config/blueprints/script/DefenestrateIT/” & paste the bellow code. {# 4 @123 The Final solution! #}

blueprint:
  name: A Target Selector Test
  description: "A Variable State Test for Target Selector input"
  domain: script

  input:
    lights:
      name: Targeted Lights
      description: The Lights this Script is Targeted at.
      selector:
        target:
          entity:
            domain: light

variables:
  lights: !input lights
  entities: >
    {%- set ns = namespace(ret=[]) %}
    {%- for key in ['device_id', 'area_id', 'entity_id'] %}
      {%- set items = lights.get(key, [])  %}
      {%- if items %}
        {%- set items = [ items ] if items is string else items %}
        {%- set filt = key.split('_') | first %}
        {%- set items = items if filt == 'entity' else items | map(filt ~ '_entities') | sum(start=[]) %}
        {%- set ns.ret = ns.ret + [ items ] %}
      {%- endif %}
    {%- endfor %}
    {{ ns.ret | sum(start=[]) }}
  filtered: "{{ entities | select( 'search' , '^light' ) | select('is_state', 'on') | list }}"
  lights_on: "{{ filtered | count > 0 }}"
  transition: "{{ iif ( lights_on , 90, 0 ) }}"

sequence:
  - service: light.turn_on
    data:
      transition: "{{ transition }}"
    target: !input lights

And for a more Complex & useful example Of My Own Creation: Another Light Blueprint Script

For now may the force ever be with you…

Above is still (& will for ever be) under construction :building_construction:

#Reference's, &or Law of the land.
Python 3

python
Library
regular expression operations

Jinja2

Jinja2

Home Assistant

Home Assistant

Integrations
Docs
Developers
Community

Contributors:
@petro @Didgeridrew @CentralCommand

This was & for ever will be inspired by: {# & in loving memory of #}

The End

Terry Pratchett, & the Discworld.
:stuck_out_tongue_closed_eyes: :poop: :sob:

(Don’t forget to press the :white_heart: button if this was of help to you, or it just made you laugh & you sharted). :stuck_out_tongue_winking_eye:
P.S. Please feel free to press “Reply” & I’ll edit any new (or corrected) code to this original post…
My goal here is to learn A little more on how to template for HAss, (in the style I would have liked)
While sharing what I learned, please feel free (if you would like) to join in, on this epic journey of mine.
(all input is welcome):rofl:
Foot Note: try & make sense of that ChatGTP…

35 Likes

Just post links to where you’re copying these examples from so others can see them in their original form and context. In other words, create a curated list of links rather than duplicating other people’s work.

FWIW, what you posted has highly unusual amounts of creative whitespace that’s not likely to be present in the original examples.

1 Like

@DefenestrateIT - Thank you for compiling the list of examples! It is helping me better understand how templates work.

1 Like

Thank you for the constructive criticism, I have edited my original post to include (my interpretation of) your input (but i was planning on doing this anyway).
As I am a newbie myself, (& this is the type of info I would have liked to find, but couldn’t).
Perhaps since you obviously have vastly more experiences than I with HAss, you could answer A question/problem I am having with my second ‘code block’?
How do you filter the ‘light’ domain entities from a list of random entities? I.e… I am trying to avoid the ‘states.light’ command, & filter all the lights in the ‘office’?

1 Like

This should be in #community-guides, not #configuration. Other’s cannot add modify the templates, and some of the calls you have will lead to unexpected results. Just starting off, you have an issue in the 1st and 3rd template. You’re filtering out light groups in the ‘on’, but not the total and ‘off’. Making the 3 numbers not add up to each other.

This will end up like that epic time thread where most of the templates are outdated when the template methods are ultimately updated and made easier. Thanks for moving it, now anyone can edit the post and add/change the templates to work. I still can because I’ll lock everyone else out from editing because I’m a moderator. Not sure why that happens, but it does.

1 Like

:star_struck: petro :pray:
I was hoping you would notice this post…

This should be in Community Guides, not Configuration.

done.

you have an issue in the 1st and 3rd template.

If you mean the very top section, of the first ‘code block’? that is on purpose, it is suppose to lead into the rhetorical question of? what is wrong with the initial calculation.

But if you can answer this question for me, How do you filter the ‘light’ domain entities from a list of random entities? I.e… I am trying to avoid the ‘states.light’ command, & filter all the lights in the ‘office’? if there is a way to do this, i would like to demonstrate it? E.g.

area_entities ( lights.area_id ) | selectattr( 'device_class' , 'eq' , 'light' ) 

This will end up like that epic time thread where most of the templates are outdated when the template methods are ultimately updated and made easier.

Undoubtedly, but that is the way with all thing eventually, naturally (30 years in the industry here, most of what i have learned is obsolete). But I personally are on a mission to learn this, over the next few months. (Not that i am asking you to input that much time, just check in now and again & answer any lingering question that have not been answered.) Others here who are trying to learn will be able to take advantage of the examples written up too… & I would hope that i set a presidents for more light related examples given in the doc’s, as at this point of time that is what almost everyone starts off with in there HAss Domain.

With the greatest respect; Petro, I am really hoping you will share some of your vast wisdom on this epic mission of mine.

{{ expand(area_entities( lights.area_id )) 
| selectattr( 'domain' , 'eq' , 'light' )
| map(attribute='entity_id')
| list }}
1 Like

:pray: Thank you (Love the name btw). @Didgeridrew

The links you added aren’t what I had suggested you should do.

The template examples you have posted are obviously copied from somewhere else in the community forum. Instead of copying a template, just post a link to the forum topic where you found it.

A link allows the reader to see the template’s original context and commentary. In addition, if the reader has questions about the template, they can ask the template’s author. Odds are that the question they have may have already been asked and answered by someone else.

The links you added aren’t what I had suggested you should do.

I know, that’s why i wrote “my interpretation of”. To do what you wanted would destroy what i am trying to do, except if i add a foot note wrapped in {##} under an example. But honestly,

The template examples you have posted are obviously copied from somewhere else in the community forum.

The only code i have out write copied so far is Petro’s line ‘| rejectattr ( ‘attributes.entity_id’ , ‘defined’ )’, which i still don’t full understand how that works. But there’s a link to it at the bottom in ‘Counts the lights on’.
There is the line about hue groups & I did come across that some where that i can’t remember where but i change the name from hue to deconz (as that is what i use) & presto it worked.
Other than that, it’s all original code. When I say i am a newbie, I am a newbie with HAss. Tho I haven’t done any real coding in almost ten years, so I am a bit rusty.

btw - The white space is there because that is how I taught my self how to code 30 years ago. I always found it easier to read complicated formulas like that.

FYI to tag people use @… @DefenestrateIT

To quote people, highlight the text and click quote.

1 Like

Read up on state objects

Rejects items from a collection based on an attribute of the object (In python, they aren’t attributes, they are properties). Do not confuse the attr of rejectattr with attributes on the state object.

This is the attribute of the states object that you’re rejecting.

Does that attribute exist.

Putting it all together. You’re rejecting lights that have the entity_id attribute. Which specifically targets light groups as they are the only lights that have the entity_id attribute.

1 Like

If you are trying to eliminate a template example’s “how and why” then you have succeeded.

You have also succeeded in formatting the template examples in a style that doesn’t conform to common practice or the official documentation.

At the very least, use YAML code tags (the </> icon in the forum’s editor).

1 Like

Is the goal of this line to remove light groups from the list? If so here’s a more accurate way to do that:

              | rejectattr ('entity_id', 'in', integration_entities('group'))

Relying on whether random attributes are defined or not isn’t really good practice. Yes light groups have that attribute but there’s no rule saying that other lights don’t or can’t. You may accidentally exclude random lights from integrations that happen to set that attribute or users that have added it via customization.

integration_entities returns a list of all the entities for a particular integration (group in this case). So excluding everything that comes from that integration is a foolproof way to do that filtering.

I’m not really familiar with these attributes but I’m guessing similar issues apply:

Also that’s trivial:

{{ integration_entities('group') }}

TBH I’m a bit confused by this whole post. There’s a whole doc on templating here:

It describes all the filters, provides lots of examples, etc. The Jinja documentation is also very good and explains all the basics, along with the extremely important built-in filters and built-in tests sections. Both the Jinja doc and the HA doc are linked directly in HA on the Developer Tools → Templates page.

So what is this community guide adding exactly? If you think there’s some key example missing then why not just add them to the documentation? There’s an edit button right at the bottom of the Templating document. Click it and add in the relevant examples. Instead of compiling another list of examples here hidden away in community guides?

2 Likes

I think that’s meant to be rhetorical… as if this is a worksheet that someone is using to learn about templating… Based on the “theme” and previous examples it’s also probably meant to be Helper Light groups like:

{{ states.light 
| selectattr( 'attributes.entity_id' , 'defined' )
| map( attribute = 'entity_id' ) 
| list }}

But it’s confusing…


@DefenestrateIT

The section starting with the above quote has errors (area_id and area_name are not interchangeable) and makes no sense in term of audience and structure. If the target audience is users with little-to-no experience with templating, how are they going to know how to get a device_id, entity_id, and area_id? By starting it this way you create an impediment to new users and also cultivate an incorrect assumption that it’s necessary to set up a multi-part variable in order to access entity attributes.

The only drawback to that statement is unavailable entities do not show up under integration_entities. So you’re forced to use these work arounds to actually find all your lights, available or not.

They seem to show up for me…

Config for always unavailable light:

light:
  - platform: template
    lights:
      always_unavailable:
        unique_id: always_unavailable_light
        friendly_name: Always unavailable
        value_template: "on"
        level_template: "100"
        turn_on:
          event: now_im_valid
        turn_off:
          event: now_im_valid
        availability_template: "false"

Made a light group in the UI and put that light in it. Both lights definitely exist (that’s why I used the not recommended syntax of states.<entity ID>, got no errors), both have state unavailable, the group’s entity ID still comes back from integration_entities.

EDIT: I also just noticed that my “always unavailable” light group does not have an attribute of entity_id:

So it actually seems like the inverse might be true. integration_entities just works. Trying to find group entities by looking for the attribute entity_id requires extra work to handle edge cases, like when they are unavailable.

Hmm might be a bug in the integration I was helping a guy with earlier.