Stupid templating question I'm having a mental block with

Yes. If you want to write it more explicitly, you could write it this way:

trigger.from_state is not none and trigger.to_state is not none

But since None evaluates to False, and a State Object would evaluate to True (in a Boolean expression), the way I originally wrote it works and is basically a short cut.

I cannot get this to trigger for some reason. motion sensor fires but it does not trigger the automation.

Thank you so much for this… However you had one small error which I had to sort out. I had to add the state attribute by changing

trigger.to_state in ('on', 'off')
to
trigger.to_state.state in ('on', 'off')

Here is the final automation I used which works!

  trigger:
    platform: state
    entity_id:
      - binary_sensor.master_closet_motion
      - binary_sensor.laundry_room_motion
      - binary_sensor.half_bathroom_motion
      - binary_sensor.night_stand_motion
  condition:
    condition: template
    value_template: >
      {{ trigger.from_state and trigger.to_state and
         trigger.from_state.state != trigger.to_state.state and
         trigger.to_state.state in ('on', 'off') }}
  action:
    service_template: "switch.turn_{{ trigger.to_state.state }}"
    data_template:
      entity_id: >
        {{ trigger.entity_id.replace('binary_sensor', 'switch').replace('_motion', '') }}

Is that ‘belt and suspenders’ condition really necessary?

It checks for:

  • the existence of from_state (which the template doesn’t use)
  • the existence of to_state (the automation just triggered so it must have a to_state)
  • from_state not being the same as to_state (a binary sensor has no attributes and only two states so how can it ever change from off to off or on to on?)
  • the state being either on or off (unless these devices can be unknown, the state can only be on or off)

:man_shrugging:

While testing it last night to troubleshoot why it wasn’t initially working, I took the condition totally out and it “worked”. However, I would rather leave it in there as it is not hurting anything when the desired action happens and, in the off chance something is messed up, it would catch it.

I understand your point, however, I think it’s better to have conditions that validate your input rather than just let anything through and hope it works out. :slight_smile:

I agree except three-quarters of the things it’s guarding against are unlikely to ever happen. However, if you really want to cover all the bases then you may as well also check that the triggering entities are actually binary_sensors (before you replace the string with switch). If you think that’s extreme, that’s how I feel about the need to confirm to_state exists in an automation that just got triggered. :thinking:

Oops, sorry about that. I’ll go back and edit my post so others don’t get tripped up by it in the future.

Glad it worked for you. :slight_smile:

Good questions…

Yes, it is used.

Not true. If the entity is deleted, it will cause a state_changed event (that will trigger the automation) where trigger.to_state will be None.

There’s no rule that says a binary_sensor can’t have attributes. In fact most do (even if it’s only friendly_name.) And, e.g., a Template Binary Sensor can have attributes that change (e.g., icon_template, entity_picture_template & attribute_templates.) Further, (per below) it’s possible a binary_sensor’s state might change from off to, say, unknown, in which case the service call would cause an error.

Yes, a binary_sensor’s state could be unknown or unavailable. “Binary” only refers to its normal states.

I’ll grant you for many binary_sensors many of these conditions probably won’t happen during normal use, and one could simplify quite a bit. But I preferred to provide an example I feel more comfortable with which is more robust.

1 Like

Now that seems a bit extreme. :wink: If you check the trigger section, only binary_sensor entities are monitored, so trigger.entity_id can only start with “binary_sensor” in this automation.

Thank you, Phil. An excellent description of the possible edge-cases. Of course, I now want to test these edge-cases.

  • Where and how is from_state used in the automation above? I see no reference to it other than in the condition itself.

  • How do you delete an entity to cause a state_changed event? In my admittedly limited time with Home Assistant, I only know how to delete an entity by erasing its config and restarting Home Assistant. Is there a service to delete an entity?

  • You’re right, friendly_name is an attribute even for a bog-standard binary_sensor. However, how would you dynamically change the friendly_name to cause a state change?

Yep, that’s where it’s used.

It’s not that simple. And, admittedly, this probably won’t happen for most entities. So the condition is more general than it probably needs to be in this exact scenario. But there are integrations that can cause entities to come and go. And I think (although don’t quote me on this) if an entity is changed, say via the entity registry (e.g., by clicking on its gear and changing its name or something), that actually causes the existing entity to (effectively) be deleted and re-created. I haven’t thoroughly tested all these scenarios. This is just my impression of what might happen after browsing through a lot of code.

Possibly via customization. It can also happen in a python_script. I think HA’s REST API is another possibilty. And there may be other ways, too.

Sorry, I’ve been an embedded software engineer for 40 years. If I’ve learned anything, it’s that if something can happen, it will happen. :slight_smile:

A small aside, I recently had to change ‘a LOT’ of my automation triggers from : -
to: ‘on’
to
from: ‘off’
to: ‘on’
As this caused a problem when changing brightness levels on lights, where they happen to already be on. This ‘has’ to use the light.turn_on platform which as a consequence was cancelling the timers associated with those lights, without turning the timers back on again (which is part of another ‘on’ trigger. So generally in favour of belt, braces, a bit of string and duct tape if you’ve got it. : - )

Sorry, not exactly following that.

First, if a light’s attributes change (e.g., brightness), but the light stays on, a state trigger which uses just to: 'on' should not trigger. If it is triggering, then almost certainly the state is changing to off (or something else???) and then back on (probably very briefly.) I would have to guess it changed to something else, because if it had changed to off, then your change should not have had any effect.

Second, I’m not sure what timers you’re referring to.

Firstly, I’d like to apologise to jwoodard for hi-jacking his thread.

Phil,
Yeah it threw me too. I have an automation that when it starts, triggered by the light coming on, checks that timer enable is set for that light and if it is, it cancels the old timer (script) and then re-initialises it

  - alias: au_light_wc_offdelay
    trigger:
      - platform: state
        entity_id: light.fib_fgd212dim2_wc_level
        from: 'off' ################# <--- This the bit in question here
        to: 'on'
    condition:
      - condition: state
        entity_id: input_boolean.ib_light_wc_timer_enable
        state: 'on'
    action:
      - service: script.turn_off
        entity_id: script.sc_light_wc_timer
      - service: script.sc_light_wc_timer

So the script takes a number from an input_number and waits that length of time before turning the light off. (Interesting point here is that after the light turns on the script shows running, turn the script off (unused items scripts toggle the said script) it appears to turn off then comes back on after 4 secs or so, wait the full period and it then turns the script off itself - but it was not running as the light does not turn off it just stays on. But the above automation is just to set the ‘delay off’ .
Regardless, the above script (without the " from: ‘off’ ") worked fine … (this was stage 1)

So the lights are set in different groups and the required light levels change through the day.
The light in a specific group comes on and another automation checks what the level should be and applies it : -

  - alias: au_aalight_lghtonbth
    trigger:
      - platform: state
        entity_id: light.fib_fgd212dim2_bath_level, light.fib_fgd212dim2_ensu_level, light.fib_fgd212dim2_wc_level
        from: 'off'
        to: 'on'
    action:
      - service: light.turn_on
        data_template:
          entity_id: "{{ trigger.entity_id }}"
          brightness_pct: "{{ states('input_number.in_aalight_bth_lvl') | int }}"

(This was stage 2) This sets the level to that stored in : - in_aalight_bth_lvl
It triggers an on but that’s the on that drives the timer AOK
Everything works tickety-boo

Now lets break things (with stage 3).
So I have a light on and the time of day changes, so I need to change the brightness
That is done and the number stored in (for this case) input_number.in_aalight_bth_lvl
A change in that triggers another automation : -

  - alias: au_light_adjust_brightness_wc
    trigger:
      - platform: state
        entity_id: input_number.in_aalight_bth_lvl
    condition:
      - condition: state
        entity_id: light.fib_fgd212dim2_wc_level
        state: 'on'
    action:
      - service: light.turn_on
        entity_id: light.fib_fgd212dim2_wc_level
        data_template:
          brightness_pct: >
            {{ states('input_number.in_aalight_bth_lvl') | int }}

So the number changes, triggers the script which then checks that the light is on (remember if I have to switch it on the level is taken care of). So trigger given, condition met, so action follows and to set brightness I have to turn on a light (that is already on) but pass it a new brightness. This some how breaks the timer and I’m left with a light that stays on forever (well, until the electricity company cuts my power for non-payment of bills).

I added the : -
from: ‘off’
And my timers work once again
It’s weird but this implies the trigger is not the turning ‘on’ of a state but simply trying to set it to ‘on’ regardless that it was already on

Sorry for the long story
I really wanted your (or petro’s) help on the other item : Setting Time Slot States on Re-Start (works but ...) which is about templating not working in a script.
Cheers
Mutt

It tests for from_state because from_state is used in the test for from_state. :point_right: :point_left:

I can confirm that changing an entity’s name via the Entity Registry will produce a state-change. I used this automation:

- alias: 'test 99'
  trigger:
    platform: state
    entity_id: light.test
  action:
    service: light.toggle
    entity_id: light.patio

and changed the light’s name from Test to Tester (via Entity Registry) and it caused the automation to trigger and toggle the patio light.

I’m still adjusting to Home Assistant’s way of doing things. In Premise, I can selectively trigger off any one of an entity’s properties (changes to a light’s powerstate, brightness, name, description, platform, etc). Alternately, I can trigger off all of them (changes to any property). I never used this kind of ‘all properties’ trigger … but this is the default for Home Assistant.

No, that would be silly. It tests that trigger.from_state is not None (and the same for trigger.to_state) so that it can test if trigger.from_state.state != trigger.to_state.state without causing an error. You can’t reference trigger.from_state.state if trigger.from_state is None (i.e., does not contain a State Object.)

That’s not true, at least for a State Trigger. If you don’t specify the from: and to: options, then it is true in that scenario. But if you specify either from: or to: or both, then it will only trigger if the “state” actually changes and meets the specified conditions. (I quote “state”, because, unfortunately, in HA, the term “state” is overloaded. It is used to refer to an entire State Object, including attributes, as well as a State Object’s state field. The term attribute, BTW, is also overloaded. Leads to much confusion. :frowning:)

just as an example for regular Hue motion binary_sensors with a few attributes:

35

which makes it quite necessary to rules these out…at least when a trigger only for state: 'on' is desired

That’s exactly the point. Without specifying from: or to: it defaults to reporting changes for all of the entity’s properties. This is the opposite of how Premise works where I’d have to explicitly specify that I want to listen for changes to all properties. The default is to listen for changes to a single chosen property (like a light’s powerstate or brightness, etc) … and you don’t have to test if some property or object exists or not. It’s a different approach and, because I have years of experience with Premise, I find myself forgetting that Home Assistant is a different beast.

I have to agree with you that the nomenclature’s choices are, to be charitable, unfortunate.

In Premise, the nomenclature adheres to tried-and-true Object-Oriented language. An ‘entity’ is called an ‘object’ and an object has properties (and methods). The value of a light’s brightness property is 0.75 and the value of its powerstate property is true. Unlike Home Assistant, there’s no catch-all term called state (which can represent different things depending on the entity). Anyway, just mentioning it to explain why I’m having a little trouble making the conceptual shift to Home Assistant.

Yep, I can certainly understand that. Luckily I only used SmartThings before HA, so anything was way better! :wink:

You hide it well (considering your very helpful contributions on this site)!

Probably not all that well in this thread … where I effectively poo-pooed the need for the ‘belt and suspenders’ condition. Sorry about that. However, now that I have a better understanding of what a (unconstrained) State Trigger listens for (i.e. pretty much everything), that condition is looking mighty reasonable to me now.

1 Like