Skip to content

Commit

Permalink
Reolink commands (#226)
Browse files Browse the repository at this point in the history
* add missing commands

* use default pwd and add docstring

* missing load

* save image

* remove cam type

* header

* put back type with default value

* prevent image none
  • Loading branch information
MateoLostanlen authored Nov 10, 2024
1 parent 4f94ad6 commit f10f7b2
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 30 deletions.
31 changes: 8 additions & 23 deletions pyroengine/sensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class ReolinkCamera:
ip_address (str): IP address of the Reolink camera.
username (str): Username for accessing the camera.
password (str): Password for accessing the camera.
cam_type (str): Type of the camera, e.g., 'static' or 'ptz' (pan-tilt-zoom).
cam_type (str): Type of the camera, e.g., 'static' or 'ptz' (pan-tilt-zoom), defaults to 'ptz'.
cam_poses (Optional[List[int]]): List of preset positions for PTZ cameras.
protocol (str): Protocol used for communication, defaults to 'https'.
Expand All @@ -44,7 +44,7 @@ def __init__(
ip_address: str,
username: str,
password: str,
cam_type: str,
cam_type: str = "ptz",
cam_poses: Optional[List[int]] = None,
protocol: str = "https",
):
Expand Down Expand Up @@ -121,19 +121,23 @@ def move_camera(self, operation: str, speed: int = 20, idx: int = 0):
response = requests.post(url, json=data, verify=False) # nosec: B501
self._handle_response(response, "PTZ operation successful.")

def move_in_seconds(self, s: int, operation: str = "Right", speed: int = 20):
def move_in_seconds(self, s: float, operation: str = "Right", speed: int = 20, save_path: str = "im.jpg"):
"""
Moves the camera in a specified direction for a specified number of seconds.
Args:
s (int): Duration in seconds to move the camera.
s (float): Duration in seconds to move the camera.
operation (str): Direction to move the camera.
speed (int): Speed of the movement.
save_path (str): After movement capture and save image at save_path
"""
self.move_camera(operation, speed)
time.sleep(s)
self.move_camera("Stop")
time.sleep(1)
im = self.capture()
if im is not None:
im.save(save_path)

def get_ptz_preset(self):
"""
Expand Down Expand Up @@ -183,25 +187,6 @@ def set_ptz_preset(self, idx: Optional[int] = None):
# Utilizing the shared response handling method
self._handle_response(response, f"Preset {name} set successfully.")

def delete_ptz_preset(self, idx: int):
"""
Deletes a PTZ preset position by setting its enable value to 0.
Args:
idx (int): The preset ID to delete.
"""
url = self._build_url("SetPtzPreset")
data = [
{
"cmd": "SetPtzPreset",
"action": 0, # The action code for setting data
"param": {"PtzPreset": {"channel": 0, "enable": 0, "id": idx}},
}
]
response = requests.post(url, json=data, verify=False) # nosec: B501
# Utilizing the shared response handling method
self._handle_response(response, f"Preset {idx} deleted successfully.")

def reboot_camera(self):
url = self._build_url("Reboot")
data = [{"cmd": "Reboot"}]
Expand Down
101 changes: 94 additions & 7 deletions src/control_reolink_cam.py
Original file line number Diff line number Diff line change
@@ -1,40 +1,108 @@
# Copyright (C) 2023-2024, Pyronear.
# Copyright (C) 2022-2024, Pyronear.

# This program is licensed under the Apache License 2.0.
# See LICENSE or go to <https://opensource.org/licenses/Apache-2.0> for full license details.


import argparse
import os

from dotenv import load_dotenv

from pyroengine.sensors import ReolinkCamera


def main():
"""
Control Reolink Camera for various operations.
This script allows you to interact with a Reolink camera to perform various actions like capturing images,
moving the camera, handling PTZ presets, and more.
Available actions:
- `capture`: Captures an image from the camera.
- `move_camera`: Moves the camera in a specified direction or to a preset position.
- `move_in_seconds`: Moves the camera in a specified direction for a certain duration.
- `get_ptz_preset`: Retrieves the list of PTZ preset positions.
- `set_ptz_preset`: Sets a PTZ preset position.
- `delete_ptz_preset`: Deletes a PTZ preset position.
- `reboot_camera`: Reboots the camera.
- `get_auto_focus`: Retrieves the current auto-focus settings.
- `set_auto_focus`: Enables or disables the auto-focus.
- `start_zoom_focus`: Starts zooming the camera to a specific focus position.
Examples:
- Capture an image:
python src/control_reolink_cam.py capture --ip 169.254.40.1 --type ptz
- Move the camera to a preset position:
python src/control_reolink_cam.py move_camera --ip 169.254.40.1 --pos_id 0 --operation ToPos
- Move the camera to the right for 3 seconds:
python src/control_reolink_cam.py move_in_seconds --ip 169.254.40.1 --operation Right --duration 3
- Get the list of PTZ presets:
python src/control_reolink_cam.py get_ptz_preset --ip 169.254.40.1 --type ptz
- Set a PTZ preset at position 1:
python src/control_reolink_cam.py set_ptz_preset --ip 169.254.40.1 --pos_id 1
- Delete a PTZ preset at position 1:
python src/control_reolink_cam.py delete_ptz_preset --ip 169.254.40.1 --pos_id 1
- Reboot the camera:
python src/control_reolink_cam.py reboot_camera --ip 169.254.40.1 --type ptz
- Get the auto-focus settings:
python src/control_reolink_cam.py get_auto_focus --ip 169.254.40.1 --type ptz
- Disable auto-focus:
python src/control_reolink_cam.py set_auto_focus --ip 169.254.40.1 --disable_autofocus
- Start zooming to focus position 5:
python src/control_reolink_cam.py start_zoom_focus --ip 169.254.40.1 --zoom_position 5
"""
# Load environment variables
load_dotenv()
cam_user = os.getenv("CAM_USER")
cam_pwd = os.getenv("CAM_PWD")

# Set up argument parsing
parser = argparse.ArgumentParser(description="Control Reolink Camera for various operations.")
parser.add_argument(
"action",
choices=["capture", "move_camera", "move_in_seconds", "get_ptz_preset", "set_ptz_preset"],
choices=[
"capture",
"move_camera",
"move_in_seconds",
"get_ptz_preset",
"set_ptz_preset",
"delete_ptz_preset",
"reboot_camera",
"get_auto_focus",
"set_auto_focus",
"start_zoom_focus",
],
help="Action to perform on the camera",
)
parser.add_argument("--ip", required=True, help="IP address of the Reolink camera")
parser.add_argument("--username", required=True, help="Username for camera access")
parser.add_argument("--password", required=True, help="Password for camera access")
parser.add_argument("--type", required=True, choices=["static", "ptz"], help="Type of the camera")
parser.add_argument("--username", help="Username for camera access", default=cam_user)
parser.add_argument("--password", help="Password for camera access", default=cam_pwd)
parser.add_argument("--protocol", help="Protocol (http or https)", default="http")
parser.add_argument(
"--pos_id", type=int, help="Position ID for moving the camera or capturing at a specific position", default=None
)
parser.add_argument("--operation", help="Operation type for moving the camera (e.g., 'Left', 'Right')")
parser.add_argument("--speed", type=int, help="Speed of the PTZ movement", default=1)
parser.add_argument("--duration", type=int, help="Duration in seconds for moving the camera", default=1)
parser.add_argument("--disable_autofocus", action="store_true", help="Disable autofocus if set")
parser.add_argument("--zoom_position", type=int, help="Zoom position for start_zoom_focus", default=None)

args = parser.parse_args()
print(args)

# Create an instance of ReolinkCamera
camera_controller = ReolinkCamera(
ip_address=args.ip, username=args.username, password=args.password, cam_type=args.type, protocol=args.protocol
ip_address=args.ip, username=args.username, password=args.password, protocol=args.protocol
)

# Handling different actions
Expand Down Expand Up @@ -62,6 +130,25 @@ def main():
camera_controller.set_ptz_preset(idx=args.pos_id)
else:
print("Position ID must be provided for setting a PTZ preset.")
elif args.action == "delete_ptz_preset":
if args.pos_id is not None:
camera_controller.delete_ptz_preset(idx=args.pos_id)
else:
print("Position ID must be provided for deleting a PTZ preset.")
elif args.action == "reboot_camera":
camera_controller.reboot_camera()
print("Camera reboot initiated.")
elif args.action == "get_auto_focus":
autofocus_settings = camera_controller.get_auto_focus()
print("AutoFocus Settings:", autofocus_settings)
elif args.action == "set_auto_focus":
camera_controller.set_auto_focus(disable=args.disable_autofocus)
print(f"AutoFocus {'disabled' if args.disable_autofocus else 'enabled'}.")
elif args.action == "start_zoom_focus":
if args.zoom_position is not None:
camera_controller.start_zoom_focus(position=args.zoom_position)
else:
print("Zoom position must be provided for starting zoom focus.")


if __name__ == "__main__":
Expand Down

0 comments on commit f10f7b2

Please sign in to comment.