How to trigger on attribute change?

I know I can do this

    trigger:
      - platform: state
        entity_id: vacuum.landroid_chugger
        attribute: rain_sensor

But what if my attribute is

rain_sensor:
  delay: 60
  triggered: false
  remaining: 40

and I want to trigger on remaining?

I’ve tried this but it doesn’t seem to work

    trigger:
      - platform: state
        entity_id: vacuum.landroid_chugger
        attribute: rain_sensor.remaining

Use a template trigger. The template needs to result in true to trigger, so something like:

platform: template
value_template: "{{ state_attr('sensor.rain_sensor','remaining')|int < 40 }}"

You can check it works properly in Dev Tools > Template first

edit: You may for may not need the |int

I wasn’t clear, sorry.

The attribute is

rain_sensor:
  delay: 60
  triggered: false
  remaining: 40

rain_senor is an attribute, remaining is an attribute of the attribute rain_sensor

Like this,

vacuum.landroid
  attribute1: some_value1
  attribute2: some_value2
  rain_sensor:
    delay: 60
    triggered: false
    remaining: 40
  attribute3: some_value3

well, OK then :wink:

try this:

platform: template
{% if state_attr('vacuum.landroid','rain_sensor').remaining <40 %} true {% endif %}"

But I don’t want to check on a specific value, I just want to trigger when it changes to anything.

Why is your initial try not doing what you want then?
Will delay or triggered change while remaining would be the same? Would it actually matter?

1 Like

It appears that a change to child-attributes does not trigger a change to the parent.
It would in this case

vacuum.landroid
  attribute1: some_value1
  attribute2: some_value2
  rain_sensor: some_value
    delay: 60
    triggered: false
    remaining: 40
  attribute3: some_value3

but in this case rain_sensor itself has no value to change.

And in any case I still want to know if the child-attribute changes. All the children change independently for different reasons.


Just so you know what I mean, remaining starts at 60 (the value of delay) and decreases with time until it reaches zero. Unless or until it goes back to 60 when triggered becomes true again.

What do you mean by “child attribute”?

Please show a screenshot of the state of your entities in the developer tools, because the way you show it doesn’t make sense in HA: attributes have only 1 “level”.

So the attributes of the “vacuum.landroid” entity might look similar to

  attribute1: some_value1
  attribute2: some_value2
  rain_sensor: "{delay: 60,  triggered: false,  remaining: 40}"
  attribute3: some_value3

Random example:

Yes it does but I can’t get the state trigger to look that ‘deep’.

put this into Dev tools > template

{{ state_attr('vacuum.landroid','rain_sensor') }}

I think you might need to add a helper to hold the last value of the attribute and then use a template trigger to run the actions when the new attribute is not equal to the old attribute value:

trigger:
  - platform: template
    value_template: "{{ state_attr('vacuum.landroid_chugger', 'rain_sensor').remaining != states('input_text.some_entity') }}"
action:
    - service: input_text.set_value
      entity_id: inout_text.some_entity
      data:
        value: "{{ state_attr('vacuum.landroid_chugger', 'rain_sensor').remaining }}"
  - some other actions

To get the value, you would use:

{{ state_attr('vacuum.landroid','rain_sensor')[0].remaining }}

My pure guess … I would believe that you could use a template trigger on the attribute ‘rain_sensor’ and trigger variables trigger.from_state and trigger.to_state to evaluate whether the change was in the remaining. Then use that variable boolean to do nothing or do something in the automation.

Never saw that before. Which integration is this?

EDIT: I guess

I’m pretty sure that what they do with objects in attributes is unsupported

Your most reliable option is to set up a template sensor to monitor the sub-attribute, then you can use a basic State trigger.

template:
  - sensor:
      - name: Landroid Remaining Rain Delay
        unit_of_measurement: minutes
        state: "{{ state_attr('vacuum.landroid','rain_sensor')[0].remaining }}"

The other option is to do as @kbrown01 suggested:

trigger:
  - platform: state
    entity_id: vacuum.landroid
condition:
  - condition: template
    value_template: |-
      {{ (trigger.to_state.attributes.rain_sensor)[0].remaining  != (trigger.from_state.attributes.rain_sensor)[0].remaining}}
action:
.....

EDIT: As pointed out below, the [0] index selection may not be necessary, but I do not use the device or integration in question and I am unable to test its necessity. Try it without first, and if you get errors try it with the index selection.


Most of the weather integrations that offer forecasts use something similar…

image

Why [0]? It’s not an array.
If {{ state_attr('vacuum.landroid','rain_sensor').remaining }} works in the developers tool, then indeed a template is the way to go.

1 Like

Have you considered making a Template Sensor for it and using that in a State Trigger?

template:
  - sensor:
      - name: Remaining
        state: "{{ state_attr('vacuum.landroid','rain_sensor').remaining }}"

Ah, indeed, I never realized. I stand corrected.

Still, your [0] is wrong, though :wink:

1 Like

I could only find 1 entity in my instance that is similar to OP’s with just a single set of sub-attributes instead of an explicit array like the weather forecasts and it throws an error (UndefinedError: 'homeassistant.helpers.template.Wrapper object' has no attribute 'today') if I don’t use [0]:man_shrugging:

That’s because it’s an array, as can be seen in the dev tools.
If the “children” start with an hyphen, it’s an array, and then [<index>] is required, indeed.
But that’s not the case for the OP, as can be seen from his screenshot.

image

The States tool doesn’t always show a hyphen for arrays. (See any thread regarding the mobile app’s Bluetooth Connection sensor and its connected_paired_devices and paired_devices attributes)

1 Like