Alias or id for time trigger

How can I set up an alias or id in time trigger for separate entities?

The example below works.

  - trigger: time
    at:
      - sensor.entity_1
      - sensor.entity_2

The example below fails to load

  - trigger: time
    at:
      - alias: alias_1
        entity_id: sensor.entity_1
      - alias: alias_2
        entity_id: sensor.entity_2

with the error:

failed to setup triggers and has been disabled: Expected HH:MM, HH:MM:SS, an Entity ID with domain ‘input_datetime’ or ‘sensor’, a combination of a timestamp sensor entity and an offset, or Limited Template @ data[‘at’][0]. Got None

Sensors are device_class: timestamp

Documentation says that “all triggers from all platforms will include the following properties: id, idx, alias, platform”.

Using a working example, I printed these shared properties to the log. The alias has value None. So not only can it not be set, but it carries no meaningful value. Like an alias, the id cannot be set either. So it carries idx as mentioned in the docs.

What am I missing? Could it be new features added after 2025.11?

If it does not work? What options do I have? A template trigger with a comparison of the sensor state to now? Is it reliable?

trigger: time
at: "07:30:00"
id: trigger_id

you can define id on trigger level, not sensor level. in your case,

- trigger: time
    id: trigger_id
    at:
      - sensor.entity_1
      - sensor.entity_2

Yeah, but I need to distinguish later on, which entity triggered the automation.

Hopefully, your input led me to check another syntax:

        - trigger: time
          alias: alias_1
          at: sensor. entity_1

        - trigger: time
          alias: alias_2
          at: sensor. entity_2

HA accepted it. Will see how does it work.

Thank you

Use trigger ids.

        - trigger: time
          id: time1
          at: sensor. entity_1

        - trigger: time
          id: time2
          at: sensor. entity_2

Or, just use a template to differentiate.

triggers:
  - trigger: time
    at:
      - sensor.entity_1
      - sensor.entity_2
variables:
    entities:
      - sensor.entity_1
      - sensor.entity_2
    triggering: >
      {% set t = now().replace(microseconds=0).isoformat() %}
      {{ entities | select('is_state', t) | first | default }}

You may need to modify the template if the timezone is UTC

or make it timezone independent like this (could be beneficial if some entities use UTC and others the local timezone)

triggers:
  - trigger: time
    at:
      - sensor.entity_1
      - sensor.entity_2
variables:
    entities:
      - sensor.entity_1
      - sensor.entity_2
    triggering: >
      {% set t = now().replace(microseconds=0) %}
      {% set datetimes = entities | map('states') | map('as_datetime', default=now()) | map('as_local') | list %}
      {{ zip(entities, datetimes) | selectattr('1', 'eq', t) | map(attribute='0') | first | default('unknown') }}

Ya, I was just trying to keep it simple for an example. I should probably add a string time compare filter/function.

Since you are using time entities instead of fixed times, another option would be to just use the entity ID in your condition, since it is stored in the trigger variable.

trigger: time
  at:
    - sensor.entity_1
    - sensor.entity_2
  variables:
    id: "{{ trigger.entity_id.split('_')[1] }}"
conditions: []
actions:
  - choose:
      - conditions:
           - "{{ id == 1 }}"
        sequence:
          # actions for 'sensor.entity_1'
      - conditions:
           - "{{ id == 2 }}"
        sequence:
          # actions for 'sensor.entity_2'

Thank you.

There are a lot of responses, and to be honest, some of the syntax you’re showing is a bit overwhelming for me :wink:

I intentionally limited my question to a specific piece of syntax, because it seemed to me that it wasn’t aligned with the documentation—most likely due to my limited familiarity with YAML. In the end, I managed to get it working by using separate time triggers within the automation. I couldn’t find any example or mention in the docs that this approach was even possible.

      triggers:
        - trigger: time
          alias: alias_1
          at: sensor. entity_1

        - trigger: time
          alias: alias_2
          at: sensor. entity_2

      variables:
        next_mode: >
          {% if trigger.alias == 'alias_1' %}
          # the rest of logic

The following is slightly off-topic, but since time zones were mentioned in your responses—and I was struggling with them in the context of syntax—I’ll use the opportunity to ask another question.

I’m quite familiar with time zones, but thanks for pointing it out. One of the first things I considered was avoiding comparisons of timestamps using their string representations. While that might work in some cases, I prefer comparing proper datetime objects.

I thought that something like this would work:

variables:
  mytime: as_datetime(states('sensor.entity_1'))
  next_mode: >
    {% if now() >= mytime %}
    # some logic

But it fails, with TypeError: '>=' not supported between instances of 'datetime.datetime' and 'NodeStrClass' error.

I made it work by assigning the entity state value to a variable, then converting it to time object during comparison

variables:
  mytime: "{{ states('sensor.entity_1') }}"
  next_mode: >
    {% if now() >= as_datetime(mytime) %}
    # some logic

Is this expected behavior or a limitation? Although it might be explained by variables only handling text values, the reference to NodeStrClass makes me wonder if I’m missing something.

It’s covered in the first section of automation trigger

and the code would be:

      triggers:
        - trigger: time
          id: alias_1
          at: sensor.entity_1

        - trigger: time
          id: alias_2
          at: sensor.entity_2

      variables:
        next_mode: >
          {% if trigger.id == 'alias_1' %}
          # the rest of logic

I think you just misunderstood the docs. What you posted…

triggers:
  - trigger: time
    at:
      - alias: alias_1
        entity_id: sensor.entity_1
      - alias: alias_2
        entity_id: sensor.entity_2

… is a single trigger, without an alias. If you review the docs, there are no examples that show individual time sources with their own alias. What you will find documented is individual aliases and ids for individual triggers:

triggers:
  - alias: alias_1
    id: 1
    trigger: time
    at:
      - entity_id: sensor.entity_1
  - alias: alias_2
    id: 2
    trigger: time
    at:
      - entity_id: sensor.entity_2

Yes, it’s expected.

Yeah, as I wrote. I’m not skilled in these constructs, so I was using examples and trying to guess the correct syntax.
For instance, I found no example covering two triggers of the same type (like in my solution). I assumed that it’s not allowed to have two of the same kind.

Right now, I scanned the documentation page mentioned by Petro and only the webhook section shows an example with two triggers of the same type.

I have to say I’m pretty excited about what I achieved using YAML-based scripting and automation. Some of you probably noticed that I was always against this way of “programming”. TBH I don’t know why I decided to try yaml instead of NR as usual.
But this time it really surprised me how clean and readable code can be achieved. The only thing that was slowing me down was the lack of complete reference documentation. Fortunately, docs are full of examples. The rest can be managed.

Would you like to provide some technical explanation? How does it work internally that it produces such a result? Is it documented somewhere (in case I missed that)

That’s a question for Petro or someone else with more dev-related knowledge. I know that datetime objects are converted to datetime strings in script variables, but the hows and whys are outside my scope.

It probably has something to do with json serialization… but that’s just a guess.

Jinja only return strings. Because of that, anything that can’t be determined as a type python can’t easily serialize is made into a string.

FWIW, the second example in the Disabling a Trigger section, of the Triggers documentation, contains two Sun Triggers. It sort of demonstrates that two identical trigger types can be used in an automation. I say “sort of” because it’s an automation blueprint and the example’s actual goal is to show how to programmatically enable/disable the triggers.

Having said that, you’re right, there aren’t many examples with multiple identical trigger types. It’s not very common unless there’s a need, as in your case with Time Trigger, to identify which one of the uniquely configured Triggers was responsible for triggering the automation.

Probably related, but I was reading the release notes for the latest changes and they mentioned time/date breaking changes, so be sure to check your code against the latest documentation and not any obsolete YouBoob videos or LLM generated slop.