Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Python 3.6+ API for interacting with Logi Circle cameras, written with asyncio and aiohttp.
This library exposes the Logi Circle family of cameras as Python objects, wrapping Logi Circle's official API.
Now available as a Home Assistant integration! :tada:
There are two versions of this API:
2.x
- which targets the public API (you are here)1.x
- which targets the private API (private-api
branch)To access the public API, you must request access from Logitech. Unfortunately, it's become increasingly difficult to get API keys issued by Logitech. Initially, API key requests were turned around in a few business days. Now, the wait time is several months.
If you still want to request access, please refer to the instructions here for more information. Otherwise, please refer to the private-api
branch.
import asyncio
from logi_circle import LogiCircle
logi = LogiCircle(client_id='your-client-id',
client_secret='your-client-secret',
redirect_uri='https://your-redirect-uri',
api_key='your-api-key')
if not logi.authorized:
print('Navigate to %s and enter the authorization code passed back to your redirect URI' % (logi.authorize_url))
code = input('Code: ')
async def authorize():
await logi.authorize(code)
await logi.close()
asyncio.get_event_loop().run_until_complete(authorize())
async def get_snapshot_images():
for camera in await logi.cameras:
if camera.streaming:
await camera.live_stream.download_jpeg(filename='%s.jpg' % (camera.name),
quality=75, # JPEG compression %
refresh=False) # Don't force cameras to wake
await logi.close()
asyncio.get_event_loop().run_until_complete(get_snapshot_images())
async def get_livestream():
camera = (await logi.cameras)[0]
filename = '%s-livestream.mp4' % (camera.name)
await camera.live_stream.download_rtsp(filename=filename,
duration=30)
await logi.close()
asyncio.get_event_loop().run_until_complete(get_livestream())
async def get_latest_activity():
for camera in await logi.cameras:
last_activity = await camera.last_activity
if last_activity:
# Get activity as image
await last_activity.download_jpeg(filename='%s-last-activity.jpg' % (camera.name))
# Get activity as video
await last_activity.download_mp4(filename='%s-last-activity.mp4' % (camera.name))
await logi.close()
asyncio.get_event_loop().run_until_complete(get_latest_activity())
async def disable_streaming_all():
for camera in await logi.cameras:
if camera.streaming:
await camera.set_config(prop='streaming',
value=False)
print('%s is now off.' % (camera.name))
else:
print('%s is already off.' % (camera.name))
await logi.close()
asyncio.get_event_loop().run_until_complete(disable_streaming_all())
async def subscribe_to_events():
subscription = await logi.subscribe(['accessory_settings_changed',
"activity_created",
"activity_updated",
"activity_finished"])
while True:
await subscription.get_next_event()
asyncio.get_event_loop().run_until_complete(subscribe_to_events())
async def play_with_props():
for camera in await logi.cameras:
last_activity = await camera.get_last_activity()
print('%s: %s' % (camera.name,
('is charging' if camera.charging else 'is not charging')))
if camera.battery_level >= 0:
print('%s: %s%% battery remaining' %
(camera.name, camera.battery_level))
print('%s: Battery saving mode is %s' %
(camera.name, 'on' if camera.battery_saving else 'off'))
print('%s: Model number is %s' % (camera.name, camera.model))
print('%s: Mount is %s' % (camera.name, camera.mount))
print('%s: Signal strength is %s%% (%s)' % (
camera.name, camera.signal_strength_percentage, camera.signal_strength_category))
if last_activity:
print('%s: last activity was at %s and lasted for %s seconds.' % (
camera.name, last_activity.start_time.isoformat(), last_activity.duration.total_seconds()))
print('%s: Firmware version %s' % (camera.name, camera.firmware))
print('%s: MAC address is %s' % (camera.name, camera.mac_address))
print('%s: Microphone is %s and gain is set to %s (out of 100)' % (
camera.name, 'on' if camera.microphone else 'off', camera.microphone_gain))
print('%s: Speaker is %s and volume is set to %s (out of 100)' % (
camera.name, 'on' if camera.speaker else 'off', camera.speaker_volume))
print('%s: LED is %s' % (
camera.name, 'on' if camera.led else 'off'))
print('%s: Recording mode is %s' % (
camera.name, 'on' if camera.recording else 'off'))
await logi.close()
asyncio.get_event_loop().run_until_complete(play_with_props())
Pull requests are very welcome, every little bit helps!
git checkout -b feature/fooBar
).git commit -am 'Add some fooBar'
).tox
to confirm no test failures.git push origin feature/fooBar
).Evan Bruhn – @evanjd – evan.bruhn@gmail.com
Distributed under the MIT license. See LICENSE
for more information.
FAQs
A Python library to communicate with Logi Circle cameras
We found that logi-circle demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.