Added Wyze
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
"""Platform for the cover integration."""
|
||||
|
||||
from abc import ABC
|
||||
import logging
|
||||
from typing import Any, Callable, List
|
||||
|
||||
from wyzeapy import Wyzeapy, CameraService
|
||||
from wyzeapy.services.camera_service import Camera
|
||||
from wyzeapy.exceptions import AccessTokenError, ParameterError, UnknownApiError
|
||||
from wyzeapy.types import DeviceTypes
|
||||
|
||||
import homeassistant.components.cover
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import ATTR_ATTRIBUTION
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.components.cover import CoverDeviceClass, CoverEntityFeature
|
||||
|
||||
|
||||
from .const import CAMERA_UPDATED, CONF_CLIENT, DOMAIN
|
||||
from .token_manager import token_exception_handler
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
ATTRIBUTION = "Data provided by Wyze"
|
||||
|
||||
|
||||
@token_exception_handler
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
async_add_entities: Callable[[List[Any], bool], None],
|
||||
) -> None:
|
||||
"""
|
||||
This function sets up the config_entry
|
||||
|
||||
:param hass: Home Assistant instance
|
||||
:param config_entry: The current config_entry
|
||||
:param async_add_entities: This function adds entities to the config_entry
|
||||
:return:
|
||||
"""
|
||||
|
||||
_LOGGER.debug("""Creating new WyzeApi cover component""")
|
||||
client: Wyzeapy = hass.data[DOMAIN][config_entry.entry_id][CONF_CLIENT]
|
||||
camera_service = await client.camera_service
|
||||
cameras: List[Camera] = await camera_service.get_cameras()
|
||||
garages = []
|
||||
for camera in cameras:
|
||||
if camera.device_params["dongle_product_model"] == "HL_CGDC":
|
||||
garages.append(WyzeGarageDoor(camera_service, camera))
|
||||
|
||||
async_add_entities(garages, True)
|
||||
|
||||
|
||||
class WyzeGarageDoor(homeassistant.components.cover.CoverEntity, ABC):
|
||||
"""Representation of a Wyze Garage Door."""
|
||||
|
||||
_attr_device_class = CoverDeviceClass.GARAGE
|
||||
_attr_supported_features = CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE
|
||||
_attr_has_entity_name = True
|
||||
|
||||
def __init__(self, camera_service: CameraService, camera: Camera):
|
||||
"""Initialize a Wyze garage door."""
|
||||
self._camera = camera
|
||||
if self._camera.type not in [DeviceTypes.CAMERA]:
|
||||
raise HomeAssistantError(f"Invalid device type: {self._camera.type}")
|
||||
|
||||
self._camera_service = camera_service
|
||||
self._available = self._camera.available
|
||||
|
||||
@property
|
||||
def device_info(self):
|
||||
"""Return device information about this entity."""
|
||||
return {
|
||||
"identifiers": {(DOMAIN, self._camera.mac)},
|
||||
"name": f"{self._camera.nickname}",
|
||||
"connections": {(dr.CONNECTION_NETWORK_MAC, self._camera.mac)},
|
||||
}
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
"""Return device attributes of the entity."""
|
||||
return {
|
||||
ATTR_ATTRIBUTION: ATTRIBUTION,
|
||||
"device model": f"{self._camera.product_model}.{self._camera.device_params['dongle_product_model']}",
|
||||
}
|
||||
|
||||
@property
|
||||
def should_poll(self) -> bool:
|
||||
return False
|
||||
|
||||
@token_exception_handler
|
||||
async def async_open_cover(self, **kwargs):
|
||||
"""Open the cover."""
|
||||
try:
|
||||
await self._camera_service.garage_door_open(self._camera)
|
||||
except (AccessTokenError, ParameterError, UnknownApiError) as err:
|
||||
raise HomeAssistantError(f"Wyze returned an error: {err.args}") from err
|
||||
except Exception as err:
|
||||
raise HomeAssistantError(err) from err
|
||||
else:
|
||||
self._camera.garage = True
|
||||
self.async_write_ha_state()
|
||||
|
||||
@token_exception_handler
|
||||
async def async_close_cover(self, **kwargs):
|
||||
"""Close the cover."""
|
||||
try:
|
||||
await self._camera_service.garage_door_close(self._camera)
|
||||
except (AccessTokenError, ParameterError, UnknownApiError) as err:
|
||||
raise HomeAssistantError(f"Wyze returned an error: {err.args}") from err
|
||||
except Exception as err:
|
||||
raise HomeAssistantError(err) from err
|
||||
else:
|
||||
self._camera.garage = False
|
||||
self.async_write_ha_state()
|
||||
|
||||
@property
|
||||
def is_closed(self):
|
||||
"""Return if the cover is closed."""
|
||||
return not self._camera.garage
|
||||
|
||||
@property
|
||||
def available(self):
|
||||
"""Return the connection status of this cover."""
|
||||
return self._camera.available
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Define a unique id for this entity."""
|
||||
return f"{self._camera.mac}_GarageDoor"
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the garage door."""
|
||||
return "Garage Door"
|
||||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
self.async_on_remove(
|
||||
async_dispatcher_connect(
|
||||
self.hass,
|
||||
f"{CAMERA_UPDATED}-{self._camera.mac}",
|
||||
self.handle_camera_update,
|
||||
)
|
||||
)
|
||||
|
||||
@callback
|
||||
def handle_camera_update(self, camera: Camera) -> None:
|
||||
"""Update the cover whenever there is an update"""
|
||||
self._camera = camera
|
||||
self.async_write_ha_state()
|
||||
Reference in New Issue
Block a user