in HA, I want to know to which Unifi AP a person is connected. And since I don’t know up front who will be connected, this needs to be flexible.
I can find this manually via the following path:
person.xyz.attributes.source
gives me the device_tracker
entity, this entity contains the attribute ap_mac
, this ap_mac
value points to the mac
attribute of the AP (device_tracker.wifi_ap_name.attributes.mac
)
So after some fiddling around, I came up with the following template that basically collects all the info I need:
{% set peepatap = namespace(loc='') %}
{# Select all the person objects that have the source attribute defined #}
{%
set peeps = states.person |
selectattr('attributes.source', 'defined') |
map(attribute='entity_id') |
list
%}
{# For each found person, find if they are connected to an AP #}
{# if no AP is found the person is away #}
{# Fill the list with the info that is needed #}{% for peep in peeps %}
{%
set aps = states.device_tracker |
selectattr('attributes.mac', 'defined') |
selectattr('attributes.mac', 'eq',
state_attr(state_attr(peep, 'source'), 'ap_mac')
) |
map(attribute='name') |
list %}
{% if peepatap.loc != '' %}{% set peepatap.loc = peepatap.loc + ',' %}{% endif %}
{% if (aps | count) == 0 %}
{% set peepatap.loc = peepatap.loc + '{ "state": "away", "friendly_name": "' + state_attr(peep,"friendly_name") + '", "person": "' + peep + '", "ap": "None" }' %}
{% else %}
{% for ap in aps %}
{% set peepatap.loc = peepatap.loc + '{ "state": "home", "friendly_name": "' + state_attr(peep,"friendly_name") + '", "person": "' + peep + '", "ap": "' + ap + '" }' %}
{% endfor %}
{% endif %}
{% endfor %}
{# Make sure it is string containing a JSON list of dict #}
{% set peepatap.loc = '[' + peepatap.loc + ']' %}
No I can get the list from
{{ peepatap.loc }}
and it looks like this:
[
{
"state": "away",
"friendly_name": "***",
"person": "person.***",
"ap": "None"
},
{
"state": "home",
"friendly_name": "***",
"person": "person.***",
"ap": "DC"
},
{
"state": "home",
"friendly_name": "***",
"person": "person.***",
"ap": "Living"
},
{
"state": "home",
"friendly_name": "***",
"person": "person.***",
"ap": "DC"
},
{
"state": "away",
"friendly_name": "***",
"person": "person.***",
"ap": "None"
},
{
"state": "away",
"friendly_name": "***",
"person": "person.***",
"ap": "None"
},
{
"state": "away",
"friendly_name": "***",
"person": "person.***",
"ap": "None"
}
]
If I would know in advance which persons I should look for, I could use this piece of template:
{{
states.device_tracker |
selectattr('attributes.mac', 'defined') |
selectattr('attributes.mac', 'eq',
state_attr(state_attr('person.***', 'source'), 'ap_mac')
) |
map(attribute='name') |
list |
first
}}
However, if the person is not connected to an AP, the list is empty and first
errors out, so I could take off | first
but this results in a list and I want a string.
And here are my questions:
- Can I use this template/list to create sensors in an automation? (This is my preferred option so that I can use the auto-entities card to populat a card with the info I want)
- Can I use this list in a Lovalace card to display the presense of people and to which AP they are connected?
- Is there a custom card that can handle this kind of templating to create cards from the info in the list I created?
If only 1 of these questions can be answered with yes, I will be elated.
Thank you very much for your help.