Coder Social home page Coder Social logo

tchellomello / python-ring-doorbell Goto Github PK

View Code? Open in Web Editor NEW
549.0 44.0 171.0 571 KB

Python Ring Door Bell is a library written in Python 3 that exposes the Ring.com devices as Python objects.

License: GNU Lesser General Public License v3.0

Python 100.00%
python python3 ring-doorbell doorbell home-automation python27

python-ring-doorbell's Introduction

Python Ring Door Bell

PyPI Version Build Status Coverage Documentation Status Py Versions

Python Ring Door Bell is a library written for Python 3.8+ that exposes the Ring.com devices as Python objects.

There is also a command line interface that is work in progress. Contributors welcome.

Currently Ring.com does not provide an official API. The results of this project are merely from reverse engineering.

Documentation: http://python-ring-doorbell.readthedocs.io/

Installation

# Installing from PyPi
$ pip install ring_doorbell

# Installing latest development
$ pip install \
    git+https://github.com/tchellomello/python-ring-doorbell@master

Event Listener

If you want the ring api to listen for push events from ring.com for dings and motion you will need to install with the listen extra:

$ pip install ring_doorbell[listen]

The api will then start listening for push events after you have first called update_dings() or update_data() but only if there is a running asyncio event loop (which there will be if using the CLI)

Using the CLI

The CLI is work in progress and currently has the following commands:

  1. Show your devices:

    $ ring-doorbell
    

    Or:

    $ ring-doorbell show
    
  2. List your device names (with device kind):

    $ ring-doorbell list
    
  3. Either count or download your vidoes or both:

    $ ring-doorbell videos --count --download-all
    
  4. Enable disable motion detection:

    $ ring-doorbell motion-detection --device-name "DEVICENAME" --on
    $ ring-doorbell motion-detection --device-name "DEVICENAME" --off
    
  5. Listen for push notifications like the ones sent to your phone:

    $ ring-doorbell listen
    
  6. List your ring groups:

    $ ring-doorbell groups
    
  7. Show your ding history:

    $ ring-doorbell history --device-name "Front Door"
    
  8. Show your currently active dings:

    $ ring-doorbell dings
    
  9. Query a ring api url directly:

    $ ring-doorbell raw-query --url /clients_api/dings/active
    
  10. Run ring-doorbell --help or ring-doorbell videos --help for full options

Using the API

The API has an async interface and a sync interface. All api calls starting async are asynchronous. This is the preferred method of interacting with the ring api and the sync versions are maintained for backwards compatability.

You cannot call sync api functions from inside a running event loop.

Initializing your Ring object

This code example is in the test.py file. For the deprecated sync example see test_sync.py.

import getpass
import asyncio
import json
from pathlib import Path

from ring_doorbell import Auth, AuthenticationError, Requires2FAError, Ring

user_agent = "YourProjectName-1.0"  # Change this
cache_file = Path(user_agent + ".token.cache")


def token_updated(token):
    cache_file.write_text(json.dumps(token))


def otp_callback():
    auth_code = input("2FA code: ")
    return auth_code


async def do_auth():
    username = input("Username: ")
    password = getpass.getpass("Password: ")
    auth = Auth(user_agent, None, token_updated)
    try:
        await auth.async_fetch_token(username, password)
    except Requires2FAError:
        await auth.async_fetch_token(username, password, otp_callback())
    return auth


async def main():
    if cache_file.is_file():  # auth token is cached
        auth = Auth(user_agent, json.loads(cache_file.read_text()), token_updated)
        ring = Ring(auth)
        try:
            await ring.async_create_session()  # auth token still valid
        except AuthenticationError:  # auth token has expired
            auth = await do_auth()
    else:
        auth = await do_auth()  # Get new auth token
        ring = Ring(auth)

    await ring.async_update_data()

    devices = ring.devices()
    pprint(devices.devices_combined)
    await auth.async_close()


if __name__ == "__main__":
    asyncio.run(main())

Listing devices linked to your account

# All devices
devices = ring.devices()
{'chimes': [<RingChime: Downstairs>],
'doorbots': [<RingDoorBell: Front Door>]}

# All doorbells
doorbells = devices['doorbots']
[<RingDoorBell: Front Door>]

# All chimes
chimes = devices['chimes']
[<RingChime: Downstairs>]

# All stickup cams
stickup_cams = devices['stickup_cams']
[<RingStickUpCam: Driveway>]

Playing with the attributes and functions

devices = ring.devices()
for dev in list(devices['stickup_cams'] + devices['chimes'] + devices['doorbots']):
    await dev.async_update_health_data()
    print('Address:    %s' % dev.address)
    print('Family:     %s' % dev.family)
    print('ID:         %s' % dev.id)
    print('Name:       %s' % dev.name)
    print('Timezone:   %s' % dev.timezone)
    print('Wifi Name:  %s' % dev.wifi_name)
    print('Wifi RSSI:  %s' % dev.wifi_signal_strength)

    # setting dev volume
    print('Volume:     %s' % dev.volume)
    await dev.async_set_volume(5)
    print('Volume:     %s' % dev.volume)

    # play dev test shound
    if dev.family == 'chimes':
        await dev.async_test_sound(kind = 'ding')
        await dev.async_test_sound(kind = 'motion')

    # turn on lights on floodlight cam
    if dev.family == 'stickup_cams' and dev.lights:
        await dev.async_lights('on')

Showing door bell events

devices = ring.devices()
for doorbell in devices['doorbots']:

    # listing the last 15 events of any kind
    for event in await doorbell.async_history(limit=15):
        print('ID:       %s' % event['id'])
        print('Kind:     %s' % event['kind'])
        print('Answered: %s' % event['answered'])
        print('When:     %s' % event['created_at'])
        print('--' * 50)

    # get a event list only the triggered by motion
    events = await doorbell.async_history(kind='motion')

Downloading the last video triggered by a ding or motion event

devices = ring.devices()
doorbell = devices['doorbots'][0]
await doorbell.async_recording_download(
    await doorbell.async_history(limit=100, kind='ding')[0]['id'],
                     filename='last_ding.mp4',
                     override=True)

Displaying the last video capture URL

print(await doorbell.async_recording_url(await doorbell.async_last_recording_id()))
'https://ring-transcoded-videos.s3.amazonaws.com/99999999.mp4?X-Amz-Expires=3600&X-Amz-Date=20170313T232537Z&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=TOKEN_SECRET/us-east-1/s3/aws4_request&X-Amz-SignedHeaders=host&X-Amz-Signature=secret'

Controlling a Light Group

groups = ring.groups()
group = groups['the-group-you-want']

print(group.lights)
# Prints True if lights are on, False if off

# Turn on lights indefinitely
await group.async_set_lights(True)

# Turn off lights
await group.async_set_lights(False)

# Turn on lights for 30 seconds
await group.async_set_lights(True, 30)

How to contribute

See our Contributing Page.

Credits && Thanks

python-ring-doorbell's People

Contributors

andrewkress avatar andrewmohawk avatar balloob avatar cosimomeli avatar cpina avatar cyberjunky avatar decompil3d avatar dependabot[bot] avatar dshokouhi avatar evanjd avatar jeromelaban avatar jlippold avatar joedaddy7105 avatar joostlek avatar jsetton avatar keeth avatar morganbulkeley avatar mwren avatar nsevent avatar ntalekt avatar prwood80 avatar sdb9696 avatar steve-gombos avatar steveww avatar tchellomello avatar twasilczyk avatar vickyg3 avatar xernaj avatar zachbenz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-ring-doorbell's Issues

Siren on Ring spotlight cam (battery)

Hi there,
I cannot get the siren to work on the spotlight cam. If I use the siren like in the scripts for the floodlight, everything stays silent.
When I use the lights however, the lights turn on. Is there something different between the floodlight and spotlight camera's?

Thanks for any help, love your work!

Limit not returning what I expected

Hi there,

Slightly confused at what the limit operation does.. I expected it to limit the number of records returned but it seams to be indicating how many records to query from the api , regardless of type.

eg.

from ring_doorbell import Ring
myring = Ring('[email protected]', 'yyyy')
print ("did we connect %s " % myring.is_connected)
for bells in list(myring.doorbells):
    for event in bells.history(limit=15,kind='ding'):
        print('ID:       %s' % event['id'])
        print('Kind:     %s' % event['kind'])
        print('Answered: %s' % event['answered'])
        print('When:     %s' % event['created_at'])
        print('--' * 50)

I expected to return the last 15 "dings" but it returns nothing
if I change the limit to 1000 then I get a couple but not 5-10 or so..

Configurable polling interval/scheduled update interval

Hi Marcello--Thank you so much for putting this package together. It works great but I was wondering if there was a way to configure either the polling interval or the scheduled update interval? My homeassistant log continuously warns me that it's taking longer to update ring than the scheduled update interval of 5 seconds. I get about 30 of these warnings or so for the first two minutes, so it might be the correct behavior but it would still be nice for the polling interval to be configurable. I took a quick peek at const.py to see if it would be straight-forward to do but it looks like it would take more effort that would be beyond my ability. Again, thank you for the package and thank you for the consideration.

Issue - live_streaming_json returns "none"

I tried to setup the SIP stream using the function live_streaming_json, but when I try and call it using both my ring doorbell, and my ring pro doorbell, it returns None.

last_recording_id

Hi!

maybe we should add check like
if event["recording"]["status"] == "ready" ?

for example, doorbell has motion.
now we should be waiting for the complete video and after - we ready to process this video

raw (schematically) code:

    n = 0
    while True:
         try:
            event = doorbell.history(limit=1)[0]
            last_recording_id = event['id']
            if event["recording"]["status"] == "ready":
               url = doorbell.recording_url(last_recording_id)
               subprocess.call (['wget', url, '-O', '/home/pi/ring/last_video.mp4'])          
               break
         except:
            pass

         n+=1
	 if n > 5:
            break
         time.sleep(1)

Using WebHooks for check_alerts()?

Hi,

I was not sure from looking at the code. I think check_alerts() is polling the ring.com api each time, correct? Is there a mechanism for using web hooks or the like with the ring.com API to decrease traffic?

Best, Markus

what mean this error?

2018-01-16 12:17:08,979 ERROR No handlers could be found for logger "ring_doorbell"
2018-01-16 12:17:08,981 ERROR Traceback (most recent call last):
2018-01-16 12:17:08,982 ERROR File "/home/pi/ring/myring.py", line 65, in

2018-01-16 12:17:08,984 ERROR File "/usr/local/lib/python2.7/dist-packages/ring_doorbell/init.py", line 53, in init
2018-01-16 12:17:08,986 ERROR self._process_cached_session()
2018-01-16 12:17:08,986 ERROR File "/usr/local/lib/python2.7/dist-packages/ring_doorbell/init.py", line 79, in _process_cached_session
2018-01-16 12:17:08,987 ERROR req = self.query(url, raw=True)
2018-01-16 12:17:08,988 ERROR File "/usr/local/lib/python2.7/dist-packages/ring_doorbell/init.py", line 172, in query
2018-01-16 12:17:08,988 ERROR req = self.session.get((url), params=urlencode(params))
2018-01-16 12:17:08,989 ERROR File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 521, in get
2018-01-16 12:17:08,992 ERROR return self.request('GET', url, **kwargs)
2018-01-16 12:17:08,993 ERROR File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 508, in request
2018-01-16 12:17:08,994 ERROR resp = self.send(prep, **send_kwargs)
2018-01-16 12:17:08,994 ERROR File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 618, in send
2018-01-16 12:17:08,996 ERROR r = adapter.send(request, **kwargs)
2018-01-16 12:17:08,996 ERROR File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py", line 508, in send
2018-01-16 12:17:08,999 ERROR raise ConnectionError(e, request=request)
2018-01-16 12:17:09,000 ERROR requests.exceptions
2018-01-16 12:17:09,000 ERROR .
2018-01-16 12:17:09,001 ERROR ConnectionError
2018-01-16 12:17:09,001 ERROR :
2018-01-16 12:17:09,002 ERROR HTTPSConnectionPool(host='api.ring.com', port=443): Max retries exceeded with url: /clients_api/ring_devices?auth_token=vA9pYT9ExX6iWxDLLDqp&api_version=9 (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x75e8d270>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution',))

Doorbell history does not return all events

When going through the history of events on a doorbell, much as in the basic examples, it doesn't seem to get all the events - I'm guessing the request that is being made for these has a hard limit/maximum (I did try setting the limit parameter to be really high), and it will probably take multiple requests to truly get all the events. Not sure what additional parameters to the URL will be necessary to select the earlier events, but I know when browsing my events on the Ring website it allows me to scroll back to my earliest events. Useful API otherwise, great work!

Add a controller to only call download_url() or download_video() if account has subscription

Add a controller to only call download_url() or download_video() if account has subscription

by @arsaboo
Looks like Ring is blocking the camera component when there is no cloud subscription. In such cases, the Ring camera component shows Image not available. It will nice if the Ring camera can check for subscription and only load if there is a subscription. If there is no subscription, it should just log an error or create a notification.

Mentioned: home-assistant/core#10736

Returning more then the first hundred events

I'm using doorbell.history, but it limits to 100 (I'm guessing a ring API issue). Is there a way to apply a paging ability to get more events?

In [77]: es = [e for e in doorbell.history(limit=115)]
In [78]: len(es)
Out[78]: 100

Fix Unit Tests

Unittests are failing.. We need to investigate and fix it

FR: Chime play custom tone

This features would allow you to play a custom tone to individual specific chimes as well as all chimes in a home (I'd be happy with just the latter). This would empower home assistant users to create automations that play certain tone for certain events (ex. left garage open) while not affecting your existing tones for doorbell motion and doorbell ring.

Not Receiving Notifications

I see some comments from over a year ago about notifications not working. I am trying now by setting persist_token=True, push_token_notify_url="http://mysite.com" when I setup my Ring object. I am not receiving anything on the site I have setup. If this is working, what am I doing wrong? If it is not working, can this be an enhancement request?

For now I will experiment with IFTTT to create the trigger, but they are not responsive. Would much rather get it directly from Ring.

Add support to Stick Up cameras

Would be awesome to have support to Stick Up cameras. I don't have one but I have plans on buying it to test it.

If anyone else wants to work on this, please you are very welcome.

history argument animal_present, person_present, vehicle_present are not implemented

Here is output where kind=none

myring.doorbells[1].history(limit=1, timezone=None, kind=None, enforce_limit=False, older_than=None, retry=8)
[{u'kind': u'ding', u'vehicle_present': None, u'person_present': None, u'created_at': datetime.datetime(2018, 5, 24, 22, 39, 31, tzinfo=<UTC>), u'favorite': False, u'animal_present': None, u'events': [], u'recording': {u'status': u'ready'}, u'answered': False, u'id': 655924564564574686, u'snapshot_url': u''}]

Here is output where kind is other than none:

myring.doorbells[1].history(limit=1, timezone=None, kind=ding, enforce_limit=False, older_than=None, retry=8)
Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'ding' is not defined

Am I doing something wrong here.

What I would like to do is write a script to test and see if the person present, and animal present features work.

So what I was trying to do was filter by dings so that I know a person is present and see if it returns that as true. If so I want to write a script that checks if those values are true and then save those videos and run machinebox facebox on those videos.

I am able to save videos and manual running those videos through the machine learning and it recognizes the faces I have trained, now I want to automate that.

Any help would be appreciated.

Thanks

Jon

Check_alerts() function not working

Hopefully I'm just doing it wrong, but the check_alerts() function for the doorbell is not working for me

I have set up a ~7s loop, to check that function and get the alert details when one happens

from ring_doorbell import Ring
from ring_doorbell import RingDoorBell
from pprint import pprint
import time

myring = Ring('creds', "False", 'True','http://localhost/', 'True', 'ring_doorbell-session.cache')

while(True):
    obj2 = RingDoorBell(myring, 'Front Door')
    checker = obj2.check_alerts()
    print checker
    print obj2.battery_life
    time.sleep(2)

This runs and continues to print None and the battery life, after creating a motion event while this loop is running i get nothing

401 Client Error: Unauthorized for url: https://api.ring.com/clients_api/session

hi
time to time I got subj.

my code is very simple

while True:
    try:
        myring = Ring(ringUsername, ringPassword, debug=True)
        if myring.is_connected==False:
           logger.error("Ring Connection Not Successful ".format(myring.is_connected))
           time.sleep(30)
        else:
           logger.info("Ring Connection Successful")

        doorbell = myring.doorbells[0] 
        while True:
              if doorbell.check_alerts() :
                    kind = doorbell.alert.get('kind')
                    print(kind)
              sleep(5)

    except Exception as d:
        logger.error(d)
        time.sleep(30)

log:
jq3z0iuspl 1

UPD!

Feature request: Live view proxy

Hi, would it be possible to use this library to allow a continuous live view stream to be exposed locally as an IP camera feed (either ONVIF or just an mp4 stream), so that it could be recorded by an NVR?

Ideally this would bypass Rings servers and just stay within the LAN (would reduce the overheads in terms of data transmission), but that doesn't seem possible at the moment, but this would allow Ring to be integrated into an existing CCTV installation instead of existing as a separate system.

Thanks,
Anthony

Add Floodlight and Stickupcam support to HomeAssistant

@tchellomello Ok I can validate that the Library can see the Flood light cam as per my tests below:

Account ID:  [REDACTED]
Address:    [REDACTED]
Family:     stickup_cams
ID:          [REDACTED]
Name:       Front house
Timezone:   America/Chicago
Wifi Name:   [REDACTED]
Wifi RSSI:  -52
Connection Status:  online
Volume:     5
Volume:     5
https://ring-transcoded-videos.s3.amazonaws.com/6477917516918700692.mp4?X-Amz-Expires=3600&X-Amz-Date=20171017T173520Z&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential= [REDACTED]/20171017/us-east-1/s3/aws4_request&X-Amz-SignedHeaders=host&X-Amz-Signature= [REDACTED]
Alert Status:  None

This means it sees my Flood Light cam as a Stickup cam, and I saw that in issue: #38

They were able to get the data for the Flood lights and Siren working.

What else can I do to help test on HA?

PS> This is the python code I used to test:

from ring_doorbell import Ring
myring = Ring('foo@bar', 'secret')

myring.is_connected
True



for dev in list(myring.stickup_cams + myring.chimes + myring.doorbells):

    # refresh data
    dev.update()

    print('Account ID: %s' % dev.account_id)
    print('Address:    %s' % dev.address)
    print('Family:     %s' % dev.family)
    print('ID:         %s' % dev.id)
    print('Name:       %s' % dev.name)
    print('Timezone:   %s' % dev.timezone)
    print('Wifi Name:  %s' % dev.wifi_name)
    print('Wifi RSSI:  %s' % dev.wifi_signal_strength)
    print('Connection Status:  %s' % dev.connection_status)    

    # setting dev volume
    print('Volume:     %s' % dev.volume)
    dev.volume = 5
    print('Volume:     %s' % dev.volume)
    print(dev.recording_url(dev.last_recording_id))
    print('Alert Status:  %s' % dev.check_alerts())

Split source code into different files

Split source code into different files. Ideally the each module should have its own file.

RingGeneric - generic.py
RingChime - chime.py
RingDoorBell - doorbell.py
RingStickUpCam - stickup_cam.py

Feature Request: Add a model property to identify the different products

With all the new products that Ring has added in the last year, it would be nice if we could catalog them and add some logic to identify their model. This is especially a need for the stickup_cam family umbrella and their different power source. For example, the battery_life property on a Floodlight cam is returning some value while that product is AC powered only and no other device property seems to identify the power source properly.

Here is all the information I was able to gather from the APK. I used the same model names listed in the application package. Some of the models use a combination of the kind and ring_cam_setup_flow properties.

Model Family Power kind ring_cam_setup_flow
Chime chimes hardwired chime
Chime Pro chimes hardwired chime_pro
Doorbell doorbots battery doorbot
doorbell
doorbell_v3
Doorbell 2 doorbots battery doorbell_v4
doorbell_v5
Doorbell Pro doorbots hardwired lpd_v1
lpd_v2
Doorbell Elite doorbots hardwired jbox_v1
Floodlight Cam stickup_cam hardwired hp_cam_v1 floodlight
Spotlight Cam Battery stickup_cam battery stickup_cam_v4 (battery)
Spotlight Cam Mount stickup_cam hardwired hp_cam_v2 mount
Spotlight Cam Solar stickup_cam battery stickup_cam_v4 solar
Spotlight Cam Wired stickup_cam hardwired hp_cam_v2 (wired)
Stick Up Cam stickup_cam battery stickup_cam
stickup_cam_v3
Stick Up Cam Battery stickup_cam battery stickup_cam_lunar
Stick Up Cam Wired stickup_cam hardwired stickup_cam_elite

Capabilities:

Model Battery Light Siren Volume
Chime ✔️
Chime Pro ✔️
Doorbell ✔️ ✔️
Doorbell 2 ✔️ ✔️
Doorbell Pro ✔️
Doorbell Elite ✔️
Floodlight Cam ✔️ ✔️
Spotlight Cam Battery ✔️ ✔️ ✔️
Spotlight Cam Mount ✔️ ✔️
Spotlight Cam Solar ✔️ ✔️ ✔️
Spotlight Cam Wired ✔️ ✔️
Stick Up Cam ✔️
Stick Up Cam Battery ✔️ ✔️
Stick Up Cam Wired ✔️

Fix traceback when trying to download a recording without subscription

>>> myring.doorbell_recording_url(123456778)
Sorry.. Something went wrong...
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
  File "/home/frank/code/python-ring-doorbell/ring_doorbell/__init__.py", line 235, in doorbell_recording_url
    if req.status_code == 200:
AttributeError: 'NoneType' object has no attribute 'status_code'

@tchellomello If someone tries to download/get the URL of a video while they have no active subscription it throws traceback:

Thanks to @syphernl for reporting the issue.

How to get RSSI?

This module is great thank you! I am using it to monitor the health of my doorbell with MRTG :)

I see the battery level is there but I don't see the RSSI which the app shows me. Anyone know how to get that?

I followed the link to the post about reverse-engineering the protocol but that page is 404 now unfortunately.

Thanks!

Feature Request: adjust mechanical chime setting

I'm using this library through home-assistant right now for motion and ding detection. I've set up rules that allow turning on lights when motion is found by Ring with the right conditions.

What I'd really like is the ability to turn on/off the mechanical doorbell connected to my Ring so I can make rules associated with that.
There's a setting in the Android app that lets you do this, but it's buried in a few menus.

[bug] Battery life shows 100 when its not

Great API here, been following for a while and now have finally got around to attempting to integrate ring into my homeautomation. I am printing the battery life for a ring doorbell, and using the battery_life method its printing 100, however when I dump the Ring doorbell object, it shows the correct battery life within there

>>>from ring_doorbell import Ring
>>>from ring_doorbell import RingDoorBell
>>>from pprint import pprint

>>>myring = Ring('user', 'pass', 'true')

>>>print myring.is_connected
True
>>>obj = RingDoorBell(myring, 'Front Door')
>>>obj.battery_life
100
>>>pprint(vars(obj))
{'_attrs': {u'address': u'myaddress',
            u'alerts': {u'connection': u'online'},
            u'battery_life': u'59',
            u'description': u'Front Door',
<omitted>
'_health_attrs': {u'average_signal_category': u'good',
                   u'average_signal_strength': -49,
                   u'battery_percentage': u'59',
                   u'battery_percentage_category': u'good',
                   u'battery_voltage': None,
                   u'battery_voltage_category': None,
                   u'firmware': u'Up to Date',
                   u'firmware_out_of_date': True,

fix my Python ignorance

I thought I was pretty oh-fey on Python matters but I cannot work out how to poll the Ring service for an activation. I have compared your code with the php original and it has a poll() function where you have a check_alerts() function but I can get nothing back. I have got the other parts of your code working and ended up with this test code.

seems the insert code doesn't like python.

`
from ring_doorbell import Ring
from time import sleep

myring = Ring('myaccount', 'password')
print (myring.is_connected)

print (myring.devices)

for doorbell in myring.doorbells:
print (doorbell.wifi_signal_strength)
print (doorbell.battery_life)
print (doorbell.firmware)

for event in doorbell.history(limit=15):
    print('ID:       %s' % event['id'])
    print('Kind:     %s' % event['kind'])
    print('Answered: %s' % event['answered'])
    print('When:     %s' % event['created_at'])
    print('--' * 50)
    
events = doorbell.history(kind='ding')
print (events)

for chime in myring.chimes:
print(chime.battery_life)

print(doorbell.recording_url(doorbell.last_recording_id))

while(1):
print ("scanning")
data = doorbell.check_alerts()
print (data)
sleep(5)
`

But just get none when trying the doorbell.

Could you post a snippet for polling the service please I'm going daft.

FR: Add doorbot motion_snooze and chime do_not_disturb functions

Set a 3 hour chime 'do_not_disturb'..

POST https://api.ring.com/clients_api/chimes/123456/do_not_disturb HTTP/1.1
Host:	api.ring.com
Content-Type:	application/json
Accept:	*/*
Content-Length:	30
Connection:	keep-alive
X-API-LANG:	en
Hardware_Id:	<GUID>
User-Agent:	ring/4.1.16 (iPhone; iOS 11.3; Scale/2.00)
Accept-Language:	en-US;q=1, es-ES;q=0.9
Authorization:	Bearer <TOKEN>
Accept-Encoding:	identity


{"api_version":"9","time":180}

Disable the motion snooze..

POST https://api.ring.com/clients_api/chimes/123456/do_not_disturb HTTP/1.1
Host:	api.ring.com
Content-Type:	application/json
Accept:	*/*
Content-Length:	19
Connection:	keep-alive
X-API-LANG:	en
Hardware_Id:	<GUID>
User-Agent:	ring/4.1.16 (iPhone; iOS 11.3; Scale/2.00)
Accept-Language:	en-US;q=1, es-ES;q=0.9
Authorization:	Bearer <TOKEN>
Accept-Encoding:	identity
{
    "api_version": "9"
}

Set a 15 minute doorbell 'motion_snooze'..

POST https://api.ring.com/clients_api/doorbots/7654321/motion_snooze HTTP/1.1
Host:	api.ring.com
Content-Type:	application/json
Accept:	*/*
Content-Length:	29
Connection:	keep-alive
X-API-LANG:	en
Hardware_Id:	<GUID>
User-Agent:	ring/4.1.16 (iPhone; iOS 11.3; Scale/2.00)
Accept-Language:	en-US;q=1, es-ES;q=0.9
Authorization:	Bearer <TOKEN>
Accept-Encoding:	identity
{
    "api_version": "9",
    "time": 15
}

Clear doorbell 'motion_snooze'..

POST https://api.ring.com/clients_api/doorbots/7654321/motion_snooze/clear HTTP/1.1
Host:	api.ring.com
Content-Type:	application/json
Accept:	*/*
Content-Length:	19
Connection:	keep-alive
X-API-LANG:	en
Hardware_Id:	<GUID>
User-Agent:	ring/4.1.16 (iPhone; iOS 11.3; Scale/2.00)
Accept-Language:	en-US;q=1, es-ES;q=0.9
Authorization:	Bearer <TOKEN>
Accept-Encoding:	identity
{
    "api_version": "9"
}

Should session cache be saved if save session is set to False?

I get an error trying to use this in an aws lambda call because it is attempting to save to cache. Is there any reason it should not be moved into the if statement above so that it doesn't attempt to save if the session will not be reused?

__init__.py on line 135
_save_cache(self.cache, self.cache_file)

Ring Team Email Communication

Email from Ring Team "Your subscription payment for $30.00 has failed for the second time. We'll try charging your account again in 3 days. To avoid service interruptions, please visit your account page"

I visit this page, no way to cancel anything????

I had already removed payment details long ago

No help on the website???

No email contact anywhere easy to find???

So I replied to this system generated message with "Stop trying to charge me, I don’t want nor like your service"

Email from Ring Team "Thank you for contacting Ring!
I apologize for the inconvenience. It seems to me that the subscription has been canceled now. Also, no further transactions will be taken from your card since it has been deleted from the profile.
Please feel free to reply to this email if you need further assistance, and I will be happy to get back to you.
If I am out of the office and you do not receive a response within 48 hours, please feel free to email Ring support at [email protected].
As always, you can reach us via phone at US +1(800) 656-1918 or INTL +1(310) 929-7085.
Alternatively, Chat agents are available via our website, www.ring.com.
Thanks for contacting Ring!"

Then Ring (Apparently from Jamie Siminoff lol) sends me a survey for the above unknown entity, not a survey on the service or product, but on this "person"

Email to Ring Team "Well you can tell Jamie Siminoff that his survey sucks as bad as his products, the survey asks about someone called Kseniia, who the hell is that, and why should I care?

I would like to be asked about my thoughts on the product, and why I don’t want to renew a subscription after owning the product for a year, isn’t this more important?

Getting realtime customer feedback on what your selling is the most important thing, unless he already knows how useless it.

List of issues:

  • Battery goes flat way to fast
  • No option for a solar system on the doorbell
  • Even if wired to mains, can’t run video feed permanently
  • Cloud feature is forced, this should be optional
  • Should be optional to have all video record locally
  • Would rather have a doorbell that can stream to a local DVR
  • Video quality is terrible, in no way is the video feed produced acceptable
    • Try increasing bit rate
    • Use better optics
    • Use H265 compression for smaller but better quality video
    • Use local storage so video size/compression is not an issue
    • Design the system to be accept gigabit lan as an option
  • After 12 months the thing is corroding away and now is an eyesore on my front porch
  • By the time someone rings and I finally get the feed up:
    • A) They have walked off.
    • B) Someone has already answer the door
  • Moral of the storey, its to bloody slow to be of any use to me, and especially my wife.

I will be replacing the ring with cheap Chinese product, that operates locally and the cloud based feature is just an option, and costs 1/6 of the price."

Email from Ring Team "My name is Kseniia, and I am the agent who has replied to your previous email, I apologize for not introducing myself.
Your feedback will surely be forwarded to the appropriate department, thank you for forwarding it to us. It helps us a lot when it comes to the product improvement.

I am terribly sorry for this situation with your device! Your frustration, in this case, is understandable and I would feel the same. Let me, please try clearing some things up:

Battery goes flat way to fast - we can troubleshoot this issue together and improve the battery life.
No option for a solar system on the doorbell - there is an option to connect it to the Solar Charger. However, this product is not available in Australia at the moment since it has been released recently.
Even if wired to mains, can’t run video feed permanently - the wiring of the Doorbell does not influence the speed of Live View opening. It might be a possible connectivity issue, and in case you would like to troubleshoot the issue we can resolve it together :)
Cloud feature is forced, this should be optional - it is totally up to you whether you would like to subscribe to our Plan and get your videos stored or use the Doorbell for Live streaming only.
Should be optional to have all video record locally - unfortunately, it is not possible to save the recordings to your cloud storage due to the technical reasons.
Would rather have a doorbell that can stream to a local DVR
Video quality is terrible, in no way is the video feed produced acceptably - it does not sound right, the video quality might be influenced by the networking issues. We can try investigating the issue and fixing it.
Try increasing bit rate- thank you for your suggestions, they will be forwarded to our management.
Use better optics
Use H265 compression for smaller but better quality video
Use local storage, so video size/compression is not an issue
Design the system to accept gigabit LAN as an option
After 12 months the thing is corroding away and now is an eyesore on my front porch - I am sorry for that. May I please see the pictures of the corrosion?
By the time someone rings and I finally get the feed up:
A) They have walked off
B) Someone has already answered the door - may I please clarify how long does it take for the video to be opened once you click on the notification?

As an apology for the whole situation let me, please offer you a couple of options to improve your experience with us :)
Your Doorbell is our of our 1-year Standard warranty. However, we still would like to offer you a replacement option. If you would like - we can send you a new Ring Video Doorbell out, and you would need to return the old unit to us.
In case you would like to try using another model (for example, Ring Video Doorbell 2, PRO and Elite have interchangeable faceplates, and the corrosion will not be an issue with these products) - we can upgrade your current device if you would like to cover the difference in the price.

Please, let me know what do you think about it.

Best regards,
Kseniia"

Email to Ring Team "I have no networking issues, I have a top of the line R9000 night hawk, which I purchased as the Ring door bell did have poor connection to my Apple airport express.

I’m am a veteren PC and network engineer, I have been playing with computers since the early 80’s, I don’t need any help, the issue ls with the IOT and cloud based solutions, I know longer want this, any device that is cloud based or IOT is useless, when the Internet goes down or goes slow, which happens often.

I will take pics and send to you, but the unit is going, I will be going for a stand alone product that can connect to my local DVR.

And I will also comment, there is no “technical” issue with recording locally, only an artificial software limitation implied by the ring team forcing one to use the cloud service, once I remove this thing, I will be disassembling and hacking the hell out of it, there are plenty of people working on this “technical issue”

You can’t help me with this product, its technically above your level, the issue is at a software engineer’s level, and Ring will not change as it's business model is based around this."

Just thought I would share, as I don't do social media and I thought someone here might get a laugh out of it

PS. And just after all this, I get junk mail from them, trying to flog more of there useless crap????

Fix urlencode for Python 2.7

Fix urlencode for Python 2.7

----> 1 from ring_doorbell import Ring

/home/user/.virtualenvs/py27/lib/python2.7/site-packages/ring_doorbell/__init__.py in <module>()
      2 # vim:sw=4:ts=4:et:
      3 """Python Ring Doorbell wrapper."""
----> 4 from urllib.parse import urlencode
      5 from datetime import datetime
      6 

ImportError: No module named parse

Feature request: Change Chime ring

In the Ring app it is possible to change the sound the Chime should use. With this we can change the volume, but it would be nice if the sound could be changed as well.

Traceback if req is None

Report by: @lunatix https://community.home-assistant.io/t/ring-doorbell/7943/300

2017-10-26 13:52:44 ERROR (MainThread) [aiohttp.server] Error handling request
Traceback (most recent call last):
  File "/srv/hass/lib/python3.6/site-packages/aiohttp/web_protocol.py", line 422, in start
    resp = yield from self._request_handler(request)
  File "/srv/hass/lib/python3.6/site-packages/aiohttp/web.py", line 306, in _handle
    resp = yield from handler(request)
  File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 213, in coro
    res = yield from res
  File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 213, in coro
    res = yield from res
  File "/srv/hass/lib/python3.6/site-packages/homeassistant/components/http/ban.py", line 58, in ban_middleware_handler
    return (yield from handler(request))
  File "/srv/hass/lib/python3.6/site-packages/homeassistant/components/http/__init__.py", line 430, in handle
    result = yield from result
  File "/srv/hass/lib/python3.6/site-packages/homeassistant/components/camera/__init__.py", line 333, in get
    response = yield from self.handle(request, camera)
  File "/srv/hass/lib/python3.6/site-packages/homeassistant/components/camera/__init__.py", line 353, in handle
    image = yield from camera.async_camera_image()
  File "/home/hass/.homeassistant/custom_components/camera/ring.py", line 70, in async_camera_image
    self.update()
  File "/home/hass/.homeassistant/custom_components/camera/ring.py", line 115, in update
    self._refresh_attrs()
  File "/home/hass/.homeassistant/custom_components/camera/ring.py", line 123, in _refresh_attrs
    self._video_url = self._camera.recording_url(self._last_video_id)
  File "/srv/hass/lib/python3.6/site-packages/ring_doorbell/__init__.py", line 615, in recording_url
    if req.status_code == 200:
AttributeError: 'NoneType' object has no attribute 'status_code'

Fix battery_lifetime() function

The battery_lifetime() is returning 4107 on my device. We need to check what is the pattern between other devices to make it return 0-100 values.

Fix __init__ methods

Some classes don't need a full init overload. We can refactor the code to simply it.

Displaying the last video capture URL no longer works

Attempting to display the last video capture URL as according to the documentation simply displays the following error message:

No handlers could be found for logger "ring_doorbell.doorbot"
False

I suspect that Ring has modified something on their end with the launch of their new products. Please advise.

Push Notification Token

Hi!
I'm not sure the push notification token works.. I've tried to put an url (a servlet) and I got 204 after the PUT request. However I don't receive any call to my servlet when the doorbot is ringing.

Am I missing something?

Thanks

Fix token refresh and push notifications

Reversing engineering using mitmproxy with a Ring software installed on a Windows box I had this:

2017-02-26 00:11:46 PUT https://api.ring.com/clients_api/device
204 No Content [no content] 104ms
Accept-Encoding:  gzip, deflate                                                                                                                     
X-API-LANG:       en                                                                                                                                
Content-Length:   661                                                                                                                               
Content-Type:     application/x-www-form-urlencoded; charset=UTF-8                                                                                  
Host:             api.ring.com                                                                                                                      
Connection:       Keep-Alive                                                                                                                        
Cache-Control:    no-cache                                                                                                                          
URLEncoded form                                                                                                                    
device[metadata][device_model]: Standard PC (i440FX + PIIX. 1996)
device[metadata][device_name]:  DESKTOP-R9971HI
device[metadata][resolution]:   919x822
device[metadata][app_version]:  1.3.806
device[metadata][app_instalation_date]:2017-02-10 08:17:26Z
device[metadata][manufacturer]: QEMU
device[metadata][device_type]:  desktop
device[metadata][architecture]: x64
device[metadata][language]:     en
auth_token:                     aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa__
device[push_notification_token]:https://bn2.notify.windows.com/?token=AwYAAAAnm5k98kgcotkr

Getting TypeError

value = int(self._attrs.get('battery_life'))
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'

Doesn't work with shared doorbells/Chimes

My Ring account has a doorbell that has been shared with me so I can get notifications, check the status through the app, e.t.c.
The problem lies when I ran myring.devices I expected one doorbell and a Chime to appear, unfortunately neither show up. I assume this has to do with the account having shared devices.
Just wondering if this can be addressed as an issue.
Thanks 🐈

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.