Request: Give the ability to add attributes to "People" entities

The way I’m imagining this working is in the /config/person menu, you can click to edit a person and it brings up the normal menu it already does, but there’s another tab where you can specify templates to act as attributes for the person.

Being able to combine all these sensors from other integrations to my person would make me very happy :smiley:

This is exactly what I need. Have you found any solution to this?
I’m trying to add MS Teams status to 50+ Persons in our Home Assistant.

3 Likes

You can add custom attributs to person by adding them in configuration.yaml
Example:

default_config:

homeassistant:
  customize:
    person.me:
      - my_attribute: myvalue
      - my_second_attribute: 
        - mysecondvalue_one
        - mysecondvalue_two
1 Like

That only allows for static attributes though, right? Not other sensors?

What I want as an attribute is their statuses across various other integrations. So like I’d want something like…

homeassistant:
  customize:
    person.me:
      - key_location: [the state of the device_tracker.my_keys]
      - xbox_status: [the state of my sesor.me_xbox_status]

That way I can just drop a person card on my lovelace, click into it, and easily see all the different values that are important to me about that person.

I’m working on something that whould show someone “gaming status” (Steam and Xbox).
And I have to do many things into the javascript card code to parse and merge different sensors data.

I’d love to be able to link sensors to persons, it would make my work a lot easier. Like being able to template the value of an attribute on a person :star_struck:

1 Like

any news on this? i want to save the access point the device is connected to in the person entity.
like this:

1 Like

I would also like this ability, adding things like:
Work_Status: Standard/Vacation/On-Call
Home_Status: Resident/Guest/Privileged_Guest/Overnight_Guest
Voice_Status: LiveMic/Muted/Offline
These attributes could be templated or just changed via an API/Service call.

Would be nice for some automations, information displays and for usage within messaging services. Some of this could be worked through by adding some things to the new calendar, but some of it would be difficult.

Next solution is valid for me: example adding nfc_card attribute to person domain.

Inside configuration.yaml

# Adding attributes to persons
homeassistant:
  customize_domain:
    person:
      nfc_card: ""
# Load python scripts
python_script:

Create: python_scripts/set_cards.py

#---------------------------------
# Set nfc_card attribute to person
#---------------------------------
inputEntity = 'person.fquinto'
inputStateObject = hass.states.get(inputEntity)
inputState = inputStateObject.state
inputAttributesObject = inputStateObject.attributes.copy()
inputAttributesObject['nfc_card'] = '12345678'
hass.states.set(inputEntity, inputState, inputAttributesObject)

Or another script like this: How to manually set state/value of sensor? - #3 by rodpayne

References

Be advised that using hass.states.set to set an entity’s state or attributes property is temporary and only lasts until Home Assistant is restarted.

do you have a better option? I appreciate the advise so everyone can reset the state via automation, but is there something you know about how to do this better?

A better option to do what exactly?

It’s advice with a significant drawback; the value that’s set is temporary.

Generally speaking, a sensor entity in Home Assistant is read-only. That’s why there’s typically no service call to set a sensor’s state. The sensor’s underlying integration has exclusive control of the sensor’s value.

If you need a sensor entity whose state value you can set permanently (i.e. the value survives a restart), consider using a Trigger-based Template Sensor. The Template integration gives you complete control over the behavior of a Template entity.

1 Like

One solution that I starting using for this was helpers, and then on-boot automation to write the appropriate data over to the person entity. This worked well when I had only a couple people and a couple attributes, but it’s ballooned way out of control, and is completely unmanageable.

For the past few years, I’ve been trying to come up with an effective way to manage people better in Home Assistant, and over that time, I’ve come across multiple half-measures, but nothing very solid to say the least.

My new in-development approach is to use AppDaemon and a couple helper text fields. All the attributes are stored in a custom sensor entity (person_attribute.store), and on start, AD applies those attributes to the people. To edit the attributes, I use the helpers to select Person Entity, Attribute name, and value, and then AppDaemon grabs those values and applies them to the person and the attribute store.

I’m about halfway done with writing it all up, so hopefully it works.

Instead, if Home Assistant would just make this easier for me, I’d like it so much better!

2 Likes

i write the attribute “last_room” to my person.ben but after some secounds it get deleted :frowning:

action: python_script.exec
data:
  file: python_scripts/set_state.py
  entity_id: person.ben
  last_room: "TEST"

+1! Would also love to add dynamic attributes to existing sensors (without some crazy python stuff), especially the person sensor. My example would be defining an own “home” status information for whether someone is connected with the WiFi or not.

1 Like

+1 from me too. I’ve been giving the LLM Vision integration a try and thought it would be great to be able to update a persons ‘status’ based on the image analysis from a camera. I think this would require the ability to add a helper sensor, but it’s a similar principal.

Person Status: ‘Watching TV’, ‘Cooking’, ‘Washing Car’, ‘On Laptop’, ‘Eating’, ‘Hanging out Washing’, ‘Watering Plants’ etc.

This could then be queried with LLM and asked things like; ‘when did Person last wash the dishes?’ or have automatic completion of personalised tasks on a to-do list that can’t be tracked directly in home assistant, like tidying a room for example.

1 Like

It’s offtopic to this thread, but the Bermuda integration somewhat recently implemented a “last room” attribute!

I want to see the people feature overhauled the same way that devices were.

Devices used to be just entities, now. Devices are a group of related entities.

People need the same treatment. There are lots of different sensors and controls that are related to a particular person.

Sure, there’s the device tracker from my primary cell phone, but what about my other devices? Like my tablet, my laptop, my backup phone, or other devices that I don’t always have on me, but still are one of my devices.

And what about things like my current steam activity, or my personal calendar, what about things like my fitness sensors or my personal to-do list?

3 Likes

I’d like to echo this request. It would be really useful to expand the core attributes on person entities, such as date of birth, email, phone number, preferred notification device etc.

With that kind of metadata, you could automate things like:
• Send an email to person.jenny on her birthday
• Remind person.sourbrambles on their tablet or preferred speaker X days before to buy a present - it’s a big one, she’s 40
Etc.

I appreciate this is already possible using calendars or other integrations, but having this information directly on the person entity would make personal automations much more natural and reduce the need for scattered helpers or workarounds.

There’s also potential for things like:
• Medication reminders
• Favourite lighting, music or temperature for scenes
• Tags like “guest”, “child”, or “pet sitter”
And that’s just scratching the surface and with little thought.

Some might argue this isn’t “home automation”, but I’d say it absolutely is. Home Assistant is the modern homemaker and giving it better context helps it do that job more thoughtfully.

4 Likes

Starting to get deeper in HA and automations, it hit me the same quest with all others: Person metadata. Till now the huge effort is to include new devices, adapt AI and make easier the UI development.
All previous are so welcome but we miss something: As devices have attributes, people also have a ton of attributes (I will not repeat all good point previously mentioned). Person Metadata are more broad approach.

Putting some AI magic the person metadata (if someone like purple color, suggest to dim lights on purple sense during night) would be a personal experience.

We really need person metadata on 2026? YES!

2 Likes

My solution to this problem ended up being a custom template sensor sensor.person_data, an AppDaemon program, with a custom Lovelace card setup to make it all work.

Then, if I want to get any data out, I just pull it out of sensor.person_data.

Template Sensor (configuration.yaml):

template:
  # Person Data Storage
  - trigger:
    - platform: event
      event_type: set_person_data
    - platform: event
      event_type: remove_person_data
    sensor:
    - unique_id: 474f308c-61fc-4732-9991-187893762636
      name: Person Data
      state: Person Data
      attributes: 
        data: >
          {% set current = this.attributes.get('data',{}) %}
          {% set person_dict = current.get(trigger.event.data.person,{}) %}
          {% if trigger.event.event_type == 'set_person_data' %}
            {% set new = {trigger.event.data.key: trigger.event.data.value} %}
            {% set person_dict = {trigger.event.data.person: dict(person_dict, **new)} %}
          {% elif trigger.event.event_type == 'remove_person_data' %}
            {% set person_dict = {trigger.event.data.person: dict(person_dict.items() | rejectattr('0', 'eq', trigger.event.data.key))} %}
          {% endif %}
          {{ dict(current, **person_dict) }}

AppDaemon:

import appdaemon.plugins.hass.hassapi as hass
from datetime import datetime
import yaml
import appdaemon.utils as utils


'''
App which manages the person attribute data store.

Home Assistant has no mechanism to programatically manage attributes for person
entities.  Instead, any custom attributes have to be managed entirely through
customize.yaml, and any changes made to those attributes outside of that file
will be lost when Home Assistant restarts.  As such, there is a need to have some
kind of datastore outside of the person entities to store this data.

This application provides this data store, as well as the necessary hooks to make
it user-friendly to edit this data.

One challenge is that, if you use any entities stored in this data store in a
template sensor, the template sensor, by default, will only update when explicitly
referenced entities change.  The entities referred to indirectly through the
data will not trigger the update.  In order to enable the desired behavior, this
app will automatically update a timestamp any time any of its underlying entities
are updated, which should trigger the corresponding update in any templates.

A downside of this approach is that all template sensors that refer to any data
in this datastore will update when any of the data in the datastore is updated,
but depending on your use case, this will hopefully not be too many updates.

Variables of relevance:
  `self.person_data` = the entity that stores the data.  To ensure that this data
    survives a reboot, it is recommended to create this data using a template
    sensor.
  
  `self.data_key` and `self.timestamp_key` = str, attribute names in self.person_data
  
  `self.person_list_entity` = input_select helper for frontend
  `self.person_attr_entity` = input_text helper for frontend
  `self.person_value_entity` = input_text helper for frontend
  
  `self.family_group` = The group that contains family members
  
Events:
  This application registers the following events:
  
  'person_data_write_int_value' causes the values in the interface helpers to be
    written into the data store.

  'person_data_del_int_value' causes the values in the interface helpers to be
    deleted from the data store.
'''

class UpdatePersonAttributes(hass.Hass):
  
  def initialize(self):
    self.log("Initialize Person Attribute Updater")
    
    #Variables
    self.person_data = 'sensor.person_data'
    self.data_key = 'data'
    self.timestamp_key = 'update_time'
    self.person_list_entity = 'input_select.person_attributes_person'
    self.person_attr_entity = 'input_text.person_attributes_attribute'
    self.person_value_entity = 'input_text.person_attributes_value'
    self.family_group = 'group.family'
    self.listener_handles = []
    
    #Listen Hooks
    self.listen_event(self.update_person_list, 'app_terminated')
    self.listen_event(self.write_value, 'person_data_write_int_value')
    self.listen_event(self.delete_value, 'person_data_del_int_value')
    self.listen_state(self.update_interface, self.person_list_entity)
    self.listen_state(self.update_interface, self.person_attr_entity)
    
    #Initialize
    self.update_person_list()
    self.update_listeners()
    
  def update_interface(self, *args, **kwargs):
    ''' Update interface based on selections '''
    
    #Get Attributes
    person = self.get_state(self.person_list_entity)
    attribute = self.get_state(self.person_attr_entity)
    
    try:
      value = self.get_state(self.person_data, attribute=self.data_key)[person][attribute]
    except KeyError:
      value = 'unknown'
      
    #Set Value
    self.set_state(self.person_value_entity, state=value)
    
  def write_value(self, *args, **kwargs):
    ''' Save the interface value into the data store '''
    
    person = self.get_state(self.person_list_entity)
    attribute = self.get_state(self.person_attr_entity)
    value = self.get_state(self.person_value_entity)
    
    full_state = self.get_state(self.person_data, attribute='all')
    full_attributes = full_state['attributes']
    full_attributes[self.data_key][person][attribute] = value
    
    self.set_state(self.person_data, attributes=full_attributes)
    self.update_listeners()

  def delete_value(self, *args, **kwargs):
    ''' Delete the interface attribute from the data store '''
    
    person = self.get_state(self.person_list_entity)
    attribute = self.get_state(self.person_attr_entity)
    
    full_state = self.get_state(self.person_data, attribute='all')
    full_attributes = full_state['attributes']
    full_attributes[self.data_key][person].pop(attribute,'unknown')
    
    self.set_state(self.person_data, attributes=full_attributes)
    self.update_listeners()

  def update_person_list(self, *args, **kwargs):
    ''' Update input select helper with list of person entities '''
    
    person_list = [p for p in self.get_state('person')]
    self.call_service('input_select/set_options', entity_id=self.person_list_entity, options=person_list)
  
  def update_listeners(self, *args, **kwargs):
    ''' Updates the listeners to include all of the different entities in the db '''
    
    for handle in self.listener_handles:
      self.cancel_listen_state(handle)
      
    self.listener_handles.clear()
    entities = []
      
    data = self.get_state(self.person_data, attribute=self.data_key)
    for person in data:
      for _, entity in data[person].items():
        if self.entity_exists(entity):
          entities += [entity]
    
    print(entities)
    self.listener_handles = self.listen_state(self.update_timestamp, entities)
    print(self.listener_handles)
    self.update_timestamp()
    
  def update_timestamp(self, *args, **kwargs):
    ''' Updates the timestamp '''
    
    full_state = self.get_state(self.person_data, attribute='all')
    full_attributes = full_state['attributes']
    full_attributes[self.timestamp_key] = datetime.now().isoformat()
    
    self.set_state(self.person_data, attributes=full_attributes)

Lovelace Card:

type: vertical-stack
cards:
  - type: entities
    title: Attributes Editor
    entities:
      - entity: input_select.person_attributes_person
      - entity: input_text.person_attributes_attribute
      - entity: input_text.person_attributes_value
      - type: custom:paper-buttons-row
        styles:
          justify-content: flex-end
        buttons:
          - icon: mdi:delete
            tap_action:
              action: fire-event
              event_type: person_data_del_int_value
          - icon: mdi:floppy
            tap_action:
              action: fire-event
              event_type: person_data_write_int_value
      - type: custom:fold-entity-row
        head:
          type: section
          label: Attributes
        entities:
          - type: custom:auto-entities
            card:
              type: entities
              card_mod:
                style: |
                  ha-card {
                    margin: 0px -16px;
                  }
            filter:
              template: >-
                {%- set data = state_attr('sensor.person_data', 'data') -%} {%-
                for

                member in data -%}  { 'entity': '{{member}}' }, {%- for key in

                data[member] -%} {% set value = data[member][key] -%} {{ {
                    'type': 'custom:template-entity-row',
                    'name': key,
                    'state': value
                } }}, {%- endfor -%}{%- endfor -%}
view_layout:
  column: 3
2 Likes