mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
Add Ezviz button entities (#93647)
* Initial commit * Add button for ptz * coveragerc * Add ptz buttons to PTZ cameras only * Describe support capbility * Improve typing * bump api version. * Match entity naming used throughout * Add translation * Create ir before execution and breaks in version * Fix for translation missing name key. * Change depreciation to 2024.2.0 * Update camera.py * Tiny spelling tweaks --------- Co-authored-by: Franck Nijhof <frenck@frenck.nl>
This commit is contained in:
parent
6717e40114
commit
5ec633a839
@ -316,6 +316,7 @@ omit =
|
|||||||
homeassistant/components/ezviz/__init__.py
|
homeassistant/components/ezviz/__init__.py
|
||||||
homeassistant/components/ezviz/alarm_control_panel.py
|
homeassistant/components/ezviz/alarm_control_panel.py
|
||||||
homeassistant/components/ezviz/binary_sensor.py
|
homeassistant/components/ezviz/binary_sensor.py
|
||||||
|
homeassistant/components/ezviz/button.py
|
||||||
homeassistant/components/ezviz/camera.py
|
homeassistant/components/ezviz/camera.py
|
||||||
homeassistant/components/ezviz/image.py
|
homeassistant/components/ezviz/image.py
|
||||||
homeassistant/components/ezviz/light.py
|
homeassistant/components/ezviz/light.py
|
||||||
|
@ -35,6 +35,7 @@ PLATFORMS_BY_TYPE: dict[str, list] = {
|
|||||||
ATTR_TYPE_CLOUD: [
|
ATTR_TYPE_CLOUD: [
|
||||||
Platform.ALARM_CONTROL_PANEL,
|
Platform.ALARM_CONTROL_PANEL,
|
||||||
Platform.BINARY_SENSOR,
|
Platform.BINARY_SENSOR,
|
||||||
|
Platform.BUTTON,
|
||||||
Platform.CAMERA,
|
Platform.CAMERA,
|
||||||
Platform.IMAGE,
|
Platform.IMAGE,
|
||||||
Platform.LIGHT,
|
Platform.LIGHT,
|
||||||
|
131
homeassistant/components/ezviz/button.py
Normal file
131
homeassistant/components/ezviz/button.py
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
"""Support for EZVIZ button controls."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Callable
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from pyezviz import EzvizClient
|
||||||
|
from pyezviz.constants import SupportExt
|
||||||
|
from pyezviz.exceptions import HTTPError, PyEzvizError
|
||||||
|
|
||||||
|
from homeassistant.components.button import ButtonEntity, ButtonEntityDescription
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
|
from .const import DATA_COORDINATOR, DOMAIN
|
||||||
|
from .coordinator import EzvizDataUpdateCoordinator
|
||||||
|
from .entity import EzvizEntity
|
||||||
|
|
||||||
|
PARALLEL_UPDATES = 1
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class EzvizButtonEntityDescriptionMixin:
|
||||||
|
"""Mixin values for EZVIZ button entities."""
|
||||||
|
|
||||||
|
method: Callable[[EzvizClient, str, str], Any]
|
||||||
|
supported_ext: str
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class EzvizButtonEntityDescription(
|
||||||
|
ButtonEntityDescription, EzvizButtonEntityDescriptionMixin
|
||||||
|
):
|
||||||
|
"""Describe a EZVIZ Button."""
|
||||||
|
|
||||||
|
|
||||||
|
BUTTON_ENTITIES = (
|
||||||
|
EzvizButtonEntityDescription(
|
||||||
|
key="ptz_up",
|
||||||
|
translation_key="ptz_up",
|
||||||
|
icon="mdi:pan",
|
||||||
|
method=lambda pyezviz_client, serial, run: pyezviz_client.ptz_control(
|
||||||
|
"UP", serial, run
|
||||||
|
),
|
||||||
|
supported_ext=str(SupportExt.SupportPtz.value),
|
||||||
|
),
|
||||||
|
EzvizButtonEntityDescription(
|
||||||
|
key="ptz_down",
|
||||||
|
translation_key="ptz_down",
|
||||||
|
icon="mdi:pan",
|
||||||
|
method=lambda pyezviz_client, serial, run: pyezviz_client.ptz_control(
|
||||||
|
"DOWN", serial, run
|
||||||
|
),
|
||||||
|
supported_ext=str(SupportExt.SupportPtz.value),
|
||||||
|
),
|
||||||
|
EzvizButtonEntityDescription(
|
||||||
|
key="ptz_left",
|
||||||
|
translation_key="ptz_left",
|
||||||
|
icon="mdi:pan",
|
||||||
|
method=lambda pyezviz_client, serial, run: pyezviz_client.ptz_control(
|
||||||
|
"LEFT", serial, run
|
||||||
|
),
|
||||||
|
supported_ext=str(SupportExt.SupportPtz.value),
|
||||||
|
),
|
||||||
|
EzvizButtonEntityDescription(
|
||||||
|
key="ptz_right",
|
||||||
|
translation_key="ptz_right",
|
||||||
|
icon="mdi:pan",
|
||||||
|
method=lambda pyezviz_client, serial, run: pyezviz_client.ptz_control(
|
||||||
|
"RIGHT", serial, run
|
||||||
|
),
|
||||||
|
supported_ext=str(SupportExt.SupportPtz.value),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||||
|
) -> None:
|
||||||
|
"""Set up EZVIZ button based on a config entry."""
|
||||||
|
coordinator: EzvizDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id][
|
||||||
|
DATA_COORDINATOR
|
||||||
|
]
|
||||||
|
|
||||||
|
# Add button entities if supportExt value indicates PTZ capbility.
|
||||||
|
# Could be missing or "0" for unsupported.
|
||||||
|
# If present with value of "1" then add button entity.
|
||||||
|
|
||||||
|
async_add_entities(
|
||||||
|
EzvizButtonEntity(coordinator, camera, entity_description)
|
||||||
|
for camera in coordinator.data
|
||||||
|
for capibility, value in coordinator.data[camera]["supportExt"].items()
|
||||||
|
for entity_description in BUTTON_ENTITIES
|
||||||
|
if capibility == entity_description.supported_ext
|
||||||
|
if value == "1"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class EzvizButtonEntity(EzvizEntity, ButtonEntity):
|
||||||
|
"""Representation of a EZVIZ button entity."""
|
||||||
|
|
||||||
|
entity_description: EzvizButtonEntityDescription
|
||||||
|
_attr_has_entity_name = True
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
coordinator: EzvizDataUpdateCoordinator,
|
||||||
|
serial: str,
|
||||||
|
description: EzvizButtonEntityDescription,
|
||||||
|
) -> None:
|
||||||
|
"""Initialize the button."""
|
||||||
|
super().__init__(coordinator, serial)
|
||||||
|
self._attr_unique_id = f"{serial}_{description.key}"
|
||||||
|
self.entity_description = description
|
||||||
|
|
||||||
|
def press(self) -> None:
|
||||||
|
"""Execute the button action."""
|
||||||
|
try:
|
||||||
|
self.entity_description.method(
|
||||||
|
self.coordinator.ezviz_client, self._serial, "START"
|
||||||
|
)
|
||||||
|
self.entity_description.method(
|
||||||
|
self.coordinator.ezviz_client, self._serial, "STOP"
|
||||||
|
)
|
||||||
|
except (HTTPError, PyEzvizError) as err:
|
||||||
|
raise HomeAssistantError(
|
||||||
|
f"Cannot perform PTZ action on {self.name}"
|
||||||
|
) from err
|
@ -263,6 +263,17 @@ class EzvizCamera(EzvizEntity, Camera):
|
|||||||
|
|
||||||
def perform_ptz(self, direction: str, speed: int) -> None:
|
def perform_ptz(self, direction: str, speed: int) -> None:
|
||||||
"""Perform a PTZ action on the camera."""
|
"""Perform a PTZ action on the camera."""
|
||||||
|
ir.async_create_issue(
|
||||||
|
self.hass,
|
||||||
|
DOMAIN,
|
||||||
|
"service_depreciation_ptz",
|
||||||
|
breaks_in_ha_version="2024.2.0",
|
||||||
|
is_fixable=True,
|
||||||
|
is_persistent=True,
|
||||||
|
severity=ir.IssueSeverity.WARNING,
|
||||||
|
translation_key="service_depreciation_ptz",
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.coordinator.ezviz_client.ptz_control(
|
self.coordinator.ezviz_client.ptz_control(
|
||||||
str(direction).upper(), self._serial, "START", speed
|
str(direction).upper(), self._serial, "START", speed
|
||||||
|
@ -81,6 +81,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"service_depreciation_ptz": {
|
||||||
|
"title": "EZVIZ PTZ service is being removed",
|
||||||
|
"fix_flow": {
|
||||||
|
"step": {
|
||||||
|
"confirm": {
|
||||||
|
"title": "[%key:component::ezviz::issues::service_depreciation_ptz::title%]",
|
||||||
|
"description": "EZVIZ PTZ service is deprecated and will be removed.\nTo move the camera, you can instead use the `button.press` service targetting the PTZ* entities.\n\nPlease remove the use of this service from your automations and scripts and select **submit** to close this issue."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"entity": {
|
"entity": {
|
||||||
@ -99,6 +110,20 @@
|
|||||||
"name": "Last motion image"
|
"name": "Last motion image"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"button": {
|
||||||
|
"ptz_up": {
|
||||||
|
"name": "PTZ up"
|
||||||
|
},
|
||||||
|
"ptz_down": {
|
||||||
|
"name": "PTZ down"
|
||||||
|
},
|
||||||
|
"ptz_left": {
|
||||||
|
"name": "PTZ left"
|
||||||
|
},
|
||||||
|
"ptz_right": {
|
||||||
|
"name": "PTZ right"
|
||||||
|
}
|
||||||
|
},
|
||||||
"binary_sensor": {
|
"binary_sensor": {
|
||||||
"alarm_schedules_enabled": {
|
"alarm_schedules_enabled": {
|
||||||
"name": "Alarm schedules enabled"
|
"name": "Alarm schedules enabled"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user