custom-components / places

Component to integrate with OpenStreetMap Reverse Geocode (places)
GNU General Public License v3.0
110 stars 22 forks source link
device-tracker geolocation home-assistant openstreetmap

places

places Logo

GitHub Release GitHub Release Date GitHub Commit Activity GitHub last commit License
HACS GitHub Workflow Status
Community Forum

_Component to integrate with OpenStreetMap Reverse Geocode and create a sensor with numerous address and place attributes from a devicetracker, person, or sensor

Home Assistant versions starting with v2024.7.2 will prevent places versions earlier than v2.7.1 from working. Be sure to upgrade.

Installation

HACS (recommended)

  1. Ensure that HACS is installed
  2. Click Here to directly open places in HACS or
      a. Navigate to HACS
      b. Click + Explore & Download Repositories
      c. Find the places integration
  3. Click Download
  4. Restart Home Assistant
  5. See Configuration below

Manual

You probably do not want to do this! Use the HACS method above unless you know what you are doing and have a good reason as to why you are installing manually 1. Using the tool of choice open the directory (folder) for your HA configuration (where you find `configuration.yaml`) 1. If you do not have a `custom_components` directory there, you need to create it 1. In the `custom_components` directory create a new folder called `places` 1. Download _all_ the files from the `custom_components/places/` directory in this repository 1. Place the files you downloaded in the new directory you created 1. Restart Home Assistant 1. See [Configuration](#configuration) below Using your HA configuration directory as a starting point you should now also have this: ```text custom_components/places/__init__.py custom_components/places/config_flow.py custom_components/places/const.py custom_components/places/manifest.json custom_components/places/sensor.py custom_components/places/strings.json custom_components/places/translations custom_components/places/translations/en.json ```

Configuration

Configuration is done in the Integrations section of Home Assistant. Configuration with configuration.yaml is no longer supported.

  1. Click Here to directly add a places sensor or
      a. In Home Assistant, go to Settings -> Integrations
      b. Click + Add Integrations and select places
  2. Add your configuration (see Configuration Options below)
  3. Click Submit
    • Repeat as needed to create additional places sensors
    • Options can be changed for existing places sensors in Home Assistant Integrations by selecting Configure under the desired places sensor.

Configuration Options

Key Required Default Description
Sensor Name Yes Friendly name of the places sensor
Tracked Entity ID Yes The location entity to track. Must have latitude and longitude as attributes. Supports these entities: device_tracker, person, sensor, variable & zone
Email Address No OpenStreetMap API key (your email address).
Display Options No zone_name, place Display options: formatted_place (exclusive option), driving (can be used with formatted_place or other options), zone or zone_name, place, place_name, street_number, street, city, county, state, postal_code, country, formatted_address, do_not_show_not_home

See optional Advanced Display Options below to use more complex display logic.
Home Zone No zone.home Used to calculate distance from home and direction of travel
Map Provider No apple google, apple, osm
Map Zoom No 18 Level of zoom for the generated map link <1-20>
Language No location's local language Requested* language(s) for state and attributes. Two-Letter language code(s), separated by commas.
*Refer to Notes
Extended Attributes No False Show extended attributes: wikidata_id, osm_dict, osm_details_dict, wikidata_dict (if they exist). Provides many additional attributes for advanced logic. Warning, this will make the attributes very long!
Show Last Updated No False Show last updated time at end of state (since xx:yy)
Use GPS Accuracy No True Use GPS Accuracy when determining whether to update the places sensor (if 0, don't update the places sensor). By not updaing when GPS Accuracy is 0, should prevent inaccurate locations from being set in the places sensors.

Set this to False if your Device Tracker has a GPS Accuracy (gps_accuracy) attribute, but it always shows 0 even if the latitude and longitude are correct.

Advanced Display Options

To use, simply enter your advanced options into the `display_options` text area. Any display_options that contain `[]` or `()` will be processed with the Advanced Display Options.
__Tip:__ _Build your advanced display options string in a text editor and copy/paste it into display_options field as it is pretty small._ ### __Brackets [ ]:__ Fields to show if initial field is blank or empty
These can be nested. #### Examples * `name[type]` will show the name, but if name is blank, will show the type instead. If type is also blank, nothing will show for that field * `name[type[category]]` will show the name, but if name is blank, will show the type instead, but if type is blank, will show the category. If category is also blank, nothing will show for that field. ### __Parenthesis ( ):__ Inclusion/Exclusion Logic to filter the field
#### To include/exclude based on the main field * __Include:__ Set the first item inside the parenthesis to + to only show the field if it equals one of the states listed * __Exclude:__ Set the first item inside the parenthesis to - to only show the field if doesn't equal one of the states listed * If + or - isn't listed as the first item inside the parenthesis, include(+) is assumed. #### Examples * `type(-, house)` will show type if it is anything but "house" * `type(+, house)` will show type only if it is "house" * `type(house)` same as `type(+, house)` * `type(-, house, retail)` will show type if it is anything but "house" or "retail" * `type(+, house, retail)` will show type only if it is "house" or "retail" #### To include/exclude based on other fields * __Include:__ List the field to test followed by another set of parenthesis. In there, set the first item inside the parenthesis to + to only show the main field if the field to be tested equals one of the states listed * __Exclude:__ List the field to test followed by another set of parenthesis. In there, set the first item inside the parenthesis to - to only show the main field if the field to be tested doesn't equal one of the states listed * As above, if + or - isn't listed as the first item inside the parenthesis, include(+) is assumed. #### Examples * `type(category(-, highway))` will show type if category is anything but "highway" * `type(category(+, highway))` will show type only if category is "highway" * `type(category(highway))` same as `type(category(+, highway))` * `type(category(-, highway, building))` will show type if category is anything but "highway" or "building" * `type(category(+, highway, building))` will show type only if category is "highway" or "building" #### The two types of include/excludes can also be combined * `type(-,motorway, category(-, highway, building))` will show type if it is not "motorway" and if category is not "highway" or "building" ### Brackets and Parenthesis can also be combined * To recreate `place`: ``` name_no_dupe, category(-, place), type(-, yes), neighborhood, house_number, street ``` * To recreate `formatted_place`: ``` zone_name[driving, name_no_dupe[type(-, unclassified, category(-, highway))[category(-, highway)], house_number, route_number(type(+, motorway, trunk))[street[route_number]], neighborhood(type(house))], city_clean[county], state_abbr] ``` ### Fields * `driving` * `name` (Synonym: `place_name`) * `name_no_dupe` (Synonym: `place_name_no_dupe`) * _Will be blank if the name is the same as one of the other attributes_ * `type` (Synonym: `place_type`) * `category` (Synonym: `place_category`) * `street_number` (Synonym: `house_number`) * `street` * `route_number` (Synonym: `street_ref`) * `neighborhood` (Synonyms: `neighbourhood`, `place_neighborhood`, `place_neighbourhood`) * `city` * `city_clean` * _`city` but removes "Township" and moves "City" to the end if it starts with "City of"_ * `postal_town` (Synonyms: `borough`, `suburb`) * `state` (Synonym: `region`) * `state_abbr` * `county` * `country` * `country_code` * `zip_code` (Synonym: `postal_code`) * `latitude` * `longitude` * `zone` * `zone_name` __Note:__ `place` and `formatted_place` are not valid fields in the advanced display options. See examples [above](#brackets-and-parenthesis-can-also-be-combined) for how to recreate them. -------
Sample attributes that can be used in notifications, alerts, automations, etc. ```json { "formatted_address": "Richmond Hill GO Station, 6, Newkirk Road, Beverley Acres, Richmond Hill, York Region, Ontario, L4C 1B3, Canada", "friendly_name": "sharon", "current_latitude": "43.874149009154095", "distance_from_home_km": 7.24, "country": "Canada", "postal_code": "L4C 1B3", "direction_of_travel": "towards home", "neighbourhood": "Beverley Acres", "entity_picture": "/local/sharon.png", "street_number": "6", "devicetracker_entityid": "device_tracker.sharon_iphone7", "home_longitude": "-79.7323453871", "devicetracker_zone": "not_home", "distance_from_home_m": 17239.053, "home_latitude": "43.983234888", "previous_location": "43.86684124904056,-79.4253896502715", "previous_longitude": "-79.4253896502715", "place_category": "building", "map_link": "https://maps.apple.com/maps/?ll=43.874149009154095,-79.42642783709209&z=18", "last_changed": "2018-05-02 13:44:51.019837", "state_province": "Ontario", "county": "York Region", "current_longitude": "-79.42642783709209", "current_location": "43.874149009154095,-79.42642783709209", "place_type": "building", "previous_latitude": "43.86684124904056", "place_name": "Richmond Hill GO Station", "street": "Newkirk Road", "city": "Richmond Hill", "home_zone": "zone.sharon_home" } ```
Sample generic `automations.yaml` snippet to send an iOS notify on any device state change (the only difference is the second one uses a condition to only trigger for a specific user) ```yaml - alias: ReverseLocateEveryone initial_state: 'on' trigger: platform: event event_type: places_state_update action: - service: notify.ios_jim_iphone8 data_template: title: 'ReverseLocate: {{ trigger.event.data.entity }} ({{ trigger.event.data.devicetracker_zone }}) {{ trigger.event.data.place_name }}' message: |- {{ trigger.event.data.entity }} ({{ trigger.event.data.devicetracker_zone }}) {{ trigger.event.data.place_name }} {{ trigger.event.data.distance_from_home_km }} km from home and traveling {{ trigger.event.data.direction_of_travel }} {{ trigger.event.data.to_state }} ({{ trigger.event.data.last_changed }}) data: attachment: url: '{{ trigger.event.data.map_link }}' hide_thumbnail: false - alias: ReverseLocateAidan initial_state: 'on' trigger: platform: event event_type: places_state_update condition: condition: template value_template: '{{ trigger.event.data.entity == "aidan" }}' action: - service: notify.ios_jim_iphone8 data_template: title: 'ReverseLocate: {{ trigger.event.data.entity }} ({{ trigger.event.data.devicetracker_zone }}) {{ trigger.event.data.place_name }}' message: |- {{ trigger.event.data.entity }} ({{ trigger.event.data.devicetracker_zone }}) {{ trigger.event.data.place_name }} {{ trigger.event.data.distance_from_home_km }} km from home and traveling {{ trigger.event.data.direction_of_travel }} {{ trigger.event.data.to_state }} ({{ trigger.event.data.last_changed }}) data: attachment: url: '{{ trigger.event.data.map_link }}' hide_thumbnail: false ```

Notes

Prior Contributions:

Contributions are welcome!

If you want to contribute to this please read the Contribution guidelines