Code Monkey home page Code Monkey logo

home-assistant_person_location's Introduction

Home Assistant Person Location Custom Integrationhacs_badge

Table of Contents

Objectives

Sample person location

Combine the status of multiple device trackers

This custom integration will look at all device trackers that are for a particular person and combine them into a single person location sensor, sensor.<name>_location. These "device trackers" can be device_tracker, sensor, binary_sensor, or person entities. Device tracker state changes are monitored rather than doing polling, averaging the states, or calculating a probability. Device trackers follow devices that the person has; the person location sensor tries to follow the person instead.

Click for More Details

For meaningful results, the device trackers should include latitude and longitude attributes, as in Mobile App, iCloud, and iCloud3 device trackers. Most location features will be skipped for updates triggered by "device trackers" that do not know the location coordinates, but these are still useful for presence detection.

The process for deciding which triggered device trackers to pay attention to is somewhat controversial, but here is how we do it. Each update of a "device tracker" (the trigger) is examined to decide if it should be used to update the person location sensor (the target).

  • Trigger is the target itself:
    • Skip
  • Trigger has gps_accuracy equal to 0 or greater than 100:
    • Skip
  • Trigger state is NotSet:
    • Skip
  • Trigger location time is before target location time (previous update):
    • Skip
  • First trigger for the target:
    • Accept
  • Target has unknown state:
    • Accept
  • Trigger source is GPS:
    • Trigger changed zones:
      • Accept
    • Trigger did not change zones:
      • Target is not "following" a particular trigger:
        • Accept
      • Target is already following this trigger:
        • Accept
      • Trigger has the same state as the one being followed:
        • Trigger accuracy is better than the one being followed:
          • Accept
  • Trigger source is not GPS
    • Trigger changed state:
      • Trigger implies Home and Target is not Home:
        • Accept
      • Trigger implies Away and Target is Home:
        • Accept

Make presence detection not so binary

When a person is detected as moving between Home and Away, instead of going straight to Home or Away, it will temporarily change the person's status to Just Arrived or Just Left so that automations can be triggered or conditions applied appropriately.

Person State Diagram

Inspired by https://philhawthorne.com/making-home-assistants-presence-detection-not-so-binary/

If CONF_SHOW_ZONE_WHEN_AWAY, then <Zone> is reported instead of Away.

Reverse geocode the location and make distance calculations

The custom integration supplies a service to reverse geocode the location (making it human readable) using Open Street Map, MapQuest, or Google Maps and calculate the distance from home (miles and minutes) using WazeRouteCalculator.

Components

Folder: custom_components/person_location

This folder contains the files that make up the Person Location custom integration.

Click for More Details

Calculated Location Attributes

By default, the custom integration will set the following attribute names in the sensor.

Attribute Name Example Description
compass_bearing: 90.0 most recent direction of travel (degrees)
meters_from_home: 71862.3 calculated distance from Home (meters)
miles_from_home: 44.7 calculated distance from Home (miles)
direction: stationary most recent direction from Home
driving_miles: 50.6 distance from Home based on Waze route
driving_minutes: 46.8 distance from Home based on Waze traffic conditions

Attribution: "Data provided by Waze App. Learn more at Waze.com"

Open Street Map Geocoding

Reverse geocoding generates an address from a latitude and longitude. The Open Street Map reverse geocoding feature sets the following attribute names in the sensor.

Attribute Name Example Description
Open_Street_Map: 1313 Mockingbird Lane Hollywood Los Angeles California 90038 United States display_name from Open Street Map
friendly_name: Rod (Rod's iPhone) is in Los Angeles formatted location to be displayed for sensor

Open Street Map (Nominatim) has a usage policy that limits the frequency of calls. The custom integration attempts to limit calls to less than once per second. To meet the requirement to be able to switch off the service, the state of person_location.person_location_api can be changed to Off. This can be done by calling service person_location.geocode_api_off and then resumed later by calling service person_location.geocode_api_on. The number of calls is also reduced by skipping updates while the person location sensor state is Home or if the location has changed by less than 10 meters. (It will update while the state is Just Arrived, so it reflects the home location while home.)

If you find problems with the OSM information results, feel free to sign up at https://www.openstreetmap.org/ and edit the map.

Attribution: "Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright"

Google Maps Geocoding

The Google Maps Geocoding feature sets the following attribute names in the sensor.

Attribute Name Example Description
Google_Maps: 1313 Mockingbird Ln, Los Angeles, CA 90038, USA formatted_address from Google Maps
friendly_name: Rod (Rod's iPhone) is in Los Angeles formatted location to be displayed for sensor

Attribution: powered by Google

MapQuest Geocoding

The MapQuest Reverse Geocoding feature sets the following attribute names in the sensor.

Attribute Name Example Description
MapQuest: 1313 Mockingbird Ln, Los Angeles, CA 90038-9436 constructed from MapQuest location attributes.
friendly_name: Rod (Rod's iPhone) is in Los Angeles formatted location to be displayed for sensor

Attribution: © 2021 MapQuest, Inc.

File: automation_folder/person_location_detection.yaml

This automation file contains example automations that call the person_location/process_trigger service. This is one of the ways to specify which device trackers will be watched for events that will trigger processing. These automations are optional and are kind of a non-standard way to configure the integration.

Click for More Details

Automation Person Location Update contains a list of device tracker entities to be monitored. Automation Person Location Device Tracker Updated looks at all state_changed events to find the ones that belong to device trackers. One automation or the other (or both) can be used to select the input for the process.

Note that Person Location Update for router home and Person Location Update for router not_home are not currently used by me because it drives my router crazy to be probed all the time. The intention here was to give a five minute delay before declaring the device not home, so that temporary WIFI dropoffs do not cause inappropriate actions.

Device tracker requirements (input)

Each device tracker that is processed (by calling the person_location/process_trigger service) needs to have the identity of the person that is being tracked. This is specified in either a person_name or account_name attribute of the device tracker. This could be done in Configuration Customizations.

Customizations Example

In the case of the Apple iCloud integration, the account_name can be specified in its configuration and this gets passed thru to the device trackers:

# Example configuration.yaml entry for iCloud presence

- platform: icloud
  username: [email protected]
  password: !secret icloud_rod
  account_name: rod

Service: person_location/process_trigger

This is the service that is called by automation Person Location Update following a state change of a device tracker such as a phone, watch, or car. It creates/updates a Home Assistant sensor named sensor.<personName>_location. The configuration can also specify that this be done for all person entities and/or for selected "device trackers".

Click for More Details
Input:
  - Parameters for the call:
      entity_id
      from_state
      to_state
  - Attributes of entity_id (supplied by device_tracker process):
      last_located (optional, from iCloud3)
      latitude
      longitude
      person_name (if different from what is implied by entity_id = device_tracker.<person_name>_whatever)
      altitude (optional, passed thru to the output sensor)
      entity_picture (optional, passed thru to the output sensor)
      gps_accuracy (optional)
      source_type (optional)
      vertical_accuracy (optional)
      zone (optional)

The sensor will be updated with a state such as Just Arrived, Home, Just Left, Away, or Extended Away. In addition, selected attributes from the triggered device tracker will be copied to the sensor. Attributes source (the triggering entity ID), reported_state (the state reported by the device tracker), icon (for the current zone), and friendly_name (the status of the person) will be updated.

Note that the person location sensor state is triggered by state changes such as a device changing zones, that way a phone left at home does not get a vote for "home". The assumption is that if the device is moving, then the person has it. An effort is also made to show more respect to devices with a higher GPS accuracy. This typically results in the mobile app being followed.

The built-in Person integration competes somewhat in combining the status of multiple device trackers. I expect that its ability to determine the actual presence and location of a person will improve with time. If you prefer the selection priority that the built-in Person integration provides, only call the person_location/process_trigger service for changes of the person.<personName> entity rather than the upstream device trackers. Do not mix the two because it is likely to double the updates and may get stuck following the wrong entity. You could follow all configured Person entities by skipping all calls to person_location/process_trigger and selecting the follow_person_integration configuration option.

Person location sensor example (output)

Entity State Attribute Name Example Description
sensor.rod_location Home source_type: gps source_type copied from device tracker
latitude: xx.136566162109375 latitude copied from device tracker
longitude: -xxx.60774422200406 longitude copied from device tracker
gps_accuracy: 65 gps_accuracy copied from device tracker
altitude: xxxx.1041374206543 altitude copied from device tracker
vertical_accuracy: 10 vertical_accuracy copied from device tracker
friendly_name: Rod (Rod's iPhone) is Home formatted location to be displayed for sensor
source: device_tracker.crab_apple device tracker that triggered the state
reported_state: Home state reported by the device tracker
update_time: 2020-12-11 17:08:52.267362 time that the device tracker location was obtained
zone: home zone reported for the location or away if not in a zone
icon: mdi:home icon for the zone of the location

Service: person_location/reverse_geocode

This is the service to reverse geocode the location in a sensor and it is called by person_location/process_trigger. It could also be called by other integrations to do the same for their sensors.

Click for More Details
Input:
  - Parameters for the call:
      entity_id
      friendly_name_template (optional)
      force_update (optional)
  - Attributes of entity_id:
      - attributes supplied by another process (to provide current location):
          latitude
          longitude
          location_time (optional)
          source (optional)

Installation

HACS

This integration can be added to HACS as a custom (non-default) repository.

Assuming you have already installed and configured HACS, follow these steps:

  1. Navigate to the HACS integrations page at http://<your-home-assistant>:8123/hacs/integrations.
  2. Click the 3 vertical dots menu in the top right corner.
  3. Choose "Custom repositories"
  4. Enter repository URL (https://github.com/rodpayne/home-assistant_person_location/) in the text field in the dialog.
  5. Choose "Integration" from the Category list in the dialog.
  6. Click "Add". The repository will now be added to your HACS.
  7. Click the "x" to close the dialog.
  8. The integration is now visible. Click "Install", and click "Install" again.
  9. Ready! Now continue with the configuration.

Manual Installation Hints

  1. Copy folder custom_components/person_location and its contents under your <config> directory.

  2. Optionally, copy and update file <config>/automation_folder/presence-detection.yaml as appropriate for your devices. (This file may need to be placed elsewhere or merged into <config>automation.yaml, depending on how your configuration is organized. My Home Assistant configuration is split into multiple folders.)

  3. Restart Home Assistant.

  4. Configure in Home Assistant Settings > Devices & services or add configuration in <config>/configuration.yaml.

  5. Restart Home Assistant if <config>/configuration.yaml was updated.

Configuration Parameters

The configuration can be updated in either the Settings > Devices & services GUI, or by adding parameters to configutation.yaml. To avoid confusion and prevent unexpected results, choose to use one or the other, not both.

GUI Parameter YAML Parameter Optional Description Default
Follow Person Integration? follow_person_integration Yes Follow updates of all Person entities rather than looking at individual device trackers. False
Friendly Name Template* friendly_name_template Yes A template that specifies how the friendly_name of the sensor is formatted. See the note concerning template variables in More Details below. The original format: {{person_name}} ({{source.attributes.friendly_name}}) {{friendly_name_location}}
Google API Key google_api_key Yes Google API Key obtained from the Google Maps Platform. Do not do the Google reverse geocoding.
Google Language language Yes Language parameter for the Google API. en
Google Region region Yes Region parameter for the Google API. US
Hours Extended Away* extended_away Yes Number of hours before changing Away into Extended Away. Set to 0 to not use Extended Away state. 48
Mapbox Access Token mapbox_api_key Yes Mapbox Access Token obtained from the Mapbox Account page. (Sign up for a free "hobbyist" account.) Do not use MapBox to generate maps.
MapQuest API Key mapquest_api_key Yes MapQuest API Key obtained from the MapQuest Developer site. Do not do the MapQuest reverse geocoding.
Minutes Just Arrived* just_arrived Yes Number of minutes before changing Just Arrived into Home. Set to 0 to not use Just Arrived state. 3
Minutes Just Left* just_left Yes Number of minutes before changing Just Left into Away. Set to 0 to not use Just Left state. 3
OSM API Key (your eMail Address) osm_api_key Yes Contact email address to be used by the Open Street Map API. Do not do the OSM reverse geocoding.
Platform for output sensor platform Yes Platform used for the person location "sensor". (Experimental.) sensor as in sensor.<name>_location.
Sensors to be created create_sensors Yes List of attributes for which individual sensors are to be created so that template sensors do not need to be configured. Choose from this list: altitude, bread_crumbs, direction, driving_miles, driving_minutes, geocoded, latitude, longitude, meters_from_home, miles_from_home. None
Show zone when away?* show_zone_when_away Yes Show the state as the zone name when it is available, rather than just Away. False
Person Location Triggers* person_names Yes List of person names and devices to be followed. (See example in More Details.) None

* Located in the options flow (activated by clicking CONFIGURE). All others are located in the configuration flow (activated when adding the integration or by clicking ... Reconfigure)

Click for More Details
# Example configuration.yaml entry
person_location:
  person_names:
    - name: Rod
      devices:
        - device_tracker.rod_iphone
        - device_tracker.rod_iphone_3
        - sensor.ford_focus_location
    - name: Pam
      devices: person.pam

GUI configuration example

In this example, sensor.rod_location will reflect changes detected in three devices; sensor.pam_location will reflect changes in the person.pam entity.

Open Street Map Geocoding Configuration

To activate the custom integration with the Open Street Map reverse geocoding feature, add a contact email address to <config>/configuration.yaml. Open Street Map is free and you do not need to sign up for an API key, so this may be a good place to start.

# Example configuration.yaml entry
person_location:
    osm_api_key: !secret gmail_address

Google Maps Geocoding Configuration

To activate the custom integration with the Google Maps Geocoding feature, add a Google API Key to <config>/configuration.yaml. A Google API Key can be obtained from the Google Maps Platform site. Unfortunately, obtaining a Key requires that billing be set up. Their free tier is generous for our purposes, but if it gives you the heebie-jeebies to give Google a credit card, stick with Open Street Map.

# Example configuration.yaml entry
person_location:
    google_api_key: !secret google_api_key

MapQuest Geocoding Configuration

To activate the custom integration with the MapQuest Reverse Geocode feature, add a MapQuest API Key to <config>/configuration.yaml. A MapQuest API Key can be obtained from the MapQuest Developer site.

# Example configuration.yaml entry
person_location:
    mapquest_api_key: !secret mapquest_api_key

Friendly Name Template Variables

Example Variable Description Sample
friendly_name_location The zone or locality that was determined. "is Away", "is at Walmart", "is in Peoria".
person_name The person's name from the configuration. "Rod"
source.attributes.friendly_name The friendly_name of the device tracker that triggered the update. "Rod's iPhone App"
target.attributes.reported_state The reported_state recorded in the output sensor. (The other attributes of the output sensor can be similarly referenced,)
Example Template Sample Result
{{ person_name }} ({{ source.attributes.friendly_name }}) {{ friendly_name_location }} "Rod (Rod's iPhone App) is in Peoria"
{{ person_name }} "Rod"
{{ person_name }} {{ friendly_name_location }} "Rod is in Peoria"
{{ person_name }}'s Location "Rod's Location"

A note about iCloud3

If you use the iCloud3 integration, the following setting helps with showing the zone and icon when you have an apostrophe in the zone's friendly name.

# config_ic3.yaml
display_zone_format: fname

Configure a Switch to control Person Location API calls (optional)

# Example configuration.yaml entry

switch:
  - platform: template
    switches:
      person_location_integration:
        friendly_name: Person Location Service
        value_template: "{{ is_state('person_location.person_location_integration', 'on') }}"
        turn_on:
          service: person_location.geocode_api_on
        turn_off:
          service: person_location.geocode_api_off
        icon_template: "{{ state_attr('person_location.person_location_integration','icon') }}"

Map Configuration Examples (Optional)

The integration provides a camera platform that can be used to provide a map image. Some knowledge of the 3rd-party mapping API is necessary to adjust these maps, so get into it only if you enjoy coding and figuring things out. The map providers each require an API key, but do not put the key into the camera configuration. Instead, pull the key from the integration using something like &key={{google_api_key}} in the camera configuration template.

Here are a few examples.

Google

See https://developers.google.com/maps/documentation/maps-static/start for help.

camera.combined_location_google

Click for Configuration Details

This one zooms the map to show the location of everyone.

# Example configuration.yaml entry

camera:
  - name: combined_location_google
    platform: person_location
    still_image_url: >-
      {%- set markers = '' -%}
      {%- set pri_entity = 'sensor.rod_location' -%}
      {%- set pri_pin = 'R' -%}
      {%- set pri_longitude = state_attr(pri_entity, 'longitude') |string -%}
      {%- set pri_latitude = state_attr(pri_entity, 'latitude') |string -%}
      {%- if (pri_longitude != None) and (pri_latitude != None) -%}
        {%- set markers = markers + '&markers=color:blue%7Csize:mid%7Clabel:' + pri_pin + '%7C' + pri_latitude + ',' + pri_longitude -%} 
      {%- endif -%}
      {%- set sec_entity = 'sensor.pam_location' -%}
      {%- set sec_pin = 'P' -%}
      {%- set sec_longitude = state_attr(sec_entity, 'longitude') |string -%}
      {%- set sec_latitude = state_attr(sec_entity, 'latitude') |string -%}
      {%- if (sec_longitude != None) and (sec_latitude != None) -%}
        {%- set markers = markers + '&markers=color:green%7Csize:mid%7Clabel:' + sec_pin + '%7C' + sec_latitude + ',' + sec_longitude -%} 
      {%- endif -%}
      {%- set home_longitude = state_attr('zone.home', 'longitude') -%}
      {%- set home_latitude = state_attr('zone.home', 'latitude') -%}
      {%- set zoom = 16 -%}
      https://maps.googleapis.com/maps/api/staticmap?size=400x400&maptype=roadmap&visible={{home_latitude}},{{home_longitude}}{{markers}}&key={{google_api_key}}
# Example ui-lovelace.yaml

    cards:
      - type: picture-entity
        entity: camera.combined_location_google
        name: Google
        show_state: false
        show_name: true

camera.rod_location_google

Click for Configuration Details
# Example configuration.yaml entry

camera:
  - name: rod_location_google
    platform: person_location
    still_image_url: >-
      {%- set pri_entity = 'sensor.rod_location' -%}
      {%- set pri_pin = 'R' -%}
      {%- set pri_longitude = state_attr(pri_entity, 'longitude') -%}
      {%- set pri_latitude = state_attr(pri_entity, 'latitude') -%}
      {%- set zoom = 16 -%}
      {%- if (pri_longitude == None) or (pri_latitude == None) -%}
        {%- set pri_longitude = state_attr('zone.home', 'longitude') -%}
        {%- set pri_latitude = state_attr('zone.home', 'latitude') -%}
      {%- endif -%}
      https://maps.googleapis.com/maps/api/staticmap?&zoom={{zoom}}&size=400x400&maptype=roadmap&markers=color:blue%7Csize:mid%7Clabel:{{pri_pin}}%7C{{pri_latitude}},{{pri_longitude}}&key={{google_api_key}}
    state: >-
      {%- set pri_entity = 'sensor.rod_location' -%}
      {{ states(pri_entity) }}
# Example ui-lovelace.yaml

    cards:
      - type: picture-entity
        entity: camera.rod_location_google
        name: Google - Rod's Location
        show_state: true

Mapbox

See https://docs.mapbox.com/api/maps/static-images/ for help.

camera.combined_location_mapbox

Click for Configuration Details

This one zooms the map to show the location of everyone. This example will show the state as either stationary or motion_detected

# Example configuration.yaml entry

camera:
  - name: combined_location_mapbox
    platform: person_location
    still_image_url: >-
      {%- set home_longitude = state_attr('zone.home', 'longitude') -%}
      {%- set home_latitude = state_attr('zone.home', 'latitude') -%}
      {%- set sec_entity = 'sensor.rod_location' -%}
      {%- set sec_pin = 'r' -%}
      {%- set sec_longitude = state_attr(sec_entity, 'longitude') |float(0) -%}
      {%- set sec_latitude = state_attr(sec_entity, 'latitude') |float(0) -%}
      {%- if (sec_longitude == 0.0) or (sec_latitude == 0.0) -%}
        {%- set sec_longitude = home_longitude -%}
        {%- set sec_latitude = home_latitude -%}
      {%- endif -%}
      {%- set pri_entity = 'sensor.pam_location' -%}
      {%- set pri_pin = 'p' -%}
      {%- set pri_longitude = state_attr(pri_entity, 'longitude') |float(0) -%}
      {%- set pri_latitude = home_latitude |float(0) -%}
      {%- if (pri_longitude == 0.0) or (pri_latitude == 0.0) -%}
        {%- set pri_longitude = home_longitude -%}
        {%- set pri_latitude = state_attr('zone.home', 'latitude') -%}
      {%- endif -%}
      {%- set min_longitude = [pri_longitude,sec_longitude,home_longitude]|min -%}
      {%- set max_longitude = [pri_longitude,sec_longitude,home_longitude]|max -%}
      {%- set min_latitude = [pri_latitude,sec_latitude,home_latitude]|min -%}
      {%- set max_latitude = [pri_latitude,sec_latitude,home_latitude]|max -%}
      {%- set style = 'mapbox/outdoors-v10' -%}
      {%- if (min_longitude == max_longitude) -%}
      {%- set min_longitude = min_longitude - 0.001 -%}
      {%- set max_longitude = max_longitude + 0.001 -%}
      {%- endif -%}
      {%- if (min_latitude == max_latitude) -%}
      {%- set min_latitude = min_latitude - 0.001 -%}
      {%- set max_latitude = max_latitude + 0.001 -%}
      {%- endif -%}
      https://api.mapbox.com/styles/v1/{{style}}/static/pin-s-{{sec_pin}}+2ecc71({{sec_longitude}},{{sec_latitude}}),pin-s-{{pri_pin}}+3498db({{pri_longitude}},{{pri_latitude}})/[{{min_longitude}},{{min_latitude}},{{max_longitude}},{{max_latitude}}]/400x400?logo=false&padding=60,21,14,21&access_token={{mapbox_api_key}}
    state: >-
      {%- set pri_entity_direction = state_attr('sensor.pam_location', 'direction') -%}
      {%- set sec_entity_direction = state_attr('sensor.rod_location', 'direction') -%}
      {%- set combined_state = 'stationary' -%}
      {%- if pri_entity_direction is not none and pri_entity_direction not in ['stationary', 'unknown', 'home'] -%}
        {%- set combined_state = 'motion_detected' -%}
      {%- elif sec_entity_direction is not none and sec_entity_direction not in ['stationary', 'unknown', 'home'] -%}
        {%- set combined_state = 'motion_detected' -%}
      {%- endif -%}
      {{ combined_state }}
# Example ui-lovelace.yaml

    cards:
      - type: picture-entity
        entity: camera.combined_location_mapbox
        name: Mapbox
        show_state: false
        show_name: true

camera.rod_location_mapbox

Click for Configuration Details
# Example configuration.yaml entry

camera:
  - name: rod_location_mapbox
    platform: person_location
    still_image_url: >-
      {%- set pri_entity = 'sensor.rod_location' -%}
      {%- set pri_pin = 'r' -%}
      {%- set pri_longitude = state_attr(pri_entity, 'longitude') -%}
      {%- set pri_latitude = state_attr(pri_entity, 'latitude') -%}
      {%- set zoom = 15 -%}
      {%- if (pri_longitude == None) or (pri_latitude == None) -%}
        None
      {%- else -%}
          https://api.mapbox.com/styles/v1/mapbox/streets-v11/static/pin-s-{{pri_pin}}+3498db({{pri_longitude}},{{pri_latitude}})/{{pri_longitude}},{{pri_latitude}},{{zoom}}/400x400?logo=false&access_token={{mapbox_api_key}}
      {%- endif -%}
    state: >-
      {%- set pri_entity = 'sensor.rod_location' -%}
      {{ states(pri_entity) }}
# Example ui-lovelace.yaml

    cards:
      - type: picture-entity
        entity: camera.rod_location_mapbox
        name: Mapbox - Rod's Location
        show_state: true

camera.rod_location_mapbox_pitched

Click for Configuration Details

This map is oriented to the individual's direction of travel.

# Example configuration.yaml entry

camera:
  - name: rod_location_mapbox_pitched
    platform: person_location
    still_image_url: >-
      {%- set pri_entity = 'sensor.rod_location' -%}
      {%- set pri_pin = 'r' -%}
      {%- set pri_longitude = state_attr(pri_entity, 'longitude') -%}
      {%- set pri_latitude = state_attr(pri_entity, 'latitude') -%}
      {%- set zoom = 14 -%}
      {%- set pitch = 60 -%}
      {%- set bearing = state_attr(pri_entity, 'compass_bearing') -%}
      {%- if (pri_longitude == None) or (pri_latitude == None) -%}
        None
      {%- else -%}
        {%- if (zoom == 'auto') or (bearing == None) -%}
          https://api.mapbox.com/styles/v1/mapbox/streets-v11/static/pin-s-{{pri_pin}}+3498db({{pri_longitude}},{{pri_latitude}})/auto/400x300?logo=false&access_token={{mapbox_api_key}}
        {%- else -%}
          https://api.mapbox.com/styles/v1/mapbox/streets-v11/static/pin-s-{{pri_pin}}+3498db({{pri_longitude}},{{pri_latitude}})/{{pri_longitude}},{{pri_latitude}},{{zoom}},{{bearing}},{{pitch}}/400x300?logo=false&access_token={{mapbox_api_key}}
        {%- endif -%}
      {%- endif -%}
    state: >-
      {%- set pri_entity = 'sensor.rod_location' -%}
      {{ states(pri_entity) }}
# Example ui-lovelace.yaml

    cards:
      - type: picture-entity
        entity: camera.rod_location_mapbox_pitched
        name: Mapbox pitch=60 - Rod's Location
        show_state: true

MapQuest

See https://developer.mapquest.com/documentation/static-map-api/v5/ for help.

camera.rod_location_mapquest

Click for Configuration Details
# Example configuration.yaml entry

camera:
  - name: rod_location_mapquest
    platform: person_location
    still_image_url: >-
      {%- set pri_entity = 'sensor.rod_location' -%}
      {%- set pri_pin = 'r' -%}
      {%- set pri_longitude = state_attr(pri_entity, 'longitude') -%}
      {%- set pri_latitude = state_attr(pri_entity, 'latitude') -%}
      {%- set zoom = 16 -%}
      {%- if (pri_longitude == None) or (pri_latitude == None) -%}
        None
      {%- else -%}
        https://www.mapquestapi.com/staticmap/v5/staticmap/map?zoom={{zoom}}&size=400,400&center={{pri_latitude}},{{pri_longitude}}&locations={{pri_latitude}},{{pri_longitude}}|marker-{{pri_pin}}&key={{mapquest_api_key}}
      {%- endif -%}
    state: >-
      {%- set pri_entity = 'sensor.rod_location' -%}
      {{ states(pri_entity) }}
# Example ui-lovelace.yaml

    cards:
      - type: picture-entity
        entity: camera.rod_location_mapquest
        name: MapQuest - Rod's Location
        show_state: true

Map Card

The map card requires no knowledge of the mapping API's but is limited in how much it can be customized.

See https://www.home-assistant.io/lovelace/map/ for help.

home_assistant_map_card

Click for Configuration Details
# Example ui-lovelace.yaml

    cards:
      - type: map
        entities:
          - sensor.rod_location
          - zone.home
        aspect_ratio: 4x4
        default_zoom: 17
        title: Home Assistant Map Card

Lovelace Examples

Show status of the Person Location Integration and allow control of API calls.

# Example ui-lovelace.yaml

    cards:
# ------------------------------------------------------
      - title: Home Assistant
        type: entities
        entities:
          - switch.person_location_integration
        show_header_toggle: false
# ------------------------------------------------------

Show all related device trackers and person location information (especially during testing).

# Example ui-lovelace.yaml

    cards:
# ------------------------------------------------------
      - type: 'custom:vertical-stack-in-card'
        cards:
# ------------------------------------------------------
        - type: custom:auto-entities
          filter:
            include:
              - entity_id: sensor.rod_location
                options:
                  secondary_info: last-changed
              - entity_id: person.rod
                options:
                  secondary_info: last-changed
              - domain: device_tracker
                attributes:
                  person_name: 'rod'
                options:
                  secondary_info: last-changed
              - domain: sensor
                attributes:
                  person_name: 'rod'
                options:
                  secondary_info: last-changed
              - domain: binary_sensor
                attributes:
                  person_name: 'rod'
                options:
                  secondary_info: last-changed
          card:            
            title: Rod's Location Devices
            show_header_toggle: false
            type: entities
#
        - type: custom:entity-attributes-card
          heading_name: Attribute
          heading_state: Value
          filter:
            include:
              - key: sensor.rod_location.*
            exclude:
              - key: sensor.rod_location.attribution
              - key: sensor.rod_location.friendly_name            
              - key: sensor.rod_location.icon
# ------------------------------------------------------

Troubleshooting

To enable detailed logging for this custom integration, add the following to configuration.yaml.

logger:
  default: warn
  logs:
    custom_components.person_location: debug  

home-assistant_person_location's People

Contributors

jackyaz avatar rodpayne avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

home-assistant_person_location's Issues

Feature Request: Configuration option for display name and state

The sensor.name_location entity currently has a display name of "Name is at Location", with a state of either: Home, Away, Just Arrived, or Just Left.

In my setup, I am using the provided location entities in a glance card and the display name is too long, and the specific zone where the person is located is not visible. I still prefer to use this integration's location entity however for the geocoded information visible when clicking on the entity, as well as the transitioning from home state status.

It would be great if this integration could add a configuration option for the sensor information to mimic a person entity (with the added benefit of Just Arrived and Just Left). Specifically, when this proposed setting is turned on, person_name is used as the entity display name and reported_state is used as the state value.

Orphaned and unremovable integration

i gave this a test drive, decided it wasn't what i was looking for and now i have it showing as an integration and it erros as not loaded all the time and i am unable to remove the integration. my only option is to leave it in the back ground and disable it. even if i remove it from teh HACS screen the integration screen still shows it as errored .

Unclear on what follow_person_integration does

I'm not sure what the follow_person_integration setting does. I track Person entities with this integration, which have a combination of static and GPS trackers attached

Should I enable follow_person_integration ?

Unable to start component: 'list' object has no attribute 'split'

After adding this component to HA from HACS and restarting my HA, I am not finding the option to add Person Location in the list of options to setup a new integration.

After bouncing over to my ssh session and editing the configuration.yaml file and restarting HA, the following error is encountered.

Error during setup of component person_location
4:08:32 AM – (ERROR) Person Location (custom integration)

Logger: homeassistant.setup
Source: custom_components/person_location/const.py:270
Integration: Person Location (documentation, issues)
First occurred: 4:08:32 AM (1 occurrences)
Last logged: 4:08:32 AM
Error during setup of component person_location
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/setup.py", line 249, in _async_setup_component
    result = await task
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 52, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/person_location/__init__.py", line 41, in setup
    pli = PERSON_LOCATION_INTEGRATION(API_STATE_OBJECT, hass, config)
  File "/config/custom_components/person_location/const.py", line 270, in __init__
    for x in self.config[DOMAIN].get(CONF_CREATE_SENSORS, []).split(",")
AttributeError: 'list' object has no attribute 'split'

I thought maybe it was caused by including my device tracker from room-assistant for my galaxy watch and commented that line out and restarted HA. It had no affect. I then went and added the Google api key and restarted. Still no effect. Last of all I commented out the "person." devices and gave HA a restart. Still no success starting this integration with no change on the error message given.

person_location:
  google_api_key: ***redacted**
  person_names:
    - name: Hath
      devices:
        - device_tracker.haths_s21
#        - device_tracker.haths_galaxy_watch_tracker
#        - person.hathakhm
    - name: Kyra
      devices:
#        - person.kyra
        - device_tracker.kyra_s_s21_ultra

Image for entity?

Not an issue as such, but more of a question. Is there any way to associate an image with the created entity? I'm using the device_tracker platform option. I've tried the customisation via configuration.yaml which works for an entity created by another integration, but doesn't seem to be working for this one.

Setup question ...

I'm still confused after setup (Home Assistant Core 2022.5.3). Installation with HACS went smooth and I found a bunch of sensors.<devicename>_geocoded_location entries afterwards. I assume, they were created by this integration, right?

I read "This custom integration will look at all device trackers that are for a particular person and combine them into a single person location sensor, sensor._location. "

First question: how does the integration determine a mapping from device to person? Is the source the same as going to Settings | People | and add devices under "Select the devices that belong to this person."?

I also noticed that I cannot change all config parameters in the GUI as described in the README. Going to Settings | Devices & Services and clicking on "Home Person Location" and "Configure" I can only change Hours Extended Away, Minutes Just Arrived and Minutes Just Left. All others like "Google Region" are no longer accessible.

Error trying to use this with 2022.2.3

GUI flow fails to load via Integrations menu. When attempting manual configuration in yaml, check configuration throws the below error

Component error: person_location - cannot import name 'REGIONS' from 'homeassistant.components.waze_travel_time.sensor' (/usr/src/homeassistant/homeassistant/components/waze_travel_time/sensor.py)

Waze Exception WRCError: Internal Error

I’m on 2022.6.4 and getting …

This error originated from a custom integration.

Logger: custom_components.person_location.reverse_geocode
Source: custom_components/person_location/reverse_geocode.py:837 
Integration: Person Location (documentation, issues) 
First occurred: 8 June 2022, 09:32:23 (68 occurrences) 
Last logged: 8 June 2022, 22:19:29

(sensor.aaa_location) Waze Exception WRCError: Internal Error
(sensor.bbb_location) Waze Exception WRCError: Internal Error
(sensor.ccc_location) Waze Exception WRCError: Internal Error

It may be related to home-assistant/core#22022 (comment) or home-assistant/core#22022 (comment).

Integration is only working with first entry in person_names ?

Hi there,

i used your addon integration for some time and was really happy with it.

Since some days (I think with one of the latest updates) only the first entry in person_names gets some sensors and is alive after reboot. The second is ignored and not generated ?

When i swap entries the other first gets evaluated ?

Maybe there is an error since the new updates ?

person_location:
  mapbox_api_key: !#secret_mapbox
  osm_api_key: !#secret_osm
  google_api_key: !#secret_google_api_key
  language: de
  region: EU
  follow_person_integration: true
  create_sensors: "direction, geocoded, altitude, meters_from_home"  
  person_names:
    - name: Wife
      devices:
        - person.susi
    - name: Husband
      devices: 
        - person.max

Greetings from Austria

Kilowatt

Camera & Google Maps Configuration

Hi Rod, thanks for all your hard work on this :)

I believe the below configuration is deprecated? Please can you let me know how to configure it now?

camera:

  • name: combined_location_google
    platform: person_location
    still_image_url: >-
    {%- set markers = '' -%}
    {%- set pri_entity = 'sensor.rod_location' -%}
    {%- set pri_pin = 'R' -%}
    {%- set pri_longitude = state_attr(pri_entity, 'longitude') |string -%}
    {%- set pri_latitude = state_attr(pri_entity, 'latitude') |string -%}
    {%- if (pri_longitude != None) and (pri_latitude != None) -%}
    {%- set markers = markers + '&markers=color:blue%7Csize:mid%7Clabel:' + pri_pin + '%7C' + pri_latitude + ',' + pri_longitude -%}
    {%- endif -%}
    {%- set sec_entity = 'sensor.pam_location' -%}
    {%- set sec_pin = 'P' -%}
    {%- set sec_longitude = state_attr(sec_entity, 'longitude') |string -%}
    {%- set sec_latitude = state_attr(sec_entity, 'latitude') |string -%}
    {%- if (sec_longitude != None) and (sec_latitude != None) -%}
    {%- set markers = markers + '&markers=color:green%7Csize:mid%7Clabel:' + sec_pin + '%7C' + sec_latitude + ',' + sec_longitude -%}
    {%- endif -%}
    {%- set home_longitude = state_attr('zone.home', 'longitude') -%}
    {%- set home_latitude = state_attr('zone.home', 'latitude') -%}
    {%- set zoom = 16 -%}
    https://maps.googleapis.com/maps/api/staticmap?size=400x400&maptype=roadmap&visible={{home_latitude}},{{home_longitude}}{{markers}}&key={{google_api_key}}

Configured Waze region (US) is not valid

I keep seeing the below error in my logs, it's persisted across multiple versions of HA, the most recent being 2023.12.0

Do I need to amend configuration or is it safe to ignore?

Source: custom_components/person_location/const.py:264
Integration: Person Location ([documentation](https://github.com/rodpayne/home-assistant_person_location/blob/master/README.md#table-of-contents), [issues](https://github.com/rodpayne/home-assistant_person_location/issues))
First occurred: 11:56:26 (1 occurrences)
Last logged: 11:56:26

Configured Waze region (US) is not valid```

SOURCE_TYPE_GPS deprecated constant which will be removed in HA Core 2025.1.

2024-04-06 20:44:39.475 WARNING (ImportExecutor_0) [homeassistant.components.device_tracker.const] SOURCE_TYPE_GPS was used from person_location, this is a deprecated constant which will be removed in HA Core 2025.1. Use SourceType.GPS instead, please report it to the author of the 'person_location' custom integration.

No data for driving minutes

Driving minutes shows 0 on the sensor.redacted-name_location entity while other attributes are being correctly populated. I see the following log message:

Logger: custom_components.person_location.reverse_geocode
Source: custom_components/person_location/reverse_geocode.py:875
integration: Person Location ([documentation](https://github.com/rodpayne/home-assistant_person_location/blob/master/README.md#table-of-contents), [issues](https://github.com/rodpayne/home-assistant_person_location/issues))
First occurred: April 19, 2024 at 6:21:10 PM (39 occurrences)
Last logged: 12:32:33 PM

(sensor.redacted-name_location) Waze Exception AttributeError: 'WazeRouteCalculator' object has no attribute 'calc_route_info'

When manually calling person_location.reverse_geocode on the same entity, it also generates the following log error:

Logger: custom_components.person_location.reverse_geocode
Source: custom_components/person_location/reverse_geocode.py:898
integration: Person Location ([documentation](https://github.com/rodpayne/home-assistant_person_location/blob/master/README.md#table-of-contents), [issues](https://github.com/rodpayne/home-assistant_person_location/issues))
First occurred: 12:32:58 PM (2 occurrences)
Last logged: 12:39:00 PM

(person.redacted-name) Exception KeyError: 'geocode_count'

Configured create_sensors error after Home Assistant upgrade from 2023.11.3 to 2023.12.3

person_location
Version: 2023.12.09

2023-12-20 06:16:06.034 ERROR (SyncWorker_11) [custom_components.person_location.const] Configured create_sensors: bread_crumbs,driving_miles,driving_minutes,geocoded,miles_from_home is not valid

2023-12-20 06:16:06.035 DEBUG (SyncWorker_11) [custom_components.person_location.const] person_name_config name = Pam
2023-12-20 06:16:06.035 DEBUG (SyncWorker_11) [custom_components.person_location.const] person_name_config device = p
2023-12-20 06:16:06.035 DEBUG (SyncWorker_11) [custom_components.person_location.const] person_name_config device = e
2023-12-20 06:16:06.037 DEBUG (SyncWorker_11) [custom_components.person_location.const] person_name_config device = r
2023-12-20 06:16:06.037 DEBUG (SyncWorker_11) [custom_components.person_location.const] person_name_config device = s
2023-12-20 06:16:06.037 DEBUG (SyncWorker_11) [custom_components.person_location.const] person_name_config device = o
2023-12-20 06:16:06.037 DEBUG (SyncWorker_11) [custom_components.person_location.const] person_name_config device = n
2023-12-20 06:16:06.037 DEBUG (SyncWorker_11) [custom_components.person_location.const] person_name_config device = .
2023-12-20 06:16:06.037 DEBUG (SyncWorker_11) [custom_components.person_location.const] person_name_config device = p
2023-12-20 06:16:06.038 DEBUG (SyncWorker_11) [custom_components.person_location.const] person_name_config device = a
2023-12-20 06:16:06.038 DEBUG (SyncWorker_11) [custom_components.person_location.const] person_name_config device = m

Configuration variable type changed from str to <class 'homeassistant.util.yaml.objects.NodeStrClass'>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.