How to check "time device has been on" as a condition in a script

I’m stumbling my way though setting up some automated lights, I managed to build a set of Automations that do what I need them to, but then I realized I’m going to be making duplicates of all of those automations for each of my different rooms, so I started looking into scripts, and I’m trying to pass in the relevant switch as a parameter (basically the light.light_name device).

I figured out how to check the basic state using the value template and my field:

  - if:
      - condition: template
        value_template: "{{ is_state(var_lightswitch, 'on') }}"
        alias: If var_lightswitch is ON

However now I’m struggling to figure out how to set a condition so that it will only run if the light (represented by the var_lightswitch parameter) has been on for over 2 seconds. I have this YAML from the working Automation, but I can’t figure out how I would turn it into a condition in my script that can take a field as a parameter

  - condition: device
    type: is_on
    device_id: 8b0a28328acd1f1369c8b77b7aaed69f
    entity_id: afa23799d89afd7723fc19b85ceae1ba
    domain: light
    for:
      hours: 0
      minutes: 0
      seconds: 2

If it makes any difference, these are Inovelli Red switches… I’m also curious if there’s some sort of console somewhere that I can use for quickly testing out all of the “state_attr” commands and the like with intellisense, because I have no idea what these objects look like under the hood. I found the Developer Tools > States screen, which is helpful, but nothing there seems to tell me when the light was last turned on… I’m guessing because it’s stored elsewhere, but I have zero idea how to even begin tracking that down.

Full example script that I’m trying to get working (I got the first if statement working, so I’m able to tell if the light I’m passing in is on currently, but the second if statement is where I’m struggling, I can’t figure out the value_template to check if the light has been on for at least 2 seconds):

alias: Temp Override Button Pressed
sequence:
  - if:
      - condition: template
        value_template: "{{ is_state(var_lightswitch, 'on') }}"
    then:
      - target:
          entity_id: "{{ var_light_lockstate }}"
        data:
          option: Automatic
        action: input_select.select_option
    else:
      - target:
          entity_id: "{{ var_light_lockstate }}"
        data:
          option: Manual
        action: input_select.select_option
  - if:
      - condition: state
        entity_id: "{{ var_lightswitch }}"
        state: "on"
        for:
          seconds: 2
    then: []
fields:
  var_lightswitch:
    selector:
      device: {}
    name: Var_Lightswitch
    description: Select the Inovelli light switch object
    required: true
    example: light.light_hallway
  var_light_lockstate:
    selector:
      entity: {}
    name: Var_Light_LockState
    description: Select the input_select object that stores the LockState for the light
    required: true
    example: input_select.light_hallway_lockstate
description: ""

State Condition

  - condition: state
    entity_id: light.your_light
    state: "on"
    for:
      seconds: 2

Which field?

Hi, I have a custom jinja template script that you can check if it will works for you.

{# tydsverloop in sekondes #}
{# {% from 'wn.jinja' import last_change_s %} #}
{% macro last_change_s(entity_id) %}
{% set laaste = states[entity_id].last_changed|as_timestamp %}
{% set sec = now()|as_timestamp - laaste %}
{{ sec|int(0) }}
{% endmacro %}

The field is “var_lightswitch”, which represents the light.light_name Device (e.g. light.light_hallway) that it should be controlling (which in the example code from the Automation, would be the device_id 8b0a28328acd1f1369c8b77b7aaed69f).

For reference this is the UI that relates to that YAML in the Automation:

I guess that’s another followup question… how can I tell what entity is represented by the “entity_id” field in the Automation YAML? I know it’s bad practice to USE those IDs rather than the entity names for things, but in this case the UI is generating YAML that’s using it, and I’m wondering how I can “resolve” the entity name that would be associated with that ID…

EDIT: And I can’t use the YAML you provided, because I want to pass the field in as the entity_id, like so:

  - condition: state
    entity_id: "{{ var_lightswitch }}"
    state: "on"
    for:
      seconds: 2

which (annoyingly…) isn’t supported by the normal state condition, and results in a “Message malformed” error, my understanding based on my previous work suggests that this needs to be a template condition, but I have no idea how to get the “for… seconds:2” represented as part of that value_template command.

Where is this field? It’s not present in any of the examples you have posted above.

I recognize that as being the UI for creating a Device Trigger. It will produce YAML like in your first post where both device_id and entity_id are alphanumeric strings (internally generated by Home Assistant).

If you use a State Trigger, it will produce YAML that looks like this where entity_id is in a user-friendly format.

  - trigger: state
    entity_id:
      - light.table_lamp
    from: "off"
    to: "on"
    for:
      hours: 0
      minutes: 10
      seconds: 0

Sorry about that, I’ve edited my original post to include the complete script I’m working on. Basically I have 2 if statements, I have the first one working to check if the light is on at all, but the second one I need to check if the light has been on for 2 seconds, and I can’t figure out how to write a value_template to do that with the template condition (the version that’s there now throws an error because you can’t use fields with the state condition…)

  - condition: template 
    value_template: >
      {{ is_state(var_lightswitch, 'on') and 
        now() - states[var_lightswitch].last_changed > timedelta(seconds=2) }}

Thanks a ton for your help, that value_template helps me understand a bit better how things are structured, but it’s failing to work in a way that makes me feel like I’m missing something fundamental…

The above value_template allows me to save the script without error, but it always resolves to false (the “else” branch).

If I swap in the actual device name instead of the Field variables it works as desired and resolves to True when the light has been on for more than 2 seconds:

{{ is_state('light.light_hallway', 'on') and 
        now() - states['light.light_hallway'].last_changed > timedelta(seconds=2) }}

So it seems like maybe it’s just not resolving the field into a device for some reason?

I did some testing and it turns out even my original

{{ is_state(var_lightswitch, 'on') }}

also always resolves to False in the script, unless I hardcode the device name in there:

{{ is_state('light.light_hallway', 'on') }}

But what confuses me is that I’ve successfully used this format for the other Field in a different script:

{{ is_state(var_light_lockstate, 'Automatic') }}

and that works as I expect it to…

Is there some fundamental difference between how an “input_select” entity returns state vs. a “light” entity that would make referencing the Field work differently?

Here’s that other whole script for reference, THIS ONE WORKS as expected and s able to use the Field reference in the Template Condition to properly detect the current state of the var_light_lockstate entity:

alias: Light Override Button Pressed
sequence:
  - if:
      - condition: template
        value_template: "{{ is_state(var_light_lockstate, 'Manual') }}"
    then:
      - target:
          entity_id: "{{ var_light_lockstate }}"
        data:
          option: Automatic
        action: input_select.select_option
    else:
      - target:
          entity_id: "{{ var_light_lockstate }}"
        data:
          option: Manual
        action: input_select.select_option
fields:
  var_lightswitch:
    selector:
      device: {}
    name: Var_Lightswitch
    description: Select the Inovelli light switch object
    required: true
    example: Light_Hallway
  var_light_lockstate:
    selector:
      entity: {}
    name: Var_Light_LockState
    description: Select the input_select object that stores the LockState for the light
    required: true
    example: input_select.light_hallway_lockstate
description: ""

Probably because your script isn’t passing an entity_id via var_lightswitch, it’s passing a device_id.

fields:
 var_lightswitch:
   selector:
     device: {}     #<----- You're using a *Device* Selector

A Device Selector will reference its selection by its device_id. The states() function reports the state of a supplied entity_id, not a device_id.

I suggest you use an Entity Selector and set its domain filter to light.

1 Like

Aha! Thank you so much! That was indeed the fundamental understanding I was missing, it’s now working as expected.

Posting the final version of this script here for prosperity/reference because I know I love to see working examples if only to see the syntax:

alias: Temp Override Button Pressed
sequence:
  - if:
      - condition: template
        value_template: |
          {{ is_state(var_lightswitch, 'on') and 
            now() - states[var_lightswitch].last_changed > timedelta(seconds=2) }}
        alias: If light has been on for at least 2 seconds
    then:
      - choose:
          - conditions:
              - alias: If current LockState is Automatic
                condition: template
                value_template: "{{ is_state(var_light_lockstate, 'Automatic') }}"
            sequence:
              - target:
                  entity_id: "{{ var_light_lockstate }}"
                data:
                  option: Temporary
                action: input_select.select_option
                alias: Switch to Temporary
          - conditions:
              - alias: If current LockState is Temporary
                condition: template
                value_template: "{{ is_state(var_light_lockstate, 'Temporary') }}"
            sequence:
              - target:
                  entity_id: "{{ var_light_lockstate }}"
                data:
                  option: Automatic
                action: input_select.select_option
                alias: Switch to Automatic
fields:
  var_lightswitch:
    selector:
      entity:
        filter:
          domain: light
    name: Var_Lightswitch
    description: Select the Inovelli light switch object
    required: true
  var_light_lockstate:
    selector:
      entity:
        filter:
          domain: input_select
    name: Var_Light_LockState
    description: Select the input_select object that stores the LockState for the light
    required: true
description: "Toggles temporary override on or off (Manual Override supercedes this, so this script does nothing if it is locked into Manual mode)"

1 Like

You’re welcome!

Please consider marking my post above with the Solution tag. It will automatically place a check-mark next to the topic’s title which signals to other users that this topic has been resolved. This helps users find answers to similar questions.

For more information about the Solution tag, refer to guideline 21 in the FAQ.

1 Like