I created this because my wife and I have one car and I don’t like when she’s texting me to ask how far I am away when picking her up. So I created this using our device_trackers into a Google map, with zoom and center controls and an ability to subscribe to traffic updates sending push notifications of either locations and the ETA with cool google street view pictures. I’ve tested it over the last few days and works surprisingly well. The push notifications send every 5 minutes until you’ve reached the same location and then will turn off.
Pre-Requisites
- A Google Account using their API for Street View, Static Maps, and Travel times. It may be a good idea to set a budget since they will bill you based on your usage. I just set mine at $3 a month just in case.
- Some sort of device_tracker from the phone (I use the iOS app here)
- Some sort of Notify (Again, using iOS)
- Optional: an image hosting site. I use www.postimg.org. For best results, use a 32x32 pixel png file. Also if you want the rounded marker type look, you will need to create the png to look like it separately. Google just uses whatever image you are referencing and adds to the static image of the map.
Automations:
#################################################################################################
# TRAVEL TIME PUSH NOTIFICATIONS #
#################################################################################################
- alias: 'Push Travel Time From Jeremy to Anja'
initial_state: on
trigger:
- platform: time
minutes: '/5'
seconds: '0'
condition:
condition: and
conditions:
- condition: template
value_template: '{{ is_state("input_boolean.push_notification_distance_jeremy_to_anja", "on") }}'
- condition: numeric_state
entity_id: sensor.google_travel_time_jeremy_to_anja
above: 1
action:
- service: notify.all_anja
data:
title: "Jeremy is {{states.sensor.google_travel_time_jeremy_to_anja.state}} minutes away"
message: "Approximate ETA based on current traffic conditions and last known location"
data:
push:
badge: 1
category: camera
entity_id: camera.street_view_jeremy_gps
- alias: 'Push Travel Time From Anja to Jeremy'
initial_state: on
trigger:
- platform: time
minutes: '/5'
seconds: '0'
condition:
condition: and
conditions:
- condition: template
value_template: '{{ is_state("input_boolean.push_notification_distance_anja_to_jeremy", "on") }}'
- condition: numeric_state
entity_id: sensor.google_travel_time_anja_to_jeremy
above: 1
action:
- service: notify.all_jeremy
data:
title: "Anja is {{states.sensor.google_travel_time_anja_to_jeremy.state}} minutes away"
message: "Approximate ETA based on current traffic conditions and last known location"
data:
push:
badge: 1
category: camera
entity_id: camera.street_view_anja_gps
- alias: 'Jeremy Has Arrived'
initial_state: on
trigger:
- platform: numeric_state
entity_id: sensor.google_travel_time_jeremy_to_anja
below: 2
condition:
condition: and
conditions:
- condition: template
value_template: '{{ is_state("input_boolean.push_notification_distance_jeremy_to_anja", "on") }}'
action:
- service: notify.all_anja
data:
title: "Jeremy has arrived!"
message: "Jeremy is here."
data:
push:
badge: 1
category: camera
entity_id: camera.street_view_jeremy_gps
- service: input_boolean.turn_off
entity_id: input_boolean.push_notification_distance_jeremy_to_anja
- alias: 'Anja Has Arrived'
initial_state: on
trigger:
- platform: numeric_state
entity_id: sensor.google_travel_time_anja_to_jeremy
below: 2
condition:
condition: and
conditions:
- condition: template
value_template: '{{ is_state("input_boolean.push_notification_distance_anja_to_jeremy", "on") }}'
action:
- service: notify.all_jeremy
data:
title: "Anja has arrived"
message: "Anja is here."
data:
push:
badge: 1
category: camera
entity_id: camera.street_view_anja_gps
- service: input_boolean.turn_off
entity_id: input_boolean.push_notification_distance_anja_to_jeremy
GROUPS:
#################################################################################################
# MAPS #
#################################################################################################
map_view:
view: yes
name: Location
entities:
- group.map
- group.location_map
- group.device_tracker_street_view
- group.send_push_updates
map:
view: no
entities:
- camera.location_map
device_tracker_street_view:
view: no
name: "Street Views"
entities:
- camera.street_view_jeremy_gps
- camera.street_view_anja_gps
send_push_updates:
view: no
name: "Travel Updates"
entities:
- input_boolean.push_notification_distance_jeremy_to_anja
- input_boolean.push_notification_distance_anja_to_jeremy
location_map:
view: no
name: "Map Controls"
entities:
- sensor.google_travel_time_jeremy_to_anja
- sensor.google_travel_time_anja_to_jeremy
- input_number.map_zoom
- input_select.center_map_on
INPUT BOOLEANS
push_notification_distance_jeremy_to_anja:
name: Send Notifications - To Anja
icon: mdi:message-alert
push_notification_distance_anja_to_jeremy:
name: Send Notifications - To Jeremy
icon: mdi:message-alert
INPUT SELECT
center_map_on:
name: Center Map On
icon: mdi:account-multiple
options:
- Jeremy
- Anja
INPUT NUMBER
map_zoom:
name: Zoom Map
icon: mdi:magnify
min: 1
max: 21
step: 1
TEMPLATE SENSORS
center_map_on:
value_template: >-
{% set center = states.input_select.center_map_on.state %}
{% if center == "Jeremy"%}
{% set lat = states.device_tracker.jeremys_iphone.attributes.latitude %}
{% set long = states.device_tracker.jeremys_iphone.attributes.longitude %}
{% elif center == "Anja"%}
{% set lat = states.device_tracker.anjas_iphone.attributes.latitude %}
{% set long = states.device_tracker.anjas_iphone.attributes.longitude %}
{% else %}
{% set lat = states.device_tracker.jeremys_iphone.attributes.latitude %}
{% set long = states.device_tracker.jeremys_iphone.attributes.longitude %}
{% endif %}
{{ [lat,long]|join(',') }}
SENSORS
- platform: google_travel_time
api_key: YOUR_GOOGLE_API_KEY
name: google_travel_time_anja_to_jeremy
origin: device_tracker.anjas_iphone
destination: device_tracker.jeremys_iphone
- platform: google_travel_time
api_key: YOUR_GOOGLE_API_KEY
name: google_travel_time_jeremy_to_anja
origin: device_tracker.jeremys_iphone
destination: device_tracker.anjas_iphone
CAMERAS (You’ll need to replace with your hosted icon images and your Google API Key)
- platform: generic
name: street_view_anja_gps
still_image_url: https://maps.googleapis.com/maps/api/streetview?size=600x300&location={{states.device_tracker.anjas_iphone.attributes.latitude}},{{states.device_tracker.anjas_iphone.attributes.longitude}}&key=YOUR_GOOGLE_API_KEY
limit_refetch_to_url_change: true
- platform: generic
name: street_view_jeremy_gps
still_image_url: https://maps.googleapis.com/maps/api/streetview?size=600x300&location={{states.device_tracker.jeremys_iphone.attributes.latitude}},{{states.device_tracker.jeremys_iphone.attributes.longitude}}&key=YOUR_GOOGLE_API_KEY
limit_refetch_to_url_change: true
- platform: generic
name: location_map
still_image_url: https://maps.googleapis.com/maps/api/staticmap?center={{states.sensor.center_map_on.state}}&zoom={{states.input_number.map_zoom.state|int}}&size=600x300&maptype=roadmap&markers=icon:YOUR_FIRST_IMAGE_URL|{{states.device_tracker.jeremys_iphone.attributes.latitude}},{{states.device_tracker.jeremys_iphone.attributes.longitude}}&markers=icon:YOUR_SECOND_IMAGE_URL|{{states.device_tracker.anjas_iphone.attributes.latitude}},{{states.device_tracker.anjas_iphone.attributes.longitude}}&key=YOUR_GOOGLE_API_KEY
limit_refetch_to_url_change: true