diff --git a/Pipfile b/Pipfile
deleted file mode 100644
index defbd59..0000000
--- a/Pipfile
+++ /dev/null
@@ -1,16 +0,0 @@
-[[source]]
-name = "pypi"
-url = "https://pypi.org/simple"
-verify_ssl = true
-
-[dev-packages]
-
-[packages]
-pillow = "*"
-pyyaml = "*"
-requests = "*"
-numpy = "*"
-opencv-python = "*"
-pysocks = "*"
-
-[requires]
diff --git a/Pipfile.lock b/Pipfile.lock
deleted file mode 100644
index 15b8698..0000000
--- a/Pipfile.lock
+++ /dev/null
@@ -1,169 +0,0 @@
-{
- "_meta": {
- "hash": {
- "sha256": "6700bce6ed08db166eff9d3105158923ffd2ffbf35c814a4d0133552bda03b5a"
- },
- "pipfile-spec": 6,
- "requires": {},
- "sources": [
- {
- "name": "pypi",
- "url": "https://pypi.org/simple",
- "verify_ssl": true
- }
- ]
- },
- "default": {
- "certifi": {
- "hashes": [
- "sha256:017c25db2a153ce562900032d5bc68e9f191e44e9a0f762f373977de9df1fbb3",
- "sha256:25b64c7da4cd7479594d035c08c2d809eb4aab3a26e5a990ea98cc450c320f1f"
- ],
- "version": "==2019.11.28"
- },
- "chardet": {
- "hashes": [
- "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
- "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
- ],
- "version": "==3.0.4"
- },
- "idna": {
- "hashes": [
- "sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb",
- "sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa"
- ],
- "version": "==2.9"
- },
- "numpy": {
- "hashes": [
- "sha256:1786a08236f2c92ae0e70423c45e1e62788ed33028f94ca99c4df03f5be6b3c6",
- "sha256:17aa7a81fe7599a10f2b7d95856dc5cf84a4eefa45bc96123cbbc3ebc568994e",
- "sha256:20b26aaa5b3da029942cdcce719b363dbe58696ad182aff0e5dcb1687ec946dc",
- "sha256:2d75908ab3ced4223ccba595b48e538afa5ecc37405923d1fea6906d7c3a50bc",
- "sha256:39d2c685af15d3ce682c99ce5925cc66efc824652e10990d2462dfe9b8918c6a",
- "sha256:56bc8ded6fcd9adea90f65377438f9fea8c05fcf7c5ba766bef258d0da1554aa",
- "sha256:590355aeade1a2eaba17617c19edccb7db8d78760175256e3cf94590a1a964f3",
- "sha256:70a840a26f4e61defa7bdf811d7498a284ced303dfbc35acb7be12a39b2aa121",
- "sha256:77c3bfe65d8560487052ad55c6998a04b654c2fbc36d546aef2b2e511e760971",
- "sha256:9537eecf179f566fd1c160a2e912ca0b8e02d773af0a7a1120ad4f7507cd0d26",
- "sha256:9acdf933c1fd263c513a2df3dceecea6f3ff4419d80bf238510976bf9bcb26cd",
- "sha256:ae0975f42ab1f28364dcda3dde3cf6c1ddab3e1d4b2909da0cb0191fa9ca0480",
- "sha256:b3af02ecc999c8003e538e60c89a2b37646b39b688d4e44d7373e11c2debabec",
- "sha256:b6ff59cee96b454516e47e7721098e6ceebef435e3e21ac2d6c3b8b02628eb77",
- "sha256:b765ed3930b92812aa698a455847141869ef755a87e099fddd4ccf9d81fffb57",
- "sha256:c98c5ffd7d41611407a1103ae11c8b634ad6a43606eca3e2a5a269e5d6e8eb07",
- "sha256:cf7eb6b1025d3e169989416b1adcd676624c2dbed9e3bcb7137f51bfc8cc2572",
- "sha256:d92350c22b150c1cae7ebb0ee8b5670cc84848f6359cf6b5d8f86617098a9b73",
- "sha256:e422c3152921cece8b6a2fb6b0b4d73b6579bd20ae075e7d15143e711f3ca2ca",
- "sha256:e840f552a509e3380b0f0ec977e8124d0dc34dc0e68289ca28f4d7c1d0d79474",
- "sha256:f3d0a94ad151870978fb93538e95411c83899c9dc63e6fb65542f769568ecfa5"
- ],
- "index": "pypi",
- "version": "==1.18.1"
- },
- "opencv-python": {
- "hashes": [
- "sha256:0f2e739c582e8c5e432130648bc6d66a56bc65f4cd9ff0bc7033033d2130c7a3",
- "sha256:0f3d159ad6cb9cbd188c726f87485f0799a067a0a15f34c25d7b5c8db3cb2e50",
- "sha256:167a6aff9bd124a3a67e0ec25d0da5ecdc8d96a56405e3e5e7d586c4105eb1bb",
- "sha256:1b90d50bc7a31e9573a8da1b80fcd1e4d9c86c0e5f76387858e1b87eb8b0332b",
- "sha256:2baf1213ae2fd678991f905d7b2b94eddfdfb5f75757db0f0b31eebd48ca200d",
- "sha256:312dda54c7e809c20d7409418060ae0e9cdbe82975e7ced429eb3c234ffc0d4a",
- "sha256:32384e675f7cefe707cac40a95eeb142d6869065e39c5500374116297cd8ca6d",
- "sha256:5c50634dd8f2f866fd99fd939292ce10e52bef82804ebc4e7f915221c3b7e951",
- "sha256:6841bb9cc24751dbdf94e7eefc4e6d70ec297952501954471299fd12ab67391c",
- "sha256:68c1c846dd267cd7e293d3fc0bb238db0a744aa1f2e721e327598f00cb982098",
- "sha256:703910aaa1dcd25a412f78a190fb7a352d9a64ee7d9a35566d786f3cc66ebf20",
- "sha256:8002959146ed21959e3118c60c8e94ceac02eea15b691da6c62cff4787c63f7f",
- "sha256:889eef049d38488b5b4646c48a831feed37c0fd44f3d83c05cff80f4baded145",
- "sha256:8c76983c9ec3e4cf3a4c1d172ec4285332d9fb1c7194d724aff0c518437471ee",
- "sha256:9cd9bd72f4a9743ef6f11f0f96784bd215a542e996db1717d4c2d3d03eb81a1b",
- "sha256:a1a5517301dc8d56243a14253d231ec755b94486b4fff2ae68269bc941bb1f2e",
- "sha256:a2b08aec2eacae868723136383d9eb84a33062a7a7ec5ec3bd2c423bd1355946",
- "sha256:a8529a79233f3581a66984acd16bce52ab0163f6f77568dd69e9ee4956d2e1db",
- "sha256:afbc81a3870739610a9f9a1197374d6a45892cf1933c90fc5617d39790991ed3",
- "sha256:baeb5dd8b21c718580687f5b4efd03f8139b1c56239cdf6b9805c6946e80f268",
- "sha256:db1d49b753e6e6c76585f21d09c7e9812176732baa9bddb64bc2fc6cd24d4179",
- "sha256:e242ed419aeb2488e0f9ee6410a34917f0f8d62b3ae96aa3170d83bae75004e2",
- "sha256:e36a8857be2c849e54009f1bee25e8c34fbc683fcd38c6c700af4cba5f8d57c2",
- "sha256:e699232fd033ef0053efec2cba0a7505514f374ba7b18c732a77cb5304311ef9",
- "sha256:eae3da9231d87980f8082d181c276a04f7a6fdac130cebd467390b96dd05f944",
- "sha256:ee6814c94dbf1cae569302afef9dd29efafc52373e8770ded0db549a3b6e0c00",
- "sha256:f01a87a015227d8af407161eb48222fc3c8b01661cdc841e2b86eee4f1a7a417"
- ],
- "index": "pypi",
- "version": "==4.2.0.32"
- },
- "pillow": {
- "hashes": [
- "sha256:0a628977ac2e01ca96aaae247ec2bd38e729631ddf2221b4b715446fd45505be",
- "sha256:4d9ed9a64095e031435af120d3c910148067087541131e82b3e8db302f4c8946",
- "sha256:54ebae163e8412aff0b9df1e88adab65788f5f5b58e625dc5c7f51eaf14a6837",
- "sha256:5bfef0b1cdde9f33881c913af14e43db69815c7e8df429ceda4c70a5e529210f",
- "sha256:5f3546ceb08089cedb9e8ff7e3f6a7042bb5b37c2a95d392fb027c3e53a2da00",
- "sha256:5f7ae9126d16194f114435ebb79cc536b5682002a4fa57fa7bb2cbcde65f2f4d",
- "sha256:62a889aeb0a79e50ecf5af272e9e3c164148f4bd9636cc6bcfa182a52c8b0533",
- "sha256:7406f5a9b2fd966e79e6abdaf700585a4522e98d6559ce37fc52e5c955fade0a",
- "sha256:8453f914f4e5a3d828281a6628cf517832abfa13ff50679a4848926dac7c0358",
- "sha256:87269cc6ce1e3dee11f23fa515e4249ae678dbbe2704598a51cee76c52e19cda",
- "sha256:875358310ed7abd5320f21dd97351d62de4929b0426cdb1eaa904b64ac36b435",
- "sha256:8ac6ce7ff3892e5deaab7abaec763538ffd011f74dc1801d93d3c5fc541feee2",
- "sha256:91b710e3353aea6fc758cdb7136d9bbdcb26b53cefe43e2cba953ac3ee1d3313",
- "sha256:9d2ba4ed13af381233e2d810ff3bab84ef9f18430a9b336ab69eaf3cd24299ff",
- "sha256:a62ec5e13e227399be73303ff301f2865bf68657d15ea50b038d25fc41097317",
- "sha256:ab76e5580b0ed647a8d8d2d2daee170e8e9f8aad225ede314f684e297e3643c2",
- "sha256:bf4003aa538af3f4205c5fac56eacaa67a6dd81e454ffd9e9f055fff9f1bc614",
- "sha256:bf598d2e37cf8edb1a2f26ed3fb255191f5232badea4003c16301cb94ac5bdd0",
- "sha256:c18f70dc27cc5d236f10e7834236aff60aadc71346a5bc1f4f83a4b3abee6386",
- "sha256:c5ed816632204a2fc9486d784d8e0d0ae754347aba99c811458d69fcdfd2a2f9",
- "sha256:dc058b7833184970d1248135b8b0ab702e6daa833be14035179f2acb78ff5636",
- "sha256:ff3797f2f16bf9d17d53257612da84dd0758db33935777149b3334c01ff68865"
- ],
- "index": "pypi",
- "version": "==7.0.0"
- },
- "pysocks": {
- "hashes": [
- "sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299",
- "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5",
- "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0"
- ],
- "index": "pypi",
- "version": "==1.7.1"
- },
- "pyyaml": {
- "hashes": [
- "sha256:059b2ee3194d718896c0ad077dd8c043e5e909d9180f387ce42012662a4946d6",
- "sha256:1cf708e2ac57f3aabc87405f04b86354f66799c8e62c28c5fc5f88b5521b2dbf",
- "sha256:24521fa2890642614558b492b473bee0ac1f8057a7263156b02e8b14c88ce6f5",
- "sha256:4fee71aa5bc6ed9d5f116327c04273e25ae31a3020386916905767ec4fc5317e",
- "sha256:70024e02197337533eef7b85b068212420f950319cc8c580261963aefc75f811",
- "sha256:74782fbd4d4f87ff04159e986886931456a1894c61229be9eaf4de6f6e44b99e",
- "sha256:940532b111b1952befd7db542c370887a8611660d2b9becff75d39355303d82d",
- "sha256:cb1f2f5e426dc9f07a7681419fe39cee823bb74f723f36f70399123f439e9b20",
- "sha256:dbbb2379c19ed6042e8f11f2a2c66d39cceb8aeace421bfc29d085d93eda3689",
- "sha256:e3a057b7a64f1222b56e47bcff5e4b94c4f61faac04c7c4ecb1985e18caa3994",
- "sha256:e9f45bd5b92c7974e59bcd2dcc8631a6b6cc380a904725fce7bc08872e691615"
- ],
- "index": "pypi",
- "version": "==5.3"
- },
- "requests": {
- "hashes": [
- "sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee",
- "sha256:b3f43d496c6daba4493e7c431722aeb7dbc6288f52a6e04e7b6023b0247817e6"
- ],
- "index": "pypi",
- "version": "==2.23.0"
- },
- "urllib3": {
- "hashes": [
- "sha256:2f3db8b19923a873b3e5256dc9c2dedfa883e33d87c690d9c7913e1f40673cdc",
- "sha256:87716c2d2a7121198ebcb7ce7cccf6ce5e9ba539041cfbaeecfb641dc0bf6acc"
- ],
- "version": "==1.25.8"
- }
- },
- "develop": {}
-}
diff --git a/README.md b/README.md
index 37f295f..e8ef0da 100644
--- a/README.md
+++ b/README.md
@@ -1,114 +1,15 @@
-
Reolink Python Api Client
-
-
-
-
-
-
-
----
-
+# (Forked) Reolink Python Api Client
A Reolink Camera client written in Python.
-Other Supported Languages:
- - Go: [reolink-go-api](https://github.com/ReolinkCameraAPI/reolink-go-api)
-
-### Join us on Discord
-
- https://discord.gg/8z3fdAmZJP
+_NB! for the original API client of this fork, go [here](https://github.com/ReolinkCameraAPI/reolink-python-api)_
### Purpose
-This repository's purpose is to deliver a complete API for the Reolink Camera's, ( TESTED on RLC-411WS )
+This repository's purpose is to deliver a complete API for the Reolink Camera's, (tested on RLC-522)
+### Installation
-### But Reolink gives an API in their documentation
+```bash
+python3 -m pip install git+https://github.com/barretobrock/reolink-python-api.git
+```
-Not really. They only deliver a really basic API to retrieve Image data and Video data.
-
-### How?
-
-You can get the Restful API calls by looking through the HTTP Requests made the camera web console. I use Google Chrome developer mode (ctr + shift + i) -> Network.
-
-### Get started
-
-Implement a "Camera" object by passing it an IP address, Username and Password. By instantiating the object, it will try retrieve a login token from the Reolink Camera. This token is necessary to interact with the Camera using other commands.
-
-See the `examples` directory.
-
-### Using the library as a Python Module
-
-Install the package via Pip
-
- pip install reolink-api==0.0.5
-
-## Contributors
-
----
-
-### Styling and Standards
-
-This project intends to stick with [PEP8](https://www.python.org/dev/peps/pep-0008/)
-
-### API Requests Implementation Plan:
-
-Stream:
-- [X] Blocking RTSP stream
-- [X] Non-Blocking RTSP stream
-
-GET:
-- [X] Login
-- [X] Logout
-- [X] Display -> OSD
-- [X] Recording -> Encode (Clear and Fluent Stream)
-- [X] Recording -> Advance (Scheduling)
-- [X] Network -> General
-- [X] Network -> Advanced
-- [X] Network -> DDNS
-- [X] Network -> NTP
-- [X] Network -> E-mail
-- [X] Network -> FTP
-- [X] Network -> Push
-- [X] Network -> WIFI
-- [X] Alarm -> Motion
-- [X] System -> General
-- [X] System -> DST
-- [X] System -> Information
-- [ ] System -> Maintenance
-- [X] System -> Performance
-- [ ] System -> Reboot
-- [X] User -> Online User
-- [X] User -> Add User
-- [X] User -> Manage User
-- [X] Device -> HDD/SD Card
-- [ ] Zoom
-- [ ] Focus
-- [ ] Image (Brightness, Contrast, Saturation, Hue, Sharp, Mirror, Rotate)
-- [ ] Advanced Image (Anti-flicker, Exposure, White Balance, DayNight, Backlight, LED light, 3D-NR)
-- [X] Image Data -> "Snap" Frame from Video Stream
-
-SET:
-- [X] Display -> OSD
-- [X] Recording -> Encode (Clear and Fluent Stream)
-- [ ] Recording -> Advance (Scheduling)
-- [X] Network -> General
-- [X] Network -> Advanced
-- [ ] Network -> DDNS
-- [ ] Network -> NTP
-- [ ] Network -> E-mail
-- [ ] Network -> FTP
-- [ ] Network -> Push
-- [X] Network -> WIFI
-- [ ] Alarm -> Motion
-- [ ] System -> General
-- [ ] System -> DST
-- [X] System -> Reboot
-- [X] User -> Online User
-- [X] User -> Add User
-- [X] User -> Manage User
-- [X] Device -> HDD/SD Card (Format)
-- [x] PTZ
-- [x] Zoom
-- [x] Focus
-- [X] Image (Brightness, Contrast, Saturation, Hue, Sharp, Mirror, Rotate)
-- [X] Advanced Image (Anti-flicker, Exposure, White Balance, DayNight, Backlight, LED light, 3D-NR)
diff --git a/api/__init__.py b/api/__init__.py
deleted file mode 100644
index 491da40..0000000
--- a/api/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from .APIHandler import APIHandler
-
-__version__ = "0.0.5"
-VERSION = __version__
diff --git a/api/APIHandler.py b/reolink_api/APIHandler.py
similarity index 92%
rename from api/APIHandler.py
rename to reolink_api/APIHandler.py
index a4a6f07..3b4754d 100644
--- a/api/APIHandler.py
+++ b/reolink_api/APIHandler.py
@@ -1,26 +1,30 @@
-from .recording import RecordingAPIMixin
-from .zoom import ZoomAPIMixin
+from reolink_api.resthandle import Request
+from .alarm import AlarmAPIMixin
from .device import DeviceAPIMixin
from .display import DisplayAPIMixin
+from .download import DownloadAPIMixin
+from .image import ImageAPIMixin
+from .motion import MotionAPIMixin
from .network import NetworkAPIMixin
+from .ptz import PtzAPIMixin
+from .recording import RecordingAPIMixin
from .system import SystemAPIMixin
from .user import UserAPIMixin
-from .ptz import PtzAPIMixin
-from .alarm import AlarmAPIMixin
-from .image import ImageAPIMixin
-from resthandle import Request
+from .zoom import ZoomAPIMixin
-class APIHandler(SystemAPIMixin,
- NetworkAPIMixin,
- UserAPIMixin,
+class APIHandler(AlarmAPIMixin,
DeviceAPIMixin,
DisplayAPIMixin,
- RecordingAPIMixin,
- ZoomAPIMixin,
+ DownloadAPIMixin,
+ ImageAPIMixin,
+ MotionAPIMixin,
+ NetworkAPIMixin,
PtzAPIMixin,
- AlarmAPIMixin,
- ImageAPIMixin):
+ RecordingAPIMixin,
+ SystemAPIMixin,
+ UserAPIMixin,
+ ZoomAPIMixin):
"""
The APIHandler class is the backend part of the API, the actual API calls
are implemented in Mixins.
diff --git a/Camera.py b/reolink_api/Camera.py
similarity index 84%
rename from Camera.py
rename to reolink_api/Camera.py
index a60490a..0a166f1 100644
--- a/Camera.py
+++ b/reolink_api/Camera.py
@@ -1,9 +1,9 @@
-from api import APIHandler
+from reolink_api import APIHandler
class Camera(APIHandler):
- def __init__(self, ip, username="admin", password="", https=False):
+ def __init__(self, ip: str, username: str = "admin", password: str = "", https: bool = False):
"""
Initialise the Camera object by passing the ip address.
The default details {"username":"admin", "password":""} will be used if nothing passed
diff --git a/ConfigHandler.py b/reolink_api/ConfigHandler.py
similarity index 99%
rename from ConfigHandler.py
rename to reolink_api/ConfigHandler.py
index 67e8d62..37f255e 100644
--- a/ConfigHandler.py
+++ b/reolink_api/ConfigHandler.py
@@ -1,5 +1,4 @@
import io
-
import yaml
diff --git a/RtspClient.py b/reolink_api/RtspClient.py
similarity index 94%
rename from RtspClient.py
rename to reolink_api/RtspClient.py
index 6cf37c1..655f95f 100644
--- a/RtspClient.py
+++ b/reolink_api/RtspClient.py
@@ -1,9 +1,7 @@
import os
from threading import ThreadError
-
import cv2
-
-from util import threaded
+from reolink_api.util import threaded
class RtspClient:
@@ -91,9 +89,6 @@ class RtspClient:
"""
Opens OpenCV Video stream and returns the result according to the OpenCV documentation
https://docs.opencv.org/3.4/d8/dfe/classcv_1_1VideoCapture.html#a473055e77dd7faa4d26d686226b292c1
-
- :param callback: The function to callback the cv::mat frame to if required to be non-blocking. If this is left
- as None, then the function returns a generator which is blocking.
"""
# Reset the capture object
diff --git a/reolink_api/__init__.py b/reolink_api/__init__.py
new file mode 100644
index 0000000..1eca8c1
--- /dev/null
+++ b/reolink_api/__init__.py
@@ -0,0 +1,4 @@
+from .APIHandler import APIHandler
+from .Camera import Camera
+
+__version__ = "0.1.0"
diff --git a/api/alarm.py b/reolink_api/alarm.py
similarity index 100%
rename from api/alarm.py
rename to reolink_api/alarm.py
diff --git a/api/device.py b/reolink_api/device.py
similarity index 83%
rename from api/device.py
rename to reolink_api/device.py
index deee890..68f8179 100644
--- a/api/device.py
+++ b/reolink_api/device.py
@@ -1,5 +1,10 @@
+from typing import List
+
+
class DeviceAPIMixin:
"""API calls for getting device information."""
+ DEFAULT_HDD_ID = [0]
+
def get_hdd_info(self) -> object:
"""
Gets all HDD and SD card information from Camera
@@ -9,12 +14,14 @@ class DeviceAPIMixin:
body = [{"cmd": "GetHddInfo", "action": 0, "param": {}}]
return self._execute_command('GetHddInfo', body)
- def format_hdd(self, hdd_id: [int] = [0]) -> bool:
+ def format_hdd(self, hdd_id: List[int] = None) -> bool:
"""
Format specified HDD/SD cards with their id's
:param hdd_id: List of id's specified by the camera with get_hdd_info api. Default is 0 (SD card)
:return: bool
"""
+ if hdd_id is None:
+ hdd_id = self.DEFAULT_HDD_ID
body = [{"cmd": "Format", "action": 0, "param": {"HddInfo": {"id": hdd_id}}}]
r_data = self._execute_command('Format', body)[0]
if r_data["value"]["rspCode"] == 200:
diff --git a/api/display.py b/reolink_api/display.py
similarity index 100%
rename from api/display.py
rename to reolink_api/display.py
diff --git a/reolink_api/download.py b/reolink_api/download.py
new file mode 100644
index 0000000..45494d9
--- /dev/null
+++ b/reolink_api/download.py
@@ -0,0 +1,15 @@
+class DownloadAPIMixin:
+ """API calls for downloading video files."""
+ def get_file(self, filename: str) -> object:
+ """
+ Download the selected video file
+ :return: response json
+ """
+ body = [
+ {
+ "cmd": "Download",
+ "source": filename,
+ "output": filename
+ }
+ ]
+ return self._execute_command('Download', body)
diff --git a/api/image.py b/reolink_api/image.py
similarity index 67%
rename from api/image.py
rename to reolink_api/image.py
index 6cdb823..0fbb952 100644
--- a/api/image.py
+++ b/reolink_api/image.py
@@ -3,22 +3,22 @@ class ImageAPIMixin:
"""API calls for image settings."""
def set_adv_image_settings(self,
- anti_flicker='Outdoor',
- exposure='Auto',
- gain_min=1,
- gain_max=62,
- shutter_min=1,
- shutter_max=125,
- blue_gain=128,
- red_gain=128,
- white_balance='Auto',
- day_night='Auto',
- back_light='DynamicRangeControl',
- blc=128,
- drc=128,
- rotation=0,
- mirroring=0,
- nr3d=1) -> object:
+ anti_flicker: str = 'Outdoor',
+ exposure: str = 'Auto',
+ gain_min: int = 1,
+ gain_max: int = 62,
+ shutter_min: int = 1,
+ shutter_max: int = 125,
+ blue_gain: int = 128,
+ red_gain: int = 128,
+ white_balance: str = 'Auto',
+ day_night: str = 'Auto',
+ back_light: str = 'DynamicRangeControl',
+ blc: int = 128,
+ drc: int = 128,
+ rotation: int = 0,
+ mirroring: int = 0,
+ nr3d: int = 1) -> object:
"""
Sets the advanced camera settings.
@@ -66,11 +66,11 @@ class ImageAPIMixin:
return self._execute_command('SetIsp', body)
def set_image_settings(self,
- brightness=128,
- contrast=62,
- hue=1,
- saturation=125,
- sharpness=128) -> object:
+ brightness: int = 128,
+ contrast: int = 62,
+ hue: int = 1,
+ saturation: int = 125,
+ sharpness: int = 128) -> object:
"""
Sets the camera image settings.
diff --git a/reolink_api/motion.py b/reolink_api/motion.py
new file mode 100644
index 0000000..1ce8071
--- /dev/null
+++ b/reolink_api/motion.py
@@ -0,0 +1,41 @@
+from datetime import datetime as dt
+
+
+class MotionAPIMixin:
+ """API calls for past motion alerts."""
+ def get_motion_files(self, start: dt, end: dt = dt.now(),
+ streamtype: str = 'main') -> object:
+ """
+ Get the timestamps and filenames of motion detection events for the time range provided.
+
+ Args:
+ start: the starting time range to examine
+ end: the end time of the time range to examine
+ streamtype: 'main' or 'sub' - the stream to examine
+ :return: response json
+ """
+ search_params = {
+ 'Search': {
+ 'channel': 0,
+ 'streamType': streamtype,
+ 'onlyStatus': 0,
+ 'StartTime': {
+ 'year': start.year,
+ 'mon': start.month,
+ 'day': start.day,
+ 'hour': start.hour,
+ 'min': start.minute,
+ 'sec': start.second
+ },
+ 'EndTime': {
+ 'year': end.year,
+ 'mon': end.month,
+ 'day': end.day,
+ 'hour': end.hour,
+ 'min': end.minute,
+ 'sec': end.second
+ }
+ }
+ }
+ body = [{"cmd": "Search", "action": 1, "param": search_params}]
+ return self._execute_command('Search', body)
diff --git a/api/network.py b/reolink_api/network.py
similarity index 94%
rename from api/network.py
rename to reolink_api/network.py
index 39af7b8..54bbe2d 100644
--- a/api/network.py
+++ b/reolink_api/network.py
@@ -1,7 +1,7 @@
class NetworkAPIMixin:
"""API calls for network settings."""
- def set_net_port(self, http_port=80, https_port=443, media_port=9000, onvif_port=8000, rtmp_port=1935,
- rtsp_port=554) -> bool:
+ def set_net_port(self, http_port: int = 80, https_port: int = 443, media_port: int = 9000,
+ onvif_port: int = 8000, rtmp_port: int = 1935, rtsp_port: int = 554) -> bool:
"""
Set network ports
If nothing is specified, the default values will be used
@@ -25,7 +25,7 @@ class NetworkAPIMixin:
print("Successfully Set Network Ports")
return True
- def set_wifi(self, ssid, password) -> object:
+ def set_wifi(self, ssid: str, password: str) -> object:
body = [{"cmd": "SetWifi", "action": 0, "param": {
"Wifi": {
"ssid": ssid,
diff --git a/api/ptz.py b/reolink_api/ptz.py
similarity index 100%
rename from api/ptz.py
rename to reolink_api/ptz.py
diff --git a/api/recording.py b/reolink_api/recording.py
similarity index 99%
rename from api/recording.py
rename to reolink_api/recording.py
index 8827249..195cce7 100644
--- a/api/recording.py
+++ b/reolink_api/recording.py
@@ -4,7 +4,7 @@ import string
from urllib import parse
from io import BytesIO
from PIL import Image
-from RtspClient import RtspClient
+from reolink_api.RtspClient import RtspClient
class RecordingAPIMixin:
diff --git a/resthandle.py b/reolink_api/resthandle.py
similarity index 94%
rename from resthandle.py
rename to reolink_api/resthandle.py
index d2f98b7..ac3fad9 100644
--- a/resthandle.py
+++ b/reolink_api/resthandle.py
@@ -1,5 +1,4 @@
import json
-
import requests
@@ -17,7 +16,8 @@ class Request:
"""
try:
headers = {'content-type': 'application/json'}
- r = requests.post(url, verify=False, params=params, json=data, headers=headers, proxies=Request.proxies)
+ r = requests.post(url, verify=False, params=params, json=data, headers=headers,
+ proxies=Request.proxies)
# if params is not None:
# r = requests.post(url, params=params, json=data, headers=headers, proxies=proxies)
# else:
diff --git a/api/system.py b/reolink_api/system.py
similarity index 100%
rename from api/system.py
rename to reolink_api/system.py
diff --git a/api/user.py b/reolink_api/user.py
similarity index 100%
rename from api/user.py
rename to reolink_api/user.py
diff --git a/util.py b/reolink_api/util.py
similarity index 100%
rename from util.py
rename to reolink_api/util.py
diff --git a/api/zoom.py b/reolink_api/zoom.py
similarity index 100%
rename from api/zoom.py
rename to reolink_api/zoom.py
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index 30b468d..0000000
--- a/requirements.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-requests
-opencv-python
-numpy
-socks
\ No newline at end of file
diff --git a/setup.py b/setup.py
index 98eba70..da818d1 100644
--- a/setup.py
+++ b/setup.py
@@ -1,32 +1,9 @@
#!/usr/bin/python3
-
import os
import re
import codecs
from setuptools import setup
-# Package meta-data.
-NAME = 'reolink-api'
-DESCRIPTION = 'Reolink Camera API written in Python 3.6'
-URL = 'https://github.com/Benehiko/ReolinkCameraAPI'
-AUTHOR_EMAIL = ''
-AUTHOR = 'Benehiko'
-LICENSE = 'GPL-3.0'
-INSTALL_REQUIRES = [
- 'pillow',
- 'pyyaml',
- 'requests>=2.18.4',
- 'numpy',
- 'opencv-python',
- 'pysocks'
-]
-
-
-here = os.path.abspath(os.path.dirname(__file__))
-# read the contents of your README file
-with open(os.path.join(here, 'README.md'), encoding='utf-8') as f:
- long_description = f.read()
-
def read(*parts):
with codecs.open(os.path.join(here, *parts), 'r') as fp:
@@ -41,32 +18,39 @@ def find_version(*file_paths):
raise RuntimeError("Unable to find version string.")
-setup(name=NAME,
- python_requires='>=3.6.0',
- version=find_version('api', '__init__.py'),
- description=DESCRIPTION,
- long_description=long_description,
- long_description_content_type='text/markdown',
- author=AUTHOR,
- author_email=AUTHOR_EMAIL,
- url=URL,
- license=LICENSE,
- install_requires=INSTALL_REQUIRES,
- py_modules=[
- 'Camera',
- 'ConfigHandler',
- 'RtspClient',
- 'resthandle',
- 'api.APIHandler',
- 'api.device',
- 'api.display',
- 'api.network',
- 'api.ptz',
- 'api.recording',
- 'api.system',
- 'api.user',
- 'api.zoom',
- 'api.alarm',
- 'api.image'
- ]
- )
+here = os.path.abspath(os.path.dirname(__file__))
+# read the contents of your README file
+with open(os.path.join(here, 'README.md'), encoding='utf-8') as f:
+ long_description = f.read()
+
+
+# Package meta-data.
+NAME = 'reolink_api'
+DESCRIPTION = 'Reolink Camera API written in Python 3.6'
+URL = 'https://github.com/Benehiko/ReolinkCameraAPI'
+AUTHOR_EMAIL = ''
+AUTHOR = 'Benehiko'
+LICENSE = 'GPL-3.0'
+INSTALL_REQUIRES = [
+ 'numpy==1.19.4',
+ 'opencv-python==4.4.0.46',
+ 'Pillow==8.0.1',
+ 'PySocks==1.7.1',
+ 'PyYaml==5.3.1',
+ 'requests>=2.18.4',
+]
+
+
+setup(
+ name=NAME,
+ python_requires='>=3.6.0',
+ version=find_version('reolink_api', '__init__.py'),
+ description=DESCRIPTION,
+ long_description=long_description,
+ long_description_content_type='text/markdown',
+ author=AUTHOR,
+ author_email=AUTHOR_EMAIL,
+ url=URL,
+ license=LICENSE,
+ install_requires=INSTALL_REQUIRES
+)
diff --git a/test.py b/test.py
deleted file mode 100644
index 796f5a2..0000000
--- a/test.py
+++ /dev/null
@@ -1,5 +0,0 @@
-from Camera import Camera
-
-c = Camera("192.168.1.112", "admin", "jUa2kUzi")
-# print("Getting information", c.get_information())
-c.open_video_stream()