Privacy-first family location for Home Assistant. PositionGuard exposes
your family group's presence as native device_tracker and
binary_sensor entities, with area-level granularity — home, school,
grandma's house — instead of exact coordinates.
Built for Home Assistant users who want reliable family presence detection without handing their family's location data to third-party services.
- Area-level, not coordinate-level. PositionGuard reports presence as "in this area" or "not in this area" — never exact GPS coordinates. Your dashboard shows where family members are grouped, not where they stand.
- One install per person. Family members install the PositionGuard app on their phone once. They don't need a Home Assistant account, the HA Companion app, or any HA configuration on their device.
- Works around iOS Private Wi-Fi Address rotation. Position is reported by the phone, not detected by the router. Family members' iPhones report reliably regardless of MAC randomization.
- Privacy-first by design. No data sale, no ads, no third-party trackers. Sharing can be paused per-person at any time.
When configured, the integration exposes one device per group with the following entities per family member:
device_tracker.<member>_in_<group>— whole-group presence. States:home(member is in any area belonging to this group),not_home(member is outside all group areas),unavailable(sharing paused).binary_sensor.<member>_at_<area>— per-area presence, one per (member, area) combination. Stateon(in this specific area),off(not in this specific area),unavailable(sharing paused). Disabled by default — enable only the ones you want to use.binary_sensor.<member>_outside_usual_area— Safety Zone status, one per member per group.onexactly when PositionGuard has a fresh position for the member and it is confirmed outside their usual area — the zone PositionGuard computes from that member's own saved places.offwhile they are at a saved place or inside their usual area.unavailablewhile their position is stale: a phone that has gone quiet is no evidence either way, so it never fires this alarm and never reads asoff(the device tracker'ssafety_statusattribute readsstaleif you want to automate on staleness separately). Alsounavailablewhen PositionGuard sends no safety data for the member — absence of knowledge is never shown as being inside. In the UI the two states read Outside and Inside; the state itself stayson/off, which is what automations and history use.
Each entity exposes useful attributes including area (the specific
area within the group, if any) and sharing_status (active or
disabled). When PositionGuard provides Safety Zone data, more ride
along: safety_status (at_area / in_zone / out_of_zone /
stale), safety_area (the name of the member's own matched place,
when you're allowed to see it), position_age_seconds, and
position_fresh. position_fresh is false while PositionGuard holds a
quiet phone at the saved place it was last confirmed in: safety_status
stays at_area and the sensor stays available, so check position_fresh
in automations that need "there right now". Servers that don't send it
leave the attribute out.
Both paused sharing and a temporary inability to reach PositionGuard render
the entity unavailable. To distinguish the two in an automation, check the
sharing_status attribute (disabled means the member paused sharing)
rather than the entity state alone.
The integration creates one device per group with all member entities, visible under Settings → Devices & Services → PositionGuard:
- Home Assistant: 2026.3 or later (required for proper icon rendering)
- PositionGuard app: latest version on iOS App Store (download). Android support is in open beta on Google Play (US and Sweden for now). If you're in another region or the beta is full, mention it in the Discussions tab and I'll help you get access.
- HACS: recommended for installation, though manual install is supported
The integration requires a PositionGuard account (free) and an API key from dev.positionguardai.com. Free tier covers a typical household:
Up to 3 groups Up to 3 areas per group Up to 10 members per group
An optional paid tier on iOS raises these limits (unlimited groups and members, up to 20 areas per group) for larger setups. A typical family — one group, home/school/work areas, everyone in it — fits comfortably in the free tier. The integration polls the PositionGuard API every 30 seconds per configured group, which is well within the API's rate limits — no tuning needed.
You'll go through three places: the PositionGuard app (to set up your account and family), the developer portal (to mint an API key), and HACS (to install this integration).
- Install PositionGuard from the App Store or Google Play.
- Sign in with your phone number (SMS verification).
- Create a family group. Default name is "Family"; rename if you like.
- Add areas to the group: at minimum a "Home" area centered on your house. Add others as needed (work, school, grandma's house, etc.). The integration will expose every member-area combination as a binary sensor.
- Invite family members to the group. They install the app and accept the invite. Sharing can be paused per-person at any time.
- Confirm your own and family members' positions update on the app's map. Wait at least 30 seconds after any change for presence state to propagate before checking in HA.
- Visit dev.positionguardai.com.
- Sign in with the same phone number you used for the app.
- Click Create API key, give it a descriptive name (e.g., "Home Assistant").
- Copy the key — it's shown once only. Store it somewhere safe (a password manager works well).
- In Home Assistant, open HACS.
- Click the three-dot menu (top right) → Custom repositories.
- Add this repository:
- Repository:
https://github.com/positionguard/positionguard-homeassistant - Type:
Integration
- Repository:
- Click Add.
- Find PositionGuard in HACS and click Download.
- Restart Home Assistant when prompted.
- Go to Settings → Devices & Services → Add Integration.
- Search for "PositionGuard" and select it.
- Paste your API key.
- Select which group(s) you want to expose to Home Assistant. You can select multiple groups (Family, Work, Activity groups, etc.). Each becomes a separate device with its own member entities.
- Done. Your family members will appear as
device_trackerentities within ~30 seconds.
If you don't use HACS:
- Clone or download this repo.
- Copy
custom_components/positionguard/into your Home Assistant/config/custom_components/directory. - Restart Home Assistant.
- Configure as in step 4 above.
In-place version updates are supported. When a new version is released,
HACS will offer the update; accept and restart HA. Entity IDs are
preserved across updates — you won't see suffixes like _2 appended
to your existing entities.
The integration is architected to support multiple Home Assistant instances (e.g. main home + vacation property, or separate hubs at different locations) — each instance runs the integration independently, and family members only join the PositionGuard group once regardless of how many instances you run.
How it's expected to work:
- Each HA instance runs the integration independently (same or separate API keys).
- "Home" / present area can be configured differently per instance if desired.
- Family members set up the app once — no extra setup per instance on their side.
- The
currentAreaattribute gives visibility across all areas from any instance.
Verified status: confirmed working in multi-instance setups on Hubitat, using the same underlying architecture. I haven't personally run it across multiple HA instances yet, so I'm not calling this fully verified on HA — but the mechanism doesn't differ per platform, and early Hubitat feedback has been positive.
If you're running a multi-site setup, I'd love to hear how it goes!
PositionGuard is built privacy-first. The integration shows presence at area level only, never exact coordinates. The map in Home Assistant will display the area boundary, not a precise location point.
What's shared:
- Whether each member is at any area in the group (
home/not_home) - Which specific area, if any, they're in
- Whether sharing is active or paused
What's never shared:
- Exact GPS coordinates
- Movement history outside of area transitions
- Any data about non-family-members nearby
When a family member pauses sharing in the app, the integration
respects this immediately. Their entities become unavailable rather
than reporting stale or fabricated data — automations correctly do not
fire on paused users.
The examples below use a sample LA family group with parents Fred and Sarah, and kids Peter, John, and Sally. Areas defined: Home, School, Grandma's House.
The Safety Zone sensor exists for exactly one automation: tell me when a family member is somewhere unexpected. No templates needed — trigger on the binary sensor directly:
automation:
- alias: "Alert when Sally is outside her usual area"
trigger:
- platform: state
entity_id: binary_sensor.sally_outside_usual_area
to: "on"
action:
- service: notify.mobile_app_freds_phone
data:
title: "PositionGuard"
message: >
Sally is outside her usual area
(last position {{ state_attr('binary_sensor.sally_outside_usual_area',
'position_age_seconds') // 60 }} minutes ago).Two properties worth knowing before you trust it with announcements:
a stale position never fires this (a phone dying in a pocket is not
evidence of being outside — check the device tracker's safety_status
attribute for stale if you want a separate "no recent position"
automation), and when PositionGuard has no safety data at all the sensor
goes unavailable rather than claiming the member is inside.
The simplest case — trigger on a member arriving home:
automation:
- alias: "Welcome John home"
trigger:
- platform: state
entity_id: device_tracker.john_in_family
to: "home"
action:
- service: light.turn_on
target:
entity_id: light.living_roomThis fires when John transitions from outside any group area to inside any group area. If you want to be specific about which area he arrived at, see the next example.
The device_tracker entity exposes an area attribute identifying
which specific area within the group the member is in. Use a template
condition to match a particular area:
automation:
- alias: "Music when family arrives at Beach House"
trigger:
- platform: state
entity_id: device_tracker.fred_in_family
to: "home"
condition:
- condition: template
value_template: >
{{ state_attr('device_tracker.fred_in_family', 'area')
== 'Beach House' }}
action:
- service: media_player.play_media
target:
entity_id: media_player.beach_house_speaker
data:
media_content_id: "spotify:playlist:..."
media_content_type: "playlist"This pattern lets you keep one Family group with multiple areas (Home, School, Beach House, Grandma's House) and use templates to distinguish which area triggered the automation. You don't need to create a separate group per area.
A reliable "kid arrived at school safely" notification is one of the killer use cases for family presence. Two approaches — pick whichever fits your style.
Using the area attribute (no entity setup needed):
automation:
- alias: "Notify when Sally arrives at School"
trigger:
- platform: state
entity_id: device_tracker.sally_in_family
to: "home"
condition:
- condition: template
value_template: >
{{ state_attr('device_tracker.sally_in_family', 'area')
== 'School' }}
action:
- service: notify.parents
data:
message: "Sally arrived at school"Using the per-area binary sensor (cleaner, requires enabling the sensor first):
automation:
- alias: "Notify when Sally arrives at School"
trigger:
- platform: state
entity_id: binary_sensor.sally_at_school
to: "on"
action:
- service: notify.parents
data:
message: "Sally arrived at school"The binary sensor approach is more readable in YAML but requires enabling the sensor first (see next section).
For each (member, area) combination, a binary_sensor exists but is
disabled by default to avoid cluttering Home Assistant with dozens
of entities most users won't reference.
To enable a binary sensor:
- Settings → Devices & Services → PositionGuard
- Click your group device
- Click the binary sensor entity (e.g.,
binary_sensor.sally_at_school) - Toggle "Enabled" on
- Restart HA or reload the integration
Once enabled, automations using these sensors are simpler than the
template-based approach — no state_attr calls, just direct state
checks.
The integration shines when you have multiple meaningful areas in a
single group. Define all your common destinations as areas in the
PositionGuard app, then write automations using the area attribute:
automation:
- alias: "Announce who arrived where"
trigger:
- platform: state
entity_id:
- device_tracker.fred_in_family
- device_tracker.sarah_in_family
- device_tracker.john_in_family
- device_tracker.peter_in_family
- device_tracker.sally_in_family
to: "home"
action:
- service: notify.family
data:
message: >
{{ trigger.to_state.attributes.friendly_name }}
arrived at
{{ trigger.to_state.attributes.area }}This single automation announces every family-member arrival at every defined area, dynamically including the area name in the notification.
When a family member pauses sharing in the PositionGuard app, their
entities become unavailable rather than not_home. Automations that
trigger on home → not_home transitions will correctly not fire
when someone simply pauses sharing — only on actual departures.
If you want to track sharing status explicitly, each entity exposes a
sharing_status attribute (active or disabled):
automation:
- alias: "Note when sharing is paused"
trigger:
- platform: state
entity_id: device_tracker.peter_in_family
condition:
- condition: template
value_template: >
{{ state_attr('device_tracker.peter_in_family',
'sharing_status') == 'disabled' }}
action:
- service: notify.parents
data:
message: "Peter has paused location sharing"AlertTicker Card by
djdevil pairs nicely with PositionGuard for moment-based presence
notifications on a dashboard. Use auto_dismiss_after for transient
arrival/departure alerts that don't clutter the dashboard:
type: custom:alertticker-card
alerts:
- entity: binary_sensor.sally_at_school
state: "on"
message: "🎒 Sally arrived at School"
theme: success
auto_dismiss_after: 60
- entity: device_tracker.fred_in_family
on_change: true
message: "👤 {{ state_attr('device_tracker.fred_in_family',
'friendly_name') }}: {{ state }}"
auto_dismiss_after: 60The first variant fires only on arrivals at a specific area. The second fires on any state transition (arrival or departure) and includes the state in the message.
In practice, this looks like:
This integration is read-only. From Home Assistant, you cannot:
- Create, modify, or delete groups, areas, or members
- Change sharing permissions
- Send messages, invitations, or notifications
These actions remain in the PositionGuard app where group members can manage their own privacy directly.
The integration polls the PositionGuard API every 30 seconds. Position changes typically reflect in Home Assistant within 30–60 seconds of the actual change.
Use the Discussions tab for questions or feedback, and Issues for bug reports.
For information about PositionGuard the app or the developer portal, visit positionguardai.com.



