Script to find all ungrouped items


#21

Here is the file of my script - I’d love you to try to help me align the file to your code.

https://paste.ofcode.org/zD2vyFfpQZksei74twkM3W

#22

You don’t put the code in the scripts.yaml file. It’s not a yaml code, it’s a python script.

  1. create a folder named python_scripts in your home assistant configuration directory (in the same directory where your configuration.yaml is located - on my Raspberry Pi install it is located at /home/homeassistant/.homeassistant)

  2. in that folder create a file called populate_catchall_group.py

  3. copy the code from the first block at the beginning of this thread into that file and then save it.

  4. in your groups configuration create a group called “catchall” from the example posted by NigeIL in post #5 above.

  5. in your configuration.yaml file add the line python_script: somewhere.

  6. save everything

  7. restart home assistant

  8. now in the developers tools section of the home assistant interface go to the services icon. there you will find a drop down menu. locate the entry “python_script.populate_catchall_group”, select it then click on the “call service” button.

  9. done. - hopefully…


#23

work :smile:


#24

yay! :grinning:


#25

Hi @finity
if you change the line

hass.states.set("group.catchall", catchall.state, attrs)

to

if len(entity_ids) > 1:
  hass.states.set("group.catchall", catchall.state, attrs)

that should do it.
(the If should be at the same indent level as the current hass.states line, and hass.states should be one level further indented)


#26

Thanks very much for helping him @Finity


#27

Thanks, I’ll give it a try.

And no problem! :grinning:


#28

I’m going to try this out and just wanted to make sure the script was correct with changes mentioned throughout:

populate_catchall_group.py

ignore = data.get("domains_to_ignore","zone,group,automation,script,zwave")
domains_to_ignore=ignore.split(",")
target_group=data.get("target_group","group.catchall")

logger.info("ignoring {} domain(s)".format(len(domains_to_ignore)))
logger.info("Targetting group {}".format(target_group))

def scan_for_new_entities(hass, logger, domains_to_ignore, target_group):
  entity_ids=[]
  groups=[]
  catchall=hass.states.get(target_group)

  if (catchall is None):
    attribs={"view":True, "friendly_name": "Ungrouped Items", "icon": "mdi:magnify"}
    hass.states.set(target_group, "", attribs)
    catchall=hass.states.get(target_group)
  
  for state in hass.states.all():
    domain = state.entity_id.split(".")[0]
    if (domain not in domains_to_ignore):
      entity_ids.append(state.entity_id)
    if (domain == "group") and (state.entity_id != target_group):
      groups.append(state.entity_id)
    

  logger.info("==== Entity count ====")
  logger.info("{0} entities".format(len(entity_ids)))
  logger.info("{0} groups".format(len(groups)))

  for groupname in groups:
    group = hass.states.get(groupname)
    for a in group.attributes["entity_id"]:
      if a in entity_ids:
        entity_ids.remove(a)

  attrs={}
  for a in catchall.attributes:
    if a != "entity_id":
      attrs[a] = catchall.attributes[a]

  entity_ids.insert(0,"script.scan_for_new_devices")
  attrs["entity_id"]=entity_ids
  if len(entity_ids) > 1:
    hass.states.set("group.catchall", catchall.state, attrs)

scan_for_new_entities(hass, logger, domains_to_ignore, target_group)

#29

I don’t have my system in front of me right now to test it, but that looks like it should work.


#30

Yes, it works great, Thanks.


#31

I see you included the line (from post #24) to prevent the catchall group from showing up if it is empty. Does it still show the catchall group even if it’s empty?

@NigelL
I can’t get that part to work correctly. mine still shows up even tho it’s empty.


#32

HI, thanks for this!

works really fine, and ive rediscovered several items lost :wink:

when including groups, the script detects all groups that have view: true as being ungrouped… Is there a way to adapt the script to include groups, but leave the views, tabs, out?

also, as a solution for displaying it without the need to put the group in a yaml group anywhere, maybe this could be included:

- service: group.set
  data:
    object_id: catchall
    view: true
    visible: true

that way it would show up as a tab in the main frontend showing all entries automatically?

like: attribs={"visible":true, "view":True, "friendly_name": "Ungrouped Items", "icon": "mdi:magnify"}

51


#33

Hi @finity, If you have the indentation levels right, it will not add the group unless there are two or more items in it (including the trigger for the script). However, there is currently nothing in the script to remove the group if it already exists.

If you have already dealt with everything in the view, and want to get rid of it, you might need to restart HA.


#34

Love this, will hopefully integrate it so that the view appears when my maintenance mode is on, and disappears when it’s off.

Thanks for sharing :+1:


#35

Hi @Mariusthvdb

in order to get groups that aren’t included anywhere, try this (I’m not actually on my HA system right now, but this should work, or at least be pretty close). I can verify it when I am done work if necessary.

Remove group from the domains_to_ignore variable or parameter

Change the block which is currently this

  for state in hass.states.all():
    domain = state.entity_id.split(".")[0]
    if (domain not in domains_to_ignore):
      entity_ids.append(state.entity_id)
    if (domain == "group") and (state.entity_id != target_group):
      groups.append(state.entity_id)

to

  for state in hass.states.all():
    domain = state.entity_id.split(".")[0]
    if (domain not in domains_to_ignore):
      entity_ids.append(state.entity_id)
    if (domain == "group"):
      if (state.entity_id != target_group):
        groups.append(state.entity_id)
      if (("view" in state.entity_id.attributes) and (state.entity_id.attributes["view"] == false)):
        entity_ids.append(state.entity_id)

I will take a look at the group.set service (I wasn’t aware of it until just now, and also see there’s a group.remove). One thing I have found frustrating is because I am doing everything inside a function, a lot of objects aren’t automatically available (which is why I pass hass and logger into the function)


#36

cool.

we can set the groups visibility and the view easily with the code I posted.

Ive filed a request to do so with a template, as is possible with group.set_visibility alone.

which is kind of cool, since one can then template that depending on a mode (in my settings a dev-mode… or not)

as it stands now, we have to hard code it. Works but less elegant.

Running the python script now creates the group as a view, as I have screenshot and posted.


#37

We should be able to toggle the view. Instead of always setting to true, we should be able to enable/disable when we want it


#38

see Allow for full templating support in Group.set


#39

Ohh…that is unfortunate. I guess, we can have two separate actions


#40

yes, that how I do it now:

scene_normal:
  alias: Call Normal scene
  sequence:
    - service: homeassistant.turn_off
      entity_id: group.philips_motion_sensor_switches
    - service: input_select.select_option
      data:
        entity_id: input_select.theme
        option: 'teal'
    - service: group.set
      data:
        object_id: developer
        view: false
        visible: false

scene_developer:
  alias: Call Developer scene
  sequence:
    - service: homeassistant.turn_off
      entity_id: group.philips_motion_sensor_switches
    - service: input_select.select_option
      data:
        entity_id: input_select.theme
        option: 'matrix'
    - service: group.set
      data:
        object_id: developer
        view: true
        visible: true