Google Maps location sharing

I’m not sure why but I started getting errors in the get_authenticated_person function.

Note that I’m using a different account that is tracking my other accounts but that has no location data for itself. I guess get_authenticated_person() wasn’t tested for this case.

home-assistant_1  | Traceback (most recent call last):
home-assistant_1  |   File "/config/deps/lib/python3.6/site-packages/locationsharinglib/locationsharinglib.py", line 305, in get_authenticated_person
home-assistant_1  |     output[9][1],
home-assistant_1  | TypeError: 'NoneType' object is not subscriptable

I suppose this is just debugging, but it is spamming my logs while it shouldn’t do that. Isn’t there a way to check if there is location data for the account owner before doing this?

1.2.1 made the logging from an exception into a debug message. This should be handled fine. Are you sure you are on 1.2.1 and not 1.2.0?

Ow, right, I’m still on 1.2.0 since 1.2.1 wasn’t available on pypi a few moments ago.

Looking at the code, I do notice that we are calling _get_data twice now. Once for the shared users, and once for the authenticated user. The second call will never return data for me, so that call is useless.

True, but we needed a way to handle situations that people actually want to retrieve their accounts which are shared. You can follow that discussion on github on the component.

Don’t forget that the call to get_data is cached for 30 seconds so it does not actually happen, just the cache is being retrieved the second time.

Okay, I didn’t know about that cache.

Updated component:

"""
Support for Google Maps location sharing.

For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.google_maps/
"""
import logging
from datetime import timedelta

import voluptuous as vol

import homeassistant.helpers.config_validation as cv
from homeassistant.components.device_tracker import (
    PLATFORM_SCHEMA, SOURCE_TYPE_GPS)
from homeassistant.const import CONF_USERNAME, CONF_PASSWORD
from homeassistant.helpers.event import track_time_interval
from homeassistant.helpers.typing import ConfigType
from homeassistant.util import slugify

_LOGGER = logging.getLogger(__name__)

REQUIREMENTS = ['locationsharinglib==1.2.1']

CONF_MAX_GPS_ACCURACY = 'max_gps_accuracy'
CREDENTIALS_FILE = '.google_maps_location_sharing.cookies'

MIN_TIME_BETWEEN_SCANS = timedelta(seconds=30)

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
    vol.Required(CONF_USERNAME): cv.string,
    vol.Required(CONF_PASSWORD): cv.string,
    vol.Optional(CONF_MAX_GPS_ACCURACY): vol.Coerce(float),
})


def setup_scanner(hass, config: ConfigType, see, discovery_info=None):
    """Set up the scanner."""
    scanner = GoogleMapsScanner(hass, config, see)
    return scanner.success_init


class GoogleMapsScanner(object):
    """Representation of an Google Maps location sharing account."""

    def __init__(self, hass, config: ConfigType, see) -> None:
        """Initialize the scanner."""
        from locationsharinglib import Service
        from locationsharinglib.locationsharinglibexceptions import InvalidUser

        self.see = see
        self.username = config[CONF_USERNAME]
        self.password = config[CONF_PASSWORD]
        self.max_gps_accuracy = config[CONF_MAX_GPS_ACCURACY]

        try:
            self.service = Service(self.username, self.password,
                                   hass.config.path(CREDENTIALS_FILE))
            self._update_info()

            track_time_interval(
                hass, self._update_info, MIN_TIME_BETWEEN_SCANS)

            self.success_init = True

        except InvalidUser:
            _LOGGER.error('You have specified invalid login credentials')
            self.success_init = False

    def _update_info(self, now=None):
        for person in self.service.get_all_people():
            dev_id = 'google_maps_{0}'.format(slugify(person.id))

            if self.max_gps_accuracy is not None and \
                    person.accuracy > self.max_gps_accuracy:
                _LOGGER.info("Ignoring update because expected GPS "
                             "accuracy %s is not met: %s",
                             self.max_gps_accuracy, person.accuracy)
                continue

            attrs = {
                'id': person.id,
                'nickname': person.nickname,
                'full_name': person.full_name,
                'last_seen': person.datetime,
                'address': person.address
            }
            self.see(
                dev_id=dev_id,
                gps=(person.latitude, person.longitude),
                gps_accuracy=person.accuracy,
                picture=person.picture_url,
                source_type=SOURCE_TYPE_GPS,
                attributes=attrs
            )

Lovely! I am on this component for a few hours now, I will let you know how it goes with false positives. I have the accuracy to 150.

No matter how many times i read this thread i cant figure out if im suppose to be able to install locationsharinglib on my hass.io installation on my pi3?

I have added the /config/custom_components/device_tracker/google_maps.py file,
but when i try tu run
core-ssh:~# pip install locationsharinglib

i only get an error:
-bash: bash:: command not found

After updating the component, I get this error at HASS startup:

2018-04-03 21:55:29 ERROR (MainThread) [homeassistant.components.device_tracker] Error setting up platform google_maps
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/device_tracker/__init__.py", line 169, in async_setup_platform
    disc_info)
  File "/usr/lib/python3.5/asyncio/futures.py", line 361, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.5/asyncio/tasks.py", line 296, in _wakeup
    future.result()
  File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result
    raise self._exception
  File "/usr/lib/python3.5/concurrent/futures/thread.py", line 55, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/var/lib/home-assistant/custom_components/device_tracker/google_maps.py", line 38, in setup_scanner
    scanner = GoogleMapsScanner(hass, config, see)
  File "/var/lib/home-assistant/custom_components/device_tracker/google_maps.py", line 58, in __init__
    self._update_info()
  File "/var/lib/home-assistant/custom_components/device_tracker/google_maps.py", line 71, in _update_info
    dev_id = 'google_maps_{0}'.format(slugify(person.id))
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/util/__init__.py", line 42, in slugify
    text = normalize('NFKD', text)
TypeError: normalize() argument 2 must be str, not None

After this, no more errors, but only 2 of 3 shared devices are discovered. The third is never seen.
Aparently, it cannot get the device id.

With previous version it worked.

I was using a max_gps_accuracy value of 55. I increased it to 150 and now all 3 devices are detected correctly, although the error keeps dumping at startup.

Aparently, now it updates OK. I’ll keep up testing…

After 10 hours, the location does not update. Neither of the 3 devices we have.

FYI, this doesn’t appear to work if the “tracking” account has a custom domain, ie if your Gmail account does not end with @gmail.com

I tested this with hass.io 0.67beta0 and it’s updating super fine. but how can I change the identifier from device_tracker.google_maps_ to something customized like device_tracker.disrupted? It didn’t create an entry in entity_registry.yaml and if I change it in known_devices.yaml I will end up with a new entry.

If you go to customize, find the entity and create a new attribute friendly_name and put what you want in the value…

Can anyone help me get this working in Hassio? I’m running the latest version at the time of writing, 66.1, but it’s just not working. I use 2FA normally, and so I generated an app specific password but when I do that it throws an invalid password related error in the log.

that doesn’t help me to change the identifier though, only the frontend name.

I’d suggest waiting a few days because it’s merged already and will be in the upcoming 0.67.0 release

2 Likes

Thanks for all your work on this! If we are using this as a custom component, will we have to do anything before upgrading to 0.67?

This seems to work well most of the time (I used the custom component before, and then 0.67 beta), but every so often I notice if I visit google maps from any device on my network (ie my mobile), I have to do a captcha to proceed because google says it detected unusual activity from my IP.

Is this expected? Anyone else getting the same?

I just removed the custom component from my setup (using hassio) and restarted HA. Seemed to work fine