tchellomello/python-arlo

Can't get base station mode

Opened this issue · 32 comments

Hi,

I can get the base station mode (I see the update in my mobile App) but base.mode (like in the sample) return an empty result even if I set it just before.

I'm on a raspberry with raspbian jessie lite with Python 2.7.9

It's working for me. If you do "arlo.base_stations", does it list only one base station? Some Netgear routers can act as Arlo base stations, and the "base = arlo.base_stations[0]" line will only work properly if the first one is the one you want.

I've done the test. I've only one base station listed.
It seems that I don't receive the callback. I will do more tests.

After some tests, it seems to be a thread issue. When the action is sent to arlo server, the code is waiting thrue two loops. During this wait, the thread watching the event queue isn't running so no event is dispatched. Once the waiting loop is finished, i can see the thread getting events and the 'modes' result event.

Tested multiple times on another raspberry 3 but with Jessy desktop:
pi@raspberrypi:~ /python-arlo $ sudo python demo.py
disarmed
pi@raspberrypi:~ /python-arlo $ sudo python demo.py
disarmed
pi@raspberrypi:~ /python-arlo $ sudo python demo.py
None
pi@raspberrypi:~ /python-arlo $ sudo python demo.py
None
pi@raspberrypi:~ /python-arlo $ sudo python demo.py
disarmed

@arasium can you test it again on the latest version to check if the issue is still happening?

Hi @tchellomello,

I checked it out yesterday (running on RPI) and get the "None" result on each execution. Only one base station identified.
Let me know if I can assist with info. :)

Is this active with the latest release? I just did some work to modes.

hi all.
Before I did the Update today to pyArlo 0.1.3 the command
base.available_modes show ['armed', 'disarmed', 'schedule', 'custom']
And i was able to switch the modes by i.e. base.mode = 'armed'

Now, after the Update there is only ['schedule'] shown.
And I could not swich the modes.

The Version I used before was from July2017

Is there any chance to get the modes back?

Cheers
mi.ke

I encountered this a few times while trying to figure out how to make schedule work correctly. In previous versions, I believe empty list was the result.

What actually happened is the other modes were not retrieved from the arlo api. 'schedule' is special and not returned from the server. Probably need to add some robustness around some of the api calls to better indicate failures such as this.

Is it doing it all the time for you? If it is, out of curiosity, what happens if you call basestation->update() before retrieving modes?

Yes, I have tried several times and the result is unfortunately always "schedule".
base.update () does not help either.
The strange thing is that I have been using the API for half a year to automatically switch between modes. There was always perfect. Until update yesterday.

Ok I just remembered something I encountered that had this same result.

Try this:

  • Login via the website with the same username/password
  • Logout
  • Try the script again

ok,
I logged in via website, than logout.
After that, I run the test-script, same result, only ['schedule']

The test-script:

from pyarlo import PyArlo
arlo  = PyArlo('user', 'xxxxx')
base = arlo.base_stations[0]
base.update()
print(base.available_modes)

You shouldn't have had to call update, it was just something to try.

I ran the following with pyarlo 0.1.2:

from pyarlo import PyArlo
arlo = PyArlo(username, password)
base = arlo.base_stations[0]
print(base.available_modes)

And got:
['schedule', 'disarmed', 'armed', 'day', 'test']

well, I added the update command only on the basis of your advice :-)

Now I downgrade pyArlo from 0.1.3 to 0.1.2 but still the same failure.

Maybe there is any other reason . . . Basestation or firmware?!
Can we compare a few points?
my device is:
basestation hardware is VMB3010r2
firmware 1.9.4.0_15548

or do you have any other ideas, what I can try out to get my mode switching back?

Same firmware here, but my hardware is the 4000 model. I'm not sure that would have anything to do with it since they would standardize their api away from different model numbers at this level (at least I would think).

Might try increased logging to see if anything falls out. Note: DON'T POST the output as it will contain your username and password.

try:

from logging import basicConfig, DEBUG
from pyarlo import PyArlo

basicConfig(level=DEBUG, format='%(asctime)s - %(levelname)s - %(name)s - %(message)s')
arlo = PyArlo(username, password)
base = arlo.base_stations[0]
print(base.available_modes)

The last couple of lines should be something like:

2018-01-22 21:17:40,387 - DEBUG - pyarlo - Querying https://arlo.netgear.com/hmsweb/client/unsubscribe on attempt: 0/3
2018-01-22 21:17:41,388 - DEBUG - urllib3.connectionpool - https://arlo.netgear.com:443 "GET /hmsweb/client/unsubscribe HTTP/1.1" 200 16
2018-01-22 21:17:41,389 - DEBUG - pyarlo - Required raw object.
['schedule', 'disarmed', 'armed', 'day', 'test']

Note that 200 response from the GET. Does yours have that?

yes, the response is everytime ok (200)
This are the last 4 lines

2018-01-23 08:35:53,369 - DEBUG - pyarlo - Querying https://arlo.netgear.com/hmsweb/client/unsubscribe on attempt: 0/3
2018-01-23 08:35:53,773 - DEBUG - sseclient - Dispatching message event, 383 bytes...
2018-01-23 08:35:53,777 - DEBUG - urllib3.connectionpool - "GET /hmsweb/client/unsubscribe HTTP/1.1" 200 16
2018-01-23 08:35:53,782 - DEBUG - pyarlo - Required raw object.
['schedule']

I'll look at this closer this evening. I want to make sure those log lines are representative of what I thought they were last night.

Didn't get an opportunity to look in depth but I do believe I had the wrong lines in mind. I'll try to look tomorrow evening. In the mean time could you revert to the version you previously had working and make sure it retrieves the modes properly for you?

Please still validate the previous version you had still works.

I was referencing the wrong lines. You'll have to search up into the output some with the debug logging enabled.

Search for the area containing (these are incomplete lines):

pyarlo.base_station - Action body: {'action': 'get', 'from': 'some_guid_web', 'properties': None, 'publishResponse': False, 'resource': 'modes',

^ This line indicates that the code is about to query the api for the list of modes.
..... 4 or so lines later .....
urllib3.connectionpool - https://arlo.netgear.com:443 "POST /hmsweb/users/devices/notify/<I_believe_base_station_id>"

Check to make sure that post return code is 200.

2018-01-25 09:28:32,276 - DEBUG - urllib3.connectionpool - "POST /hmsweb/users/devices/notify/BASESTATION_ID HTTP/1.1" **200** 16

Then I searched for "HTTP/1.1" in the log
Everytime the respose is "200"

Unfortunately, I do not know how to install an older version.
I download the Zip-File (tag.0.0.9) and unzip it. But how can I install it over the curent version without using PIP?
(sorry about my unskilled questions and my worse english)

Now I got it:
sudo python setup.py install

Here is the result:
I ran the following with pyarlo various versions:

from pyarlo import PyArlo
arlo = PyArlo(username, password)
base = arlo.base_stations[0]
print(base.available_modes)

what did I expect?
['schedule', 'armed', 'disarmed', 'nurEingang'', 'test']

with pyArlo 0.0.6 I got:
['schedule', 'armed', 'disarmed', 'custom']
Incidentally, here it is only possible to switch between armed, disarmed and custom.

with pyArlo 0.0.7 I got:

Traceback (most recent call last):
  File "ArloTest.py", line 4, in <module>
    print(base.available_modes)
  File "build/bdist.linux-armv7l/egg/pyarlo/base_station.py", line 237, in available_modes
  File "build/bdist.linux-armv7l/egg/pyarlo/base_station.py", line 244, in available_modes_with_ids
TypeError: 'NoneType' object is not iterable

with pyArlo 0.0.8 I got:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/threading.py", line 763, in run
    self.__target(*self.__args, **self.__kwargs)
  File "build/bdist.linux-armv7l/egg/pyarlo/base_station.py", line 54, in thread_function
    for event in (self.__sseclient).events():
  File "/usr/local/lib/python2.7/dist-packages/sseclient/__init__.py", line 58, in events
    for chunk in self._read():
  File "/usr/local/lib/python2.7/dist-packages/sseclient/__init__.py", line 48, in _read
    for chunk in self._event_source:
  File "/usr/lib/python2.7/dist-packages/requests/models.py", line 656, in generate
    raise ChunkedEncodingError(e)
ChunkedEncodingError: ('Connection broken: IncompleteRead(46 bytes read)', IncompleteRead(46 bytes read))

['schedule']

with pyArlo 0.0.9 I got:
['schedule']

with pyArlo 0.1.0 I got:
['schedule']

with pyArlo 0.1.1 I got:
['schedule']

with pyArlo 0.1.2 I got:
['schedule']

with pyArlo 0.1.3 I got:
['schedule']

I am now back with the productive system to 0.0.6, so that my cameras automatically switch again when I come to home, or the patio door is opened. Unfortunately, the new features are gone.

Incidentally, I got a 4000 basestation in the meantime. No difference to the 3000 (concerning this topic)

Is there anything that I can do to help?

This is great information. I'll have a look at it tonight if I can.

edit: No longer tied to my earlier PR

I have more info now that I've looked at the code. It looks like it really wasn't doing anything in v0.0.6, those modes: ['schedule', 'armed', 'disarmed', 'custom'] are all hard-coded in that version.

With the latest version, what does this result in? print(base.get_available_modes()) should be a list of dictionaries containing the modes and rules for each mode.

from logging import basicConfig, DEBUG, INFO, getLogger
from pyarlo import PyArlo

basicConfig(level=INFO, format='%(asctime)s - %(levelname)s - %(name)s - %(message)s')
arlo = PyArlo(username, password)
base = arlo.base_stations[0]
print(base.available_modes)
print(base.get_available_modes())

Tried with pyarlo 0.1.2
The output is:

2018-01-27 17:08:54,224 - INFO - urllib3.connectionpool - Starting new HTTPS connection (1): arlo.netgear.com
2018-01-27 17:08:56,207 - INFO - urllib3.connectionpool - Starting new HTTPS connection (2): arlo.netgear.com
['schedule']
None

I wasn't sure if I understood correctly.
So here is additionally the output from pyArlo 0.0.6:

2018-01-27 20:26:57,610 - INFO - urllib3.connectionpool - Starting new HTTPS connection (1): arlo.netgear.com
['schedule', 'armed', 'disarmed', 'custom']
Traceback (most recent call last):
File "ArloTest2.py", line 8, in <module>
print(base.get_available_modes())
AttributeError: 'ArloBaseStation' object has no attribute 'get_available_modes'

I was wondering about the 0.1.2. It looks like for some reason it isn't retrieving modes within the specified wait. Currently it will wait 5 seconds for the response before continuing and silently failing.

Try the following with v0.1.2 and post the result.

from logging import basicConfig, DEBUG, INFO, getLogger
from pyarlo import PyArlo
from timeit import timeit

basicConfig(level=INFO, format='%(asctime)s - %(levelname)s - %(name)s - %(message)s')
arlo = PyArlo(username, password)
base = arlo.base_stations[0]
print(timeit(base.get_available_modes, number=1))

with pyArlo 0.1.2:

2018-01-27 21:26:58,909 - INFO - urllib3.connectionpool - Starting new HTTPS connection (1): arlo.netgear.com
2018-01-27 21:27:00,876 - INFO - urllib3.connectionpool - Starting new HTTPS connection (2): arlo.netgear.com
10.6914310455

Ok, its definitely not getting responses when expected. Out of curiosity can you successfully get/set modes or other properties?

Yes, with the 0.1.2 I can switch from any mode to the 'Schedule' mode.
With the 0.0.6 I can switch from anyone mode to another.

What do you think of making the waiting time more dynamic?
So wait until the answer, but max e.g. 15 seconds?

I found a little solution for me by using the old pyArlo 0.0.6

In the file "const.py" I change the following lines:

# define action modes
ACTION_MODES = {
    'armed': 'mode1',
    'disarmed': 'mode0',
    'custom': 'mode2',
    'schedule': 'true',
}

with

# define action modes
ACTION_MODES = {
     'AllesDeaktiviert': 'mode0',    
     'AllesAktiviert': 'mode1',
     'nurInnenbereich': 'mode2',
     'nurAussenbereich': 'mode3',
     'nurGarten': 'mode4',
     'nurGarage': 'mode5',
     'schedule': 'true',
}

The names of the mode assignment correspond exactly to what is entered in the arloAPP.
Now I'm able to address each mode specifically by script.

This works without delay and I do not need a scheduler anymore, because my smarthome knows exactly whether I'm at home or not, whether I have barbecue in the garden or if my motorcycle is in the garage etc.

Ok, sorry I haven't gotten a chance to look at the master branch in a few days. Hopefully we can resolve this.

@Berjler are you still hitting this problem with the latest version?