How to get the 'old' value of an attribute?
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?
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.
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'
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.
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.
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