Add services to ezviz integration (#48984)

Co-authored-by: Franck Nijhof <frenck@frenck.nl>
This commit is contained in:
RenierM26 2021-06-15 13:23:32 +02:00 committed by GitHub
parent 515bd18ddd
commit 22b8dc16c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 274 additions and 30 deletions

View file

@ -2,7 +2,8 @@
from datetime import timedelta
import logging
from pyezviz.client import EzvizClient, HTTPError, InvalidURL, PyEzvizError
from pyezviz.client import EzvizClient
from pyezviz.exceptions import HTTPError, InvalidURL, PyEzvizError
from homeassistant.const import (
CONF_PASSWORD,

View file

@ -1,29 +1,43 @@
"""Support ezviz camera devices."""
import asyncio
from datetime import timedelta
import logging
from haffmpeg.tools import IMAGE_JPEG, ImageFrame
from pyezviz.exceptions import HTTPError, InvalidHost, PyEzvizError
import voluptuous as vol
from homeassistant.components.camera import PLATFORM_SCHEMA, SUPPORT_STREAM, Camera
from homeassistant.components.ffmpeg import DATA_FFMPEG
from homeassistant.config_entries import SOURCE_DISCOVERY, SOURCE_IGNORE, SOURCE_IMPORT
from homeassistant.const import CONF_IP_ADDRESS, CONF_PASSWORD, CONF_USERNAME
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers import config_validation as cv, entity_platform
from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import (
ATTR_DIRECTION,
ATTR_ENABLE,
ATTR_LEVEL,
ATTR_SERIAL,
ATTR_SPEED,
ATTR_TYPE,
CONF_CAMERAS,
CONF_FFMPEG_ARGUMENTS,
DATA_COORDINATOR,
DEFAULT_CAMERA_USERNAME,
DEFAULT_FFMPEG_ARGUMENTS,
DEFAULT_RTSP_PORT,
DIR_DOWN,
DIR_LEFT,
DIR_RIGHT,
DIR_UP,
DOMAIN,
MANUFACTURER,
SERVICE_ALARM_SOUND,
SERVICE_ALARM_TRIGER,
SERVICE_DETECTION_SENSITIVITY,
SERVICE_PTZ,
SERVICE_WAKE_DEVICE,
)
CAMERA_SCHEMA = vol.Schema(
@ -40,8 +54,6 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
_LOGGER = logging.getLogger(__name__)
MIN_TIME_BETWEEN_SESSION_RENEW = timedelta(seconds=90)
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up a Ezviz IP Camera from platform config."""
@ -157,6 +169,46 @@ async def async_setup_entry(hass, entry, async_add_entities):
async_add_entities(camera_entities)
platform = entity_platform.current_platform.get()
platform.async_register_entity_service(
SERVICE_PTZ,
{
vol.Required(ATTR_DIRECTION): vol.In(
[DIR_UP, DIR_DOWN, DIR_LEFT, DIR_RIGHT]
),
vol.Required(ATTR_SPEED): cv.positive_int,
},
"perform_ptz",
)
platform.async_register_entity_service(
SERVICE_ALARM_TRIGER,
{
vol.Required(ATTR_ENABLE): cv.positive_int,
},
"perform_sound_alarm",
)
platform.async_register_entity_service(
SERVICE_WAKE_DEVICE, {}, "perform_wake_device"
)
platform.async_register_entity_service(
SERVICE_ALARM_SOUND,
{vol.Required(ATTR_LEVEL): cv.positive_int},
"perform_alarm_sound",
)
platform.async_register_entity_service(
SERVICE_DETECTION_SENSITIVITY,
{
vol.Required(ATTR_LEVEL): cv.positive_int,
vol.Required(ATTR_TYPE): cv.positive_int,
},
"perform_set_alarm_detection_sensibility",
)
class EzvizCamera(CoordinatorEntity, Camera, RestoreEntity):
"""An implementation of a Ezviz security camera."""
@ -232,6 +284,24 @@ class EzvizCamera(CoordinatorEntity, Camera, RestoreEntity):
"""Camera Motion Detection Status."""
return self.coordinator.data[self._idx]["alarm_notify"]
def enable_motion_detection(self):
"""Enable motion detection in camera."""
try:
self.coordinator.ezviz_client.set_camera_defence(self._serial, 1)
except InvalidHost as err:
_LOGGER.error("Error enabling motion detection")
raise InvalidHost from err
def disable_motion_detection(self):
"""Disable motion detection."""
try:
self.coordinator.ezviz_client.set_camera_defence(self._serial, 0)
except InvalidHost as err:
_LOGGER.error("Error disabling motion detection")
raise InvalidHost from err
@property
def unique_id(self):
"""Return the name of this camera."""
@ -271,3 +341,52 @@ class EzvizCamera(CoordinatorEntity, Camera, RestoreEntity):
self._rtsp_stream = rtsp_stream_source
return rtsp_stream_source
return None
def perform_ptz(self, direction, speed):
"""Perform a PTZ action on the camera."""
_LOGGER.debug("PTZ action '%s' on %s", direction, self._name)
try:
self.coordinator.ezviz_client.ptz_control(
str(direction).upper(), self._serial, "START", speed
)
self.coordinator.ezviz_client.ptz_control(
str(direction).upper(), self._serial, "STOP", speed
)
except HTTPError as err:
_LOGGER.error("Cannot perform PTZ")
raise HTTPError from err
def perform_sound_alarm(self, enable):
"""Sound the alarm on a camera."""
try:
self.coordinator.ezviz_client.sound_alarm(self._serial, enable)
except HTTPError as err:
_LOGGER.debug("Cannot sound alarm")
raise HTTPError from err
def perform_wake_device(self):
"""Basically wakes the camera by querying the device."""
try:
self.coordinator.ezviz_client.get_detection_sensibility(self._serial)
except (HTTPError, PyEzvizError) as err:
_LOGGER.error("Cannot wake device")
raise PyEzvizError from err
def perform_alarm_sound(self, level):
"""Enable/Disable movement sound alarm."""
try:
self.coordinator.ezviz_client.alarm_sound(self._serial, level, 1)
except HTTPError as err:
_LOGGER.error("Cannot set alarm sound level for on movement detected")
raise HTTPError from err
def perform_set_alarm_detection_sensibility(self, level, type_value):
"""Set camera detection sensibility level service."""
try:
self.coordinator.ezviz_client.detection_sensibility(
self._serial, level, type_value
)
except (HTTPError, PyEzvizError) as err:
_LOGGER.error("Cannot set detection sensitivity level")
raise PyEzvizError from err

View file

@ -1,8 +1,15 @@
"""Config flow for ezviz."""
import logging
from pyezviz.client import EzvizClient, HTTPError, InvalidURL, PyEzvizError
from pyezviz.test_cam_rtsp import AuthTestResultFailed, InvalidHost, TestRTSPAuth
from pyezviz.client import EzvizClient
from pyezviz.exceptions import (
AuthTestResultFailed,
HTTPError,
InvalidHost,
InvalidURL,
PyEzvizError,
)
from pyezviz.test_cam_rtsp import TestRTSPAuth
import voluptuous as vol
from homeassistant.config_entries import ConfigFlow, OptionsFlow

View file

@ -6,29 +6,30 @@ MANUFACTURER = "Ezviz"
# Configuration
ATTR_SERIAL = "serial"
CONF_CAMERAS = "cameras"
ATTR_SWITCH = "switch"
ATTR_ENABLE = "enable"
ATTR_DIRECTION = "direction"
ATTR_SPEED = "speed"
ATTR_LEVEL = "level"
ATTR_TYPE = "type_value"
DIR_UP = "up"
DIR_DOWN = "down"
DIR_LEFT = "left"
DIR_RIGHT = "right"
ATTR_LIGHT = "LIGHT"
ATTR_SOUND = "SOUND"
ATTR_INFRARED_LIGHT = "INFRARED_LIGHT"
ATTR_PRIVACY = "PRIVACY"
ATTR_SLEEP = "SLEEP"
ATTR_MOBILE_TRACKING = "MOBILE_TRACKING"
ATTR_TRACKING = "TRACKING"
CONF_FFMPEG_ARGUMENTS = "ffmpeg_arguments"
ATTR_HOME = "HOME_MODE"
ATTR_AWAY = "AWAY_MODE"
ATTR_TYPE_CLOUD = "EZVIZ_CLOUD_ACCOUNT"
ATTR_TYPE_CAMERA = "CAMERA_ACCOUNT"
# Services data
DIR_UP = "up"
DIR_DOWN = "down"
DIR_LEFT = "left"
DIR_RIGHT = "right"
ATTR_ENABLE = "enable"
ATTR_DIRECTION = "direction"
ATTR_SPEED = "speed"
ATTR_LEVEL = "level"
ATTR_TYPE = "type_value"
# Service names
SERVICE_PTZ = "ptz"
SERVICE_ALARM_TRIGER = "sound_alarm"
SERVICE_WAKE_DEVICE = "wake_device"
SERVICE_ALARM_SOUND = "alarm_sound"
SERVICE_DETECTION_SENSITIVITY = "set_alarm_detection_sensibility"
# Defaults
EU_URL = "apiieu.ezvizlife.com"
RUSSIA_URL = "apirus.ezvizru.com"

View file

@ -3,7 +3,7 @@ from datetime import timedelta
import logging
from async_timeout import timeout
from pyezviz.client import HTTPError, InvalidURL, PyEzvizError
from pyezviz.exceptions import HTTPError, InvalidURL, PyEzvizError
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed

View file

@ -4,7 +4,7 @@
"documentation": "https://www.home-assistant.io/integrations/ezviz",
"dependencies": ["ffmpeg"],
"codeowners": ["@RenierM26", "@baqs"],
"requirements": ["pyezviz==0.1.8.7"],
"requirements": ["pyezviz==0.1.8.9"],
"config_flow": true,
"iot_class": "cloud_polling"
}

View file

@ -0,0 +1,111 @@
alarm_sound:
name: Set warning sound level.
description: Set movement warning sound level.
target:
entity:
integration: ezviz
domain: camera
fields:
level:
name: Sound level
description: Sound level (2 is disabled, 1 intensive, 0 soft).
required: true
example: 0
default: 0
selector:
number:
min: 0
max: 2
step: 1
mode: box
ptz:
name: PTZ
description: Moves the camera to the direction, with defined speed
target:
entity:
integration: ezviz
domain: camera
fields:
direction:
name: Direction
description: Direction to move camera (up, down, left, right).
required: true
example: "up"
default: "up"
selector:
select:
options:
- "up"
- "down"
- "left"
- "right"
speed:
name: Speed
description: Speed of movement (from 1 to 9).
required: true
example: 5
default: 5
selector:
number:
min: 1
max: 9
step: 1
mode: box
set_alarm_detection_sensibility:
name: Detection sensitivity
description: Sets the detection sensibility level.
target:
entity:
integration: ezviz
domain: camera
fields:
level:
name: Sensitivity Level
description: 'Sensibility level (1-6) for type 0 (Normal camera)
or (1-100) for type 3 (PIR sensor camera).'
required: true
example: 3
default: 3
selector:
number:
min: 1
max: 100
step: 1
mode: box
type_value:
name: Detection type
description: 'Type of detection. Options : 0 - Camera or 3 - PIR Sensor Camera'
required: true
example: '0'
default: '0'
selector:
select:
options:
- '0'
- '3'
sound_alarm:
name: Sound Alarm
description: Sounds the alarm on your camera.
target:
entity:
integration: ezviz
domain: camera
fields:
enable:
description: Enter 1 or 2 (1=disable, 2=enable).
required: true
example: 1
default: 1
selector:
number:
min: 1
max: 2
step: 1
mode: box
wake_device:
name: Wake Camera
description: This can be used to wake the camera/device from hibernation.
target:
entity:
integration: ezviz
domain: camera

View file

@ -1411,7 +1411,7 @@ pyephember==0.3.1
pyeverlights==0.1.0
# homeassistant.components.ezviz
pyezviz==0.1.8.7
pyezviz==0.1.8.9
# homeassistant.components.fido
pyfido==2.1.1

View file

@ -776,7 +776,7 @@ pyeconet==0.1.14
pyeverlights==0.1.0
# homeassistant.components.ezviz
pyezviz==0.1.8.7
pyezviz==0.1.8.9
# homeassistant.components.fido
pyfido==2.1.1

View file

@ -2,8 +2,13 @@
from unittest.mock import patch
from pyezviz.client import HTTPError, InvalidURL, PyEzvizError
from pyezviz.test_cam_rtsp import AuthTestResultFailed, InvalidHost
from pyezviz.exceptions import (
AuthTestResultFailed,
HTTPError,
InvalidHost,
InvalidURL,
PyEzvizError,
)
from homeassistant.components.ezviz.const import (
ATTR_SERIAL,