Count people that are home

this could be a quick one:

what about the /www/badge .png’s
if show_badges:
for badge in groups_badge:
if (badge != ‘’):
entity_id = ‘sensor.{}_badge’.format(badge.replace(’ ', ‘’).lower());
hidden = False if (groups_count[idx] > 0 or debug) else True
fname = groups_desc[idx] if debug else ’ ’
picture = ‘/local/badges/{}.png’.format(groups_badge_pic[idx]) if (groups_badge_pic[idx] != ‘’) else ‘’

and activity? Id like to show these too. Bug is only if an error/alert is present i think?, but the sensor.activitiy.badge need the underscore too.I cant show the correct png’s for the same reason as the profile selection.

Btw, Would it be cool to combine these in to one bigger Summary, import the activity into the python script and see it as one ‘package’. Might be easier to debug and not as complicated finding al references which now are spread a bit over the various files?

hmmmmm:

Log Details (ERROR)
Wed Dec 06 2017 23:48:08 GMT+0100 (CET)

Error loading script summary.py: Line 120: SyntaxError: invalid character in identifier in on statement: 'entity_picture':  '/local/profiles/{' '}.png'.format(state.state.lower().replace(’ ', ‘_’)),

never mind that one, was an wrong ’ ’ error.
Still no pictures are displayed, must try something else :wink:
Cheers,
Marius

Yes, bug is only visible when there is a problem (1+ device offline)
You need to do a replace for each set picture, the image file cannot contains space, in all other places stay with space…
I have updated my script and tested this, seems all working (I set it up to ignore space, so ‘Show off’, has a ‘showoff.png’)…

I decide to do the activity in a separate script because this funcionality will grow, and have in a separated file it will be more readible. Also I’m using datetime.now and notification (in the future) so the script need to be called only when a activity changed, not in a time interval (like summary).
For the other packages I put links to the related files inside the script :wink:

Cool!
I can confirm the developer bit to work right now and change pictures correctly, in 2 ways: in the first place does it change, and 2, it reads the right pictures with and without spaces:

Activity does not do that yet in my setting. It doesn’t change automatically, and it doesn’t read the right pictures, or doesn’t show the pictures where spaces are involved. will try to debug that.

maybe has to do with this:

Log Details (ERROR)
Thu Dec 07 2017 08:07:38 GMT+0100 (CET)

Error executing script: 'NoneType' object is not callable
Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/homeassistant/components/python_script.py", line 166, in execute
    exec(compiled.code, restricted_globals, local)
  File "last_cmd.py", line 7, in <module>
TypeError: 'NoneType' object is not callable

Could we add and display the Activity mode in the Summary Badge, below the selected profile? Making it into a real Summary!

I was thinking to have 4 Modes:
1 Normal. speaks for itself :wink: That is to say, only load Overview, Map, logbook history and shopping list (possibly LogOut) in the left side menubar
2 Crowded: all kinds of automatics going on to have the house setup for climatic adjustments, maybe even automatically triggered by several sensors
3 Your Show-off, I’ve renamed that to Kiosk: show HA in Kiosk mode. NO left side bar at all
4 developer: with all dev tools in the left side menu bar (IDE, Terminal, NodeRed, IDE,Configurator, maybe even Hassio and the developer tools at the bottom ) this it what i would want to take out in the Normal mode.

Don’t know if thats even possible, would probably require restarts for each mode, but how cool wold that be!

Cheers,
Marius

Indeed, that’s the way i would like the updating to happen: based on state changes, not the brute force method of every 2 seconds.

Thats why I’ve tried this for the alarm-clock module, but it doesn’t call the python script, as i thought it would.
I thought to have learned not defining a specific state change, would mean the automation to hit on any state change?
alarmclock_full = alarm clock_wd+alarmclock_we

# Call Python:Summary after AlarmClock state change
  - alias: 'Sense Alarmclock state-change and update Summary'
    id: '1511601479003'
    hide_entity: True
    initial_state: 'on'
    trigger:
      - platform: state
        entity_id: group.alarmclock_full
    condition: []
    action:
      - service: python_script.summary

for what its worth,
ive debugged some of the automations, and found some listings that consisted of only one time, but still had the - in front of them.

changed that into this for example:

automation:
  - alias: 'Profile change'
    id: '1511601479005'
    hide_entity: True
    initial_state: 'on'
    trigger:
      platform: state
      entity_id: input_select.ha_mode
    condition: []
    action:
#      service: script.refresh
      service: python_script.summary

And working perfectly and instantaneous now. Will try the other automations with this approach and see what happens.

—edit-----

same goes for activity now, changed it like this:

# Sensor update
hass.states.set('sensor.activity_badge', state_value, {
    'friendly_name': ' ',
    'entity_picture': '/local/activities/{' '}.png'.format(state_value.replace(' ','').lower()),
    'unit_of_measurement': 'Act'
})


Cool!

@mviezzer
HI, doing some serious training here, thanks to your wonderful scripts!
For my assurance i would love to have a thumbs up in place of the Bug, when all devices are ok. So i cn be 100% positive the scripts and automations are working as they should.
What would i need to change in the groups_badge definition to get that to show up?
Please have a look how we can do that.

thumbsup

Thanks,
Marius

1 Like

Yeah, not ideal, but I don’t want set each entity in automations… But now I think that I found a generic way, trying later on…

I’ll try this, but in a nutshell here is the idea.
groups_badge_pic = [‘’, ‘’, ‘ok|bug|error’] # a list of images to mach the count, for 0 use ok, 1 bug, 3+ error…
groups_min_show = [1, 1, 0] # a new array with minimun count to show

I’ll create a new thread for the Summary script.

That would be wise;-)

I for one would like to accomplish the text below the Badges, i cant get it to happen…

btw, adding the customization to these badges doesn’t do anything in my setup, with or without, they show as attached:

##########################################################################################
# Summary
##########################################################################################
#sensor.activity_badge:
#  state_card_mode: badges
#sensor.profile_badge:
#  state_card_mode: badges
#sensor.home_badge:
#  state_card_mode: badges
#sensor.inuse_badge:
#  state_card_mode: badges
#sensor.alert_badge:
#  state_card_mode: badges

I’ve checked again, and although in the documentation is pointed out this should work, and a state change for the entities in the group should cause the automation to trigger, it actually doesn’t. And when i check in the <> developers state inspector, that seems correct, for the group is stated Home, even when members are not home …

Hence i tried this:

# Call Summary after Family Presence change
- alias: 'Sense Family presence and update'
  id: '1511601478031'
#  hide_entity: True
  initial_state: 'on'
  trigger:
    platform: state
    entity_id: device_tracker.marijn,device_tracker.wijke,device_tracker.frederike,
               device_tracker.marte,device_tracker.louise,device_tracker.hanna
  condition: []
  action:
    service: python_script.summary

And with immediate succes.

Leads to the next desire: to have an automation dynamically be created for group members of the focus groups in the Python script Summary:

definitions Summary right now:

# Entities summary by group name
groups = ['group.family', 'group.audio', 'group.imac']
groups_format = ['{} at home: {}', '{} in use: {}', '!{} offline: {}']
groups_filter = ['home', 'on|playing|home', 'off|idle|not_home']
groups_badge = ['Home', 'In use', 'Alert']
groups_badge_pic = ['', '', 'bug']
groups_desc = ['Nobody in home', '', '']
groups_count = [0, 0, 0]

So automation should be created for members of group.family, group.audio, group.imac.

Is that possible, preferably in 1 automation? That would catch all issues left.

Cheers,
Marius

New topic for the summary: Summary card and badges for people, devices and status (with python script and custom card)
I found a way to call the summary only when needed (for scripts and switchs at least). For people I set a 1 minute interval automation…

Please help
Error when restart home assistant:
the following components and platforms could not be set up python script

What this error means:

expected an indented block in on statement: state = hass.states.get(entity_id)

Hi, very good python script.
Is it possible to filter some people by the friendly_name ?

Found it by myself

for entity_id in hass.states.entity_ids('device_tracker'):
  state = hass.states.get(entity_id)
  if state.name == 'XXXXX':
   continue
  if state.state == 'home':
			home = home + 1	

You can also use the persons:

home_count = 0
home_desc = ""
inuse_count = 0
inuse_desc = ""
summary = ""

for entity_id in hass.states.entity_ids('person'):
    state = hass.states.get(entity_id)
    if state.state == 'home':
        home_count = home_count + 1
        home_desc = home_desc + state.name + ', '

if home_count > 0:
    home_desc = str(home_count) + ' Personen: ' + home_desc[:-2]
else:
    home_desc = 'Niemand zu Hause'

summary = home_desc

hass.states.set('sensor.people_home', home_desc, {
    'friendly_name': 'Personen zu Hause'
})
1 Like

o dear this has been a long time…

evolved from the summary script quite extensively, and, using the people counter has become this in my setup:

familyEntities = 'group.family_home'
daughterEntities = 'group.daughters_home'
familyColor = ['grey',  # count_home = 0 #808080
               'steelblue',  # = 1
               'saddlebrown',      # = 2 #00f
               'gold',   # = 3 #fbd229
               'darkorange',    # = 4 #ff8700
               'maroon',     # = 5 #ff0f00
               'green']      # = 6

familyIcon = ['mdi:account-off',      # count_home = 0
              'mdi:account',          # = 1
              'mdi:account-multiple', # = 2
              'mdi:account-multiple-check', # = 3
              'mdi:account-group']    # > 3

utc_offset = hass.states.get('sensor.utc_offset').state
timeDifference = float(utc_offset)

def CountMyEntities(hass, entity_list, entity_state=None, not_state=None):
    cnt = 0
    for entity_id in hass.states.get(entity_list).attributes['entity_id']:
        state = hass.states.get(entity_id)
        if entity_state is not None and state.state == entity_state:
            cnt = cnt + 1
        if not_state is not None and state.state != not_state:
            cnt = cnt + 1
    return cnt


count_home = CountMyEntities(hass, familyEntities, 'home')
count_away = CountMyEntities(hass, familyEntities, not_state='home')


daughter_count_home =  CountMyEntities(hass, daughterEntities, 'home')
daughter_count_away =  CountMyEntities(hass, daughterEntities, not_state='home')

def NameMyEntities(hass, entity_list, entity_state=None, not_state=None):
    global timeDifference
    names = []
    for entity_id in hass.states.get(entity_list).attributes['entity_id']:
        state = hass.states.get(entity_id)
        dt = state.last_changed + datetime.timedelta(hours= timeDifference)
        time = '%02d:%02d' % (dt.hour, dt.minute)
        if entity_state is not None and state.state == entity_state:
            name = '{} ({})'.format(state.attributes['friendly_name'], time)
            names.append(name)
        if not_state is not None and state.state != not_state:
            name = '{} ({})'.format(state.attributes['friendly_name'], time)
            names.append(name)

    return names

home = NameMyEntities(hass,familyEntities,'home')
away = NameMyEntities(hass,familyEntities,not_state='home')


daughter_home = NameMyEntities(hass,daughterEntities,'home')
daughter_away = NameMyEntities(hass,daughterEntities,not_state='home')


familyCount = count_home + count_away
daughterCount= daughter_count_home + daughter_count_away

daughterIcon = familyIcon[daughter_count_home] if daughter_count_home <= 3 else familyIcon[-1]
whichIcon = familyIcon[count_home] if count_home <= 3 else familyIcon[-1]

# the % symbol is mod, that means it will cycle through the list and never get 'Index out of range'
icon_color = familyColor[count_home%len(familyColor)]
daughter_icon_color = familyColor[daughter_count_home%len(familyColor)]

hass.states.set('sensor.family_home',count_home,{
    'friendly_name':'Family Home?',
    'home':', '.join(home),
    'away':', '.join(away),
    'icon':whichIcon,
    'count_home':count_home,
    'count_away':count_away,
    'family_count':familyCount,
    'icon_color':icon_color
     })

hass.states.set('sensor.daughters_home',daughter_count_home,{
    'friendly_name':'Daughters Home?',
    'home':', '.join(daughter_home),
    'away':', '.join(daughter_away),
    'icon':daughterIcon,
    'count_home':daughter_count_home,
    'count_away':daughter_count_away,
    'daughter_count':daughterCount,
    'icon_color':daughter_icon_color
     })

does a few more things, guards for None entities, checks the correct time using sensor.utc_offset and customizes (because python created entities cant be customized using regular ha customize: )

2 Likes

Isn’t this easier to just use?

{{states.person|selectattr('state', '==', 'home')|list|count}}
2 Likes

I did the same and actually it works quite fine for me… just counting the persons at home of course… YAMIL script works as sensor in my case, actually I would test a group with the “expand” function so that it would be easy to enlarge or reduce the group when necessary instead of listing person.person1…X in the sensor code.

I’d suggest, yes :slight_smile:

Thanks, saved me the effort of working this out :grinning_face_with_smiling_eyes:

Using a recent version of Home Assistant it is even easier, as zones now have a state representing the number of persons in it:

{{ states('zone.home') | int }}
1 Like