home-assistant / core

:house_with_garden: Open source home automation that puts local control and privacy first.
https://www.home-assistant.io
Apache License 2.0
71.7k stars 29.96k forks source link

google_maps device_tracker: TypeError: 'NoneType' object is not iterable #17410

Closed sagilo closed 5 years ago

sagilo commented 5 years ago

Running latest version - 0.80.0

Configuration:

  - platform: google_maps
    username: !secret google_maps_username
    password: !secret google_maps_password
    max_gps_accuracy: 200

In 0.79.3 .google_maps_location_sharing.cookies was created but nothing appeared in logs and no new device_tracker in HA. After upgrading to 0.80.0 I get the following error:

home-assistant   | 2018-10-13 18:57:35 ERROR (MainThread) [homeassistant.components.device_tracker] Error setting up platform google_maps
home-assistant   | Traceback (most recent call last):
home-assistant   |   File "/usr/src/app/homeassistant/components/device_tracker/__init__.py", line 184, in async_setup_platform
home-assistant   |     disc_info)
home-assistant   |   File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 56, in run
home-assistant   |     result = self.fn(*self.args, **self.kwargs)
home-assistant   |   File "/usr/src/app/homeassistant/components/device_tracker/google_maps.py", line 46, in setup_scanner
home-assistant   |     scanner = GoogleMapsScanner(hass, config, see)
home-assistant   |   File "/usr/src/app/homeassistant/components/device_tracker/google_maps.py", line 66, in __init__
home-assistant   |     self._update_info()
home-assistant   |   File "/usr/src/app/homeassistant/components/device_tracker/google_maps.py", line 78, in _update_info
home-assistant   |     for person in self.service.get_all_people():
home-assistant   |   File "/usr/local/lib/python3.6/site-packages/locationsharinglib/locationsharinglib.py", line 459, in get_all_people
home-assistant   |     people = self.get_shared_people() + [self.get_authenticated_person()]
home-assistant   |   File "/usr/local/lib/python3.6/site-packages/locationsharinglib/locationsharinglib.py", line 421, in get_shared_people
home-assistant   |     for info in output[0]:
home-assistant   | TypeError: 'NoneType' object is not iterable

Nothing appears in Device Activity page.

Running in docker over Ubuntu 16.04

dshokouhi commented 5 years ago

How did you setup the component? Did you make sure to create a separate account and share your locations to that one? Did a file known_devices.yaml get created and do your see the device_tracker entities in there?

sagilo commented 5 years ago

Hi @dshokouhi Component setup published in the post (or you mean something else?) I did create a fresh new google account and shared my location from my personal account to the newly created one. no new entities under known_devices.yaml and no google device_tracker anywhere.

BTW After that didn't work I logged in to the new google account using the HA system (this time the system did appear in the device activity page), but still, same error in logs and no new devices.

dshokouhi commented 5 years ago

Are you able to see your devices if you use the library directly? If you don't see the devices create an issue in that repo, if you do see your devices comment back here so they can know next steps.

https://github.com/costastf/locationsharinglib

sagilo commented 5 years ago

You are right, the error comes from locationsharinglib (version 3.0.6) Test:

service = Service(username, password, 'google_maps_location_sharing.conf')
for person in service.get_all_people():
    print(person)

Output: Traceback (most recent call last):

  File "test.py", line 6, in <module>
    for person in service.get_all_people():
  File "/home/sagi/venv/temp/lib/python3.5/site-packages/locationsharinglib/locationsharinglib.py", line 459, in get_all_people
    people = self.get_shared_people() + [self.get_authenticated_person()]
  File "/home/sagi/venv/temp/lib/python3.5/site-packages/locationsharinglib/locationsharinglib.py", line 420, in get_shared_people
    for info in output[0]:
TypeError: 'NoneType' object is not iterable

I've opened a new issue in the relevant repository: https://github.com/costastf/locationsharinglib/issues/42

WedHumpDay commented 5 years ago

Are you able to see your devices if you use the library directly? If you don't see the devices create an issue in that repo, if you do see your devices comment back here so they can know next steps.

https://github.com/costastf/locationsharinglib

How would one go about using the directory directly?

dshokouhi commented 5 years ago

@WedHumpDay click on the link and go to the docs

WedHumpDay commented 5 years ago

@dshokouhi If you're referring to https://locationsharinglib.readthedocs.io/en/latest/installation.html I've already gone through this process: ( pip install locationsharinglib ) with no luck.. Problem is, I'm on Hass.io build 79.3 and each time I restart HA, Hass.io reverts back to the a different version. Been at this for days and it just will not login to Google. https://myaccount.google.com/device-activity never receives a request.

device_tracker:
  - platform: google_maps
    username: !secret google-user
    password: !secret google-pass
    max_gps_accuracy: 100
    new_device_defaults:
      track_new_devices: true

known_devices is created automatically. Cookie is created. config/components/device_tracker/google_maps.py

Log Details (ERROR)
Sun Oct 14 2018 18:52:54 GMT-0400 (Eastern Daylight Time)

Error setting up platform google_maps
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/device_tracker/__init__.py", line 183, in async_setup_platform
    disc_info)
  File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 56, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/device_tracker/google_maps.py", line 44, in setup_scanner
    scanner = GoogleMapsScanner(hass, config, see)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/device_tracker/google_maps.py", line 63, in __init__
    hass.config.path(CREDENTIALS_FILE))
  File "/config/deps/lib/python3.6/site-packages/locationsharinglib/locationsharinglib.py", line 370, in __init__
    cookies_file=cookies_file)
  File "/config/deps/lib/python3.6/site-packages/locationsharinglib/locationsharinglib.py", line 194, in __init__
    if cookies_file and self._validate_cookie(cookies_file):
  File "/config/deps/lib/python3.6/site-packages/locationsharinglib/locationsharinglib.py", line 221, in _validate_cookie
    raise InvalidCookies(message)
locationsharinglib.locationsharinglibexceptions.InvalidCookies: The cookies provided do not provide a valid session.Please authenticate normally and save a valid session again
MuppetOwl commented 5 years ago

Can confirm same error TypeError: 'NoneType' object is not iterable

Also tried latest hass Dev version that includes google_map.py version 3.0.6 but still same.

shr00mie commented 5 years ago

i'm working on rewriting locationsharinglib at the moment.

right now i got it working with 2FA device notification: image

gonna do some cleanup and optimization on my code and then implant/replace locationsharinglib.

might need some help from the HA devs as i'm not terribly familiar with upstream data flow, but i'm pretty sure i can figure it out...

WedHumpDay commented 5 years ago

@shr00mie Hopefully progress is moving along?

shr00mie commented 5 years ago

@WedHumpDay how bout them fuckin' apples? image

fucking lol image

shr00mie commented 5 years ago

oh...i probably have lat and lon reversed. oops.

there we go...

image

shr00mie commented 5 years ago

ok...couple things:

  1. my solution is currently using selenium + chrome webdriver which also requires a chrome install. how much of an issue could this present or can we just add a script to google_maps documentation page so users can just install chrome manually if they need to?
  2. i suppose this could be rewritten yet again back to straight requests, but i really like some of the functionality offered via selenium for control and debugging.
  3. i basically threw locationsharinglib out the window and wrote my own module consisting of cookie and query modules under a parent. went to town on google_maps as well a bit.

not sure what to do next. could throw it up under a repo so you guys could check it out i suppose?

dshokouhi commented 5 years ago

@shr00mie without a hassio addon to go along with it, nobody in hassio will be able to use this unfortunately. The USPS component required selenium but it did not work for all users. Any reason why you decided to abandon the original repo? Locataionsharinglib was recently created and it worked well for the most part. This issue in particular is also being looked at by the owner of that repo. Why not combine forces for a better product?

shr00mie commented 5 years ago

because owners can be possessive and i don't like going through committee to get to the best solution in the shortest amount of time...the only way i can see selenium not working is again based on poor implementation specifically as it pertains to the webdriver (for which the solution is the chromedriver_binary pip package). the only variable is the local chrome install. other than that, and assuming your paths aren't totally borked, shouldn't be an issue.

to clarify: if it was a couple lines of code. sure. fix it. this was not a couple lines of code.

wcomartin commented 5 years ago

out of curiosity, could Chrome headless be installed in the docker container for this to work in docker?

shr00mie commented 5 years ago

@wcomartin ...you sir, are a genius. since i'm running HA as a service under a standard ubuntu server install, my thinking wasn't even in containerland. implementing this with any of the containerized options would be exponentially easier as the chrome requirement could be incorporated into the build requirements. take the requirement out of the users hands and call it a day. just include the browser with the default container image for hass and crack open a beer.

shr00mie commented 5 years ago

ok...so who wants to help me figure out why it's not updating regularly? :smiley:

shr00mie commented 5 years ago

alright. fixed updating. it's pretty much ready to plug in at this point. no one's hit me up to test, so shit or get off the pot. hit me up and i'll toss you a repo invite.

shr00mie commented 5 years ago

you guys have the attention span of a damn goldfish...

hereyago.

WedHumpDay commented 5 years ago

@shr00mie I would say we are just busy. Was traveling for business, but back home this coming week. I'd be willing to to give this a go around.

To confirm, will this work on Hass.io? Its a custom VM instance install running Ubuntu with Hass.io.

Also, would be great if an addon was developed for Hass.io users. https://developers.home-assistant.io/docs/en/hassio_addon_tutorial.html

I would attempt but at this time I cannot commit to a development project as I'm quite busy at the office till end of the year.

sarabveer commented 5 years ago

I had downgraded HA to v0.78.0 for another issue and location tracking was working fine. After updating back to v0.80.3, it stopped working, again.

shr00mie commented 5 years ago

@WedHumpDay right now, i would probably consider this a proof of concept. the approach uses selenium instead of requests for cookie generation. it does require the host to have a working install of google chrome as well. implementation and testing of proposed changes would be easier for advanced users under docker, and manageable for less skilled users under a normal linux server install as you can just ssh in and git clone to the .homeassistant config folder. if people like the approach and we get some of the bugs ironed out as well as add some more error catching, this could be very easily rolled into a container image without any further action from users. this is my first time contributing to a project, and i have no idea how to package, so i'd definitely need some help with that if/when this is deemed viable.

@Sarabveer that seems to be the theme. my approach works with 0.80.3 and uses selenium to interact with the css elements via chrome. it was also designed and tested with device notification 2FA, but could very easily be modified by using configuration input for other login types as long as they are not of the captcha variety. i could see it working with authenticator as well by sensing the 2FA prompt and presenting an input popup/notification via HA frontend for input.

acarlo79 commented 5 years ago

It looks like the original library used by the component has been fixed : https://github.com/costastf/locationsharinglib/issues/42#issuecomment-431195508

I believe we should only get the fix imported into HassIO

sagilo commented 5 years ago

It looks like the original library used by the component has been fixed : costastf/locationsharinglib#42 (comment)

I believe we should only get the fix imported into HassIO

The library is still not fixed..

acarlo79 commented 5 years ago

well...the fix has been given to the library's owner, waiting for him to commit the changes into the code

WedHumpDay commented 5 years ago

@acarlo79 which fix are you referring? Not to confuse everybody, but there are couple of requested fixes in the pipeline. More importantly, needs to resolve for all HA configurations, including Hass.io, Virtualization, Hassbian, etc.

acarlo79 commented 5 years ago

google_maps component uses locationsharinglib to get the GPS position, with the proposed fix (which I tested also with HassIO) the component will work again correctly (still missing the 2FA). So once the fix (to authenticate the library using the google api) will be committed, we have to wait for a new HassIO/Hasbian/Virt release to contain the updated library.

does it make sense?

shr00mie commented 5 years ago

@acarlo79 locationsharinglib doesn't use google api, but go on...

WedHumpDay commented 5 years ago

Anyone confirmed Hass.io 81.0 resolved this?

sagilo commented 5 years ago

Anyone confirmed Hass.io 81.0 resolved this?

This issue relays in locationsharinglib library and the issue is still open, so it can't be fixed in HA yet.

royduin commented 5 years ago

For reference, there is a PR: https://github.com/costastf/locationsharinglib/pull/43. When that one is tested, approved, merged, there is a new version tagged and the requirement is updated in HA it should work. So probably the next release.

Yevrashka commented 5 years ago

Hope it wil be fixed.. Can't get it working sinse my first install on 0.78.0 and locashionsharinglib v3.0.0 Have reported twice to the lib author, but still no working desicion..

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 184, in async_setup_platform
    disc_info)
  File "/usr/lib/python3.5/asyncio/futures.py", line 380, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.5/asyncio/tasks.py", line 304, in _wakeup
    future.result()
  File "/usr/lib/python3.5/asyncio/futures.py", line 293, 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 "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/device_tracker/google_maps.py", line 46, in setup_scanner
    scanner = GoogleMapsScanner(hass, config, see)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/device_tracker/google_maps.py", line 66, in __init__
    self._update_info()
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/device_tracker/google_maps.py", line 78, in _update_info
    for person in self.service.get_all_people():
  File "/srv/homeassistant/lib/python3.5/site-packages/locationsharinglib/locationsharinglib.py", line 459, in get_all_people
    people = self.get_shared_people() + [self.get_authenticated_person()]
  File "/srv/homeassistant/lib/python3.5/site-packages/locationsharinglib/locationsharinglib.py", line 420, in get_shared_people
    for info in output[0]:
TypeError: 'NoneType' object is not iterable
shr00mie commented 5 years ago

you can lead a horse to water...

image

image

WedHumpDay commented 5 years ago

tried with 0.81.2, no go under Hass.io. Appears it hasnt been merged as of yet

wattsra commented 5 years ago

Does it make sense to update the components wiki page to say that this is currently broken?

WedHumpDay commented 5 years ago

Where does this leave the resolution for Hass.io users?

WedHumpDay commented 5 years ago

.82.0 release notes doesn't indicate this was resolved. Will retest sometime this week as I'm traveling.

shr00mie commented 5 years ago

bummer...

image

image

WedHumpDay commented 5 years ago

Hate to be a bare of bad news, still broken for Hass.io !! Still cannot get the device to show up under dummy Google account. And, yes, I have to phones sharing to the dummy account.

Details (ERROR)
Tue Nov 13 2018 21:24:07 GMT-0500 (Eastern Standard Time)

Error setting up platform google_maps
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/device_tracker/__init__.py", line 184, in async_setup_platform
    disc_info)
  File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 56, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/device_tracker/google_maps.py", line 46, in setup_scanner
    scanner = GoogleMapsScanner(hass, config, see)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/device_tracker/google_maps.py", line 65, in __init__
    hass.config.path(CREDENTIALS_FILE))
  File "/usr/local/lib/python3.6/site-packages/locationsharinglib/locationsharinglib.py", line 386, in __init__
    cookies_file=cookies_file)
  File "/usr/local/lib/python3.6/site-packages/locationsharinglib/locationsharinglib.py", line 210, in __init__
    if cookies_file and self._validate_cookie(cookies_file):
  File "/usr/local/lib/python3.6/site-packages/locationsharinglib/locationsharinglib.py", line 237, in _validate_cookie
    raise InvalidCookies(message)
locationsharinglib.locationsharinglibexceptions.InvalidCookies: The cookies provided do not provide a valid session.Please authenticate normally and save a valid session again
MuppetOwl commented 5 years ago

Its not listed as fixed yet. Only workaround now is the custom lib shr00mie fix? or wait for this pull request to be included? https://github.com/costastf/locationsharinglib/pull/43

shr00mie commented 5 years ago

Its not listed as fixed yet. Only workaround now is the custom lib shr00mie fix? or wait for this pull request to be included? costastf/locationsharinglib#43

personally, i consider gps related libraries to be vital to presence detection and automation. and said libraries should be well supported and updated as regularly as necessary to fix any upstream changes. feels like the current lib is maintained by only one person, which is a pretty damn big point of failure when so many people depend on its continued and reliable functionality.

i don't know or think that my resolution is the best for the time being or going forward. that said, i'm a solutions kinda guy. instead of waiting around for what at this point i consider an unacceptable period of time, put something else in place and move on. just because it's been done a certain way, doesn't mean it's what should be used going forward if it's so easy to break and takes so damn long to fix. we're not mapping the human genome here. let's not get married to what exists if it's not working or isn't getting fixed.

wcomartin commented 5 years ago

In regards to @shr00mie's comment, if location is a critical component and its going to be unreliable like this, perhaps it should be considered adding the functionality of the library directly in the home assistant repository instead, that way the whole team has access and can fix any issues that arise instead of relying on a single developer of a project to fix/merge a solution

perhaps @shr00mie's solution should be integrated into the home assistant repository and maybe make it use PhantomJS so there is no requirement on installing chrome, and everything can be installed from pip

thoughts?

WedHumpDay commented 5 years ago

In agreement. Having been a QA Build Engineer for a software developing company back in the day. The current process seems to be failing. This is directly in relation to a single threaded developer providing updates. As @wcomartin mention, ideally, placing the function directly within HA would be an overall better solution.

From a business perspective; now that HA is charging a monthly premium, development should be re-evaluated to be more structured on how updates are provided in a timely manner.

shr00mie commented 5 years ago

In regards to @shr00mie's comment, if location is a critical component and its going to be unreliable like this, perhaps it should be considered adding the functionality of the library directly in the home assistant repository instead, that way the whole team has access and can fix any issues that arise instead of relying on a single developer of a project to fix/merge a solution

perhaps @shr00mie's solution should be integrated into the home assistant repository and maybe make it use PhantomJS so there is no requirement on installing chrome, and everything can be installed from pip

thoughts?

i'd veto the PhantomJS path as HA is python, and keeping things consistent would i think be preferable instead of having people jump around languages/configs. thought process with my approach was that if we're trying to access google assets, while it could be achieved with other approaches, maybe a chrome browser would provide the highest degree of compatibility/inter-connectivity/wordsthatendwithity given the task. hence chrome+selenium.

i'm a big fan of the higher level abstraction and functionality offered by selenium compared to requests for the login/cookie component. it felt like the original library was using a lot of RE to figure out what was on the page which could be achieved with considerably less lines via selenium. it's possible that this approach/conclusion is simply due to my ignorance of requests capabilities, but it felt like controlling and interacting with, for all intents and purposes, a full browser, provided not only more control at low-high levels, but might be a stronger long term solution. not gonna lie, the screenshot capability came in stupid handy during development as well as ongoing debugging.

and i have a hard time believing that there aren't other libraries/components that couldn't be streamlined or might benefit from being able to leverage a full fledged browser being made available to HA.

another benefit of rolling this into HA is that the browser could be rolled into the container build image in the Hass.io variant while simply providing a chrome install script for the more hands on standalone install. logic being that if you're going the standalone route, you probably know how to install chrome on your linux server...

anyway. i'm just spitballing here. i've never put together a package or know what checks needs doing, but i fucking love HA and whatever i can do to help/contribute...

:eggplant:

wcomartin commented 5 years ago

@shr00mie Selenium+PhantomJS was just an example of something easily installed via a package manager, perhaps there is something in pip that could be used. but my main point was something that was integrated more closely with HA so that external packages didn't have to be installed especially chrome unless it can be installed in that fashion,

but I'm not opposed to chrome as long as its pre-installed in the docker container which is what I use.

shr00mie commented 5 years ago

@wcomartin i honestly think that inclusion of chrome within docker would be the most ideal and foolproof approach. again, the thinking being that if you're doing a standalone install, you can probably be trusted to figure out how to install chrome on your own to make this work. literally a couple lines of code.

that said, anyone else tried this in standalone install (ideally on ubuntu as i haven't tested any other distros)? i know it works for me in my environment, but if we could get some other feedback, that would be nice. especially as it pertains to various login methods (this was designed for device notification auth as that seems to be the best use case for headless). i haven't built any other ones out, but was thinking that login method/2fa can be included in config.yaml to then be passed to the lib which would alter its function based that setting. could probably get it to do google auth popup via the HA UI...somehow...

sherbang commented 5 years ago

Until the code is updated, you can temporarily work around the problem by using lufton's code to create the cookie file separately (I did it on a separate linux box and then uploaded the cookie file to hassos).

git clone https://github.com/lufton/locationsharinglib.git
cd locationsharinglib/
mkvirtualenv -p `which python3` locationsharinglib
pip install -r requirements.txt 
python cli.py --email '<your email>' --password '<your password>' --cookies-file 
.google_maps_location_sharing.cookies
mjnaylor8 commented 5 years ago

@sherbang Thanks that worked just fine!

dartfrogdk commented 5 years ago

where did you add the cookie file to in hassos