Compare commits
11 Commits
5f3b6f9a5b
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 37b929fcbe | |||
|
|
f15171147b | ||
|
|
7999ce8108 | ||
|
|
59945861b0 | ||
|
|
a61e86cfa4 | ||
|
|
77eaff9edf | ||
|
|
23209f47f4 | ||
|
|
37dd49f936 | ||
|
|
d59cefff52 | ||
|
|
8b6049bb26 | ||
|
|
936c43b6fa |
@@ -149,6 +149,7 @@ do not work and is not supported here.
|
|||||||
- RLC-423
|
- RLC-423
|
||||||
- RLC-420-5MP
|
- RLC-420-5MP
|
||||||
- RLC-410-5MP
|
- RLC-410-5MP
|
||||||
|
- RLC-510A
|
||||||
- RLC-520
|
- RLC-520
|
||||||
- C1-Pro
|
- C1-Pro
|
||||||
- D400
|
- D400
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from reolinkapi.handlers.api_handler import APIHandler
|
from reolinkapi.handlers.api_handler import APIHandler
|
||||||
from .camera import Camera
|
from .camera import Camera
|
||||||
|
|
||||||
__version__ = "0.1.3"
|
__version__ = "0.1.5"
|
||||||
|
|||||||
@@ -2,12 +2,27 @@ from reolinkapi.handlers.api_handler import APIHandler
|
|||||||
|
|
||||||
|
|
||||||
class Camera(APIHandler):
|
class Camera(APIHandler):
|
||||||
|
def __exit__(self):
|
||||||
|
if self._token is not None:
|
||||||
|
print('Logging out')
|
||||||
|
self.logout()
|
||||||
|
else:
|
||||||
|
print('not logged in, logging out')
|
||||||
|
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
if self._token is not None:
|
||||||
|
print('Logging out')
|
||||||
|
self.logout()
|
||||||
|
else:
|
||||||
|
print('not logged in, logging out')
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, ip: str,
|
def __init__(self, ip: str,
|
||||||
username: str = "admin",
|
username: str = "admin",
|
||||||
password: str = "",
|
password: str = "",
|
||||||
https: bool = False,
|
https: bool = False,
|
||||||
defer_login: bool = False,
|
defer_login: bool = True,
|
||||||
profile: str = "main",
|
profile: str = "main",
|
||||||
**kwargs):
|
**kwargs):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -52,11 +52,28 @@ class APIHandler(AlarmAPIMixin,
|
|||||||
scheme = 'https' if https else 'http'
|
scheme = 'https' if https else 'http'
|
||||||
self.url = f"{scheme}://{ip}/cgi-bin/api.cgi"
|
self.url = f"{scheme}://{ip}/cgi-bin/api.cgi"
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
self.token = None
|
self._token = None
|
||||||
self.username = username
|
self.username = username
|
||||||
self.password = password
|
self.password = password
|
||||||
Request.proxies = kwargs.get("proxy") # Defaults to None if key isn't found
|
Request.proxies = kwargs.get("proxy") # Defaults to None if key isn't found
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
if name == 'token':
|
||||||
|
if self._token is None:
|
||||||
|
self.login()
|
||||||
|
return self._token
|
||||||
|
|
||||||
|
else:
|
||||||
|
return getattr(self, name)
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
if self._token is not None:
|
||||||
|
print('Logging out')
|
||||||
|
self.logout()
|
||||||
|
else:
|
||||||
|
print('not logged in, logging out')
|
||||||
|
|
||||||
|
|
||||||
def login(self) -> bool:
|
def login(self) -> bool:
|
||||||
"""
|
"""
|
||||||
Get login token
|
Get login token
|
||||||
@@ -72,7 +89,7 @@ class APIHandler(AlarmAPIMixin,
|
|||||||
data = response.json()[0]
|
data = response.json()[0]
|
||||||
code = data["code"]
|
code = data["code"]
|
||||||
if int(code) == 0:
|
if int(code) == 0:
|
||||||
self.token = data["value"]["Token"]["name"]
|
self._token = data["value"]["Token"]["name"]
|
||||||
print("Login success")
|
print("Login success")
|
||||||
return True
|
return True
|
||||||
print(self.token)
|
print(self.token)
|
||||||
@@ -95,6 +112,7 @@ class APIHandler(AlarmAPIMixin,
|
|||||||
try:
|
try:
|
||||||
data = [{"cmd": "Logout", "action": 0}]
|
data = [{"cmd": "Logout", "action": 0}]
|
||||||
self._execute_command('Logout', data)
|
self._execute_command('Logout', data)
|
||||||
|
self._token = None
|
||||||
# print(ret)
|
# print(ret)
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -124,7 +142,7 @@ class APIHandler(AlarmAPIMixin,
|
|||||||
tgt_filepath = data[0].pop('filepath')
|
tgt_filepath = data[0].pop('filepath')
|
||||||
# Apply the data to the params
|
# Apply the data to the params
|
||||||
params.update(data[0])
|
params.update(data[0])
|
||||||
with requests.get(self.url, params=params, stream=True, verify=False, timeout=(1, None)) as req:
|
with requests.get(self.url, params=params, stream=True, verify=False, timeout=(1, None), proxies=Request.proxies) as req:
|
||||||
if req.status_code == 200:
|
if req.status_code == 200:
|
||||||
with open(tgt_filepath, 'wb') as f:
|
with open(tgt_filepath, 'wb') as f:
|
||||||
f.write(req.content)
|
f.write(req.content)
|
||||||
|
|||||||
@@ -12,3 +12,7 @@ class AlarmAPIMixin:
|
|||||||
"""
|
"""
|
||||||
body = [{"cmd": "GetAlarm", "action": 1, "param": {"Alarm": {"channel": 0, "type": "md"}}}]
|
body = [{"cmd": "GetAlarm", "action": 1, "param": {"Alarm": {"channel": 0, "type": "md"}}}]
|
||||||
return self._execute_command('GetAlarm', body)
|
return self._execute_command('GetAlarm', body)
|
||||||
|
|
||||||
|
def get_ai_state(self) -> Dict:
|
||||||
|
body = [{"cmd": "GetAIState"}]
|
||||||
|
return self._execute_command('GetAlarm', body)
|
||||||
|
|||||||
@@ -46,7 +46,12 @@ class MotionAPIMixin:
|
|||||||
body = [{"cmd": "Search", "action": 1, "param": search_params}]
|
body = [{"cmd": "Search", "action": 1, "param": search_params}]
|
||||||
|
|
||||||
resp = self._execute_command('Search', body)[0]
|
resp = self._execute_command('Search', body)[0]
|
||||||
result = resp['value']['SearchResult']
|
if 'value' not in resp:
|
||||||
|
return []
|
||||||
|
values = resp['value']
|
||||||
|
if 'SearchResult' not in values:
|
||||||
|
return []
|
||||||
|
result = values['SearchResult']
|
||||||
files = result.get('File', [])
|
files = result.get('File', [])
|
||||||
if len(files) > 0:
|
if len(files) > 0:
|
||||||
# Begin processing files
|
# Begin processing files
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
import time
|
||||||
|
|
||||||
class PtzAPIMixin:
|
class PtzAPIMixin:
|
||||||
"""
|
"""
|
||||||
@@ -121,3 +121,65 @@ class PtzAPIMixin:
|
|||||||
:return: response json
|
:return: response json
|
||||||
"""
|
"""
|
||||||
return self._send_operation('Auto', speed=speed)
|
return self._send_operation('Auto', speed=speed)
|
||||||
|
|
||||||
|
def get_zoom_focus_pos(self) -> Dict:
|
||||||
|
body = [{"cmd": "GetZoomFocus", "action": 0, "param": {'channel':0}}]
|
||||||
|
return self._execute_command('GetZoomFocus',body)
|
||||||
|
|
||||||
|
def set_auto_focus_state(self, state: bool = True) -> Dict:
|
||||||
|
body = [{"cmd": "SetAutoFocus", "action": 0, "param": {'AutoFocus':{'channel':0,'disable':int(state)}}}]
|
||||||
|
return self._execute_command('SetAutoFocus',body)
|
||||||
|
|
||||||
|
def get_auto_focus_state(self) -> bool:
|
||||||
|
body = [{"cmd": "GetAutoFocus", "action": 1, "param": {'channel':0}}]
|
||||||
|
return bool(self._execute_command('GetAutoFocus',body)[0]['value']['AutoFocus']['disable'])
|
||||||
|
|
||||||
|
|
||||||
|
def set_zoom_pos(self, pos: int) -> Dict:
|
||||||
|
body = [{"cmd": "StartZoomFocus", "action": 0, "param": {'ZoomFocus':{'channel':0,'pos':pos,'op':'ZoomPos'}}}]
|
||||||
|
self._execute_command('StartZoomFocus',body)
|
||||||
|
|
||||||
|
|
||||||
|
def set_focus_pos(self, pos: int) -> Dict:
|
||||||
|
body = [{"cmd": "StartZoomFocus", "action": 0, "param": {'ZoomFocus':{'channel':0,'pos':pos,'op':'FocusPos'}}}]
|
||||||
|
self._execute_command('StartZoomFocus',body)
|
||||||
|
|
||||||
|
|
||||||
|
def generic_set_block(self, pos:int, get_func, set_func) -> int:
|
||||||
|
|
||||||
|
|
||||||
|
change_index = 0
|
||||||
|
last_pos = get_func()
|
||||||
|
pos = min([pos,254])
|
||||||
|
pos = max([pos, 0])
|
||||||
|
|
||||||
|
target_pos = pos
|
||||||
|
set_func(pos)
|
||||||
|
for i in range(100):
|
||||||
|
cpos = get_func()
|
||||||
|
if cpos != last_pos:
|
||||||
|
change_index = i
|
||||||
|
|
||||||
|
if cpos == target_pos:
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
if (i - change_index) > 8:
|
||||||
|
break
|
||||||
|
|
||||||
|
last_pos = cpos
|
||||||
|
time.sleep(0.25)
|
||||||
|
|
||||||
|
return cpos
|
||||||
|
|
||||||
|
def set_focus_pos_block(self, pos: int) -> int:
|
||||||
|
return self.generic_set_block(pos, self.get_focus_pos, self.set_focus_pos)
|
||||||
|
|
||||||
|
def set_zoom_pos_block(self, pos: int) -> int:
|
||||||
|
return self.generic_set_block(pos, self.get_zoom_pos, self.set_zoom_pos)
|
||||||
|
|
||||||
|
def get_zoom_pos(self) -> int:
|
||||||
|
return self.get_zoom_focus_pos()[0]['value']['ZoomFocus']['zoom']['pos']
|
||||||
|
|
||||||
|
def get_focus_pos(self) -> int:
|
||||||
|
return self.get_zoom_focus_pos()[0]['value']['ZoomFocus']['focus']['pos']
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
.
|
Pillow
|
||||||
|
opencv-python
|
||||||
|
|||||||
Reference in New Issue
Block a user