async def _get_ezviz_client_instance(hass: HomeAssistant, entry: ConfigEntry) -> EzvizClient: """Initialize a new instance of EzvizClientApi with username and password.""" ezviz_client = EzvizClient( entry.data[CONF_USERNAME], entry.data[CONF_PASSWORD], entry.data[CONF_URL], entry.options.get(CONF_TIMEOUT, DEFAULT_TIMEOUT), ) _token = await hass.async_add_executor_job(ezviz_client.login) if _token: _LOGGER.info("Updating Ezviz Login token") hass.config_entries.async_update_entry( entry, data={ CONF_URL: entry.data[CONF_URL], CONF_SESSION_ID: _token[CONF_SESSION_ID], CONF_RFSESSION_ID: _token[CONF_RFSESSION_ID], CONF_TYPE: ATTR_TYPE_CLOUD, }, ) return ezviz_client
def _get_ezviz_client_instance(entry: ConfigEntry) -> EzvizClient: """Initialize a new instance of EzvizClientApi.""" ezviz_client = EzvizClient( entry.data[CONF_USERNAME], entry.data[CONF_PASSWORD], entry.data[CONF_REGION] ) # , entry.options.get(CONF_TIMEOUT, DEFAULT_TIMEOUT) ezviz_client.login() return ezviz_client
def setup_platform(hass, config, add_entities, discovery_info=None): """Set up the Ezviz IP Cameras.""" conf_cameras = config[CONF_CAMERAS] account = config[CONF_USERNAME] password = config[CONF_PASSWORD] try: ezviz_client = EzvizClient(account, password) ezviz_client.login() cameras = ezviz_client.load_cameras() except PyEzvizError as exp: _LOGGER.error(exp) return # now, let's build the HASS devices camera_entities = [] # Add the cameras as devices in HASS for camera in cameras: camera_username = DEFAULT_CAMERA_USERNAME camera_password = "" camera_rtsp_stream = "" camera_serial = camera["serial"] # There seem to be a bug related to localRtspPort in Ezviz API... local_rtsp_port = DEFAULT_RTSP_PORT if camera["local_rtsp_port"] and camera["local_rtsp_port"] != 0: local_rtsp_port = camera["local_rtsp_port"] if camera_serial in conf_cameras: camera_username = conf_cameras[camera_serial][CONF_USERNAME] camera_password = conf_cameras[camera_serial][CONF_PASSWORD] camera_rtsp_stream = f"rtsp://{camera_username}:{camera_password}@{camera['local_ip']}:{local_rtsp_port}" _LOGGER.debug("Camera %s source stream: %s", camera["serial"], camera_rtsp_stream) else: _LOGGER.info( "Found camera with serial %s without configuration. Add it to configuration.yaml to see the camera stream", camera_serial, ) camera["username"] = camera_username camera["password"] = camera_password camera["rtsp_stream"] = camera_rtsp_stream camera["ezviz_camera"] = EzvizCamera(ezviz_client, camera_serial) camera_entities.append(HassEzvizCamera(**camera)) add_entities(camera_entities)
def _get_ezviz_client_instance(data): """Initialize a new instance of EzvizClientApi.""" ezviz_client = EzvizClient( data[CONF_USERNAME], data[CONF_PASSWORD], data.get(CONF_URL, EU_URL), data.get(CONF_TIMEOUT, DEFAULT_TIMEOUT), ) ezviz_client.login() return ezviz_client
def validate_input(hass: HomeAssistantType, data: dict) -> Dict[str, Any]: """Validate the user input allows us to connect. Data has the keys from DATA_SCHEMA with values provided by the user. """ # constructor does login call EzvizClient( data[CONF_USERNAME], data[CONF_PASSWORD], data[CONF_REGION], data.get(CONF_TIMEOUT, DEFAULT_TIMEOUT), ) return True
async def _validate_and_create_camera_rtsp(self, data: dict) -> FlowResult: """Try DESCRIBE on RTSP camera with credentials.""" # Get Ezviz cloud credentials from config entry ezviz_token = { CONF_SESSION_ID: None, CONF_RFSESSION_ID: None, "api_url": None, } ezviz_timeout = DEFAULT_TIMEOUT for item in self._async_current_entries(): if item.data.get(CONF_TYPE) == ATTR_TYPE_CLOUD: ezviz_token = { CONF_SESSION_ID: item.data.get(CONF_SESSION_ID), CONF_RFSESSION_ID: item.data.get(CONF_RFSESSION_ID), "api_url": item.data.get(CONF_URL), } ezviz_timeout = item.data.get(CONF_TIMEOUT, DEFAULT_TIMEOUT) # Abort flow if user removed cloud account before adding camera. if ezviz_token.get(CONF_SESSION_ID) is None: return self.async_abort(reason="ezviz_cloud_account_missing") ezviz_client = EzvizClient(token=ezviz_token, timeout=ezviz_timeout) # We need to wake hibernating cameras. # First create EZVIZ API instance. await self.hass.async_add_executor_job(ezviz_client.login) # Secondly try to wake hybernating camera. await self.hass.async_add_executor_job( ezviz_client.get_detection_sensibility, data[ATTR_SERIAL]) # Thirdly attempts an authenticated RTSP DESCRIBE request. await self.hass.async_add_executor_job(_test_camera_rtsp_creds, data) return self.async_create_entry( title=data[ATTR_SERIAL], data={ CONF_USERNAME: data[CONF_USERNAME], CONF_PASSWORD: data[CONF_PASSWORD], CONF_TYPE: ATTR_TYPE_CAMERA, }, options=DEFAULT_OPTIONS, )
def _validate_and_create_auth(data: dict) -> dict[str, Any]: """Try to login to ezviz cloud account and return token.""" # Verify cloud credentials by attempting a login request with username and password. # Return login token. ezviz_client = EzvizClient( data[CONF_USERNAME], data[CONF_PASSWORD], data[CONF_URL], data.get(CONF_TIMEOUT, DEFAULT_TIMEOUT), ) ezviz_token = ezviz_client.login() auth_data = { CONF_SESSION_ID: ezviz_token[CONF_SESSION_ID], CONF_RFSESSION_ID: ezviz_token[CONF_RFSESSION_ID], CONF_URL: ezviz_token["api_url"], CONF_TYPE: ATTR_TYPE_CLOUD, } return auth_data
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up Ezviz from a config entry.""" hass.data.setdefault(DOMAIN, {}) sensor_type: str = entry.data[CONF_TYPE] ezviz_client = None if not entry.options: options = { CONF_FFMPEG_ARGUMENTS: DEFAULT_FFMPEG_ARGUMENTS, CONF_TIMEOUT: DEFAULT_TIMEOUT, } hass.config_entries.async_update_entry(entry, options=options) if PLATFORMS_BY_TYPE[sensor_type]: # Get user account token if not present. if not entry.data.get(CONF_SESSION_ID): try: ezviz_client = await _get_ezviz_client_instance(hass, entry) except (InvalidURL, HTTPError, PyEzvizError) as error: _LOGGER.error("Unable to connect to Ezviz service: %s", str(error)) raise ConfigEntryNotReady from error if not ezviz_client: # No Ezviz login session, call api login(). ezviz_client = EzvizClient( token={ CONF_SESSION_ID: entry.data.get(CONF_SESSION_ID), CONF_RFSESSION_ID: entry.data.get(CONF_RFSESSION_ID), "api_url": entry.data.get(CONF_URL), }, timeout=entry.options.get(CONF_TIMEOUT, DEFAULT_TIMEOUT), ) try: await hass.async_add_executor_job(ezviz_client.login) except (EzvizAuthTokenExpired, EzvizAuthVerificationCode) as error: raise ConfigEntryAuthFailed from error except (InvalidURL, HTTPError, PyEzvizError) as error: _LOGGER.error("Unable to connect to Ezviz service: %s", str(error)) raise ConfigEntryNotReady from error coordinator = EzvizDataUpdateCoordinator( hass, api=ezviz_client, api_timeout=entry.options[CONF_TIMEOUT]) hass.data[DOMAIN][entry.entry_id] = {DATA_COORDINATOR: coordinator} await coordinator.async_config_entry_first_refresh() entry.async_on_unload(entry.add_update_listener(_async_update_listener)) if sensor_type == ATTR_TYPE_CAMERA: if hass.data.get(DOMAIN): for item in hass.config_entries.async_entries(domain=DOMAIN): if item.data.get(CONF_TYPE) == ATTR_TYPE_CLOUD: _LOGGER.info("Reload Ezviz main account with camera entry") await hass.config_entries.async_reload(item.entry_id) return True hass.config_entries.async_setup_platforms(entry, PLATFORMS_BY_TYPE[sensor_type]) return True
def setup_platform(hass, config, add_entities, discovery_info=None): """Set up the Ezviz IP Cameras.""" conf_cameras = config[ATTR_CAMERAS] account = config[CONF_USERNAME] password = config[CONF_PASSWORD] region = config[CONF_REGION] try: ezviz_client = EzvizClient(account, password, region) ezviz_client.login() cameras = ezviz_client.load_cameras() except PyEzvizError as exp: _LOGGER.error(exp) return # now, let's build the HASS devices camera_entities = [] # Add the cameras as devices in HASS for camera in cameras: camera_username = DEFAULT_CAMERA_USERNAME camera_password = "" camera_rtsp_stream = "" camera_serial = camera["serial"] # There seem to be a bug related to localRtspPort in Ezviz API... local_rtsp_port = DEFAULT_RTSP_PORT if camera["local_rtsp_port"] and camera["local_rtsp_port"] != 0: local_rtsp_port = camera["local_rtsp_port"] if camera_serial in conf_cameras: camera_username = conf_cameras[camera_serial][CONF_USERNAME] camera_password = conf_cameras[camera_serial][CONF_PASSWORD] camera_rtsp_stream = f"rtsp://{camera_username}:{camera_password}@{camera['local_ip']}:{local_rtsp_port}" _LOGGER.debug("Camera %s source stream: %s", camera["serial"], camera_rtsp_stream) else: _LOGGER.info( "Found camera with serial %s without configuration. Add it to configuration.yaml to see the camera stream", camera_serial, ) camera["username"] = camera_username camera["password"] = camera_password camera["rtsp_stream"] = camera_rtsp_stream camera["ezviz_client"] = ezviz_client camera["ezviz_camera"] = EzvizCamera(ezviz_client, camera_serial) camera_entities.append(HassEzvizCamera(hass, **camera)) add_entities(camera_entities) """Setup Services""" def ezviz_wake_device(service): """Basicaly queries device to wake.""" ezviz_client.get_detection_sensibility(str(service.data['serial'])) def ezviz_switch_set(service): """Set camera switch service.""" service_switch = getattr(DeviceSwitchType, service.data[ATTR_SWITCH]) ezviz_client.switch_status(service.data[ATTR_SERIAL], service_switch.value, service.data[ATTR_ENABLE]) def ezviz_alarm_sound(service): """Enable/Disable movement sound alarm.""" ezviz_client.alarm_sound(str(service.data[ATTR_SERIAL]), int(service.data['level']), 1) def ezviz_set_alarm_detection_sensibility(service): """Set camera detection sensibility level service.""" ezviz_client.detection_sensibility(str(service.data[ATTR_SERIAL]), int(service.data['level']), int(service.data['type'])) def ezviz_ptz(service): """Camera PTZ service.""" ezviz_client.ptzControl( str(service.data[ATTR_DIRECTION]).upper(), service.data[ATTR_SERIAL], 'START', service.data[ATTR_SPEED]) ezviz_client.ptzControl( str(service.data[ATTR_DIRECTION]).upper(), service.data[ATTR_SERIAL], 'STOP', service.data[ATTR_SPEED]) hass.services.register(DOMAIN, "ezviz_wake_device", ezviz_wake_device) hass.services.register(DOMAIN, "ezviz_switch_set", ezviz_switch_set, schema=SERVICE_SET_SWITCH_SCHEMA) hass.services.register(DOMAIN, "ezviz_ptz", ezviz_ptz, SERVICE_PTZ_SCHEMA) hass.services.register(DOMAIN, "ezviz_alarm_sound", ezviz_alarm_sound) hass.services.register(DOMAIN, "ezviz_set_alarm_detection_sensibility", ezviz_set_alarm_detection_sensibility)