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
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
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
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
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
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 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 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
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
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
# 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
#!/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()
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(
# -*- 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")
############################################################################### # 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):
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
# -*- 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)
# 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()
# 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
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'
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")
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.')
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
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'