Help understanding "random" template sensor activations

Hi,

I have some template sensors that I use to monitor triggers from Alexa devices. Alexa has the ability to run a routine when it hears certain things, like an appliance beep.

What I have done is create an input_button helper for each Alexa device I want to monitor for sound alerts, and then a template binary_sensor to monitor the state of that input_button. See this example below:

input_button:
  sh_sound_helper:
    name: sh_sound_helper

template:
  - binary_sensor:
      - unique_id: sh_sound
        name: sh_sound
        delay_on:
          seconds: 5
        device_class: sound
        state: >-
          {{ ( now() - states( "input_button.sh_sound_helper" ) | as_datetime ).seconds <= 90 }}
        availability: >-
          {{ state_attr("media_player.shed_echo","available") }}

The Alexa devices have a routine that triggers input_button.sh_sound_helper as a “scene” when it detects sound. This Alexa routine can only “trigger” - it cannot turn on/off like the motion sensing routine can. This is why I have used an input_button, and exposed that to Alexa. These Alexa routine triggers have a minimum “cooldown” of 1 minute before they can trigger again. So on the binary_sensor.sh_sound sensor I evaluate if the input_button has been trigged in the last 90 seconds and if not, turn off the binary_sensor. I understand that the template evaluation of templates containing “now()” only happens at the start of every minute. I am comfortable with this behaviour, even if it won’t fully represent the same thing as when the Alexa device is hearing sound or not. Also, I have added an availability template to use the Alexa media player integration to monitor if the Alexa device goes offline. The delay_on: setting was added later in attempt to “debounce” any temporary state changes to/from “unavailable” (I’m not sure how successful this has been).

Now, the behaviour that I am seeing is that randomly (randomly to me) this binary_sensor is saying it is detecting sound, even though the input_button is not being triggered. Further, this “random” change of state is happening once a day at the same time every day. I have three more of these sensors/Alexa setups in place, and their binary_sensors all show the same behaviour, though at different times in the day. No reloads, restarts, or other HA actions are occurring at these times, and the history log shows that binary_sensor changes state, but the linked input_button isn’t showing a change.


As you can see from the screenshot, there is not input_button trigger, the sensor doesn’t become available, it just changes state.

Can anyone help me understand why this happens?

Regards,

Not sure why you have this behavior. You could make template sensors to monitor the different expressions of the template and debug it that way.
Anyhow there is an easy fix to your problem: add a trigger (= button press) to your template sensor: Template - Home Assistant
This way you shouldn’t have false positives

I monitor sounds as well through input buttons on my Alexa, but don’t derive sensors from it as I only need them as triggers in automations.

Thanks! Funnily enough I used triggers on other template sensors to get better control over when they fire, but I wasn’t sure if that was the right approach here.

Do you know if the now() part of the template with continue to be evaluated at the start of every minute with this trigger in place? That’s a key part of “resetting” the state of the binary sensor.

Resetting with just one trigger is in this case not possible. The now() is just evaluated when a trigger fires.
You could add a second time pattern trigger that fires e.g. every minute.
In the template you just evaluate which trigger was fired.

It’s working as written. You want total_seconds() not seconds. Look at the time of day when it goes to “detected” in the graph.

EDIT (after Petro’s post below): apologies, was tight for time with my original reply.

See the Python docs for timedelta:

In particular:

Only days , seconds and microseconds are stored internally. Arguments are converted to those units

So the seconds attribute rolls over to zero after each day, giving rise to the behaviour you’re seeing. The total_seconds() method does what you want:

to clarify what troon is saying. .seconds is the number of seconds from the current day. So if you have a timedelta object that is 1 hour and 10 seconds, .seconds will be 3610. If you have a timedelta object that is 3 days 1 hour and 10 seconds, .seconds will be 3610 because .seconds only looks at the current day.

.total_seconds() gives you the total seconds in the timedelta object including days.

Thank you all for your information!

@Troon, @petro, thank you both for those links and the explanation behind them. To clarify, I wasn’t expecting anything to be wrong with HA (sorry if that was the inference), and fully expected that it was my understanding of the internal process that was lacking. I had looked at those Python pages linked from the HA Templating page, but incorrectly assumed I was dealing with a datetime object so had only looked the appropriate attributes for that.

Thank you for correcting my misunderstanding and pointing out that its a timedelta object (its obvious now when I look at it) and the nuance of the rolling over of the internal attribute seconds.

Regards,

Thanks mate. I’ve accepted your post above as the solution and highlighted where I was wrong. I’m not sure further discussion of my incompetence will help.