Initial Home Assistant commit
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
"""
|
||||
This module handles the Wyze Home Monitoring system
|
||||
"""
|
||||
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
from typing import Optional, Callable, List, Any
|
||||
from aiohttp.client_exceptions import ClientConnectionError
|
||||
|
||||
from homeassistant.components.alarm_control_panel import (
|
||||
AlarmControlPanelState,
|
||||
AlarmControlPanelEntity,
|
||||
AlarmControlPanelEntityFeature,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import ATTR_ATTRIBUTION
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from wyzeapy import Wyzeapy, HMSService
|
||||
from wyzeapy.services.hms_service import HMSMode
|
||||
from wyzeapy.exceptions import AccessTokenError, ParameterError, UnknownApiError
|
||||
from .token_manager import token_exception_handler
|
||||
from homeassistant.helpers.entity import DeviceInfo
|
||||
|
||||
from .const import DOMAIN, CONF_CLIENT
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
ATTRIBUTION = "Data provided by Wyze"
|
||||
SCAN_INTERVAL = timedelta(seconds=15)
|
||||
|
||||
|
||||
@token_exception_handler
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
async_add_entities: Callable[[List[Any], bool], None],
|
||||
):
|
||||
"""
|
||||
This function sets up the integration
|
||||
|
||||
:param hass: Reference to the HomeAssistant instance
|
||||
:param config_entry: Reference to the config entry we are setting up
|
||||
:param async_add_entities:
|
||||
"""
|
||||
|
||||
_LOGGER.debug("""Creating new WyzeApi Home Monitoring System component""")
|
||||
client: Wyzeapy = hass.data[DOMAIN][config_entry.entry_id][CONF_CLIENT]
|
||||
|
||||
hms_service = await client.hms_service
|
||||
if await hms_service.has_hms:
|
||||
async_add_entities([WyzeHomeMonitoring(hms_service)], True)
|
||||
|
||||
|
||||
class WyzeHomeMonitoring(AlarmControlPanelEntity):
|
||||
"""
|
||||
A representation of the Wyze Home Monitoring system that works for wyze
|
||||
"""
|
||||
|
||||
DEVICE_MODEL = "HMS"
|
||||
MANUFACTURER = "WyzeLabs"
|
||||
NAME = "Wyze Home Monitoring System"
|
||||
AVAILABLE = True
|
||||
_attr_has_entity_name = True
|
||||
_attr_name = None
|
||||
|
||||
def __init__(self, hms_service: HMSService):
|
||||
self._attr_unique_id = hms_service.hms_id
|
||||
|
||||
self._hms_service = hms_service
|
||||
self._state = AlarmControlPanelState.DISARMED
|
||||
self._server_out_of_sync = False
|
||||
|
||||
@property
|
||||
def alarm_state(self) -> str:
|
||||
return self._state
|
||||
|
||||
# NotImplemented Methods
|
||||
def alarm_arm_vacation(self, code: Optional[str] = None) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def alarm_arm_night(self, code: Optional[str] = None) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def alarm_trigger(self, code: Optional[str] = None) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def alarm_arm_custom_bypass(self, code: Optional[str] = None) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
# Implemented Methods
|
||||
@token_exception_handler
|
||||
async def async_alarm_disarm(self, code: Optional[str] = None) -> None:
|
||||
"""Send disarm command."""
|
||||
try:
|
||||
await self._hms_service.set_mode(HMSMode.DISARMED)
|
||||
except (AccessTokenError, ParameterError, UnknownApiError) as err:
|
||||
raise HomeAssistantError(f"Wyze returned an error: {err.args}") from err
|
||||
except ClientConnectionError as err:
|
||||
raise HomeAssistantError(err) from err
|
||||
else:
|
||||
self._state = "disarmed"
|
||||
self._server_out_of_sync = True
|
||||
|
||||
@token_exception_handler
|
||||
async def async_alarm_arm_home(self, code: Optional[str] = None) -> None:
|
||||
try:
|
||||
await self._hms_service.set_mode(HMSMode.HOME)
|
||||
except (AccessTokenError, ParameterError, UnknownApiError) as err:
|
||||
raise HomeAssistantError(f"Wyze returned an error: {err.args}") from err
|
||||
except ClientConnectionError as err:
|
||||
raise HomeAssistantError(err) from err
|
||||
else:
|
||||
self._state = "armed_home"
|
||||
self._server_out_of_sync = True
|
||||
|
||||
@token_exception_handler
|
||||
async def async_alarm_arm_away(self, code: Optional[str] = None) -> None:
|
||||
try:
|
||||
await self._hms_service.set_mode(HMSMode.AWAY)
|
||||
except (AccessTokenError, ParameterError, UnknownApiError) as err:
|
||||
raise HomeAssistantError(f"Wyze returned an error: {err.args}") from err
|
||||
except ClientConnectionError as err:
|
||||
raise HomeAssistantError(err) from err
|
||||
else:
|
||||
self._state = "armed_away"
|
||||
self._server_out_of_sync = True
|
||||
|
||||
@property
|
||||
def supported_features(self) -> int:
|
||||
return (
|
||||
AlarmControlPanelEntityFeature.ARM_HOME
|
||||
| AlarmControlPanelEntityFeature.ARM_AWAY
|
||||
)
|
||||
|
||||
@property
|
||||
def device_info(self) -> DeviceInfo:
|
||||
return DeviceInfo(
|
||||
identifiers={(DOMAIN, self.unique_id)},
|
||||
name=self.NAME,
|
||||
manufacturer=self.MANUFACTURER,
|
||||
model=self.DEVICE_MODEL,
|
||||
)
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict | None:
|
||||
"""Return device attributes of the entity."""
|
||||
return {ATTR_ATTRIBUTION: ATTRIBUTION, "mac": self.unique_id}
|
||||
|
||||
@token_exception_handler
|
||||
async def async_update(self) -> None:
|
||||
"""Update the entity with data from the Wyze servers"""
|
||||
|
||||
if not self._server_out_of_sync:
|
||||
state = await self._hms_service.update(self._hms_service.hms_id)
|
||||
if state is HMSMode.DISARMED:
|
||||
self._state = AlarmControlPanelState.DISARMED
|
||||
elif state is HMSMode.AWAY:
|
||||
self._state = AlarmControlPanelState.ARMED_AWAY
|
||||
elif state is HMSMode.HOME:
|
||||
self._state = AlarmControlPanelState.ARMED_HOME
|
||||
elif state is HMSMode.CHANGING:
|
||||
self._state = AlarmControlPanelState.DISARMED
|
||||
else:
|
||||
_LOGGER.warning(f"Received {state} from server")
|
||||
|
||||
self._server_out_of_sync = False
|
||||
Reference in New Issue
Block a user