(Using notification to read outcome of vars.)
- alias: Light
trigger:
- platform: state
entity_id: light.sat
action:
- service: notify.mobile_app_sat
data:
message: "state={{states.light.sat.state}} from_state={{trigger.from_state.state}} to_state={{trigger.to_state.state}}"
On switching the light on/off, the notification reveals that from
and to
have the same value. From off to off, and from on to on. 
When including a to
field in the trigger
it becomes ‘correct’.
- alias: Light
trigger:
- platform: state
entity_id: light.sat
to: 'on'
action:
- service: notify.mobile_app_sat
data:
message: "state={{states.light.sat.state}} from_state={{trigger.from_state.state}} to_state={{trigger.to_state.state}}"
Here the result from
off to
on obtained in the notification. And opposite for when using to: 'off'
.
What is the technical explanation here? In the first situation the state of the light is still changing from off to on or from on to off, why is this not given in the notification?
According to the state trigger documentation:
If only entity_id
is given, the trigger will fire for all state changes, even if only state attributes change.
When you turn a light on or off, especially if it fades, its state will update multiple times. If you only want the automation to trigger once when it turns on or off, then use this for the trigger:
- platform: state
entity_id: light.sat
to:
- 'on'
- 'off'
Funny enough, I thought about this too and indeed implemented that solution. It works.
Your reply got me to look further. I added mode: parallel
to the automation and now get 2 notifications, one with the expected state change (on <-> off) and the one mentioned in topic start. As far as I can see, Zigbee2MQTT only sends out one message. Verified via Z2M debug log level and looking at MQTT Explorer. When setting the state via MQTT Explorer, the same happens. I looked at a lot of atrributes but none seem to change in between, including last_updated
and last_changed
.
I really wonder what is causing a 2nd change or update, that appears so fast that it gets processed earlier than the ‘real one’. 
The best way to figure out what’s going on is to turn on some debug messages:
logger:
default: info
logs:
homeassistant.components.automation: debug
homeassistant.components.script: debug
homeassistant.core: debug
Then, after restarting HA, when the problem happens, look in home-assistant.log. There will be details there about the light state changes, as well has the automation being triggered & running.