Script to find all ungrouped items

After you have the group.catchall, can you run the group.set service from dev panel to see if it is removed/hidden?

I hope to do that by selecting the normal_mode again, or switching of my dev_mode switch. But here’s the dev tools:
09

and, unfortunately the group stays in view…
and, also unfortunately, I see a group.catchall_2… !
this is new, worked before.
maybe take the visibility and view out of the python.

Same here…something is not quite right there.

the script itself does work, I do it with my dev tools, and they show and hide on command. It is a predefined group though, which I simply have not grouped anywhere, so it shows up in the far right of the tab-bar, when made visible and a view by the script.

We should probably try to do the same with this Ungrouped catch_all group.

check, this works:

group:
  developer:
    name: Developer
    icon: mdi:developer-board
#    view: true
    entities:
      - switch.mode_developer
      - script.reload_frontend
      - script.reload_python
      - script.catchall
      - script.restart_ha
      - script.rc_reboot_iungo
      - script.sc_reboot_iungo
      - group.catchall # if made on the fly by python_script

group.developer is displayed as view in dev_mode (see previously posted switch, or input_select.mode).
it reveals the script for running the python script. (Ive removed the view: true in the python script)

running the script

script:
  catchall:
    alias: Catch all ungrouped
    sequence:
      - service: python_script.populate_catchall

creates the group.catchall, which is then displayed. Switching of dev-mode, takes it all out again :wink:

Cheers,
Marius

Hi guys,

here’s an updated version of the script.

I added three new parameters
show_as_view (whether to create it as a view or a group, defaults to True)
show_if_empty (whether to show the group or not depending on the number of items, defaults to False)
min_items_to_show (this controls the show_if_empty. It defaults to showing the group if at least one uncaught item was found).

I’ve also modified the script so that it doesn’t exclude Groups by default, so it will find groups that aren’t included anywhere (I found a few I’d forgotten about).

It also ignores Hidden items (alerts were causing me problems while testing, not sure how I will deal with this in the long run).

def scan_for_new_entities(hass, logger, data):
  ignore = data.get("domains_to_ignore","zone,automation,script,zwave")
  domains_to_ignore=ignore.split(",")
  target_group=data.get("target_group","group.catchall")
  show_as_view = data.get("show_as_view", True)
  show_if_empty = data.get("show_if_empty", False)
  min_items_to_show = data.get("min_items_to_show", 1)
  
  logger.info("ignoring {} domain(s)".format(len(domains_to_ignore)))
  logger.info("Targetting group {}".format(target_group))

  entity_ids=[]
  groups=[]
  
  for s in hass.states.all():
    state=hass.states.get(s.entity_id)
    domain = state.entity_id.split(".")[0]
    
    if (domain not in domains_to_ignore):
      if (domain != "group"):
        if (("hidden" not in state.attributes) or
             (state.attributes["hidden"] == False)):  
          entity_ids.append(state.entity_id)
      else:
        if (("view" not in state.attributes) or 
          (state.attributes["view"] == False)):
          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)))

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

  attrs={}
  attrs["view"]=show_as_view

  if (len(entity_ids)) > min_items_to_show or show_if_empty:
    attrs["visible"]=True
  else:
    attrs["visible"]=False

  attrs["friendly_name"]="Ungrouped Items"
  attrs["icon"]= "mdi:magnify"
  attrs["view"]=show_as_view
  attrs["order"] = high_order
  entity_ids.insert(0,"script.scan_for_new_devices")
  attrs["entity_id"]=entity_ids

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

scan_for_new_entities(hass, logger, data)
2 Likes

@NigelL

I’ve updated to the latest version of your script above and for some reason the catchall group/tab still shows up even though it is empty.

here is the automation that runs the script on start up (copied from yours above also - I did remove ‘automation’ because I like to list all my automations on a tab):

- alias: Get Ungrouped Entities On Start
  #hide_entity: true
  trigger:
    platform: homeassistant
    event: start
  action:
    service: python_script.populate_catchall_group
    data:
      domains_to_ignore: "zone,group,script,zwave"
      target_group: "group.catchall"

I’m not sure if I’m doing something wrong or if it’s bug related to my setup. I’m running hassbian, V0.69.1 so I wouldn’t think my setup is causing it.

Anything I can check?

The only thing I can think of would to change your logging level to Info so that you can see how many items the script thinks it has.

I did have a lot more logging lines in the code originally, but I removed them before posting it.

if the logging says there are entitys to be displayed, you could add this block of code at the same level as the logger.info lines.

for id in entity_ids:
  logger.info(id)

You might have some items from domains I didn’t ignore that don’t normally show up.

Unfortunately that’s all I can think of for now, I can try to reproduce it tomorrow after work.

How do I do that?

And where do I find those logs?

There’s a service on the developer-tools section called logger.setlevel

I believe the json you need to provide it is {“homeassistant.components”:“info”}

To find the logs, click on i in a circle on the right side of dev-tools

(I actually setup an input_select with the various log levels, and this automation)

- alias: Log Level
  trigger:
    platform: state
    entity_id: input_select.log_level
  action:
    service: logger.set_level
    data_template:
      homeassistant.components: "{{ trigger.to_state.state }}"

Thanks!

I’ll give it a try and let you know if I see anything.

For completeness sake, here’s the definition of the input_select I use

input_select:
  log_level:
    name: Log Level
    options:
      - critical
      - fatal
      - error
      - warning
      - warn
      - info
      - debug
      - notset
    initial: warn
    icon: mdi:file-document-box

awesome! Saves me the work of researching the different logger levels. Thanks again.

I changed the log level to info then re-ran the script from the services section and nothing showed up in the log.

that might be very useful, though, does this override the settings in the logger.yaml, or put differently, how does this interfere with logger.yaml? Wouldn’t want to set the log settings system wide on all components. Maybe set the data_template to homeassistant.components.python_script ?

thing to note: this line ignore = data.get("domains_to_ignore","zone,automation,script,zwave,scene") doesn’t allow spaces after a comma, or else it ignores the domain.

also, setting the view: True, fixes it in the tab bar (might be very dangerous depending on whats found…) so making that dynamic, based on a dev-mode setting seems preferable. As per i’ve describe above. I can confirm this works just as fine with your newest version, which is able to ignore ‘hidden’ entities, thanks for that.
Cool, a really useful tool you’ve made here. :+1:

@finity you probably want to set the view parameter to false based on Marius’ most recent comment.

@Mariusthvdb
The logger script I posted was what I use, and probably needs to be modified for anyone who is using it. It would be better if I could programmatically build a list of items we might want to set a log level for, but I haven’t looked at that yet.

The modification to allow spaces after commas will only take me a couple of minutes after work, so that will be up later today (my time)

If you don’t want the group set as a view, then I would suggest either passing a parameter to disable it, or changing the default value. Most people don’t have the Dev - mode, so I can’t code this around that

If I do that it doesn’t show at all, even if there are ungrouped items.

However, in poking around I found something interesting that might explain why it’s still showing in the tabs even if it’s empty:

Here is a screen grab showing that an entity still exists in the group but the tab is empty:

It’s the ‘script.scan_for_new_devices’ entity_id at the bottom.

of course you have to set it to be visible and show as view, if you desire to do so. after finishing whatever you need to do, you can close it again. I dont run the python on homeassistant.start but per manually started script in my tools:

had a nice cleanup!:

13

only two left, which I will probably leave there, to be sure the script is running alright :wink:

ive found this btw:

hass.states.set("group.catchall", "new", attrs) as also depicted in @finity 's screenshot. Is ‘new’ a special group state? havent seen that before, and not sure what is does.

check this:

ive set both view and visible to false, and the group is still showing. Might need a reload after having changed the python script on both settings to False (and let my automation take care of it), but maybe this ‘new’ interferes somehow? Why not have it set to 'On/ Off ’ depending on the state?

This is a half-lazy/half-lost post from half-lazily scanning the thread and getting half-lost trying to follow which replies are to which posts…

Can we have a consolidated post with the latest version of the python-script, and a working automation that creates/shows/hides the view on demand please? Save me working it out for myself when it appears all the work has already been done :smile:

this is the way I do it:

have an automation call these scripts for dev/normal mode:

scene_normal:
  alias: Call Normal scene
  sequence:
    - service: homeassistant.turn_off
      entity_id: group.philips_motion_sensor_switches
    - service: frontend.set_theme
      data_template:
        name: >
          {{ states.sensor.sun_based_theme.state }}
    - 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

have a group.developer with entity script.catchall:

script.catchall:
  action_name: 'Catch!'
  icon: mdi:baseball
  show_last_changed: true

##########################################################################################
## Groups
##########################################################################################

group:
  developer:
name: Developer
icon: mdi:developer-board
#    view: true
entities:
  - switch.mode_developer
  - script.reload_frontend
  - script.reload_python
  - script.catchall
  - script.restart_ha
  - script.rc_reboot_iungo
  - script.sc_reboot_iungo
  - input_select.log_level # package hassio_pi3_system
  - group.catchall # if made on the fly by python_script

set view and visible in the python_script to False , and let these automation and script hide/show the group catchall as part of the group.developer on demand.

run script.catchall manually if eand when desired.

screenshot:

normal mode:
54

click dev mode:
16

09
revealing group.developer and some, click Catch! and show Ungrouped Items:

flip developer mode switch back off:

31

using the last python_script here: Script to find all ungrouped items - #52 by NigelL

as a side note: the view setting can’t be templated, hence the hardcoding in the automation. I have several groups with visible: {{ true/false}} that can be templated based on the state of a mode switch.

  - alias: 'Dev Mode selection'
    id: 'Dev Mode selection'
    initial_state: 'on'
    trigger:
      platform: state
      entity_id: input_select.mode
    action:
      - service: group.set_visibility
        entity_id:
          - group.developer_links
        data_template:
          visible: "{{ is_state('input_select.mode', 'Developer') }}"

Unfortunately not an option (yet ) for view:

Filed a request for that. don’t expect too much of that ;-(

2 Likes