Automations like "turn the heating down when everyone leaves" or "turn on the porch light when I get home" stand or fall on one thing: Home Assistant has to know who is at home. A single phone app or router check gets it wrong surprisingly often. GPS drifts, phones put Wi-Fi to sleep, and a restart can leave a tracker in an old state for a while.

Home Assistant handles this with person entities. A person can have several device trackers assigned, and Home Assistant decides the person's state from all of them by fixed rules. Combine a tracker that knows the location with one that knows the phone is on the home network, and you get a state that is both quick and hard to fool. Then you build automations on zones and persons instead of on individual trackers.

Two kinds of trackers

Device trackers come in two types, and the difference decides how they are combined.

  • Position trackers report coordinates (latitude, longitude, GPS accuracy). Home Assistant works out which zone they are in. The Home Assistant Companion app on a phone is the usual example.
  • Connection trackers only know whether a device is connected to something, such as a router, a Wi-Fi access point or a Bluetooth beacon. They have no coordinates. When connected, they put the device in their associated zone, which is home by default.

The state of a tracker is the name of the zone it is in, home, not_home, unavailable or unknown. If a device is in several overlapping zones, the state is the smallest one, and the in_zones attribute lists all of them, smallest first.

One more note: the device tracker docs say legacy trackers that do not report a tracking type are scheduled to be removed in the first half of 2027. If you still use an old YAML-based tracker, check whether it has a modern integration.

How a person picks its state

This is the part worth knowing well, because it explains most of the "why does it say I'm away" puzzles. According to the person integration docs, when a person has several trackers, the state is chosen in this order:

  1. If any connection tracker reports the device as connected (home), the most recently updated of those wins.
  2. Otherwise, the most recently updated position tracker wins.
  3. If neither applies, the most recent tracker reporting not_home is used.

In practice, while you are at home, the router or ping tracker has the final word and a jumpy GPS reading does not move you out of the house. When you leave and the connection tracker goes to not_home, the phone's location takes over and shows which zone you are in. The person entity also copies latitude, longitude, gps_accuracy and in_zones from whichever tracker it is following at the moment.

The docs walk through a seven-step example with a GPS tracker, a router tracker and a BLE tracker, including what happens after a restart. It is worth reading once if your household has more than one tracker per person.

Step 1: the Companion app as a position tracker

Install the Home Assistant Companion app on each phone and sign in. The app creates a device tracker for the phone. The settings that matter for presence:

  • Location Sent. The app can send the exact location, the zone name only, or nothing. The docs point out that "Zone Name Only" sends just the zone name or not_home, which is enough for presence detection without exposing your location.
  • Location permission. Give the app background location access, otherwise it can only report while it is open.
  • On Android, zone-based tracking. The app reports when you enter or leave a zone only when this is enabled. Android can also send background updates, which the docs say typically arrive every one to three minutes. High accuracy mode is available, with a default interval of 5 seconds, but it drains the battery, so it can be limited to times when the phone is connected to a given Bluetooth device or is inside a zone.
  • On iOS, significant location changes. Besides zone entry and exit, iOS sends an update after a significant change in location, which Apple, as quoted in the docs, defines as 500 meters or more. Such updates also wake the app at least once every 15 minutes.

The app also has a sensor.last_update_trigger sensor that tells you why the last location update was sent. It is the first thing to check when an update came late.

Step 2: a connection tracker on the home network

A second tracker that only answers "is the phone on my network" makes the at-home state far steadier. If your router has a Home Assistant integration with device tracking, use it. If not, the Ping integration works with any network:

  1. Give the phone a fixed address: a static IP or, better, a DHCP reservation in the router.
  2. Add the Ping integration in Settings > Devices & services and enter the phone's address.
  3. Enable the device tracker entity. The docs note that it is disabled by default.

By default, Ping checks the device every 30 seconds with 5 pings. A tracker only switches to away after the device has not answered for the "Consider home" period, 180 seconds by default, so short silences do not count as leaving. Because Ping does not depend on ARP or MAC addresses, it also works when the phones are on a different subnet than Home Assistant, where methods based on ARP fail.

The Ping docs themselves point out the weak spot: phones turn Wi-Fi off or stop answering while idle, so a Ping tracker alone is unreliable. That is exactly why it should not be alone. It sits on the person next to the Companion app.

Step 3: put the trackers on a person

Go to Settings > People and open the person, or add one. A person does not need a Home Assistant login, so you can create persons for family members who never open the dashboard. Under the trackers section, add the Companion app tracker and the Ping (or router) tracker for that person.

Persons can also be defined in YAML:

person:
  - name: Nina
    id: nina
    device_trackers:
      - device_tracker.nina_phone
      - device_tracker.nina_phone_ping

After editing the YAML, reload persons with the person.reload action.

Step 4: set up zones

The home zone is created during onboarding from your home location with a 100 meter radius. It cannot be deleted. Check that it really sits on your house. If GPS often places you just outside it, increase the radius rather than adding more trackers.

Other zones are managed in Settings > Areas, labels & zones, on the Zones tab. Set the location on the map and the radius in meters. A zone marked as Passive is hidden from the frontend and is not used for device tracker state, but you can still use it in automations. The docs mention one useful detail: since Companion app 2026.6.0 with Home Assistant 2026.6.0, the app can report all zones you are in, including passive ones, as a beta feature.

The state of each zone is the number of persons in it. zone.home showing 2 means two persons are at home, and this is what the occupancy triggers below are built on.

Step 5: automations on persons and zones

The device tracker docs recommend this pattern: put trackers on persons and write automations with zone triggers on those persons. The zone integration provides four triggers: zone.entered, zone.left, zone.occupancy_detected and zone.occupancy_cleared. This example comes from the zone docs:

alias: "Notify when Nina arrives at work"
triggers:
  - trigger: zone.entered
    target:
      entity_id: person.nina
    options:
      zone: zone.work
actions:
  - action: notify.send_message
    target:
      entity_id: notify.my_device
    data:
      message: "Nina arrived at work."

For "the last person left", use the occupancy trigger on the home zone. It fires when the zone goes from occupied to unoccupied, so it does not matter who leaves last:

alias: "Everyone left"
triggers:
  - trigger: zone.occupancy_cleared
    options:
      zone: zone.home
actions:
  - action: climate.set_preset_mode
    target:
      entity_id: climate.living_room
    data:
      preset_mode: away

zone.occupancy_detected is the matching "first person came home" trigger. For conditions there are zone.in_zone, zone.not_in_zone, zone.occupancy_is_detected and zone.occupancy_is_not_detected. The older trigger: zone with event: enter or event: leave still works if you have existing automations built on it.

A related detail from the trigger docs: triggers fire at the moment of a change, and most entity triggers do not fire on a change from unavailable or unknown. A restart that brings a person back from unknown to home will not usually be treated as an arrival.

Common mistakes

  • Automations on a single tracker instead of the person. Use person.* and zones, so improving the trackers later does not mean rewriting automations.
  • Only a Ping tracker. Phones sleep their Wi-Fi, and the person jumps to away. Pair it with the Companion app.
  • No DHCP reservation. The phone gets a new address and the Ping tracker watches the wrong one.
  • Forgetting to enable the Ping device tracker entity. It is disabled by default.
  • Home zone in the wrong place or too small. Check it on the map before tuning anything else.
  • Background location turned off for the app. The phone then reports only when the app is open.
  • Checking the state of zone.home against a name. The state is a count of persons, not home or away.