{ "info": { "author": "Evan Bruhn", "author_email": "evan.bruhn@gmail.com", "bugtrack_url": null, "classifiers": [ "Environment :: Other Environment", "Framework :: AsyncIO", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Home Automation", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "# Python Logi Circle API\n\n> Python 3.6+ API for interacting with Logi Circle cameras, written with asyncio and aiohttp.\n\n[![PyPI version](https://badge.fury.io/py/logi-circle.svg)](https://badge.fury.io/py/logi-circle)\n![License](https://img.shields.io/packagist/l/doctrine/orm.svg)\n[![Build Status][travis-badge]][travis-url]\n[![Coverage Status][coverage-badge]][coverage-url]\n[![Open Issues][open-issues-badge]][open-issues-url]\n\nThis library exposes the [Logi Circle](https://www.logitech.com/en-us/product/circle-2-home-security-camera) family of cameras as Python objects, wrapping Logi Circle's official API.\n\n[Now available as a Home Assistant integration!](https://www.home-assistant.io/components/logi_circle/) :tada:\n\n**The API this library wraps is not yet publicly available.** If you want something you can use today, check out the [v0.1 branch](https://github.com/evanjd/python-logi-circle/tree/v0.1.x). Please note that v0.1.x wraps Logitech's private API and won't be supported once the public API is released.\n\n## Features implemented\n\n- Download real-time live stream data to disk or serve to your application as a raw bytes object\n- Download any activity video to disk or serve to your application as a raw bytes object\n- Download still images from camera to disk or serve to your application as a raw bytes object\n- Query/filter the activity history by start time and/or activity properties (duration, relevance)\n- Set name, timezone, streaming mode and privacy mode of a given camera\n- On-demand polling from server to update camera properties\n- Subscribe to WebSocket API to handle camera property updates and activities pushed from API\n- Read camera properties (see \"play with props\" example)\n\n## To do\n\n- ~Update Home Assistant integration to support v0.2.x version of this library.~ PR has been raised.\n- Publish documentation on readthedocs.\n\n## Usage example\n\n#### Setup and authenticate:\n\nRequires API access from Logitech (not yet publicly available).\n\n```python\nimport asyncio\nfrom logi_circle import LogiCircle\n\nlogi = LogiCircle(client_id='your-client-id',\n client_secret='your-client-secret',\n redirect_uri='https://your-redirect-uri',\n api_key='your-api-key')\n\nif not logi.authorized:\n print('Navigate to %s and enter the authorization code passed back to your redirect URI' % (logi.authorize_url))\n code = input('Code: ')\n\n async def authorize():\n await logi.authorize(code)\n await logi.close()\n\n asyncio.get_event_loop().run_until_complete(authorize())\n```\n\n#### Grab latest still image:\n\n```python\nasync def get_snapshot_images():\n for camera in await logi.cameras:\n if camera.streaming:\n await camera.live_stream.download_jpeg(filename='%s.jpg' % (camera.name),\n quality=75, # JPEG compression %\n refresh=False) # Don't force cameras to wake\n await logi.close()\n\nasyncio.get_event_loop().run_until_complete(get_snapshot_images())\n```\n\n#### Download 30s of live stream video from 1st camera (requires ffmpeg):\n\n```python\nasync def get_livestream():\n camera = (await logi.cameras)[0]\n filename = '%s-livestream.mp4' % (camera.name)\n\n await camera.live_stream.download_rtsp(filename=filename,\n duration=30)\n\n await logi.close()\n\nasyncio.get_event_loop().run_until_complete(get_livestream())\n```\n\n#### Download latest activity for all cameras:\n\n```python\nasync def get_latest_activity():\n for camera in await logi.cameras:\n last_activity = await camera.last_activity\n if last_activity:\n # Get activity as image\n await last_activity.download_jpeg(filename='%s-last-activity.jpg' % (camera.name))\n # Get activity as video\n await last_activity.download_mp4(filename='%s-last-activity.mp4' % (camera.name))\n\n await logi.close()\n\nasyncio.get_event_loop().run_until_complete(get_latest_activity())\n```\n\n#### Turn off streaming for all cameras:\n\n```python\nasync def disable_streaming_all():\n for camera in await logi.cameras:\n if camera.streaming:\n await camera.set_config(prop='streaming',\n value=False)\n print('%s is now off.' % (camera.name))\n else:\n print('%s is already off.' % (camera.name))\n await logi.close()\n\nasyncio.get_event_loop().run_until_complete(disable_streaming_all())\n```\n\n#### Subscribe to camera events with WS API:\n\n```python\nasync def subscribe_to_events():\n subscription = await logi.subscribe(['accessory_settings_changed',\n \"activity_created\",\n \"activity_updated\",\n \"activity_finished\"])\n while True:\n await subscription.get_next_event()\n\nasyncio.get_event_loop().run_until_complete(subscribe_to_events())\n```\n\n#### Play with props:\n\n```python\nasync def play_with_props():\n for camera in await logi.cameras:\n last_activity = await camera.get_last_activity()\n print('%s: %s' % (camera.name,\n ('is charging' if camera.charging else 'is not charging')))\n if camera.battery_level >= 0:\n print('%s: %s%% battery remaining' %\n (camera.name, camera.battery_level))\n print('%s: Battery saving mode is %s' %\n (camera.name, 'on' if camera.battery_saving else 'off'))\n print('%s: Model number is %s' % (camera.name, camera.model))\n print('%s: Mount is %s' % (camera.name, camera.mount))\n print('%s: Signal strength is %s%% (%s)' % (\n camera.name, camera.signal_strength_percentage, camera.signal_strength_category))\n if last_activity:\n print('%s: last activity was at %s and lasted for %s seconds.' % (\n camera.name, last_activity.start_time.isoformat(), last_activity.duration.total_seconds()))\n print('%s: Firmware version %s' % (camera.name, camera.firmware))\n print('%s: MAC address is %s' % (camera.name, camera.mac_address))\n print('%s: Microphone is %s and gain is set to %s (out of 100)' % (\n camera.name, 'on' if camera.microphone else 'off', camera.microphone_gain))\n print('%s: Speaker is %s and volume is set to %s (out of 100)' % (\n camera.name, 'on' if camera.speaker else 'off', camera.speaker_volume))\n print('%s: LED is %s' % (\n camera.name, 'on' if camera.led else 'off'))\n print('%s: Recording mode is %s' % (\n camera.name, 'on' if camera.recording else 'off'))\n await logi.close()\n\nasyncio.get_event_loop().run_until_complete(play_with_props())\n```\n\n## Thanks\n\n- This first version of API borrowed a lot of the design and some utility functions from [tchellomello's](https://github.com/tchellomello) [Python Ring Doorbell](https://github.com/tchellomello/python-ring-doorbell) project. It made a great template for how to implement a project like this, so thanks!\n- Thanks [sergeymaysak](https://github.com/sergeymaysak) for suggesting a switch to aiohttp, it made integrating with Home Assistant much easier.\n- Logitech for reaching out and providing support to reimplement this library using their official API.\n\n## Contributing\n\nPull requests are very welcome, every little bit helps!\n\n1. Raise an issue with your feature request or bug before starting work.\n2. Fork it ().\n3. Create your feature branch (`git checkout -b feature/fooBar`).\n4. Commit your changes (`git commit -am 'Add some fooBar'`).\n5. Add/update tests if needed, then run `tox` to confirm no test failures.\n6. Push to the branch (`git push origin feature/fooBar`).\n7. Create a new pull request!\n\n## Meta\n\nEvan Bruhn \u2013 [@evanjd](https://github.com/evanjd) \u2013 evan.bruhn@gmail.com\n\nDistributed under the MIT license. See `LICENSE` for more information.\n\n\n\n[open-issues-badge]: https://img.shields.io/github/issues/evanjd/python-logi-circle.svg\n[open-issues-url]: https://github.com/evanjd/python-logi-circle/issues\n[travis-badge]: https://travis-ci.com/evanjd/python-logi-circle.svg?branch=master\n[travis-url]: https://travis-ci.com/evanjd/python-logi-circle\n[coverage-badge]: https://img.shields.io/coveralls/github/evanjd/python-logi-circle/master.svg\n[coverage-url]: https://coveralls.io/github/evanjd/python-logi-circle?branch=master", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/evanjd/python-logi-circle", "keywords": "logi,logi circle,logitechhome automation", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "logi-circle", "package_url": "https://pypi.org/project/logi-circle/", "platform": "", "project_url": "https://pypi.org/project/logi-circle/", "project_urls": { "Homepage": "https://github.com/evanjd/python-logi-circle" }, "release_url": "https://pypi.org/project/logi-circle/0.2.2/", "requires_dist": null, "requires_python": "", "summary": "A Python library to communicate with Logi Circle cameras", "version": "0.2.2" }, "last_serial": 4749630, "releases": { "0.1.1": [ { "comment_text": "", "digests": { "md5": "f4f1d51e12209e760f3ee624c22b738c", "sha256": "d0f8d26f9e64d0c2e9d2460f7e929c639b86fa38d999ce51e59aa3bd1b66720b" }, "downloads": -1, "filename": "logi_circle-0.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "f4f1d51e12209e760f3ee624c22b738c", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 16190, "upload_time": "2018-08-21T10:57:05", "url": "https://files.pythonhosted.org/packages/97/ee/0b60c249fff13824f4c1ae9d36d9f0b561f55f8a04be15827b6313f9c459/logi_circle-0.1.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "468ff8287bf24ddb151f30dafe83592b", "sha256": "d5985d9d9b2928dc89fd8b75f541e6f0f6dd7781570bd669739305cc00681fc9" }, "downloads": -1, "filename": "logi_circle-0.1.1.tar.gz", "has_sig": false, "md5_digest": "468ff8287bf24ddb151f30dafe83592b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17064, "upload_time": "2018-08-21T10:57:07", "url": "https://files.pythonhosted.org/packages/08/3c/15102a547270097da665770ddfd32e80f2f3a46c6563c4a995d34db38e83/logi_circle-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "e51389727609116693f6fee30e62e3e3", "sha256": "749789b7ca0d51dd15b8956009b126dc1de5f7dc9bc0ceb11ca9bdf56f929dd6" }, "downloads": -1, "filename": "logi_circle-0.1.2-py3-none-any.whl", "has_sig": false, "md5_digest": "e51389727609116693f6fee30e62e3e3", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 16838, "upload_time": "2018-08-25T11:16:41", "url": "https://files.pythonhosted.org/packages/5e/c1/7bcfaced81e6e9758d7fd56b958f232f540121ca4e9ad166356347c06db2/logi_circle-0.1.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "643200bfe747af4bfe8476a231ce2aa3", "sha256": "3fb9cc6e7907d443160f6cf384e92146db58cfe2fdfc66075dda08fd29b6fd73" }, "downloads": -1, "filename": "logi_circle-0.1.2.tar.gz", "has_sig": false, "md5_digest": "643200bfe747af4bfe8476a231ce2aa3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17842, "upload_time": "2018-08-25T11:16:44", "url": "https://files.pythonhosted.org/packages/5a/41/c733193f203c984c32fce5788a2c45130e4741f2f8d8c4ecad100e13df8c/logi_circle-0.1.2.tar.gz" } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "9eed3d5c6d84d9bea071f6d007c1c275", "sha256": "cb222afb475e64474c0ef7d60bca74d2996ed5d79190069b69537a7dfb008274" }, "downloads": -1, "filename": "logi_circle-0.1.3-py3-none-any.whl", "has_sig": false, "md5_digest": "9eed3d5c6d84d9bea071f6d007c1c275", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 17147, "upload_time": "2018-09-01T10:58:48", "url": "https://files.pythonhosted.org/packages/03/54/44bba006e58d59bfec20e03591df4450fd505ece80257bef02ba464b3e98/logi_circle-0.1.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "bccf1d195034ab04a33a5f9e561f34eb", "sha256": "54a588928ee34c9cdbb31fd0c5eb5a4093c5ebdb35b8bd978085b986adfb81a4" }, "downloads": -1, "filename": "logi_circle-0.1.3.tar.gz", "has_sig": false, "md5_digest": "bccf1d195034ab04a33a5f9e561f34eb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18162, "upload_time": "2018-09-01T10:58:51", "url": "https://files.pythonhosted.org/packages/92/d9/6b95e9754263156474f3febd0566018f9367a715baa0e1cac1593e866c3e/logi_circle-0.1.3.tar.gz" } ], "0.1.4": [ { "comment_text": "", "digests": { "md5": "76e29f481280a7596aeb6ae3547ff8e4", "sha256": "2472449bbc4c066e2f36b2393d100de90f7f7ae5eb5d385670003b9571f517c5" }, "downloads": -1, "filename": "logi_circle-0.1.4-py3-none-any.whl", "has_sig": false, "md5_digest": "76e29f481280a7596aeb6ae3547ff8e4", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 17173, "upload_time": "2018-09-01T21:55:07", "url": "https://files.pythonhosted.org/packages/e8/91/521b7bd3689cbcc3c40f76ebb78ec402a348c5ecf4dfc9e4f339896e7cb5/logi_circle-0.1.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1e0068bf5ce8f48ea3e16e0366a19b29", "sha256": "43924f6ebba1e2876a3a3eebea00e4401f7277802456451d86cb4f693e2af9c0" }, "downloads": -1, "filename": "logi_circle-0.1.4.tar.gz", "has_sig": false, "md5_digest": "1e0068bf5ce8f48ea3e16e0366a19b29", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18209, "upload_time": "2018-09-01T21:55:11", "url": "https://files.pythonhosted.org/packages/15/45/1fd255c169f008d5f5502a4425709caf2eddcada163d3bbeea8ad0ff7f07/logi_circle-0.1.4.tar.gz" } ], "0.1.5": [ { "comment_text": "", "digests": { "md5": "df91a7a9fc1ba94edac9681757535a99", "sha256": "b5137527843cde1795172ca067aae0870e09e706148b36073165ab4c542e2963" }, "downloads": -1, "filename": "logi_circle-0.1.5-py3-none-any.whl", "has_sig": false, "md5_digest": "df91a7a9fc1ba94edac9681757535a99", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 18898, "upload_time": "2018-09-07T03:36:29", "url": "https://files.pythonhosted.org/packages/45/b7/ef36611bf82328a5bb34869b7f93e13820a17d49c4a4a9ae3d74a1cc1e29/logi_circle-0.1.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0a025be7b31ad876ca6b3b78783c477c", "sha256": "5c29d12f98be10e012bbe49258b9328eca2318afdb8ae78e985d81bedddae0b5" }, "downloads": -1, "filename": "logi_circle-0.1.5.tar.gz", "has_sig": false, "md5_digest": "0a025be7b31ad876ca6b3b78783c477c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19887, "upload_time": "2018-09-07T03:36:33", "url": "https://files.pythonhosted.org/packages/59/14/b38481a4fc66ad57675631cfc6cc0708621b1ed3113b88823394e540bb2a/logi_circle-0.1.5.tar.gz" } ], "0.1.6": [ { "comment_text": "", "digests": { "md5": "ce8fda6605806e946ff4ad85bb3b05df", "sha256": "3f46f9624f745f568139d59483920548e01808e9b83c1c3b231f0fd3061df7c3" }, "downloads": -1, "filename": "logi_circle-0.1.6-py3-none-any.whl", "has_sig": false, "md5_digest": "ce8fda6605806e946ff4ad85bb3b05df", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 19186, "upload_time": "2018-09-10T10:52:53", "url": "https://files.pythonhosted.org/packages/52/fc/6b8e76c1135e80e698fd055f015d712cc33729ba425f8fdaa7f99388964b/logi_circle-0.1.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "d09890258a08518cdd28fefe624cf338", "sha256": "f5e0cd47a2dedbf871476dea5312886c9706c2cfb255f69bb0bae1cfc14a117a" }, "downloads": -1, "filename": "logi_circle-0.1.6.tar.gz", "has_sig": false, "md5_digest": "d09890258a08518cdd28fefe624cf338", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20311, "upload_time": "2018-09-10T10:52:58", "url": "https://files.pythonhosted.org/packages/fc/3f/281d981fa9a16db179667234859315af4a71c9e763aa2d2bb401b9be29a7/logi_circle-0.1.6.tar.gz" } ], "0.1.7": [ { "comment_text": "", "digests": { "md5": "143c77c8785f399f8642ce74f8208fdf", "sha256": "e5b6a4d5b802481460efb82c75a4d27bdf420d4caec793a97127b48316a7cbce" }, "downloads": -1, "filename": "logi_circle-0.1.7-py3-none-any.whl", "has_sig": false, "md5_digest": "143c77c8785f399f8642ce74f8208fdf", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 19448, "upload_time": "2018-09-10T11:27:48", "url": "https://files.pythonhosted.org/packages/33/93/e18767ed39be68a5cd65c99505857a065fc844a50e02883b4bb1cc4f8566/logi_circle-0.1.7-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "97ee56164b85455e0d683a442998afe0", "sha256": "2fe6394db01646d65e68c0d3138d1a8c036da786f01d712f7c185e40d2019187" }, "downloads": -1, "filename": "logi_circle-0.1.7.tar.gz", "has_sig": false, "md5_digest": "97ee56164b85455e0d683a442998afe0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20571, "upload_time": "2018-09-10T11:27:53", "url": "https://files.pythonhosted.org/packages/fd/2f/2748a75b856f40be907f1b40ae31facd578687cd4027fe507ca3d0cc4878/logi_circle-0.1.7.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "8ee81cb82985396b1ede460e38ab7a8d", "sha256": "c0f0507f5e2914b09ecca90d5de51e57ba0268da0ac394378e3ce2d7fbe94aad" }, "downloads": -1, "filename": "logi_circle-0.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "8ee81cb82985396b1ede460e38ab7a8d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 19166, "upload_time": "2019-01-17T02:04:32", "url": "https://files.pythonhosted.org/packages/2b/c7/52d008e1c3379611e8257413b46ff9b6d88a33b65eb6072a9ca231b1e30d/logi_circle-0.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1eb3e50d3a3b9d3a328d4938e479e61a", "sha256": "0b74647d84684b4f4581cd28277beb6a35921d84eafa711a5099aeb933d0a474" }, "downloads": -1, "filename": "logi_circle-0.2.0.tar.gz", "has_sig": false, "md5_digest": "1eb3e50d3a3b9d3a328d4938e479e61a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17731, "upload_time": "2019-01-17T02:04:40", "url": "https://files.pythonhosted.org/packages/80/66/ba799306a052c2b91bec9c4165caa520c23921aae75d052d7445f7c377c0/logi_circle-0.2.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "8b5e8d978808c65453066ab21ca6d0c6", "sha256": "5cf730961d10d29e1f47defd47ced68e647f9a13dcb981b6ebce3ed551bdb3f4" }, "downloads": -1, "filename": "logi_circle-0.2.1.tar.gz", "has_sig": false, "md5_digest": "8b5e8d978808c65453066ab21ca6d0c6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17997, "upload_time": "2019-01-28T00:04:09", "url": "https://files.pythonhosted.org/packages/de/7f/ae4ec276eff59daf0f7240c3b26f1efefdd407a9b733b867c0cb623a6b33/logi_circle-0.2.1.tar.gz" } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "3f03671f211d9b0025aec45fece2c079", "sha256": "7e6e25f3d1cefd17ed0e6d0fdcf4eee61f5fa24772b6e601d981a6b5270a74f1" }, "downloads": -1, "filename": "logi_circle-0.2.2.tar.gz", "has_sig": false, "md5_digest": "3f03671f211d9b0025aec45fece2c079", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18042, "upload_time": "2019-01-28T10:54:14", "url": "https://files.pythonhosted.org/packages/80/73/1e515bcb768a9d28a19458c94725d04bc706b87daa125db73d4ae16b6b41/logi_circle-0.2.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "3f03671f211d9b0025aec45fece2c079", "sha256": "7e6e25f3d1cefd17ed0e6d0fdcf4eee61f5fa24772b6e601d981a6b5270a74f1" }, "downloads": -1, "filename": "logi_circle-0.2.2.tar.gz", "has_sig": false, "md5_digest": "3f03671f211d9b0025aec45fece2c079", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18042, "upload_time": "2019-01-28T10:54:14", "url": "https://files.pythonhosted.org/packages/80/73/1e515bcb768a9d28a19458c94725d04bc706b87daa125db73d4ae16b6b41/logi_circle-0.2.2.tar.gz" } ] }