def __init__(self):
     self.cam = AmcrestCamera('192.168.1.108', 80, 'user',
                              'abc123abc').camera
     rospy.init_node('amcrest_controller', anonymous=True)
     rospy.Subscriber("/joy", Joy, self.joy_callback)
     self.init_move_logic()
     self.r = rospy.Rate(5)
def initializeCamera():
  global camera, cam2
  ip = '10.21.4.48'
  port = 80
  username = '******'
  password = '******'
  camera = AmcrestCamera(ip, port, username, password, retries_connection=5).camera
  cam2 = AmcrestCamera(ip,port,username, password,retries_connection=5).camera
Example #3
0
 def fetchFeed(camera):
     logger = logging.getLogger(__name__)
     try:
         device = AmcrestCamera(host= camera.ip_address, port = 80, user = camera.username, password =camera.password).camera
         to_return = device.mjpeg_url()
         return to_return
     except:
         path = "/Images/int_error.png"
         return path
Example #4
0
    def __init__(self, args: argparse.Namespace, logger: logging.Logger) -> None:
        super().__init__(args, logger)
        self.snapshot_dir = tempfile.mkdtemp()
        if self.args.snapshot_channel is None:
            self.args.snapshot_channel = self.args.channel - 1
        if self.args.motion_index is None:
            self.args.motion_index = self.args.snapshot_channel

        self.camera = AmcrestCamera(
            self.args.ip, 80, self.args.username, self.args.password
        ).camera
Example #5
0
def setup_platform(hass, config, add_devices, discovery_info=None):
    """Set up a sensor for an Amcrest IP Camera."""
    from amcrest import AmcrestCamera

    camera = AmcrestCamera(config.get(CONF_HOST), config.get(CONF_PORT),
                           config.get(CONF_USERNAME),
                           config.get(CONF_PASSWORD)).camera

    persistent_notification = loader.get_component('persistent_notification')
    try:
        camera.current_time
    except (ConnectTimeout, HTTPError) as ex:
        _LOGGER.error("Unable to connect to Amcrest camera: %s", str(ex))
        persistent_notification.create(
            hass,
            'Error: {}<br />'
            'You will need to restart hass after fixing.'
            ''.format(ex),
            title=NOTIFICATION_TITLE,
            notification_id=NOTIFICATION_ID)
        return False

    sensors = []
    for sensor_type in config.get(CONF_MONITORED_CONDITIONS):
        sensors.append(AmcrestSensor(config, camera, sensor_type))

    add_devices(sensors, True)

    return True
Example #6
0
def setup(hass, config):
    """Set up the Amcrest IP Camera component."""
    from amcrest import AmcrestCamera

    amcrest_cams = config[DOMAIN]

    persistent_notification = loader.get_component('persistent_notification')
    for device in amcrest_cams:
        camera = AmcrestCamera(device.get(CONF_HOST), device.get(CONF_PORT),
                               device.get(CONF_USERNAME),
                               device.get(CONF_PASSWORD)).camera
        try:
            camera.current_time

        except (ConnectTimeout, HTTPError) as ex:
            _LOGGER.error("Unable to connect to Amcrest camera: %s", str(ex))
            persistent_notification.create(
                hass,
                'Error: {}<br />'
                'You will need to restart hass after fixing.'
                ''.format(ex),
                title=NOTIFICATION_TITLE,
                notification_id=NOTIFICATION_ID)
            return False

        ffmpeg_arguments = device.get(CONF_FFMPEG_ARGUMENTS)
        name = device.get(CONF_NAME)
        resolution = RESOLUTION_LIST[device.get(CONF_RESOLUTION)]
        sensors = device.get(CONF_SENSORS)
        stream_source = STREAM_SOURCE_LIST[device.get(CONF_STREAM_SOURCE)]

        username = device.get(CONF_USERNAME)
        password = device.get(CONF_PASSWORD)

        # currently aiohttp only works with basic authentication
        # only valid for mjpeg streaming
        if username is not None and password is not None:
            if device.get(CONF_AUTHENTICATION) == HTTP_BASIC_AUTHENTICATION:
                authentication = aiohttp.BasicAuth(username, password)
            else:
                authentication = None

        discovery.load_platform(
            hass, 'camera', DOMAIN, {
                'device': camera,
                CONF_AUTHENTICATION: authentication,
                CONF_FFMPEG_ARGUMENTS: ffmpeg_arguments,
                CONF_NAME: name,
                CONF_RESOLUTION: resolution,
                CONF_STREAM_SOURCE: stream_source,
            }, config)

        if sensors:
            discovery.load_platform(hass, 'sensor', DOMAIN, {
                'device': camera,
                CONF_NAME: name,
                CONF_SENSORS: sensors,
            }, config)

    return True
Example #7
0
 def __init__(self, parent, primary, user, password, config=None, manifest=None, node_address=None):
     self.parent       = parent
     self.primary      = primary
     self.user         = user
     self.password     = password
     self.connected    = 0
     self.node_address = "none"
     self.l_info("init","config={0}".format(config))
     self.status = {}
     if manifest is not None:
         #
         # TODO: Get this working...
         #
         self.name  = manifest['name']
         if node_address is None:
             self.parent.send_error("Amcrest1:init:%s: node_address must be passed in when using manifest for: " % (name,manifest))
             return False
         self.node_address = node_address
         # TODO: It's ok to not have drivers?  Just let query fill out the info? 
         if not 'drivers' in manifest:
             self.parent.send_error("Amcrest1:init:%s: no drivers in manifest: " % (name,manifest))
             return False
         drivers = manifest['drivers']
         # Get the things we need from the drivers, the rest will be queried.
         self.ip    = long2ip(drivers['GV2'])
         self.port  = drivers['GV3']
         self.sys_ver = drivers['GV11']
         self.full_sys_ver = self.sys_ver
     elif config is not None:
         # Connect to the camera to get it's info.
         self.host      = config['host']
         self.port      = 80
         self.l_info("init","connecting to {0}".format(self.host))
         self.camera    = AmcrestCamera(self.host, self.port, self.user, self.password).camera
         self.l_info("init","got {0}".format(self.camera))
         # Name is the machine name
         self.name      = self.camera.machine_name.decode('utf-8').split('=')[-1].rstrip()
         # Node_Address is last 14 characters of the serial number
         self.node_address = self.camera.serial_number.decode('utf-8').split()[0][-14:].lower()
     else:
         self.parent.send_error("Amcrest1:init:%s: One of manifest or config must be passed in." % (node_address))
         return False
     # Add the Camera
     self.l_info("init","Adding %s %s" % (self.name,self.node_address))
     super(Amcrest1, self).__init__(parent, self.node_address, self.name, primary, manifest)
     # This tracks if _set_motion_params was successful
     self.set_motion_params_st = True
     # Call query to pull in the rest of the params.
     self.query();
     # Add my motion node now that the camera is defined.
     #self.motion = Motion(parent, self, manifest)
     # Tell the camera to ping the parent server on motion.
     #self._set_alarm_params({
     #    'motion_armed': 1,
     #    'http':         1,
     #    'http_url':     "http://%s:%s/motion/%s" % (parent.server.server_address[0], parent.server.server_address[1], self.motion.address)
     #});
     # Query again now that we have set paramaters
     #self.query();
     self.l_info("init","Done Adding camera at %s:%s '%s' %s" % (self.host,self.port,self.name,self.node_address))
Example #8
0
 def update_config(self,user,password,config=None):
     self.name      = "NewCamera"
     self.host      = config['host']
     if 'port' in config:
         self.port = config['port']
     else:
         self.port = 80
     # Need to connect to camera to get it's info.
     self.l_info("init","connecting to {0}".format(self.host))
     #
     # TODO: What happens in error? try/catch?
     self.camera    = AmcrestCamera(self.host, self.port, self.user, self.password).camera
     self.l_info("init","got {0}".format(self.camera))
     # Node_Address is last 14 characters of the serial number
     self.address = get_valid_node_name(self.camera.serial_number.split()[0][-14:].lower())
     # Name is the machine name
     self.name      = get_valid_node_name(self.camera.machine_name.split('=')[-1].rstrip())
     self.ip = get_network_ip(self.host)
     self.sys_ver      = 0
Example #9
0
    def fetchFrame(camera):
        logger = logging.getLogger(__name__)

        try:
            device = AmcrestCamera(host= camera.ip_address, port = 80, user = camera.username, password =camera.password).camera
            cwd = os.getcwd()
            img_path = '/Images/' + camera.short_name + '.png'  
            full_path =cwd +img_path 
            request = device.snapshot(path_file = full_path)
            if request._fp_bytes_read <1000:  
                os.remove(full_path)
                raise AmcrestError            
            del device
            return img_path

        except AmcrestError:
            camera_source = '/Images/cam_not_found.png'
            logging.error("Camera Error: "+ camera.short_name)
            return camera_source
        except:
            path = "/Images/int_error.png"
            return path
Example #10
0
def takeSnap():
    timeLag(1.5)
    for i in range(1):
        global img_no
        global camera
        image_path = image_dir + '/image' + str(img_no) + '.png'
        img = camera.snapshot(0, image_path)
        print(img.status)
        if img.status != 200:
            camera = AmcrestCamera(ip, port, username, password).camera
            print('image data not found')
            print('trying again')
            return -1
        img_no += 1
Example #11
0
def setup_platform(hass, config, add_devices, discovery_info=None):
    """Set up an Amcrest IP Camera."""
    from amcrest import AmcrestCamera
    data = AmcrestCamera(config.get(CONF_HOST), config.get(CONF_PORT),
                         config.get(CONF_USERNAME), config.get(CONF_PASSWORD))

    persistent_notification = loader.get_component('persistent_notification')
    try:
        data.camera.current_time
    # pylint: disable=broad-except
    except Exception as ex:
        _LOGGER.error("Unable to connect to Amcrest camera: %s", str(ex))
        persistent_notification.create(
            hass,
            'Error: {}<br />'
            'You will need to restart hass after fixing.'
            ''.format(ex),
            title=NOTIFICATION_TITLE,
            notification_id=NOTIFICATION_ID)
        return False

    add_devices([AmcrestCam(config, data)])
    return True
Example #12
0
# Exit if any of the required vars are not provided
if amcrest_host is None:
    log("Please set the AMCREST_HOST environment variable", level="ERROR")
    sys.exit(1)

if amcrest_password is None:
    log("Please set the AMCREST_PASSWORD environment variable", level="ERROR")
    sys.exit(1)

if mqtt_username is None:
    log("Please set the MQTT_USERNAME environment variable", level="ERROR")
    sys.exit(1)

# Connect to camera
camera = AmcrestCamera(amcrest_host, amcrest_port, amcrest_username,
                       amcrest_password).camera

device_type = camera.device_type.replace("type=", "").strip()
log(f"Device type: {device_type}")

serial_number = camera.serial_number.strip()
log(f"Serial number: {serial_number}")

sw_version = camera.software_information[0].replace("version=", "").strip()
log(f"Software version: {sw_version}")

device_name = camera.machine_name.replace("name=", "").strip()
device_slug = slugify(device_name, separator="_")
log(f"Device name: {device_name}")

# Connect to MQTT
Example #13
0
#!/usr/bin/python

import subprocess
import serial
from amcrest import AmcrestCamera
import time
amcrest = AmcrestCamera('192.168.0.32', 80, 'admin', 'perception1')
camera = amcrest.camera
camera.snapshot(channel=0, path_file="/home/ramakuma/catkin_ws/src/FileExchangeEntry/image.jpg")
camera.snapshot(channel=0, path_file="/home/ramakuma/catkin_ws/src/FileExchangeEntry/Caminput_images2/image.jpg")
#ser = serial.Serial('/dev/ttyACM0',9600)
#print "start"
subprocess.call("./run_mat.sh", shell=True)
file = open("out.txt", "r") 
a= file.read() 
print a
#ser.write(a)
file = open("out.txt", "r") 
a= file.read()
print a
file.close()
with open("ros_node.sh", "r") as file:
    data = file.readlines()
data[1] = 'rostopic pub trash_no std_msgs/UInt16 '+str(a)+'\n'
with open("ros_node.sh", "w") as file:
    file.writelines( data )
file.close()
subprocess.call("./ros_node.sh", shell=True)
file = open("out.txt", "w") 
file.write('0') 
file.close()
Example #14
0

def stream_audio():
    camera.audio_stream_capture(httptype="singlepart", channel=1)


# Main function for initializing a process for each camera
if __name__ == '__main__':
    globalVars.init()
    quitEvent = threading.Event()
    processes = []

    try:
        for camera in globalVars.cameraList:

            amcrest = AmcrestCamera(camera['hostname'], camera['port'],
                                    camera['username'], camera['password'])

            tenantName = camera['chameleontenantname']
            containerName = camera['chameleoncontainername']
            path = camera['chameleonpath']
            path = path.lstrip("/")
            path = path.rstrip("/")

            cameraURL = "rtsp://" + camera['username'] + ":" + camera[
                'password'] + "@" + camera[
                    'hostname'] + ":554/cam/realmonitor?channel=1&subtype=0"

            camera = amcrest.camera
            cameraName = camera.machine_name[5:].strip()

            camera.realtime_swift_stream = types.MethodType(
Example #15
0
# -*- coding: utf-8 -*-
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# vim:sw=4:ts=4:et

from amcrest import AmcrestCamera

amcrest = AmcrestCamera('192.168.1.10', 80, 'admin', 'super_password')
camera = amcrest.camera

camera.snapshot(channel=0, path_file="/tmp/snapshot.jpg")
Example #16
0
###############################################################################
# API Connections - Global
###############################################################################
global twilio
global bucket
global camera

# Twilio API
twilio = Client(cfg.TWILIO_ACCOUNT_SID, cfg.TWILIO_AUTH_TOKEN)

# AWS S3 Connection
s3 = boto.connect_s3(cfg.AWS_ACCESS_KEY_ID, cfg.AWS_SECRET_ACCESS_KEY)
bucket = s3.get_bucket(cfg.AWS_BUCKET_NAME)

# Amcrest Cameras
camera = AmcrestCamera(cfg.AMCREST_IP, 80, cfg.AMCREST_USER,
                       cfg.AMCREST_PASS).camera


###############################################################################
# Logging Helper Function
###############################################################################
def log(out):
    print(str(datetime.now()) + " " + out)


###############################################################################
# Doorbell Thread Alert Thread
###############################################################################


class doorbell_alert(threading.Thread):
Example #17
0
def setup(hass, config):
    """Set up the Amcrest IP Camera component."""
    from amcrest import AmcrestCamera, AmcrestError

    hass.data.setdefault(DATA_AMCREST, {'devices': {}, 'cameras': []})
    devices = config[DOMAIN]

    for device in devices:
        name = device[CONF_NAME]
        username = device[CONF_USERNAME]
        password = device[CONF_PASSWORD]

        try:
            api = AmcrestCamera(device[CONF_HOST], device[CONF_PORT], username,
                                password).camera
            # pylint: disable=pointless-statement
            # Test camera communications.
            api.current_time

        except AmcrestError as ex:
            _LOGGER.error("Unable to connect to %s camera: %s", name, str(ex))
            hass.components.persistent_notification.create(
                'Error: {}<br />'
                'You will need to restart hass after fixing.'
                ''.format(ex),
                title=NOTIFICATION_TITLE,
                notification_id=NOTIFICATION_ID)
            continue

        ffmpeg_arguments = device[CONF_FFMPEG_ARGUMENTS]
        resolution = RESOLUTION_LIST[device[CONF_RESOLUTION]]
        binary_sensors = device.get(CONF_BINARY_SENSORS)
        sensors = device.get(CONF_SENSORS)
        switches = device.get(CONF_SWITCHES)
        stream_source = device[CONF_STREAM_SOURCE]

        # currently aiohttp only works with basic authentication
        # only valid for mjpeg streaming
        if device[CONF_AUTHENTICATION] == HTTP_BASIC_AUTHENTICATION:
            authentication = aiohttp.BasicAuth(username, password)
        else:
            authentication = None

        hass.data[DATA_AMCREST]['devices'][name] = AmcrestDevice(
            api, authentication, ffmpeg_arguments, stream_source, resolution)

        discovery.load_platform(hass, CAMERA, DOMAIN, {
            CONF_NAME: name,
        }, config)

        if binary_sensors:
            discovery.load_platform(hass, BINARY_SENSOR, DOMAIN, {
                CONF_NAME: name,
                CONF_BINARY_SENSORS: binary_sensors
            }, config)

        if sensors:
            discovery.load_platform(hass, SENSOR, DOMAIN, {
                CONF_NAME: name,
                CONF_SENSORS: sensors,
            }, config)

        if switches:
            discovery.load_platform(hass, SWITCH, DOMAIN, {
                CONF_NAME: name,
                CONF_SWITCHES: switches
            }, config)

    if not hass.data[DATA_AMCREST]['devices']:
        return False

    def have_permission(user, entity_id):
        return not user or user.permissions.check_entity(
            entity_id, POLICY_CONTROL)

    async def async_extract_from_service(call):
        if call.context.user_id:
            user = await hass.auth.async_get_user(call.context.user_id)
            if user is None:
                raise UnknownUser(context=call.context)
        else:
            user = None

        if call.data.get(ATTR_ENTITY_ID) == ENTITY_MATCH_ALL:
            # Return all entity_ids user has permission to control.
            return [
                entity_id for entity_id in hass.data[DATA_AMCREST]['cameras']
                if have_permission(user, entity_id)
            ]

        call_ids = await async_extract_entity_ids(hass, call)
        entity_ids = []
        for entity_id in hass.data[DATA_AMCREST]['cameras']:
            if entity_id not in call_ids:
                continue
            if not have_permission(user, entity_id):
                raise Unauthorized(context=call.context,
                                   entity_id=entity_id,
                                   permission=POLICY_CONTROL)
            entity_ids.append(entity_id)
        return entity_ids

    async def async_service_handler(call):
        args = []
        for arg in CAMERA_SERVICES[call.service][2]:
            args.append(call.data[arg])
        for entity_id in await async_extract_from_service(call):
            async_dispatcher_send(hass, service_signal(call.service,
                                                       entity_id), *args)

    for service, params in CAMERA_SERVICES.items():
        hass.services.async_register(DOMAIN, service, async_service_handler,
                                     params[0])

    return True
Example #18
0
# -*- coding: utf-8 -*-
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# vim:sw=4:ts=4:et

import datetime
from amcrest import AmcrestCamera

amcrest = AmcrestCamera("192.168.1.10", 80, "admin", "super_password")
camera = amcrest.camera

end_time = datetime.datetime.now()
start_time = end_time - datetime.timedelta(hours=1)

for text in camera.log_find(start_time, end_time):
    print(text)
Example #19
0
# Setup logging
logging.basicConfig(
    format="%(asctime)s %(levelname)s %(message)s",
    level=logging.INFO,
    datefmt="%m/%d/%Y %I:%M:%S %p",
)

url = os.getenv("CAVA_URL")
uri = os.getenv("CAVA_URI")
mycamera = os.getenv("CAVA_CAMERA")
user = os.getenv("CAVA_USER")
password = os.getenv("CAVA_PASSWORD")

logging.info("Starting Amcrest Sensor")
camera = AmcrestCamera(mycamera, 80, user, password).camera
logging.info(f"Attempting to connect to camera {mycamera}")
device = camera.machine_name.rstrip()
# device = device.split("=")[1]
logging.info(f"Connected to {device} on {mycamera}")

for event in camera.event_stream("VideoMotion"):
    event = event.rstrip().strip()  # Get rid of carriage returns
    parsed_event = event.split(";")
    my_event = amcrest_event()
    my_event.camera = mycamera
    for item in parsed_event:
        element = item.split("=")
        if element[0].lower() == "code":
            my_event.code = element[1]
        if element[0].lower() == "action":
class ros_amcrest:
    def __init__(self):
        self.cam = AmcrestCamera('192.168.1.108', 80, 'user',
                                 'abc123abc').camera
        rospy.init_node('amcrest_controller', anonymous=True)
        rospy.Subscriber("/joy", Joy, self.joy_callback)
        self.init_move_logic()
        self.r = rospy.Rate(5)

    def init_move_logic(self):
        astep = 45  #math.radians(45) #angle step
        self.angles = []
        self.speeds = range(9)
        for i in range(8):
            self.angles.append(i * astep)

    def joy_callback(self, data):
        self.last_joy = data

    def move(self):
        try:
            joy_data = self.last_joy
        except:
            return
        x = -joy_data.axes[3]  #collect joy stick position
        y = -joy_data.axes[4]
        angle = math.atan2(y, x)  #calcualte angle
        mag = math.sqrt(x**2 + y**2)
        if angle < 0:  #check if in 3 and 4 quadrant and convert to angle from +x
            angle = angle + 2 * math.pi
        angle = math.degrees(angle)  #convert to degrees
        joy_angle = takeClosest(
            self.angles, angle)  #get closest multiple of 45 to measured angle
        joy_mag = takeClosest(self.speeds, mag * 8)
        if joy_mag > 0:
            #print(joy_angle,joy_mag) #Debug

            #Call correct command based on angle:
            if joy_angle == 0:
                self.cam.move_right(action="start",
                                    channel=0,
                                    vertical_speed=joy_mag)
            elif joy_angle == 45:
                self.cam.move_right_up(action="start",
                                       channel=0,
                                       vertical_speed=joy_mag)
            elif joy_angle == 90:
                self.cam.move_up(action="start",
                                 channel=0,
                                 vertical_speed=joy_mag)
            elif joy_angle == 135:
                self.cam.move_left_up(action="start",
                                      channel=0,
                                      vertical_speed=joy_mag)
            elif joy_angle == 180:
                self.cam.move_left(action="start",
                                   channel=0,
                                   vertical_speed=joy_mag)
            elif joy_angle == 225:
                self.cam.move_left_down(action="start",
                                        channel=0,
                                        vertical_speed=joy_mag)
            elif joy_angle == 270:
                self.cam.move_down(action="start",
                                   channel=0,
                                   vertical_speed=joy_mag)
            elif joy_angle == 315:
                self.cam.move_right_down(action="start",
                                         channel=0,
                                         vertical_speed=joy_mag)
        else:
            self.cam.move_right(
                action="stop", channel=0,
                vertical_speed=0)  #stop motor if no speed requested

    def spinner(self):
        while not rospy.is_shutdown():
            self.move()
            self.r.sleep()
Example #21
0
# bit rate 512           0.94

# frame interval 30 (default)
# 15 fps  15 interval  0.94
# 15 fps  30 interval  0.94
# 15 fps 150 interval  0.94

# 4K   15 fps  0.75
# 4K   10 fps
# 4K    2 fps  0.75, slower lag
#      15 fps  4096 bit   0.75

# 1080   15 fps, 0.93

# camera = AmcrestCamera("192.168.1.109",80,"admin","uwasat0ad").camera
camera = AmcrestCamera("192.168.1.142", 80, "admin", "jg00dman").camera
cv2.namedWindow('Amcrest', cv2.WINDOW_NORMAL)

# works
# http://admin:[email protected]/cgi-bin/snapshot.cgi?channel=1
# http://admin:[email protected]/cgi-bin/snapshot.cgi
# http://admin:[email protected]/cgi-bin/snapshot.cgi

# http://admin:[email protected]/cgi-bin/mjpg/video.cgi
# http://admin:[email protected]/cgi-bin/mjpg/video.cgi

# http://admin:[email protected]/cgi-bin/devAudioInput.cga?action=getCollect

# works
# http://admin:[email protected]/cgi-bin/configManager.cgi?action=getConfig&name=Snap
Example #22
0
class Amcrest1(Node):
    """ 
    Node that contains the Amcrest connection settings
    """

    def __init__(self, parent, primary, user, password, config=None, manifest=None, node_address=None):
        self.parent       = parent
        self.primary      = primary
        self.user         = user
        self.password     = password
        self.connected    = 0
        self.node_address = "none"
        self.l_info("init","config={0}".format(config))
        self.status = {}
        if manifest is not None:
            #
            # TODO: Get this working...
            #
            self.name  = manifest['name']
            if node_address is None:
                self.parent.send_error("Amcrest1:init:%s: node_address must be passed in when using manifest for: " % (name,manifest))
                return False
            self.node_address = node_address
            # TODO: It's ok to not have drivers?  Just let query fill out the info? 
            if not 'drivers' in manifest:
                self.parent.send_error("Amcrest1:init:%s: no drivers in manifest: " % (name,manifest))
                return False
            drivers = manifest['drivers']
            # Get the things we need from the drivers, the rest will be queried.
            self.ip    = long2ip(drivers['GV2'])
            self.port  = drivers['GV3']
            self.sys_ver = drivers['GV11']
            self.full_sys_ver = self.sys_ver
        elif config is not None:
            # Connect to the camera to get it's info.
            self.host      = config['host']
            self.port      = 80
            self.l_info("init","connecting to {0}".format(self.host))
            self.camera    = AmcrestCamera(self.host, self.port, self.user, self.password).camera
            self.l_info("init","got {0}".format(self.camera))
            # Name is the machine name
            self.name      = self.camera.machine_name.decode('utf-8').split('=')[-1].rstrip()
            # Node_Address is last 14 characters of the serial number
            self.node_address = self.camera.serial_number.decode('utf-8').split()[0][-14:].lower()
        else:
            self.parent.send_error("Amcrest1:init:%s: One of manifest or config must be passed in." % (node_address))
            return False
        # Add the Camera
        self.l_info("init","Adding %s %s" % (self.name,self.node_address))
        super(Amcrest1, self).__init__(parent, self.node_address, self.name, primary, manifest)
        # This tracks if _set_motion_params was successful
        self.set_motion_params_st = True
        # Call query to pull in the rest of the params.
        self.query();
        # Add my motion node now that the camera is defined.
        #self.motion = Motion(parent, self, manifest)
        # Tell the camera to ping the parent server on motion.
        #self._set_alarm_params({
        #    'motion_armed': 1,
        #    'http':         1,
        #    'http_url':     "http://%s:%s/motion/%s" % (parent.server.server_address[0], parent.server.server_address[1], self.motion.address)
        #});
        # Query again now that we have set paramaters
        #self.query();
        self.l_info("init","Done Adding camera at %s:%s '%s' %s" % (self.host,self.port,self.name,self.node_address))

    def query(self, **kwargs):
        """ query the camera """
        # pylint: disable=unused-argument
        self.l_info("query","start")
        self._get_status()
        if self.connected == 1:
            # Full System Version
            self.full_sys_ver = self.camera.software_information[0].split('=')[1].decode('utf-8');
            sys_ver_l = self.full_sys_ver.split('.')
            # Just the first part as a float
            self.sys_ver      = myfloat("{0}.{1}".format(sys_ver_l[0],sys_ver_l[1]))
            self.set_driver('GV1', self.sys_ver, uom=56)
            # Initialize network info
            self.ip_address = get_network_ip(self.host)
            self.set_driver('GV2',  ip2long(self.ip_address), uom=56, report=False)
            self.set_driver('GV3',  self.port, uom=56, report=False)
            # Motion
            self.set_driver('GV5', bool2int(self.camera.is_motion_detector_on()), uom=2)
            self._get_motion_params()
            self.set_driver('GV6', self.record_enable,   uom=2)
            self.set_driver('GV7', self.mail_enable,     uom=2)
            self.set_driver('GV8', self.snapshot_enable, uom=2)
            self.set_driver('GV9', self.snapshot_times,  uom=56)
            # All done.
            self.report_driver()
        self.l_info("query","done")
        return True

    def poll(self):
        """ Nothing to poll?  """
        #response = os.system("ping -c 1 -w2 " + self.ip + " > /dev/null 2>&1")
        # Fix the motion params if it failed the last time.
        #if not self.set_motion_params_st and self.connected == 1:
        #    self._set_motion_params()
        self.l_debug("poll","none")
        return

    def long_poll(self):
        self.l_info("long_poll","start")
        # get_status handles properly setting self.connected and the driver
        # so just call it.
        self._get_status()
        self.l_debug("long_poll","done")
        return
    
    def l_info(self, name, string):
        self.parent.logger.info("%s:%s:%s: %s" %  (self.node_def_id,self.node_address,name,string))
        
    def l_error(self, name, string):
        estr = "%s:%s:%s: %s" % (self.node_def_id,self.node_address,name,string)
        self.parent.logger.error(estr)
        self.parent.send_error(estr)
    
    def l_warning(self, name, string):
        self.parent.logger.warning("%s:%s:%s: %s" % (self.node_def_id,self.node_address,name,string))
        
    def l_debug(self, name, string):
        self.parent.logger.debug("%s:%s:%s: %s" % (self.node_def_id,self.node_address,name,string))
        
    # **********************************************************************
    #
    # Functions to grab current state of camera.
    #
    
    def _get_status(self):
        """
        Simple check if the camera is responding.
        """
        self.l_info("_get_status","%s:%s" % (self.host,self.port))
        # Get the led_mode since that is the simplest return status
        rc = self.camera.machine_name
        self.parent.logger.info("_get_status: {0}".format(rc))
        if rc == 0:
            connected = 0
            self.l_error("_get_status"," Failed to get_status: {0}".format(rc))
        else:
            connected = 1
        if connected != self.connected:
            self.connected = connected
            self.set_driver('GV4', self.connected, uom=2, report=True)
        return self.connected
        
    def _get_motion_params(self):
        self.l_info("_get_motion_params","start")
        self.mail_enable     = 0
        self.record_enable   = 0
        self.snapshot_enable = 0
        self.snapshot_times  = 0
        #
        # Grab all motion detect params in one call
        #
        ret = self.camera.motion_detection
        for s in ret.split():
            if '=' in s:
                a = s.split('=')
                name  = a[0]
                value = a[1]
                if '.MailEnable' in name:
                    self.l_info("_get_motion_params","name='{0}' value={1}".format(name,value))
                    self.mail_enable = str2int(value)
                elif '.RecordEnable' in name:
                    self.l_info("_get_motion_params","name='{0}' value={1}".format(name,value))
                    self.record_enable = str2int(value)
                elif '.SnapshotEnable' in name:
                    self.l_info("_get_motion_params","name='{0}' value={1}".format(name,value))
                    self.snapshot_enable = str2int(value)
                elif '.SnapshotTimes' in name:
                    self.l_info("_get_motion_params","name='{0}' value={1}".format(name,value))
                    self.snapshot_times = int(value)
        self.l_info("_get_motion_params","done")
        return

    # **********************************************************************
    #
    # Functions to set state of camera.
    #
    def _set_vmd_enable(self, driver=None, **kwargs):
        """
        Video Motion Detect
        """
        value = kwargs.get("value")
        if value is None:
            self.l_error("_set_vmd_enable","_set_vmd_enable not passed a value: %s" % (value))
            return False
        # TODO: Should use the _driver specified function instead of int.
        self.l_info("_set_vmd_enable","_set_vmd_enable %s" % (value))
        self.camera.motion_detection = int2str(value)
        self.l_info("_set_vmd_enable","is_motion_detector_on: {0}".format(self.camera.is_motion_detector_on()))
        self.set_driver(driver, bool2int(self.camera.is_motion_detector_on()), uom=2, report=True)
        return True

    def _set_motion_param(self, driver=None, param=None, convert=None, **kwargs):
        value = kwargs.get("value")
        if value is None:
            self.l_error("_set_motion_param","not passed a value: %s" % (value) )
            return False
        if convert is not None:
            if convert == "int2str":
                sval = int2str(value)
            elif convert == "int":
                sval = int(value)
            else:
                self.l_info("_set_motion_param","unknown convert={0}".format(convert))
        command = 'configManager.cgi?action=setConfig&MotionDetect[0].EventHandler.{0}={1}'.format(param,sval)
        self.l_info("_set_motion_param","comand={0}".format(command))
        rc = self.camera.command(command)
        self.l_info("_set_motion_param","return={0}".format(rc.content.decode('utf-8')))
        if "ok" in rc.content.decode('utf-8').lower():
            self.set_driver(driver, int(value)) #, 56
            return True
        self.parent.send_error("_set_motion_param failed to set {0}={1} return={2}".format(param,value,rc))
        return False

    def _goto_preset(self, **kwargs):
        """ Goto the specified preset. """
        value = kwargs.get("value")
        if value is None:
            self.parent.send_error("_goto_preset not passed a value: %s" % (value) )
            return False
        rc = self.camera.go_to_preset(action='start', channel=0, preset_point_number=int(value))
        self.l_info("_goto_preset","return={0}".format(rc))
        if "ok" in rc.decode('utf-8').lower():
            return True
        self.parent.send_error("_goto_preset failed to set {0} message={1}".format(int(value),rc))
        return True

    _drivers = {
        # Camera System Version
        'GV1': [0, 56, myfloat],
        # IP Address
        'GV2': [0, 56, myint],
        # Port
        'GV3': [0, 56, myint],
        # Responding
        'GV4': [0, 2,  myint],
        # Video motion detect
        'GV5': [0, 2,  myint],
        'GV6': [0, 2,  myint],
        'GV7': [0, 2,  myint],
        'GV8': [0, 2,  myint],
        'GV9': [0, 56, myint],
    }
    _commands = {
        'QUERY': query,
        'SET_VMD_ENABLE':  partial(_set_vmd_enable,  driver="GV5" ),
        'SET_VMD_RECORD': partial(_set_motion_param, driver="GV6", param='MailEnable', convert="int2str"),
        'SET_VMD_EMAIL': partial(_set_motion_param, driver="GV7", param='RecordEnable', convert="int2str"),
        'SET_VMD_SNAPSHOT': partial(_set_motion_param, driver="GV8", param='SnapshotEnable', convert="int2str"),
        'SET_VMD_SNAPSHOT_COUNT': partial(_set_motion_param, driver="GV9", param='SnapshotTimes', convert="int"),
        'SET_POS':   _goto_preset,
#        'REBOOT':    _reboot,
    }
    # The nodeDef id of this camers.
    node_def_id = 'Amcrest1'
Example #23
0
class DahuaCam(UnifiCamBase):
    def __init__(self, args: argparse.Namespace, logger: logging.Logger) -> None:
        super().__init__(args, logger)
        self.snapshot_dir = tempfile.mkdtemp()
        if self.args.snapshot_channel is None:
            self.args.snapshot_channel = self.args.channel - 1
        if self.args.motion_index is None:
            self.args.motion_index = self.args.snapshot_channel

        self.camera = AmcrestCamera(
            self.args.ip, 80, self.args.username, self.args.password
        ).camera

    @classmethod
    def add_parser(cls, parser: argparse.ArgumentParser) -> None:
        super().add_parser(parser)
        parser.add_argument(
            "--username",
            "-u",
            required=True,
            help="Camera username",
        )
        parser.add_argument(
            "--password",
            "-p",
            required=True,
            help="Camera password",
        )
        parser.add_argument(
            "--channel",
            "-c",
            required=False,
            type=int,
            default=1,
            help="Camera channel",
        )
        parser.add_argument(
            "--snapshot-channel",
            required=False,
            type=int,
            default=None,
            help="Snapshot channel",
        )
        parser.add_argument(
            "--main-stream",
            required=False,
            type=int,
            default=0,
            help="Main Stream subtype index",
        )
        parser.add_argument(
            "--sub-stream",
            required=False,
            type=int,
            default=1,
            help="Sub Stream subtype index",
        )
        parser.add_argument(
            "--motion-index",
            required=False,
            type=int,
            default=None,
            help="VideoMotion event index",
        )

    async def get_snapshot(self) -> Path:
        img_file = Path(self.snapshot_dir, "screen.jpg")
        try:
            snapshot = await self.camera.async_snapshot(
                channel=self.args.snapshot_channel
            )
            with img_file.open("wb") as f:
                f.write(snapshot)
        except CommError as e:
            self.logger.warning("Could not fetch snapshot", exc_info=e)
            pass
        return img_file

    async def run(self) -> None:
        if self.args.motion_index == -1:
            return
        while True:
            self.logger.info("Connecting to motion events API")
            try:
                async for event in self.camera.async_event_actions(
                    eventcodes="VideoMotion,SmartMotionHuman,SmartMotionVehicle"
                ):
                    code = event[0]
                    action = event[1].get("action")
                    index = event[1].get("index")

                    if not index or int(index) != self.args.motion_index:
                        self.logger.debug(f"Skipping event {event}")
                        continue

                    object_type = None
                    if code == "SmartMotionHuman":
                        object_type = SmartDetectObjectType.PERSON
                    elif code == "SmartMotionVehicle":
                        object_type = SmartDetectObjectType.VEHICLE

                    if action == "Start":
                        self.logger.info(f"Trigger motion start for index {index}")
                        await self.trigger_motion_start(object_type)
                    elif action == "Stop":
                        self.logger.info(f"Trigger motion end for index {index}")
                        await self.trigger_motion_stop()
            except (CommError, httpx.RequestError):
                self.logger.error("Motion API request failed, retrying")

    async def get_stream_source(self, stream_index: str) -> str:

        if stream_index == "video1":
            subtype = self.args.main_stream
        else:
            subtype = self.args.sub_stream
        try:
            return await self.camera.async_rtsp_url(
                channel=self.args.channel, typeno=subtype
            )
        except (CommError, httpx.RequestError):
            raise RetryableError("Could not generate RTSP URL")
Example #24
0
from amcrest import AmcrestCamera
import time
import datetime
import os
from PIL import Image
import io
from matplotlib import pyplot as plt
import cv2
import numpy as np

# camera configuarations
ip = '10.21.5.26'
port = 80
username = '******'
password = '******'
camera = AmcrestCamera(ip, port, username, password).camera
img_no = 1

# session details
ts = time.time()
time_string = '%d-%m-%Y_%Hh%Mm'
st = datetime.datetime.fromtimestamp(ts).strftime(time_string)
image_dir = './session_images/' + st
if not os.path.exists(image_dir):
    try:
        os.makedirs(image_dir)
        print('[INFO] Directory created.')
    except:
        print('[ERROR] Directory could not be created.')
else:
    print('[INFO] Directory already present.')
Example #25
0
def setup(hass, config):
    """Set up the Amcrest IP Camera component."""
    from amcrest import AmcrestCamera

    hass.data[DATA_AMCREST] = {}
    amcrest_cams = config[DOMAIN]

    for device in amcrest_cams:
        try:
            camera = AmcrestCamera(device.get(CONF_HOST),
                                   device.get(CONF_PORT),
                                   device.get(CONF_USERNAME),
                                   device.get(CONF_PASSWORD)).camera
            # pylint: disable=pointless-statement
            camera.current_time

        except (ConnectError, ConnectTimeout, HTTPError) as ex:
            _LOGGER.error("Unable to connect to Amcrest camera: %s", str(ex))
            hass.components.persistent_notification.create(
                'Error: {}<br />'
                'You will need to restart hass after fixing.'
                ''.format(ex),
                title=NOTIFICATION_TITLE,
                notification_id=NOTIFICATION_ID)
            continue

        ffmpeg_arguments = device.get(CONF_FFMPEG_ARGUMENTS)
        name = device.get(CONF_NAME)
        resolution = RESOLUTION_LIST[device.get(CONF_RESOLUTION)]
        sensors = device.get(CONF_SENSORS)
        switches = device.get(CONF_SWITCHES)
        stream_source = STREAM_SOURCE_LIST[device.get(CONF_STREAM_SOURCE)]

        username = device.get(CONF_USERNAME)
        password = device.get(CONF_PASSWORD)

        # currently aiohttp only works with basic authentication
        # only valid for mjpeg streaming
        if username is not None and password is not None:
            if device.get(CONF_AUTHENTICATION) == HTTP_BASIC_AUTHENTICATION:
                authentication = aiohttp.BasicAuth(username, password)
            else:
                authentication = None

        hass.data[DATA_AMCREST][name] = AmcrestDevice(camera, name,
                                                      authentication,
                                                      ffmpeg_arguments,
                                                      stream_source,
                                                      resolution)

        discovery.load_platform(hass, 'camera', DOMAIN, {
            CONF_NAME: name,
        }, config)

        if sensors:
            discovery.load_platform(hass, 'sensor', DOMAIN, {
                CONF_NAME: name,
                CONF_SENSORS: sensors,
            }, config)

        if switches:
            discovery.load_platform(hass, 'switch', DOMAIN, {
                CONF_NAME: name,
                CONF_SWITCHES: switches
            }, config)

    return True
Example #26
0
class Amcrest(polyinterface.Node):
    def __init__(self, controller, user, password, config=None, node_data=None):
        self.user = user
        self.password = password
        if node_data is None:
            # Only config is passed in for a new node, so we need start to get some info.
            self.init      = True
            self.update_config(user,password,config=config)
        else:
            # Re-adding an existing node, which happens on restart.
            self.init      = False
            self.name      = node_data['name']
            self.address   = node_data['address']
        self.st  = False
        super(Amcrest, self).__init__(controller, self.address, self.address, self.name)

    # This is called by __init__ and the Controller during a discover
    def update_config(self,user,password,config=None):
        self.name      = "NewCamera"
        self.host      = config['host']
        if 'port' in config:
            self.port = config['port']
        else:
            self.port = 80
        # Need to connect to camera to get it's info.
        self.l_info("init","connecting to {0}".format(self.host))
        #
        # TODO: What happens in error? try/catch?
        self.camera    = AmcrestCamera(self.host, self.port, self.user, self.password).camera
        self.l_info("init","got {0}".format(self.camera))
        # Node_Address is last 14 characters of the serial number
        self.address = get_valid_node_name(self.camera.serial_number.split()[0][-14:].lower())
        # Name is the machine name
        self.name      = get_valid_node_name(self.camera.machine_name.split('=')[-1].rstrip())
        self.ip = get_network_ip(self.host)
        self.sys_ver      = 0

    def update_drivers(self):
        self.setDriver('GV2',  ip2long(self.ip))
        self.setDriver('GV3',  self.port)
        self.setDriver('GV11', self.sys_ver)

    def start(self):
        if self.init:
            self.update_drivers()
        else:
            # It's an existing Node, so get the info we need from it.
            g_ip    = self.getDriver('GV2')
            g_port  = self.getDriver('GV3')
            g_authm = self.getDriver('GV10')
            self.l_info("start","ip={0} port={1} auth_mode={2}".format(g_ip,g_port,g_authm))
            if int(g_ip) == 0:
                self.l_error("start","The IP address (GV2) was set to zero?  That's not good, you will need to run discover again")
            if int(g_port) == 0:
                self.l_error("start","The port (GV3) was set to zero?  That's not good, you will need to run discover again")
            self.ip        = long2ip(int(g_ip))
            self.port      = g_port
            self.auth_mode = int(g_authm)
            self.l_info("start","ip={0} port={1} auth_mode={2}".format(self.ip,self.port,self.auth_mode))
            # This will force query to get it
            self.sys_ver      = 0
            self.full_sys_ver = None
            # Make sure drivers are up to date.
            self.update_drivers()
        # Add my motion node now that the camera is defined.
        self.motion = self.controller.addNode(Motion(self.controller, self, self))
        # Call query to pull in the params before adding the motion node.
        self.query();

    def query(self):
        """ query the camera """
        # pylint: disable=unused-argument
        self.l_info("query","start")
        self.get_status()
        if self.st:
            # Full System Version
            self.full_sys_ver = str_d(self.camera.software_information[0].split('=')[1]);
            sys_ver_l = self.full_sys_ver.split('.')
            # Just the first part as a float
            self.sys_ver      = myfloat("{0}.{1}".format(sys_ver_l[0],sys_ver_l[1]))
            self.setDriver('GV1', self.sys_ver)
            # Initialize network info
            # Motion
            self.setDriver('GV5', bool2int(self.camera.is_motion_detector_on()))
            self.get_motion_params()
            self.setDriver('GV6', self.record_enable)
            self.setDriver('GV7', self.mail_enable)
            self.setDriver('GV8', self.snapshot_enable)
            self.setDriver('GV9', self.snapshot_times)
            # All done.
            self.reportDrivers()
        self.l_info("query","done")
        return True

    def shortPoll(self):
        """ Nothing to poll?  """
        #response = os.system("ping -c 1 -w2 " + self.ip + " > /dev/null 2>&1")
        # Fix the motion params if it failed the last time.
        #if not self.set_motion_params_st and self.connected == 1:
        #    self.set_motion_params()
        #self.l_debug("poll","none")
        return

    def longPoll(self):
        self.l_info("long_poll","start")
        # get_status handles properly setting self.connected and the driver
        # so just call it.
        self.get_status()
        self.l_debug("long_poll","done")
        return

    def l_info(self, name, string):
        LOGGER.info("%s:%s:%s: %s" %  (self.id,self.name,name,string))

    def l_error(self, name, string):
        LOGGER.error("%s:%s:%s: %s" % (self.id,self.name,name,string))

    def l_warning(self, name, string):
        LOGGER.warning("%s:%s:%s: %s" % (self.id,self.name,name,string))

    def l_debug(self, name, string):
        LOGGER.debug("%s:%s:%s: %s" % (self.id,self.name,name,string))

    # **********************************************************************
    #
    # Functions to set drivers
    #

    def set_st(self,value,force=False):
        if not force and self.st == value:
            return value
        self.st = value
        if value:
            self.setDriver('ST', 1)
        else:
            self.setDriver('ST', 0)
        return value

    # **********************************************************************
    #
    # Functions to grab current state of camera.
    #

    def get_status(self):
        """
        Simple check if the camera is responding.
        """
        self.l_info("get_status","%s:%s" % (self.host,self.port))
        # Get the led_mode since that is the simplest return status
        rc = self.camera.machine_name
        self.l_info("get_status","rc={0}".format(rc))
        if rc == 0:
            connected = False
            self.l_error("get_status"," Failed to get_status: {0}".format(rc))
        else:
            connected = True
        return self.set_st(connected)

    def get_motion_status(self):
        """
        Called by motion node to return the current motion status.
        0 = Off
        1 = On
        2 = Unknown
        """
        self.l_error('get_motion_status','Not implemented yet')
        #self.get_status()
        #if not self.cam_status or not 'alarm_status' in self.cam_status:
        #    return 2
        #return int(self.cam_status['alarm_status'])

    def get_motion_params(self):
        self.l_info("get_motion_params","start")
        self.mail_enable     = 0
        self.record_enable   = 0
        self.snapshot_enable = 0
        self.snapshot_times  = 0
        #
        # Grab all motion detect params in one call
        #
        ret = self.camera.motion_detection
        for s in ret.split():
            if '=' in s:
                a = s.split('=')
                name  = a[0]
                value = a[1]
                if '.MailEnable' in name:
                    self.l_info("get_motion_params","name='{0}' value={1}".format(name,value))
                    self.mail_enable = str2int(value)
                elif '.RecordEnable' in name:
                    self.l_info("get_motion_params","name='{0}' value={1}".format(name,value))
                    self.record_enable = str2int(value)
                elif '.SnapshotEnable' in name:
                    self.l_info("get_motion_params","name='{0}' value={1}".format(name,value))
                    self.snapshot_enable = str2int(value)
                elif '.SnapshotTimes' in name:
                    self.l_info("get_motion_params","name='{0}' value={1}".format(name,value))
                    self.snapshot_times = int(value)
        self.l_info("get_motion_params","done")
        return

    # **********************************************************************
    #
    # Functions to set state of camera.
    #
    def set_vmd_enable(self, driver=None, **kwargs):
        """
        Video Motion Detect
        """
        value = kwargs.get("value")
        if value is None:
            self.l_error("set_vmd_enable","_set_vmd_enable not passed a value: %s" % (value))
            return False
        # TODO: Should use the _driver specified function instead of int.
        self.l_info("set_vmd_enable","_set_vmd_enable %s" % (value))
        self.camera.motion_detection = int2str(value)
        self.l_info("set_vmd_enable","is_motion_detector_on: {0}".format(self.camera.is_motion_detector_on()))
        self.setDriver(driver, bool2int(self.camera.is_motion_detector_on()))
        return True

    def set_motion_param(self, driver=None, param=None, convert=None, **kwargs):
        value = kwargs.get("value")
        if value is None:
            self.l_error("set_motion_param","not passed a value: %s" % (value) )
            return False
        if convert is not None:
            if convert == "int2str":
                sval = int2str(value)
            elif convert == "int":
                sval = int(value)
            else:
                self.l_info("set_motion_param","unknown convert={0}".format(convert))
        command = 'configManager.cgi?action=setConfig&MotionDetect[0].EventHandler.{0}={1}'.format(param,sval)
        self.l_info("set_motion_param","comand={0}".format(command))
        rc = self.camera.command(command)
        self.l_debug("set_motion_param","rc={0}".format(rc))
        # Used to check content here, but status_code seems better.
        if hasattr(rc,'status_code'):
            if rc.status_code == 200:
                self.setDriver(driver, int(value))
                return True
            else:
                self.l_error("set_motion_param","command failed response_code={0}".format(rc.status_code))
        else:
            self.l_error("set_motion_param","command response object does not contain a status_code {0}".format(rc))
        self.l_error("set_motion_param","failed to set {0}={1} return={2}".format(param,value,rc))
        return False

    def cmd_set_vmd_enable(self,command):
        value = command.get("value")
        return self.set_vmd_enable(driver="GV5", value=value)

    def cmd_set_vmd_record(self,command):
        value = command.get("value")
        self.set_motion_param(driver="GV6", param='MailEnable', convert="int2str", value=value)

    def cmd_set_vmd_email(self,command):
        value = command.get("value")
        self.set_motion_param(driver="GV7", param='RecordEnable', convert="int2str", value=value)

    def cmd_set_vmd_snapshot(self,command):
        value = command.get("value")
        self.set_motion_param(driver="GV8", param='SnapshotEnable', convert="int2str", value=value)

    def cmd_set_vmd_snapshot_count(self,command):
        value = command.get("value")
        self.set_motion_param(driver="GV9", param='SnapshotTimes', convert="int", value=value)

    def cmd_goto_preset(self, command):
        """ Goto the specified preset. """
        value = command.get("value")
        if value is None:
            self.parent.send_error("_goto_preset not passed a value: %s" % (value) )
            return False
        rc = self.camera.go_to_preset(action='start', channel=0, preset_point_number=int(value))
        self.l_info("_goto_preset","return={0}".format(rc))
        if "ok" in str_d(rc).lower():
            return True
        self.parent.send_error("_goto_preset failed to set {0} message={1}".format(int(value),rc))
        return True

    drivers = [
        {'driver': 'ST',   'value': 0,  'uom': 2},  # Responding
        {'driver': 'GV0',  'value': 0,  'uom': 2},  # -- Not used --
        {'driver': 'GV1',  'value': 0,  'uom': 56}, # Camera System Version
        {'driver': 'GV2',  'value': 0,  'uom': 56}, # IP Address
        {'driver': 'GV3',  'value': 0,  'uom': 56}, # Port
        {'driver': 'GV4',  'value': 0,  'uom': 2},  # -- Not Used --
        {'driver': 'GV5',  'value': 0,  'uom': 2},  # Video motion detect
        {'driver': 'GV6',  'value': 0,  'uom': 2},  #
        {'driver': 'GV7',  'value': 0,  'uom': 2},  #
        {'driver': 'GV8',  'value': 0,  'uom': 2},  #
        {'driver': 'GV9',  'value': 0,  'uom': 56}  #
    ]
    commands = {
        'QUERY': query,
        'SET_VMD_ENABLE':         cmd_set_vmd_enable,
        'SET_VMD_RECORD':         cmd_set_vmd_record,
        'SET_VMD_EMAIL':          cmd_set_vmd_email,
        'SET_VMD_SNAPSHOT':       cmd_set_vmd_snapshot,
        'SET_VMD_SNAPSHOT_COUNT': cmd_set_vmd_snapshot_count,
        'SET_POS':                cmd_goto_preset,
        #'REBOOT':    _reboot,
    }
    # The nodeDef id of this camers.
    id = 'Amcrest'