Introduction: MOTIONEYE NVR PAN/TILT

motionEye is a web based NVR (Network Video Recorder). It is a web front end for the motion daemon. It is developed in python2.7

More detail on motionEye can be found at:

https://github.com/ccrisan/motioneye

Instalation instructions can be found at:

https://github.com/ccrisan/motioneye/wiki/Installation

motionEye capture video streams via RTSP (Real Time Streaming Protocol) or HTTP. RTSP is a pure streaming protocol and pan/tilt commands can not be send to the camera via RTSP. You may or may not be able to find the HTTP commands for your specific camera's pan / tilt commands in your cameras documentation. To avoid this complexities, it is easier to send ONVIF commands to an ONVIF compliant camera

Since the basics of motionEye is covered at the above mentioned web pages, I will not go through it again, but I will focus on how to control ONVIF compliant cameras pan and tilt function via motionEye. ONVIF is an open industry forum that provides and promotes standardized interfaces for effective interoperability of IP-based physical security products.

This tutorial is for motionEye running on a standard Linux system (In my case Raspberry PI OS). You can try this tutorial also on motionEyeOS (A custom Linux distribution specially build for motionEye), but installation of the python onvif module may be tricky on this busybox tipe of distribution.

System Requirements: Linux with Python2.7, motionEye and Python3

Before you start, make sure that the above is installed and that motionEye can view your cameras.

Supplies

  • Some IP Cameras that is ONVIF compliant
  • Linux computer (I used Raspberry PI OS)

If your IP Camera is not ONVIF compliant, you may search Github for suitable hacks to make the camera ONVIF compliant.

Sonoff GK-200MP2-B Wi-Fi IP Security Camera (This instructable was tested with this camera)

Sonoff GK-200MP2-B Wi-Fi IP Security Camera

https://github.com/roleoroleo/sonoff-hack

Yi 1080p Home

https://github.com/roleoroleo/yi-hack-Allwinner#is-my-cam-supported.

Step 1: Install Python Onvif for Python3

The Python Onvif Module will make it possible to execute pan/tilt commands from motionEye.

To install Python Onvif for Python 3

sudo pip3 install suds-py3
sudo pip3 install git+https://github.com/miuhaki/suds-passworddigest-py3.git
sudo pip3 install onvif-py3

Also make sure your wsdl directory is located in /etc/onvif/ . You can use sudo pcmanfm to search for it and copy it to the right path.

You can also try to install Python Onvif for Python 2. The installation work great, but motionEye could for some reason not execute the the files. It did not give any error messages, but pan and tilt did not work. I tried all versions of the shebang #!/usr/bin/env python, #!/usr/bin/env python2, #!/usr/bin/env python2.7.....#!/usr/bin/python, #!/usr/bin/python2.7

Step 2: Creating Pan and Tilt Commands

Create a file called down_1 with the following content in /etc/motioneye. I suggest you do it with the file manager as root user to avoid permission problems. On Raspberry PI OS the following command will work

sudo pcmanfm 

If you installed Python Onvif for Python 3, change the shebang to #!/usr/bin/env python3

Raplace the CAMERA_IP, PORT, USERAME, PASSWORD to the correct ones in the code. Also make sure that the content of wsdl is located in '/etc/onvif/wsdl/'

#!/usr/bin/env python3

#Pan Tilt application for ONVIF devices

from time import sleep
from onvif import ONVIFCamera

XMAX = 1
XMIN = -1
YMAX = 1
YMIN = -1

def perform_move(ptz, request, timeout):
    # Start continuous move
    ptz.ContinuousMove(request)
    # Wait a certain time
    sleep(timeout)
    # Stop continuous move
    ptz.Stop({'ProfileToken': request.ProfileToken})

def move_up(ptz, request, timeout=1):
    print('move up...')
    request.Velocity.PanTilt._x = 0
    request.Velocity.PanTilt._y = YMAX
    perform_move(ptz, request, timeout)

def move_down(ptz, request, timeout=1):
    print('move down...')
    request.Velocity.PanTilt._x = 0
    request.Velocity.PanTilt._y = YMIN
    perform_move(ptz, request, timeout)

def move_right(ptz, request, timeout=1):
    print('move right...')
    request.Velocity.PanTilt._x = XMAX
    request.Velocity.PanTilt._y = 0
    perform_move(ptz, request, timeout)

def move_left(ptz, request, timeout=1):
    print('move left...')
    request.Velocity.PanTilt._x = XMIN
    request.Velocity.PanTilt._y = 0
    perform_move(ptz, request, timeout)

def continuous_move():
    mycam = ONVIFCamera('CAMERA_IP', 'PORT', 'USERNAME', 'PASSWORD', '/etc/onvif/wsdl/')
    # Create media service object
    media = mycam.create_media_service()
    # Create ptz service object
    ptz = mycam.create_ptz_service()

    # Get target profile
    media_profile = media.GetProfiles()[0]

    # Get PTZ configuration options for getting continuous move range
    request = ptz.create_type('GetConfigurationOptions')
    request.ConfigurationToken = media_profile.PTZConfiguration._token
    ptz_configuration_options = ptz.GetConfigurationOptions(request)

    request = ptz.create_type('ContinuousMove')
    request.ProfileToken = media_profile._token

    ptz.Stop({'ProfileToken': media_profile._token})

    # Get range of pan and tilt
    # NOTE: X and Y are velocity vector
    global XMAX, XMIN, YMAX, YMIN
    XMAX = ptz_configuration_options.Spaces.ContinuousPanTiltVelocitySpace[0].XRange.Max
    XMIN = ptz_configuration_options.Spaces.ContinuousPanTiltVelocitySpace[0].XRange.Min
    YMAX = ptz_configuration_options.Spaces.ContinuousPanTiltVelocitySpace[0].YRange.Max
    YMIN = ptz_configuration_options.Spaces.ContinuousPanTiltVelocitySpace[0].YRange.Min

#PT control

    move_down(ptz, request)

if __name__ == '__main__':
    continuous_move()

Save the file in /etc/motioneye with nanme down_1 with no extention.

Make sure the file is executable by right click, properties, permission tab, execute=Anyone

down_1 will create a down button for camera one. Do this for all your cameras.

Do the same for up, left, right for all your cameras. Remember to change the 3rd last line of python code to the proper direction ie move_up(ptz, request) for moving up

Also make sure your wsdl directory is located in /etc/onvif/ . You can use sudo pcmanfm to search for it and copie it to the right path

More info on action buttons.

Restart motioneye with

systemctl restart motioneye

You should now see the action buttons on the motionEye web interface and they should be able to pan and tilt your ONVIF compliant cameras.

Automation Contest

Participated in the
Automation Contest