=====================
Python Ring Door Bell
=====================
.. image:: https://badge.fury.io/py/ring-doorbell.svg
:alt: PyPI Version
:target: https://badge.fury.io/py/ring-doorbell
.. image:: https://github.com/tchellomello/python-ring-doorbell/actions/workflows/ci.yml/badge.svg?branch=master
:alt: Build Status
:target: https://github.com/tchellomello/python-ring-doorbell/actions/workflows/ci.yml?branch=master
.. image:: https://coveralls.io/repos/github/tchellomello/python-ring-doorbell/badge.svg?branch=master
:alt: Coverage
:target: https://coveralls.io/github/tchellomello/python-ring-doorbell?branch=master
.. image:: https://readthedocs.org/projects/python-ring-doorbell/badge/?version=latest
:alt: Documentation Status
:target: https://python-ring-doorbell.readthedocs.io/?badge=latest
.. image:: https://img.shields.io/pypi/pyversions/ring-doorbell.svg
:alt: Py Versions
:target: https://pypi.python.org/pypi/ring-doorbell
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 <https://python-ring-doorbell.readthedocs.io/contributing.html>`_.
*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/ <http://python-ring-doorbell.readthedocs.io/>`_
Installation
------------
.. code-block:: bash
# 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 <https://docs.python.org/3/library/asyncio.html>`_ 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
#. List your device names (with device kind)::
$ ring-doorbell list
#. Either count or download your vidoes or both::
$ ring-doorbell videos --count --download-all
#. Enable disable motion detection::
$ ring-doorbell motion-detection --device-name "DEVICENAME" --on
$ ring-doorbell motion-detection --device-name "DEVICENAME" --off
#. Listen for push notifications like the ones sent to your phone::
$ ring-doorbell listen
#. List your ring groups::
$ ring-doorbell groups
#. Show your ding history::
$ ring-doorbell history --device-name "Front Door"
#. Show your currently active dings::
$ ring-doorbell dings
#. Query a ring api url directly::
$ ring-doorbell raw-query --url /clients_api/dings/active
#. Run ``ring-doorbell --help`` or ``ring-doorbell videos --help`` for full options
Initializing your Ring object
-----------------------------
.. code-block:: python
import getpass
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
def do_auth():
username = input("Username: ")
password = getpass.getpass("Password: ")
auth = Auth(user_agent, None, token_updated)
try:
auth.fetch_token(username, password)
except Requires2FAError:
auth.fetch_token(username, password, otp_callback())
return auth
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:
ring.create_session() # auth token still valid
except AuthenticationError: # auth token has expired
auth = do_auth()
else:
auth = do_auth() # Get new auth token
ring = Ring(auth)
ring.update_data()
devices = ring.devices()
print(devices)
if __name__ == "__main__":
main()
Listing devices linked to your account
--------------------------------------
.. code-block:: python
# 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
-----------------------------------------
.. code-block:: python
devices = ring.devices()
for dev in list(devices['stickup_cams'] + devices['chimes'] + devices['doorbots']):
dev.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)
dev.volume = 5
print('Volume: %s' % dev.volume)
# play dev test shound
if dev.family == 'chimes':
dev.test_sound(kind = 'ding')
dev.test_sound(kind = 'motion')
# turn on lights on floodlight cam
if dev.family == 'stickup_cams' and dev.lights:
dev.lights = 'on'
Showing door bell events
------------------------
.. code-block:: python
devices = ring.devices()
for doorbell in devices['doorbots']:
# listing the last 15 events of any kind
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)
# get a event list only the triggered by motion
events = doorbell.history(kind='motion')
Downloading the last video triggered by a ding or motion event
--------------------------------------------------------------
.. code-block:: python
devices = ring.devices()
doorbell = devices['doorbots'][0]
doorbell.recording_download(
doorbell.history(limit=100, kind='ding')[0]['id'],
filename='last_ding.mp4',
override=True)
Displaying the last video capture URL
-------------------------------------
.. code-block:: python
print(doorbell.recording_url(doorbell.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
-------------------------
.. code-block:: python
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
group.lights = True
# Turn off lights
group.lights = False
# Turn on lights for 30 seconds
group.lights = (True, 30)
How to contribute
-----------------
See our `Contributing Page <https://python-ring-doorbell.readthedocs.io/contributing.html>`_.
Credits && Thanks
-----------------
* This project was inspired and based on https://github.com/jeroenmoors/php-ring-api. Many thanks @jeroenmoors.
* A guy named MadBagger at Prism19 for his initial research (http://www.prism19.com/doorbot/second-pass-and-comm-reversing/)
* The creators of mitmproxy (https://mitmproxy.org/) great http and https traffic inspector
* @mfussenegger for his post on mitmproxy and virtualbox https://zignar.net/2015/12/31/sniffing-vbox-traffic-mitmproxy/
* To the project http://www.android-x86.org/ which allowed me to install Android on KVM.
* Many thanks to Carles Pina I Estany <carles@pina.cat> for creating the python-ring-doorbell Debian Package (https://tracker.debian.org/pkg/python-ring-doorbell).
Raw data
{
"_id": null,
"home_page": "https://github.com/tchellomello/python-ring-doorbell",
"name": "ring-doorbell",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.8",
"maintainer_email": null,
"keywords": "ring, door bell, camera, home automation",
"author": "Marcelo Moreira de Mello",
"author_email": "tchello.mello@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/62/05/84d19256ee5a23b54cdcd77f2893aabd3c6ee4f951ecf4b889c6fabf98c3/ring_doorbell-0.8.11.tar.gz",
"platform": null,
"description": "=====================\nPython Ring Door Bell\n=====================\n\n.. image:: https://badge.fury.io/py/ring-doorbell.svg\n :alt: PyPI Version\n :target: https://badge.fury.io/py/ring-doorbell\n\n.. image:: https://github.com/tchellomello/python-ring-doorbell/actions/workflows/ci.yml/badge.svg?branch=master\n :alt: Build Status\n :target: https://github.com/tchellomello/python-ring-doorbell/actions/workflows/ci.yml?branch=master\n\n.. image:: https://coveralls.io/repos/github/tchellomello/python-ring-doorbell/badge.svg?branch=master\n :alt: Coverage\n :target: https://coveralls.io/github/tchellomello/python-ring-doorbell?branch=master\n\n.. image:: https://readthedocs.org/projects/python-ring-doorbell/badge/?version=latest\n :alt: Documentation Status\n :target: https://python-ring-doorbell.readthedocs.io/?badge=latest\n\n.. image:: https://img.shields.io/pypi/pyversions/ring-doorbell.svg\n :alt: Py Versions\n :target: https://pypi.python.org/pypi/ring-doorbell\n\n\nPython Ring Door Bell is a library written for Python 3.8+\nthat exposes the Ring.com devices as Python objects.\n\nThere is also a command line interface that is work in progress. `Contributors welcome <https://python-ring-doorbell.readthedocs.io/contributing.html>`_.\n\n*Currently Ring.com does not provide an official API. The results of this project are merely from reverse engineering.*\n\nDocumentation: `http://python-ring-doorbell.readthedocs.io/ <http://python-ring-doorbell.readthedocs.io/>`_\n\n\nInstallation\n------------\n\n.. code-block:: bash\n\n # Installing from PyPi\n $ pip install ring_doorbell\n\n # Installing latest development\n $ pip install \\\n git+https://github.com/tchellomello/python-ring-doorbell@master\n\nEvent Listener\n++++++++++++++\n\nIf you want the ring api to listen for push events from ring.com for dings and motion you\nwill need to install with the `listen` extra::\n\n $ pip install ring_doorbell[listen]\n\nThe api will then start listening for push events after you have first called `update_dings()` \nor `update_data()` but only if there is a running `asyncio <https://docs.python.org/3/library/asyncio.html>`_ event loop (which there will be if using the CLI)\n\nUsing the CLI\n-------------\n\nThe CLI is work in progress and currently has the following commands:\n\n1. Show your devices::\n \n $ ring-doorbell\n\n Or::\n\n $ ring-doorbell show\n\n#. List your device names (with device kind)::\n \n $ ring-doorbell list\n\n#. Either count or download your vidoes or both::\n\n $ ring-doorbell videos --count --download-all\n\n#. Enable disable motion detection::\n\n $ ring-doorbell motion-detection --device-name \"DEVICENAME\" --on\n $ ring-doorbell motion-detection --device-name \"DEVICENAME\" --off\n\n#. Listen for push notifications like the ones sent to your phone::\n\n $ ring-doorbell listen\n\n#. List your ring groups::\n\n $ ring-doorbell groups\n\n#. Show your ding history::\n\n $ ring-doorbell history --device-name \"Front Door\"\n\n#. Show your currently active dings::\n\n $ ring-doorbell dings\n\n#. Query a ring api url directly::\n\n $ ring-doorbell raw-query --url /clients_api/dings/active\n\n#. Run ``ring-doorbell --help`` or ``ring-doorbell videos --help`` for full options\n\nInitializing your Ring object\n-----------------------------\n\n.. code-block:: python\n\n import getpass\n import json\n from pathlib import Path\n\n from ring_doorbell import Auth, AuthenticationError, Requires2FAError, Ring\n\n user_agent = \"YourProjectName-1.0\" # Change this\n cache_file = Path(user_agent + \".token.cache\")\n\n\n def token_updated(token):\n cache_file.write_text(json.dumps(token))\n\n\n def otp_callback():\n auth_code = input(\"2FA code: \")\n return auth_code\n\n\n def do_auth():\n username = input(\"Username: \")\n password = getpass.getpass(\"Password: \")\n auth = Auth(user_agent, None, token_updated)\n try:\n auth.fetch_token(username, password)\n except Requires2FAError:\n auth.fetch_token(username, password, otp_callback())\n return auth\n\n\n def main():\n if cache_file.is_file(): # auth token is cached\n auth = Auth(user_agent, json.loads(cache_file.read_text()), token_updated)\n ring = Ring(auth)\n try:\n ring.create_session() # auth token still valid\n except AuthenticationError: # auth token has expired\n auth = do_auth()\n else:\n auth = do_auth() # Get new auth token\n ring = Ring(auth)\n\n ring.update_data()\n\n devices = ring.devices()\n print(devices)\n\n\n if __name__ == \"__main__\":\n main()\n\n\nListing devices linked to your account\n--------------------------------------\n\n.. code-block:: python\n\n # All devices\n devices = ring.devices()\n {'chimes': [<RingChime: Downstairs>],\n 'doorbots': [<RingDoorBell: Front Door>]}\n\n # All doorbells\n doorbells = devices['doorbots']\n [<RingDoorBell: Front Door>]\n\n # All chimes\n chimes = devices['chimes']\n [<RingChime: Downstairs>]\n\n # All stickup cams\n stickup_cams = devices['stickup_cams']\n [<RingStickUpCam: Driveway>]\n\nPlaying with the attributes and functions\n-----------------------------------------\n.. code-block:: python\n\n devices = ring.devices()\n for dev in list(devices['stickup_cams'] + devices['chimes'] + devices['doorbots']):\n dev.update_health_data()\n print('Address: %s' % dev.address)\n print('Family: %s' % dev.family)\n print('ID: %s' % dev.id)\n print('Name: %s' % dev.name)\n print('Timezone: %s' % dev.timezone)\n print('Wifi Name: %s' % dev.wifi_name)\n print('Wifi RSSI: %s' % dev.wifi_signal_strength)\n\n # setting dev volume\n print('Volume: %s' % dev.volume)\n dev.volume = 5\n print('Volume: %s' % dev.volume)\n\n # play dev test shound\n if dev.family == 'chimes':\n dev.test_sound(kind = 'ding')\n dev.test_sound(kind = 'motion')\n\n # turn on lights on floodlight cam\n if dev.family == 'stickup_cams' and dev.lights:\n dev.lights = 'on'\n\n\nShowing door bell events\n------------------------\n.. code-block:: python\n\n devices = ring.devices()\n for doorbell in devices['doorbots']:\n\n # listing the last 15 events of any kind\n for event in doorbell.history(limit=15):\n print('ID: %s' % event['id'])\n print('Kind: %s' % event['kind'])\n print('Answered: %s' % event['answered'])\n print('When: %s' % event['created_at'])\n print('--' * 50)\n\n # get a event list only the triggered by motion\n events = doorbell.history(kind='motion')\n\n\nDownloading the last video triggered by a ding or motion event\n--------------------------------------------------------------\n.. code-block:: python\n\n devices = ring.devices()\n doorbell = devices['doorbots'][0]\n doorbell.recording_download(\n doorbell.history(limit=100, kind='ding')[0]['id'],\n filename='last_ding.mp4',\n override=True)\n\n\nDisplaying the last video capture URL\n-------------------------------------\n.. code-block:: python\n\n print(doorbell.recording_url(doorbell.last_recording_id))\n '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'\n\nControlling a Light Group\n-------------------------\n.. code-block:: python\n\n groups = ring.groups()\n group = groups['the-group-you-want']\n\n print(group.lights)\n # Prints True if lights are on, False if off\n\n # Turn on lights indefinitely\n group.lights = True\n\n # Turn off lights\n group.lights = False\n\n # Turn on lights for 30 seconds\n group.lights = (True, 30)\n\nHow to contribute\n-----------------\nSee our `Contributing Page <https://python-ring-doorbell.readthedocs.io/contributing.html>`_.\n\n\nCredits && Thanks\n-----------------\n\n* This project was inspired and based on https://github.com/jeroenmoors/php-ring-api. Many thanks @jeroenmoors.\n* A guy named MadBagger at Prism19 for his initial research (http://www.prism19.com/doorbot/second-pass-and-comm-reversing/)\n* The creators of mitmproxy (https://mitmproxy.org/) great http and https traffic inspector\n* @mfussenegger for his post on mitmproxy and virtualbox https://zignar.net/2015/12/31/sniffing-vbox-traffic-mitmproxy/\n* To the project http://www.android-x86.org/ which allowed me to install Android on KVM.\n* Many thanks to Carles Pina I Estany <carles@pina.cat> for creating the python-ring-doorbell Debian Package (https://tracker.debian.org/pkg/python-ring-doorbell). \n",
"bugtrack_url": null,
"license": "LGPLv3+",
"summary": "A Python library to communicate with Ring Door Bell (https://ring.com/)",
"version": "0.8.11",
"project_urls": {
"Bug Tracker": "https://github.com/tchellomello/python-ring-doorbell/issues",
"Documentation": "http://python-ring-doorbell.readthedocs.io/",
"Homepage": "https://github.com/tchellomello/python-ring-doorbell",
"Repository": "https://github.com/tchellomello/python-ring-doorbell"
},
"split_keywords": [
"ring",
" door bell",
" camera",
" home automation"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "1d6dd48efcfe8b580bbdc3c78a8da2e1545f670c954bc46007eab367ec172657",
"md5": "3a85b99ebff11cba2431c14675ee672c",
"sha256": "01c486e8d7ab02175332a812d2e6fc243f0ee319b027d2aa14e0bdd4dce0d063"
},
"downloads": -1,
"filename": "ring_doorbell-0.8.11-py3-none-any.whl",
"has_sig": false,
"md5_digest": "3a85b99ebff11cba2431c14675ee672c",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.8",
"size": 43032,
"upload_time": "2024-04-09T06:18:10",
"upload_time_iso_8601": "2024-04-09T06:18:10.207138Z",
"url": "https://files.pythonhosted.org/packages/1d/6d/d48efcfe8b580bbdc3c78a8da2e1545f670c954bc46007eab367ec172657/ring_doorbell-0.8.11-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "620584d19256ee5a23b54cdcd77f2893aabd3c6ee4f951ecf4b889c6fabf98c3",
"md5": "5c1f6917295e8b1c37201eec1f8e4f5f",
"sha256": "5f28157c87face52b2da4bfff5328b1bc329617e189f36082a2486ee73f9608f"
},
"downloads": -1,
"filename": "ring_doorbell-0.8.11.tar.gz",
"has_sig": false,
"md5_digest": "5c1f6917295e8b1c37201eec1f8e4f5f",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.8",
"size": 49990,
"upload_time": "2024-04-09T06:18:12",
"upload_time_iso_8601": "2024-04-09T06:18:12.243694Z",
"url": "https://files.pythonhosted.org/packages/62/05/84d19256ee5a23b54cdcd77f2893aabd3c6ee4f951ecf4b889c6fabf98c3/ring_doorbell-0.8.11.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-04-09 06:18:12",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "tchellomello",
"github_project": "python-ring-doorbell",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"tox": true,
"lcname": "ring-doorbell"
}