This should work..greet recognised person from double take

I am basically modifying a automation i used previously that worked fine (albeit without the condition it seems to fail on) and i can’t get it to work seemingly. It keeps failing on what seems like, the first condition in the value_template.

If anyone has any insights as to what i could improve it would be greatly appreciated.

alias: Greet person based on time of day
description: >-
  Good morning that uses face recognition (Compreface and Doubletake) and the
  time of day sensor to recognise the person who it sees.


  It uses double_take_camera and checks if there is a match, then says good
  timeofday using the appropriate alexa that is closest to the camera by using a trigger.id then delays by   the defined time in time of day sensor so it only runs once.
trigger:
  - platform: state
    entity_id:
      - sensor.double_take_kitchen
    attribute: matches
    id: garage
  - platform: state
    entity_id:
      - sensor.double_take_diningroom
    attribute: matches
    id: dining_room
  - platform: state
    entity_id:
      - sensor.double_take_garage_camera_2
    attribute: matches
    id: garden
condition:
  - condition: template
    value_template: |
      condition: template
      value_template: >-
          {% set f = state_attr(trigger.entity_id, 'matches') %} 
          {{f[0].name if f is iterable or f|count > 0 or f[0].name is defined else
          "Unrecognized" }}
          {{ states('counter.greet_' ~ states('sensor.time_of_day') ~ '_' ~ state_attr(trigger.entity_id,'matches')) | int(0) < 1 or 'unknown' }}
action:
  - service: notify.alexa_media_{{ trigger.id }}
    data:
      message: >-
        Good {{ states('sensor.time_of_day') }} {% set f =
        state_attr(trigger.entity_id, 'matches') %} {{ f[0].name if f is
        iterable and f|count > 0 and f[0].name is defined else "Unrecognized"
        }}.
      data:
        type: tts
        method: all
  - service: counter.increment
    data: {}
    target:
      entity_id: >-
        counter.greet_{{ states('sensor.time_of_day') }}_{{
        state_attr(trigger.entity_id,'matches') }}
mode: single

There are several errors in the Template Condition. The most obvious one is duplication.

The result of a Template Condition should ultimately be a boolean value (true/false) but your template includes the possibility of reporting string values like Unrecognized and unknown. In addition, the template attempts to report two values when it should only report one.

Explain what you want the template to compute and I will help you create it.

Thanks @123.

I removed the duplicated section. I guess my eyesight is starting to fail me!

What i want the condition to do is to check :

  1. If it actually has a match. If it does, double_take_kitchen (for example) would hold the name it recognised in the matches output.
  2. If it does have a match, increase the counter (i created counters for everyone it recognises in the family and a unknown counter in case double_take says the person is unrecognized.

The counters looks like this: counter.greet_morning_person, counter.greet_afternoon_person and it increases it by 1 after it ran the action once. If the counter already has one, it won’t run the action (e.g. the condition) and won’t say good morning .

I’m sure you’re familiar with double_take, but in case you’re not, it’s a add on for frigate which helps with facial recognition. It creates sensors for every person (or room, which is what i’m working with here).

sensor.double_take_diningroom content that holds no matches in matches:

id: 1682171297.92653-nnayxh
duration: 0.34
timestamp: 2023-04-22T14:05:30.340Z
attempts: 18
camera: diningroom
zones:
matches:
misses:
unknowns:
personCount: 0
counts:
person: 0
match: 0
miss: 0
unknown: 0

and if it does hold a match:
matches:

  • name: atvvta

As it is the first field in matches i check for f[0].name. I added the check for unknown in there in case in case there would be no match at all, but i don’t see how that would be possible as this would be covered by the triggers (if they trigger, there is a match).

Hope this helps a bit.

I hacked around with this for a bit, i now got it working but some questions i have outstanding:
Code with excerpts and questions:

condition:
  - condition: template
    value_template: >
      {% set f = state_attr(trigger.entity_id, 'matches') %} 

      {{ states('counter.greet_' ~ states('sensor.time_of_day') ~ '_' ~
      f[0].name) | int(0) < 1 }}

I removed the duplication as mentioned and i also removed the checking for if f is defined and iterable so to avoid having multiple outputs. And as it triggers on the camera entities, it should always be filled by matches anyway. However, it would be better probably to have it in there. I should be able to add it by combining both the counter condition and that check in one statement (and?) but couldn’t get it to work.

action:
  - service: notify.alexa_media_{{ trigger.id }}
    data:
      message: >-
        Good {{ states('sensor.time_of_day') }} {% set f =
        state_attr(trigger.entity_id, 'matches') %} {{ f[0].name if f is
        iterable and f|count > 0 and f[0].name is defined else "Unrecognized"
        }}.
      data:
        type: tts
        method: all

This works fine, but it would be cleaner if i could just use f from the previous condition somehow? But i think these are local variables?

service: counter.increment
data: {}
target:
entity_id: >-
counter.greet_{{ states(‘sensor.time_of_day’) }}_{{
state_attr(trigger.entity_id,‘matches’)[0].name }}
mode: single

Same here, i’d rather use f[0].name here, it will be cleaner and work more accurately of course (otherwise there is a possibility that i might get Good morning X, but the counter would be increased for another person if it would have a new match while this automation would be running).

Full working code:

alias: Greet person based on time of day
description: >-
  Good morning that uses face recognition (Compreface and Doubletake) and the
  time of day sensor to recognise the person who it sees.


  It uses double_take_camera and checks if there is a match, then says good
  timeofday using the appropriate alexa using a trigger.id then delays by the
  defined time in time of day sensor so it only runs once.
trigger:
  - platform: state
    entity_id:
      - sensor.double_take_kitchen
    attribute: matches
    id: garage
  - platform: state
    entity_id:
      - sensor.double_take_diningroom
    attribute: matches
    id: dining_room
  - platform: state
    entity_id:
      - sensor.double_take_garage_camera_2
    attribute: matches
    id: garden
condition:
  - condition: template
    value_template: >
      {% set f = state_attr(trigger.entity_id, 'matches') %} 

      {{ states('counter.greet_' ~ states('sensor.time_of_day') ~ '_' ~
      f[0].name) | int(0) < 1 }}
action:
  - service: notify.alexa_media_{{ trigger.id }}
    data:
      message: >-
        Good {{ states('sensor.time_of_day') }} {% set f =
        state_attr(trigger.entity_id, 'matches') %} {{ f[0].name if f is
        iterable and f|count > 0 and f[0].name is defined else "Unrecognized"
        }}.
      data:
        type: tts
        method: all
  - service: counter.increment
    data: {}
    target:
      entity_id: >-
        counter.greet_{{ states('sensor.time_of_day') }}_{{
        state_attr(trigger.entity_id,'matches')[0].name }}
mode: single
1 Like

Hi @atv , I’d like to implement something similar. Can you please add your definitions for the sensors and counters you are using.
Thanks