starkillerOG / reolink_aio

Reolink NVR/camera API PyPI package
MIT License
65 stars 13 forks source link

Add ONVIF subscription example #52

Closed nicolasbrailo closed 7 months ago

nicolasbrailo commented 8 months ago

To test what how a camera was behaving, I found useful to have the ability to dump onvif messages to a console. This PR

  1. extracts into a helper function the logic needed to parse Reolink onvif subscription messages
  2. Creates an example showing how to dump said messages to stdout

The top of the PR integrates the helper function back to the main API, however that's not quite ready to be merged: I have no idea how to test that bit, so I haven't :)

starkillerOG commented 8 months ago

@nicolasbrailo First of all, thank you for your contribution and wanting to help out!

Could you please seperate PRs to only make a single change: So a seperate PR to add the examples and a seperate PR to changes to the api.py or helpers.py files (if needed).

Moreover if at all possible I would like to keep the ONVIF_event_callback function unchanged since that has been extensively tested. So please first explain why a change would be needed there.

Regarding the example, would it be possible to combine both python scripts into 1:

I think it would also be nice if we could use the aiohttp web instead of flask, than we do not have to install any aditional dependency besides reolink_aio for the example to work.

starkillerOG commented 8 months ago

Maybe you will find this example of ONVIF long polling usefull too:

import logging
import asyncio
from reolink_aio import api
from datetime import datetime, timedelta

_LOGGER = logging.getLogger(__name__)
logging.basicConfig(level="DEBUG")

IP = '192.168.1.100'
username = 'admin'
password = 'PASSWORD'

async def poll_demo(host):
    start = datetime.now()
    while True:
        try:
            await host.pull_point_request()
        except Exception as err:
            _LOGGER.exception(err)
            pass
        if datetime.now() - start > timedelta(minutes=5):
            break

async def asyncio_demo(loop):
    host = api.Host(host=IP, username=username, password=password)

    await host.get_host_data()
    await host.get_states()

    await host.subscribe(sub_type = api.SubType.long_poll)
    task = asyncio.create_task(poll_demo(host))
    await asyncio.sleep(90)
    await host.renew(api.SubType.long_poll)
    await asyncio.sleep(90)
    task.cancel()
    await host.unsubscribe(api.SubType.long_poll)

    await host.logout()

if __name__ == "__main__":
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    loop.run_until_complete(asyncio_demo(loop))

I really schould write some proper documentation some day....

nicolasbrailo commented 7 months ago

@starkillerOG

Could you please seperate PRs to only make a single change:

Sure. Created a couple of PRs, I'll close this one and we can followup on the new ones.