pyscript icon indicating copy to clipboard operation
pyscript copied to clipboard

How to get the 'old' value of an attribute?

Open MizterB opened this issue 3 years ago • 5 comments

I would like to compare the new and old values of an attribute when it changes. Specifically, I'd like to compare the current and previous brightness of a light when I detect the brightness attribute changing in a @state_trigger.

When I create a @state_trigger for an entity attribute, I do not have access to the 'old' value of that attribute inside the function. I understand that the domain.name.old.attr form is available inside the decorator's expression, but that does not appear to carry into the function itself. Instead, the value and old_value arguments always refer back to the entity state, not the entity attribute referenced in the trigger.

Is it possible to make this data available?

MizterB avatar Jan 30 '23 23:01 MizterB

You are correct that the domain.name.old.attr form only works in trigger expressions.

However, inside the function, old_value.attr should allow you to get the attributes of the prior entity state.

craigbarratt avatar Jan 30 '23 23:01 craigbarratt

Unfortunately, that's not the behavior I'm seeing with this code:

@state_trigger("light.upstairs_hall_1_1_upstairs_hall_ceiling_motion_dimmer.brightness")
def jasco_motiondimmer_state(value=None, old_value=None):
    result = {}
    if value.brightness > 0:
        result["button_label"] = "up"
    elif value.brightness == 0:
        result["button_label"] = "down"
    log.debug(result)

When triggered, it throws

AttributeError: 'StateVal' object has no attribute 'brightness'

MizterB avatar Jan 31 '23 01:01 MizterB

Since your state trigger is the attribute light.upstairs_hall_1_1_upstairs_hall_ceiling_motion_dimmer.brightness, I believe value and old_value are the attribute value, not the entity (just based on quick inspection of the code; I haven't tested this).

Assuming my statement is correct, there are two different fixes. Either change your trigger to:

@state_trigger("light.upstairs_hall_1_1_upstairs_hall_ceiling_motion_dimmer")

or change your function to just use value and old_value instead of value.brightness etc.

craigbarratt avatar Jan 31 '23 19:01 craigbarratt

That's what I assumed, but it wasn't the behavior I was seeing - hence the issue. I was triggering on the attribute, but the values reflected the entity 'state' value, not the 'attribute' one.

MizterB avatar Jan 31 '23 19:01 MizterB

Just retested to make sure...

@state_trigger("light.upstairs_hall_1_1_upstairs_hall_ceiling_motion_dimmer.brightness")
def jasco_motiondimmer_state(value=None, old_value=None):
    log.debug(f"value: {value}, old_value: {old_value}")

returns state, not attribute

value: on, old_value: off

MizterB avatar Feb 02 '23 17:02 MizterB