Catching enter/leave events

How do I listen to enter/leave zone events fired by a device tracker? I’ve zones set up, it works fine as a part of an automation rule:

- id: '1569482179999'
  alias: Check zones
  trigger:
  - entity_id: device_tracker.life360
    event: enter
    platform: zone
    zone: zone.work
  condition: []
  action:
  - data:
      message: Entered work
      title: Zone changed
    service: notify.myself

I was trying to accomplish the same thing using AppDaemon with no luck. If I run the code shown below (assuming every event should be captured), it catches some events from a Xiaomi button and HA internals like call service, but none related to zones:

def initialize(self):
    self.listen_event(self.catchall)

What am I doing wrong?

I don’t use the zone integration myself, so probably can’t help you much.

Does the device tracker “device_tracker.life360” have an attribute, which shows in which zone the device_tracker is in?

Or does the state of the device tracker change to the name of the zone when you enter a different zone?
So for example if you leave home and enter work, does the status of the device tracker change from “home” to “work”?

Yes, I can track changes to tracker entity state, that works. Just curious why zone events doesn’t work in AD.

If you enter the zone “work”, what is the state of the “device_tracker.life360”, is it “work” or “not_home”?

I’ve read some posts of people with a similar setup and as far as I understand, if the device tracker changes zones, the device tracker will show the name of the zone as the status of the device tracker.

If this is correct, you can use “listen_state” on the device tracker, something like this:

def initialize(self):
    self.listen_state("device_tracker.life360", self.zone_changed)

def zone_changed(self, entity, attribute, old, new, kwargs):
    if old != new:
        # notify that zone changed for device tracker life360, old=previous zone, new=current zone

The new state is “work” so yes, your approach will work, thank you for the comprehensive answer!
But I’m still wondering why listen_event approach does not work. :thinking: