jeffreydwalter / arlo

Python module for interacting with Netgear's Arlo camera system.
Apache License 2.0
520 stars 123 forks source link

Check to see if camera is provisioned #123

Closed molotov6969 closed 5 years ago

molotov6969 commented 5 years ago

I'm using the example code from "Taking-Full-Screen-Snapshots" and it is executing but failing. It looks like arlo.GetDevices('camera') returns back every camera I ever had even ones that have been removed from the base station or are associated but inactive.

A couple examples: Request (POST https://my.arlo.com/hmsweb/users/devices/fullFrameSnapshot) failed: {'data': {'error': '2222', 'message': "Your account does not support the addition of another device. Now's a great time to upgrade your account. Or you can remove one of your other devices.", 'reason': 'Device Not Provisioned'}, 'success': False}

Request (POST https://my.arlo.com/hmsweb/users/devices/takeSnapshot) failed: {'data': {'error': '2217', 'message': 'The device does not exist.', 'reason': 'No such device.'}, 'success': False}

@jeffreydwalter was nice enough to guide me towards the need to "filter" only the cameras that have state = provisioned. I've tried several variations of "if" statements but I can't figure it out. The general error is 'dict' object has no attribute 'state' Any help would be much appreciated! Thank you.

https://github.com/jeffreydwalter/arlo/issues/121#issuecomment-508901213_

molotov6969 commented 5 years ago

What version of Python are you using (python -V)? Python 3.7.3

What operating system and processor architecture are you using (python -c 'import platform; print(platform.uname());')? Windows 10 Home. Intel core i7 x64. (I tried the command but am getting invalid syntax.)

Which Python packages do you have installed (run the pip freeze or pip3 freeze command and paste output)? arlo==1.2.23 certifi==2019.6.16 chardet==3.0.4 idna==2.8 monotonic==1.5 PySocks==1.7.0 requests==2.22.0 six==1.12.0 sseclient==0.0.24 urllib3==1.25.3

Which Arlo hardware do you have (camera types - [Arlo, Pro, Q, etc.], basestation model, etc.)? 1 Arlo Pro base, 1 Arlo Pro 2 base, mix of Arlo, Pro, and Pro 2 cameras.

What did you do? Attemped to run Taking-Full-Screen-Snapshots

What did you expect to see? An image file for each camera created in the directory of the script

What did you see instead? Described in detail in the above post^

Does this issue reproduce with the latest release? Yes

molotov6969 commented 5 years ago

do i need to tag this "help wanted"?

jeffreydwalter commented 5 years ago

You need to provide a script the reproduces the issue you're having, including what you've tried for filtering out the cameras that aren't provisioned. I'm happy to help you, but you need to help me.

molotov6969 commented 5 years ago
from arlo import Arlo

USERNAME = 'user@example.com'
PASSWORD = 'supersecretpassword'

try:
    # Instantiating the Arlo object automatically calls Login(), which returns an oAuth token that gets cached.
    # Subsequent successful calls to login will update the oAuth token.
    arlo = Arlo(USERNAME, PASSWORD)
    # At this point you're logged into Arlo.

    # Get the list of devices and filter on device type to only get the basestation.
    # This will return an array which includes all of the basestation's associated metadata.
    basestations = arlo.GetDevices('basestation')

        # Get the list of devices and filter on device type to only get the camera.
        # This will return an array which includes all of the camera's associated metadata.
        cameras = arlo.GetDevices('camera')

        # Tells the Arlo basestation to trigger a snapshot on the given camera.
        # This snapshot is not instantaneous, so this method waits for the response and returns the url
        # for the snapshot, which is stored on the Amazon AWS servers. 
        snapshot_url = arlo.TriggerFullFrameSnapshot(basestations[0], cameras[0])

        # This method requests the snapshot for the given url and writes the image data to the location specified.
        # In this case, to the current directory as a file named "snapshot.jpg"
        # Note: Snapshots are in .jpg format.
        arlo.DownloadSnapshot(snapshot_url, 'snapshot.jpg')

except Exception as e:
    print(e)

and i tried adding this after the cameras =.... line if camera[0].state == "provisioned":

jeffreydwalter commented 5 years ago

cameras[0]

On Tue, Jul 16, 2019, 9:21 AM molotov6969 notifications@github.com wrote:

from arlo import Arlo

USERNAME = 'user@example.com' PASSWORD = 'supersecretpassword'

try:

Instantiating the Arlo object automatically calls Login(), which returns

an oAuth token that gets cached.

Subsequent successful calls to login will update the oAuth token.

arlo = Arlo(USERNAME, PASSWORD)

At this point you're logged into Arlo.

Get the list of devices and filter on device type to only get the basestation.

This will return an array which includes all of the basestation's associated metadata.

basestations = arlo.GetDevices('basestation')

# Get the list of devices and filter on device type to only get the camera.
# This will return an array which includes all of the camera's associated metadata.
cameras = arlo.GetDevices('camera')

# Tells the Arlo basestation to trigger a snapshot on the given camera.
# This snapshot is not instantaneous, so this method waits for the response and returns the url
# for the snapshot, which is stored on the Amazon AWS servers.
snapshot_url = arlo.TriggerFullFrameSnapshot(basestations[0], cameras[0])

# This method requests the snapshot for the given url and writes the image data to the location specified.
# In this case, to the current directory as a file named "snapshot.jpg"
# Note: Snapshots are in .jpg format.
arlo.DownloadSnapshot(snapshot_url, 'snapshot.jpg')

except Exception as e: print(e)

and i tried adding this after the cameras =.... line if camera[0].state == "provisioned":

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/jeffreydwalter/arlo/issues/123?email_source=notifications&email_token=AAEKOB2VTPENA73W2LKMDTLP7XKM3A5CNFSM4H6T7MLKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD2BAJVA#issuecomment-511837396, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEKOBYJ4CG33NOEYPNVDLDP7XKM3ANCNFSM4H6T7MLA .

molotov6969 commented 5 years ago

sorry, typo up there. i actually have cameras not camera. the error when running the script is: 'dict' object has no attribute 'state'

jeffreydwalter commented 5 years ago

Again, you're not helping... You need to paste the actual script you're using that's giving you that error, not the example code.

jeffreydwalter commented 5 years ago

You should also put in some print statements to facilitate debugging, and include the output of those.

molotov6969 commented 5 years ago

this is exactly what i'm using except with my own username and password.

from arlo import Arlo

USERNAME = 'user@domain.com'
PASSWORD = 'password'

try:
        # Instantiating the Arlo object automatically calls Login(), which returns an oAuth token that gets cached.
        # Subsequent successful calls to login will update the oAuth token.
        arlo = Arlo(USERNAME, PASSWORD)
        # At this point you're logged into Arlo.

        # Get the list of devices and filter on device type to only get the basestation.
        # This will return an array which includes all of the basestation's associated metadata.
        basestations = arlo.GetDevices('basestation')

        # Get the list of devices and filter on device type to only get the camera.
        # This will return an array which includes all of the camera's associated metadata.
        cameras = arlo.GetDevices('camera')

        if cameras[0].state == 'provisioned':
                snapshot_url = arlo.TriggerFullFrameSnapshot(basestations[0], cameras[0])
                arlo.TriggerStreamSnapshot(basestations[0], cameras[0])
                arlo.DownloadSnapshot(snapshot_url, 'snapshot.jpg')
        else:
                print ("No provisioned cameras found.")
except Exception as e:
    print(e)
jeffreydwalter commented 5 years ago

Looks like I told you the wrong syntax (I haven't been writing much Python lately).

See this:

$ python
Python 2.7.15 (default, Feb 17 2019, 12:51:35) 
[GCC 4.2.1 Compatible Apple LLVM 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> cameras = [{ "state": "unprovisioned"}, { "state": "provisioned"}]
>>> cameras[0]
{'state': 'unprovisioned'}
>>> cameras[0].state
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'state'
>>> cameras[0].get("state")
'unprovisioned'

So, change cameras[0].state to cameras[0].get("state").

molotov6969 commented 5 years ago

thank you jeffrey! that got us past the previous error. i appreciate your help very much. what's happening now is that it's going to my "else" statement and not taking a snapshot. my guess as to what's happening is that the first camera device returned in the long cameras list is not "state": "provisioned" and it's not checking any other cameras after that.

jeffreydwalter commented 5 years ago

you need to loop over those cameras and filter out the ones that are unprovisioned.

jeffreydwalter commented 5 years ago

provisioned_cameras = [ camera for camera in cameras if camera.get("state") == "provisioned"]

jeffreydwalter commented 5 years ago

If you want further support, I'm happy to accept donations. You're basically asking for Python programming lessons at this point.

molotov6969 commented 5 years ago

sorry if you feel you're wasting your time on this. my very first post in the other thread was about how we identified that TriggerFullFrameSnapshot (and the like) were running on inactive cameras - which is something that would never work. i didn't realize that this was unique to me and that i had to engineer my own solution around it. honestly thought i was helping and if a change were made to the main code, it would benefit the community and all your followers. i've never programmed anything before but i really do appreciate the learning experience. thank you.

jeffreydwalter commented 5 years ago

I don't mind helping, but my time is very limited (I work two jobs, have a family, and maintain multiple open source projects) and thus valuable to me. I don't have problem supporting this library I wrote, but if you want programming lessons, feel free to pay me something. I think that's very fair.