Hi all,
I'm working on a script to move my camera using
These are the details of my camera
"""
Model: DS-2DE2A204IW-DE3
Firmware Version:V5.6.16 build 200925
Encoding Version: V7.3 build 200907
Web Version:V4.0.1 build 191111
Plugin Version:3.0.7.25
"""
Here is the code I'm using
I made the for loop to test my theory of sending the command over time to make sure it will move, and it did move. How can i make sure that the camera will move only with one command?
I'm working on a script to move my camera using
/ISAPI
endpoints. I have set a ptz location for a preset with ID 1 so I can go back to it when I want. I can see the live feed of my camera to keep track of what is happening. When I send the preset command, the camera moves a little to that direction and not fully. I checked if the problem is in my connection, but sometimes it moves on one command, and sometimes not.These are the details of my camera
"""
Model: DS-2DE2A204IW-DE3
Firmware Version:V5.6.16 build 200925
Encoding Version: V7.3 build 200907
Web Version:V4.0.1 build 191111
Plugin Version:3.0.7.25
"""
Here is the code I'm using
Python:
import logging
import xml.etree.ElementTree as ET
import requests
from requests.auth import HTTPDigestAuth
logger = logging.getLogger(__name__)
class CameraControl:
def __init__(self, base_url, user, password):
self.base_url = base_url
self.user = user
self.password = password
def adjust_ptz(
self,
pan=None,
tilt=None,
panSpeed=100,
tiltSpeed=100,
duration=500,
method="Continuous",
):
try:
# pan = tilt [-100:100]
if method == "Momentary":
url = f"{self.base_url}/ISAPI/PTZCtrl/channels/1/Momentary"
payload = f"<PTZData><pan>{pan}</pan><tilt>{tilt}</tilt><panSpeed>{panSpeed}</panSpeed><tiltSpeed>{tiltSpeed}</tiltSpeed><zoom>0</zoom><Momentary><duration>{duration}</duration></Momentary></PTZData>"
elif method == "Continuous":
url = f"{self.base_url}/ISAPI/PTZCtrl/channels/1/Continuous"
payload = f"<PTZData><pan>{pan}</pan><tilt>{tilt}</tilt><panSpeed>{panSpeed}</panSpeed><tiltSpeed>{tiltSpeed}</tiltSpeed><zoom>0</zoom><Continuous><duration>{duration}</duration></Continuous></PTZData>"
elif method == "Absolute":
# pan [0:3550], tilt [0-900]
url = f"{self.base_url}/ISAPI/PTZCtrl/channels/1/Absolute"
payload = (
"<PTZData>"
f"<AbsoluteHigh><azimuth>{pan}</azimuth><elevation>{tilt}</elevation><panSpeed>{panSpeed}</panSpeed><tiltSpeed>{tiltSpeed}</tiltSpeed><absoluteZoom>10</absoluteZoom></AbsoluteHigh>"
"</PTZData>"
)
response = requests.put(
url,
auth=HTTPDigestAuth(self.user, self.password),
data=payload,
headers={"Content-Type": "application/xml"},
)
if response.status_code == 200:
return "Success: PTZ adjusted."
else:
logger.info(
f"Error: Unexpected response {response.status_code} - {response.text}"
)
return f"Error: Unexpected response {response.status_code} - {response.text}"
except requests.exceptions.RequestException as err:
return f"Error: {err}"
def get_ptz_status(self):
url = f"{self.base_url}/ISAPI/PTZCtrl/channels/1/status"
try:
response = requests.get(url, auth=HTTPDigestAuth(self.user, self.password))
response.raise_for_status()
xml_root = ET.fromstring(response.content)
ns = {"hik": "http://www.hikvision.com/ver20/XMLSchema"}
azimuth = xml_root.find("./hik:azimuth", ns).text
elevation = xml_root.find("./hik:elevation", ns).text
return (azimuth, elevation)
except requests.exceptions.RequestException as e:
return f"Failed to get PTZ status: {e}"
except ET.ParseError as e:
return f"XML parsing error: {e}"
def set_home_position(self):
url = f"{self.base_url}/ISAPI/PTZCtrl/channels/1/homeposition/set"
response = requests.put(url, auth=HTTPDigestAuth(self.user, self.password))
try:
response.raise_for_status()
return "Success: Home position set."
except requests.exceptions.HTTPError as err:
return f"Error: {err}"
def goto_home_position(self):
url = f"{self.base_url}/ISAPI/PTZCtrl/channels/1/homeposition/goto"
response = requests.put(url, auth=HTTPDigestAuth(self.user, self.password))
try:
response.raise_for_status()
if response.status_code == 200:
return "Success: Camera moved to Home position."
else:
logger.info(
f"Error: Unexpected response {response.status_code} - {response.text}"
)
return f"Error: Unexpected response {response.status_code} - {response.text}"
except requests.exceptions.HTTPError as err:
return f"Error: {err}"
def set_preset_position(self, preset_id):
"""Sets the current position of the PTZ camera as a preset position."""
url = f"{self.base_url}/ISAPI/PTZCtrl/channels/1/presets/{preset_id}"
payload = f"<PTZPreset><id>{preset_id}</id><presetName>Preset{preset_id}</presetName></PTZPreset>"
response = requests.put(
url,
auth=HTTPDigestAuth(self.user, self.password),
data=payload,
headers={"Content-Type": "application/xml"},
)
try:
response.raise_for_status()
if response.status_code == 200:
return f"Success: Preset position {preset_id} set."
else:
logger.info(
f"Error: Unexpected response {response.status_code} - {response.text}"
)
return f"Error: Unexpected response {response.status_code} - {response.text}"
except requests.exceptions.HTTPError as err:
return f"Error: {err}"
def goto_preset_position(self, preset_id):
"""Moves the PTZ camera to a specific preset position."""
url = f"{self.base_url}/ISAPI/PTZCtrl/channels/1/presets/{preset_id}/goto"
response = requests.put(
url,
auth=HTTPDigestAuth(self.user, self.password),
headers={"Content-Type": "application/xml"},
)
try:
response.raise_for_status()
if response.status_code == 200:
logger.info(f"went to preset {preset_id}")
return f"Success: Camera moved to preset position {preset_id}."
else:
logger.info(
f"Error: Unexpected response {response.status_code} - {response.text}"
)
return f"Error: Unexpected response {response.status_code} - {response.text}"
except requests.exceptions.HTTPError as err:
return f"Error: {err}"
def get_preset_position(self, preset_id):
"""Gets the coordinates of a preset position."""
url = f"{self.base_url}/ISAPI/PTZCtrl/channels/1/presets/{preset_id}"
try:
response = requests.get(url, auth=HTTPDigestAuth(self.user, self.password))
response.raise_for_status()
xml_root = ET.fromstring(response.content)
ns = {"hik": "http://www.hikvision.com/ver20/XMLSchema"}
azimuth = xml_root.find("./hik:azimuth", ns).text
elevation = xml_root.find("./hik:elevation", ns).text
return (azimuth, elevation)
except requests.exceptions.RequestException as e:
return f"Failed to get preset position: {e}"
except ET.ParseError as e:
return f"XML parsing error: {e}"
camera_control = CameraControl(f"http://192.168.1.64:80", "user1", "HaikuPlot876")
i = 1
while i < 6000:
camera_control.adjust_ptz(pan="1800", tilt="10", duration=300, method="Absolute")
i += 1
print(camera_control.get_ptz_status())
I made the for loop to test my theory of sending the command over time to make sure it will move, and it did move. How can i make sure that the camera will move only with one command?