Intro
This is just a mini tutorial on how to use the Dahua HTTP API and Python (pygame) to control a Dahua PTZ camera. Tested it on a Dahua SD1A404XB-GNR and a Dahua SD49425XB-HNR. It may work on HikVision and Amcrest cameras as well, although i have not tested that (the API looks the same)
This joystick script is part of a larger project i’m working on which is made up by modules and one of these modules requires control over the PTZ functions of a Dahua camera. Specifically the Continuously function of the Dahua HTTP API
Table of Contents
Dahua API
Looking at the Dahua HTTP API PDF documentation they offer two types of movement
- PTZ Basic Movement
- issued by the start action
- code indicates direction (Up, Down, Left, Right)
- to stop issue a stop action
- example request
http://192.168.1.108/cgi-bin/ptz.cgi?action=stop&code=Up&channel=1&arg1=0&arg2=0&arg3=0
- PTZ Continuously Moving
- issued by start action
- arg1
- positive values – turn right
- negative values – turn left
- arg2
- positive values – move down
- negative values – move up
- arg3
- positive values – zoom out
- negative values – zoom in
- arg4
- duration (unused)
- to stop issue a stop action
- opted for just issuing arg0=0, arg1=0, arg2=0, arg3=0
- example request:
http://192.168.1.108/cgi-bin/ptz.cgi?action=start&code=Continuously&channel=1&arg1=5&arg2=5&arg3=5&arg4=60
Obviously i needed the Continuously moving type, this will send all of the desired movement arguments in a sequence to the camera.
Joystick
Now let’s move onto the joystick. It can be any kind of joystick plugged in to USB or Bluetooth. The controller i’m using is a PS3 controller from AliExpress which can be acquired for less than € 10,-
This controller has 6 axes and 17 buttons so i needed to find out which axes belongs to which movement. For that i used a program called jstest-gtk for Linux. From there i could determine that:
- Left stick
- axis 0 controls left and right
- axis 1 controls up and down
- Right stick
- axis 3 controls left and right
- axis 4 controls up and down
Was thinking what would be the most instinctive (for me at least) control layout and came up with the following. For controlling the camera’s movement
For controlling the camera’s zoom capabilities.
The script also has some button actions mapped. When pressed these buttons activate the camera’s presets. The x_button initiates preset 1, square_button initiates preset 2 and so on.
Enough talking, show me the code 😀
Code
Okay let’s jump right in and my code from Github
git clone https://github.com/wvthoog/Dahua-Joystick-PTZ-Control.git
Then install the dependencies. Preferably within a virtual environment ( python -m venv venv
)
pip install -r requirements.txt
This will install the pygame and requests libraries.
Before launching the script you probably need to change a couple of values in the script itself. Namely these values:
# Camera settings
ip = '192.168.2.21' # change
username = 'admin' # change
password = '12345678910' # change
channel = 1
Speaks for itself, but here are some pointers anyway. Change ip to the IP address of your camera, change the username to a username which has PTZ control permissions and lastly change the password with the password for that user. And you’re practically done. You can now fire up the script with a joystick connected to your computer
python dahua_joystick.py
Additional parameters
Some minor tuning can also be done by adjusting these values. The threshold value is the minimal value to be registered before the code detects movement from both sticks. Increase if you feel that the camera moves too quickly when pushing the sticks. (max is 1)
The movement_multiplier controls how fast the camera moves in either direction. I’ve set it to 10 because that value best suits my needs. Decrease if you want movements to be slower, increase for faster. Same goes for zoom_speed_multiplier, increasing the value increases the zoom-in and zoom-out speed.
# Joystick settings
threshold = 0.1
movement_multiplier = 10
zoom_speed_multiplier = 100
Button mapping
Under the same joystick settings you find the button mappings. You can change those if they are different in your setup
x_button = 0
square_button = 3
triangle_button = 2
circle_button = 1
Presets
It is also possible to change which preset is activated when a certain button is pressed.
# Define actions for each button
if button_pressed == x_button: # X Button
print("X Button pressed. Performing preset action...")
preset_number = 1
elif button_pressed == circle_button: # Circle Button
print("Circle Button pressed. Performing preset action...")
preset_number = 4
In this part of the code when the x_button is pressed preset 1 will be activated on the camera, when circle_button is pressed preset 4 will be activated. Change the settings to your liking or perhaps add some more presets and add additional elif statements for that.
ToDo
- Maybe add stop action command if this code gives me issues
Ah……So it’s a program which uses joystick to control the Dahua Camera,right?
Yes, that’s right. Just a simple pygame script essentially
Looks cool.Maybe you can add a feature so that you can control the camera and watch the screen at the same time.
It’s a pity that I cannot join this project as I do not have this camera 🙁 .
That’s not a bad idea actually and quite easy to add. (using OpenCV probably) Putting that on my todo list