Script to find all ungrouped items

That’s perfect…dev mode on/off :slight_smile:

Okay, when I get home this evening, I will look at adding a couple more parameters (and maybe a bit of restructuring)

  1. show_as_view to control whether it is set as a view or not (default true)
  2. show_if_empty to control whether it is shown if there are no ungrouped items (I guess you guys want default false?)

I believe that should allow you guys to do what you’re looking to?

I haven’t tried Developer mode yet, but this way to toggle it is really cool. I’m learning a lot just from what you guys are sharing, thanks!

of course, I should have added this to my template switch:

switch:
  - platform: template
    switches:
      mode_developer:
        friendly_name: Developer mode switch
        value_template: >
          {{ is_state('input_select.mode', 'Developer') }}
        turn_on:
          - service: script.mode_developer_direct
          - service: homeassistant.turn_on
            entity_id: input_boolean.notify_developing

        turn_off:
          - service: script.mode_normal_direct
          - service: homeassistant.turn_off
            entity_id: input_boolean.notify_developing

Weirdly enough, when I run group.set with {"object_id": "catchall", "view":false, "visible":false}, instead of modifying group.catchall, it creates new group.catchall_2, group.catchall_3,…

besides a typo (had true instead of True for visible, attribs={“visible”:True, “view”:True, “friendly_name”: “Ungrouped Items”, “icon”: “mdi:magnify”}

all is fine here:

before:

33

click:

49

after:

14
32

changing Execute into Catch!

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

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.