tchellomello / python-amcrest

A Python 2.7/3.x module for Amcrest and Dahua Cameras using the SDK HTTP API.
GNU General Public License v2.0
216 stars 76 forks source link

Added get_event_stream() to allow real time streaming of camera events #140

Closed NickWaterton closed 4 years ago

NickWaterton commented 4 years ago

Added a new method get_event_stream(eventcode='VideoMotion', callback, timeout)

Default eventcode is VideoMotion, this is a string and can be a comma separated list of event codes (no spaces allowed). callback is optional, and is intended for when this method is used in a Thread (the best way to use it). The method will never return (unless there is an error or timeout) if callback is given. The events (string) are passed as the first argument to callback.

timeout is optional, and is a standard requests int, float or tuple. If not given, the default connect timeout is used, and the streaming timeout is 1 year.

If no callback is given, the method will return the first eventcode string detected, if that occurs before timeout has elapsed. If timeout occurs first, None is returned (as it is for an error).

Example events look like:

Code=VideoMotion;action=Start;index=0;data={
   "RegionName" : [ "Region1", "Region2" ]
}
Code=VideoMotion|action=Stop|index=0|data={
   "RegionName" : [ "Region1", "Region2" ]
}
Code=AlarmLocal;action=Start;index=0;data={
   "EventID" : 1850153,
   "PTS" : 43326212790.0,
   "SenseMethod" : "",
   "UTC" : 1578657901.0
}

Which can be parsed in callback.

Example use:

#!/usr/bin/env python3

#Amcrest camera motion detection

from amcrest import AmcrestCamera
from threading import Thread
import time

def cb(text):
    #process events
    print(text)

camera = AmcrestCamera('192.168.100.125', 80, 'admin', 'xxxxxxxxx').camera

try:
    _events = Thread(target=camera.get_event_stream, args=('VideoMotion', cb), daemon=True)
    _events.start()
    while True:
        #do other stuff
        time.sleep(60)

except KeyboardInterrupt:
    print('exited')
coveralls commented 4 years ago

Coverage Status

Coverage decreased (-0.5%) to 31.185% when pulling a9dc42891ab02af6e3fe859c46ae62310c7f2616 on NickWaterton:master into fdbb775be57f650d47801a2a3008125e979223b1 on tchellomello:master.

pnbruckner commented 4 years ago

Thanks for the good work! I've been wanting to change HomeAssistant's amcrest integration to use this feature for its motion detection binary sensor (as opposed to polling), but never got around to it. This is a great start!

I've played around with your code a bit and I think I have some good improvement suggestions. I'll provide those as part of a review I'll start now.

pnbruckner commented 4 years ago

Also, this new method should be in event.py instead of special.py. I'm going to close this PR, but I'm going to take your great start and create a new PR. I'll give you a chance to review it before I merge it.