Customize python created entities: attributes 'templates"

hi,

apparently one can not customize a sensor created in a python_script the way we can using regular or custom_ui templating. Ive used this:

sensor.family_home:
  templates:
    icon_color: >
      {% if state === '0' %} 'rgb(128, 128, 128)'
      {% elif state === '1' %} 'rgb(248, 248, 255)'
      {% elif state === '2' %} 'rgb(30, 144, 255)'
      {% elif state ==='3' %} 'rgb(0, 128, 0)'
      {% elif state === '4' %} 'rgb(255, 255, 0)'
      {% elif state === '5' %} 'rgb(255, 165, 0)'
      {% elif state === '6' %} 'rgb(255, 165, 0)'
      {% else %} 'rgb(117, 21, 120)'
      {% endif %}

#      {% if is_state('sensor.family_home', '0') %} 'rgb(128, 128, 128)'
#      {% elif is_state('sensor.family_home','1') %} 'rgb(248, 248, 255)'
#      {% elif is_state('sensor.family_home','2') %} 'rgb(30, 144, 255)'
#      {% elif is_state('sensor.family_home','3' )%} 'rgb(0, 128, 0)'
#      {% elif is_state('sensor.family_home','4') %} 'rgb(255, 255, 0)'
#      {% elif is_state('sensor.family_home','5') %} 'rgb(255, 165, 0)'
#      {% elif is_state('sensor.family_home','6') %} 'rgb(255, 165, 0)'
#      {% else %} 'rgb(117, 21, 120)'
#      {% endif %}

on this basic sensor created in Python_script:

hass.states.set('sensor.family_home', count_home, {
    'custom_ui_state_card': 'state-card-custom-ui',
    'friendly_name': "Family Home?",
    'home': ', '.join(home),
    'away': ', '.join(away),
    'icon': whichIcon,
    'count_home': count_home,
    'count_away': count_away,
    'family_count': familyCount,
    'show_last_changed': 'true'
     })

as you can see ive enabled the custom_ui for this sensor, but no succes.

ive other python_script sensors using a templates attribute with succes. I cant find a way though to use the above template in this setting:

hass.states.set('sensor.family_home', count_home, {
    'custom_ui_state_card': 'state-card-custom-ui',
    'friendly_name': "Family Home?",
    'home': ', '.join(home),
    'away': ', '.join(away),
    'icon': whichIcon,
    'count_home': count_home,
    'count_away': count_away,
    'family_count': familyCount,
    **'templates': icon_color,**
    'show_last_changed': 'true'
     })

any thoughts on how to do this appreciated please?

thx,
Marius

hass.states.set doesn’t create an entity. It only creates state in the state machine.

Hi
Not sure What you’re saying, since all the other attributes work as expected.
See the Icon or show_last_changed.

Icon is set via the variable declared in the python . That’s why I hoped icon_color could be templated too.

00

below is an example of a script that uses templates:

    hass.states.set(entity_id, groups_count[idx], {
      'friendly_name': fname,
      'desc' : badges_desc[idx],
      'unit_of_measurement': badge,
      'entity_picture': picture,
      'templates': { 'theme': theme }
    })

and the theme is ‘templated’ as follows:

    themelist = groups_theme[idx].split('|')
    if len(themelist) > 1:
        try:
            theme = themelist[groups_count[idx]]
        except IndexError:
            theme = 'green_badge'
    else:
        theme = 'black_badge'

would have hoped this to work, but not yet…

family_color = ['rgb(128, 128, 128)'|'rgb(248, 248, 255)'|'rgb(30, 144, 255)'|'rgb(0, 128, 0)'|'rgb( 255, 255, 0)'|'rgb( 255, 165, 0 )'| 'rgb(117, 21, 120)']

icon_color = family_color[count_home].split('|')

and then finally:

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,
‘templates’: { ‘icon_color’: icon_color },
‘show_last_changed’: ‘true’
})

@petro would you have a suggestion? Ive also tried the family_color list without the [ ] , but that doesn’t make a difference in the error call:

Error executing script: unsupported operand type(s) for |: 'str' and 'str'
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/python_script.py", line 166, in execute
    exec(compiled.code, restricted_globals, local)
  File "family_home.py", line 11, in <module>

ive been able to verify this works:

'templates': { 'icon_color': 'rgb(169, 104, 54)' },

09

so it’s a matter of getting these rgb colors (dont take the specific colors serious yet, its a quick cut and paste):

familyColor = ['rgb(128, 128, 128)', #count_home = 0
               'rgb(248, 248, 255)',  #count_home = 1
               'rgb(30, 144, 255)',  #count_home = 2
               'rgb(0, 128, 0)',  #count_home = 3
               'rgb(255, 255, 0)',  #count_home = 4
               'rgb(255, 165, 0)',  #count_home = 5
               'rgb(117, 21, 120)'] #  #count_home = 6

into this variable:

icon_color = familyColor[count_home] somehow…

well, sorry, but I seem to have answered my own question, this is working fine now …:wink:

##########################################################################################
# family_home.py, based on Whats_on.py, previously known as Anything_on...
# by https://community.home-assistant.io/u/Mariusthvdb/summary
##########################################################################################

familyEntities = 'group.family'
familyColor = ['rgb(128, 128, 128)',  # count_home = 0
               'rgb(128, 205, 128)',  # = 1
               'rgb(0, 0, 255)',      # = 2
               'rgb(251, 210, 41)',   # = 3
               'rgb(255, 135, 0)',    # = 4
               'rgb(255, 15, 0)',     # = 5
               'rgb(0, 137, 0)']      # = 6

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

def CountMyEntities(hass, entity_list, entity_state):
    cnt = 0
    for entity_id in hass.states.get(entity_list).attributes['entity_id']:
        state = hass.states.get(entity_id)
        if state.state == entity_state:
            cnt = cnt + 1

    return cnt

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


def NameMyEntities(hass, entity_list, entity_state):
    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= 2)
        time = '%02d:%02d' % (dt.hour, dt.minute)
        if state.state == entity_state:
            name = '{} ({})'.format(state.attributes['friendly_name'], time)
            names.append(name)
    
    return names

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

familyCount = count_home + count_away
#whichIcon = 'mdi:account-off' if count_home == 0 else \
#            'mdi:account' if count_home == 1 else \
#            'mdi:account-multiple' if count_home == 2 else \
#            'mdi:account-group'

try: whichIcon = familyIcon[count_home] 
except IndexError: whichIcon = 'mdi:account-group' # count_home > 2

icon_color = familyColor[count_home]

hass.states.set('sensor.family_home', count_home, {
    'custom_ui_state_card': 'state-card-custom-ui',
    'friendly_name': "Family Home?",
    'home': ', '.join(home),
    'away': ', '.join(away),
    'icon': whichIcon,
    'count_home': count_home,
    'count_away': count_away,
    'family_count': familyCount,
    'templates': { 'icon_color': icon_color },
    'show_last_changed': 'true'
     })

nice:

5136
04

change this to

family_color = ['rgb(128, 128, 128)','rgb(248, 248, 255)','rgb(30, 144, 255)','rgb(0, 128, 0)','rgb( 255, 255, 0)','rgb( 255, 165, 0 )','rgb(117, 21, 120)']
# the % symbol is mod, that means it will cycle through the list and never get 'Index out of range'
icon_color = family_color[count_home%len(family_color)]

also, this is bad practice:

try:

# If we have less than or equal to 2 people home, get the correct icon, otherwise just use the last icon in the list.
whichIcon = familyIcon[count_home] if count_home <= 2 else familyIcon[-1]

thanks! done.
had the whichIcon setup like that before, but wasn’t sure about the else definition so created the same construction as in the summary.py we discussed earlier. This is cleaner and much simpler :wink:

about the mod: will this imply that if a 7th family member were to be created (… pure technically speaking that is …) , it would get the color if the 1st item in the list again?

Yes, this is a table going to 40:

Number of family members list index color
0 0 rgb(128, 128, 128)
1 1 rgb(248, 248, 255)
2 2 rgb(30, 144, 255)
3 3 rgb(0, 128, 0)
4 4 rgb( 255, 255, 0)
5 5 rgb( 255, 165, 0 )
6 6 rgb(117, 21, 120)
7 0 rgb(128, 128, 128)
8 1 rgb(248, 248, 255)
9 2 rgb(30, 144, 255)
10 3 rgb(0, 128, 0)
11 4 rgb( 255, 255, 0)
12 5 rgb( 255, 165, 0 )
13 6 rgb(117, 21, 120)
14 0 rgb(128, 128, 128)
15 1 rgb(248, 248, 255)
16 2 rgb(30, 144, 255)
17 3 rgb(0, 128, 0)
18 4 rgb( 255, 255, 0)
19 5 rgb( 255, 165, 0 )
20 6 rgb(117, 21, 120)
21 0 rgb(128, 128, 128)
22 1 rgb(248, 248, 255)
23 2 rgb(30, 144, 255)
24 3 rgb(0, 128, 0)
25 4 rgb( 255, 255, 0)
26 5 rgb( 255, 165, 0 )
27 6 rgb(117, 21, 120)
28 0 rgb(128, 128, 128)
29 1 rgb(248, 248, 255)
30 2 rgb(30, 144, 255)
31 3 rgb(0, 128, 0)
32 4 rgb( 255, 255, 0)
33 5 rgb( 255, 165, 0 )
34 6 rgb(117, 21, 120)
35 0 rgb(128, 128, 128)
36 1 rgb(248, 248, 255)
37 2 rgb(30, 144, 255)
38 3 rgb(0, 128, 0)
39 4 rgb( 255, 255, 0)

cool, that would suffice :wink:

glad to have it working, so many thanks!

really cool to finally have solved the customizing of sensors, and probably other components created in a python_script. Had that on the todo list for a longer time, and now can create several nice embellishments.

Will change the thread title accordingly, so others can benefit from it too.

wrapping it up, and make it complete, one has to run the python_script of course. I do it per timed trigger, and not per state change, since that is still somewhat awkward with these devices, that trigger the state change also when attributes change, and even then, are not always as reliable. One can template that in the condition:

condition:
  - condition: template
    value_template: >
      {{ trigger.to_state.state is not none and
         trigger.from_state.state is not none and
         trigger.to_state.state != trigger.from_state.state }}

or simply run it every 30 sec or so:

- alias: 'Call Family Home'
  id: 'Call Family Home'
#  initial_state: 'on'
  trigger:
    platform: time
    seconds: '/30'
  action:
    service: python_script.family_home

lastly, other than listing all devices entity_ids in the trigger: state part of the automation, Ive learned with @pnbruckner that this can also be done using the event state change:

- alias: 'State changed Family'
  id: 'State changed Family'
#  hide_entity: True
#  initial_state: 'on'
  trigger:
    platform: event
    event_type: state_changed
  condition:
    condition: template
    value_template: >
      {{ trigger.event.data.entity_id in state_attr('group.family','entity_id') }}

very nice to have in the automations toolbox.

Thx,
Marius

1 Like