Add Config flow to august (#32133)
* Add battery sensors for August devices * Additional tests and cleanup in prep for config flow and device registry * pylint * update name for new style guidelines - https://developers.home-assistant.io/docs/development_guidelines/#use-new-style-string-formatting * Config Flow for august push * Update homeassistant/components/august/__init__.py Co-Authored-By: Paulus Schoutsen <paulus@home-assistant.io> * Address review items * Update tests Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
This commit is contained in:
parent
900714a3ee
commit
2925e0617c
25 changed files with 1686 additions and 444 deletions
|
@ -6,43 +6,44 @@ from august.activity import ActivityType
|
|||
from august.lock import LockDoorStatus
|
||||
from august.util import update_lock_detail_from_activity
|
||||
|
||||
from homeassistant.components.binary_sensor import BinarySensorDevice
|
||||
from homeassistant.components.binary_sensor import (
|
||||
DEVICE_CLASS_CONNECTIVITY,
|
||||
DEVICE_CLASS_MOTION,
|
||||
DEVICE_CLASS_OCCUPANCY,
|
||||
BinarySensorDevice,
|
||||
)
|
||||
|
||||
from . import DATA_AUGUST
|
||||
from .const import DATA_AUGUST, DEFAULT_NAME, DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
SCAN_INTERVAL = timedelta(seconds=5)
|
||||
|
||||
|
||||
async def _async_retrieve_online_state(data, doorbell):
|
||||
async def _async_retrieve_online_state(data, detail):
|
||||
"""Get the latest state of the sensor."""
|
||||
detail = await data.async_get_doorbell_detail(doorbell.device_id)
|
||||
if detail is None:
|
||||
return None
|
||||
|
||||
return detail.is_online
|
||||
return detail.is_online or detail.status == "standby"
|
||||
|
||||
|
||||
async def _async_retrieve_motion_state(data, doorbell):
|
||||
async def _async_retrieve_motion_state(data, detail):
|
||||
|
||||
return await _async_activity_time_based_state(
|
||||
data, doorbell, [ActivityType.DOORBELL_MOTION, ActivityType.DOORBELL_DING]
|
||||
data,
|
||||
detail.device_id,
|
||||
[ActivityType.DOORBELL_MOTION, ActivityType.DOORBELL_DING],
|
||||
)
|
||||
|
||||
|
||||
async def _async_retrieve_ding_state(data, doorbell):
|
||||
async def _async_retrieve_ding_state(data, detail):
|
||||
|
||||
return await _async_activity_time_based_state(
|
||||
data, doorbell, [ActivityType.DOORBELL_DING]
|
||||
data, detail.device_id, [ActivityType.DOORBELL_DING]
|
||||
)
|
||||
|
||||
|
||||
async def _async_activity_time_based_state(data, doorbell, activity_types):
|
||||
async def _async_activity_time_based_state(data, device_id, activity_types):
|
||||
"""Get the latest state of the sensor."""
|
||||
latest = await data.async_get_latest_device_activity(
|
||||
doorbell.device_id, *activity_types
|
||||
)
|
||||
latest = await data.async_get_latest_device_activity(device_id, *activity_types)
|
||||
|
||||
if latest is not None:
|
||||
start = latest.activity_start_time
|
||||
|
@ -57,15 +58,19 @@ SENSOR_STATE_PROVIDER = 2
|
|||
|
||||
# sensor_type: [name, device_class, async_state_provider]
|
||||
SENSOR_TYPES_DOORBELL = {
|
||||
"doorbell_ding": ["Ding", "occupancy", _async_retrieve_ding_state],
|
||||
"doorbell_motion": ["Motion", "motion", _async_retrieve_motion_state],
|
||||
"doorbell_online": ["Online", "connectivity", _async_retrieve_online_state],
|
||||
"doorbell_ding": ["Ding", DEVICE_CLASS_OCCUPANCY, _async_retrieve_ding_state],
|
||||
"doorbell_motion": ["Motion", DEVICE_CLASS_MOTION, _async_retrieve_motion_state],
|
||||
"doorbell_online": [
|
||||
"Online",
|
||||
DEVICE_CLASS_CONNECTIVITY,
|
||||
_async_retrieve_online_state,
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up the August binary sensors."""
|
||||
data = hass.data[DATA_AUGUST]
|
||||
data = hass.data[DOMAIN][config_entry.entry_id][DATA_AUGUST]
|
||||
devices = []
|
||||
|
||||
for door in data.locks:
|
||||
|
@ -98,6 +103,7 @@ class AugustDoorBinarySensor(BinarySensorDevice):
|
|||
self._door = door
|
||||
self._state = None
|
||||
self._available = False
|
||||
self._firmware_version = None
|
||||
|
||||
@property
|
||||
def available(self):
|
||||
|
@ -132,6 +138,7 @@ class AugustDoorBinarySensor(BinarySensorDevice):
|
|||
lock_door_state = None
|
||||
if detail is not None:
|
||||
lock_door_state = detail.door_state
|
||||
self._firmware_version = detail.firmware_version
|
||||
|
||||
self._available = lock_door_state != LockDoorStatus.UNKNOWN
|
||||
self._state = lock_door_state == LockDoorStatus.OPEN
|
||||
|
@ -141,6 +148,16 @@ class AugustDoorBinarySensor(BinarySensorDevice):
|
|||
"""Get the unique of the door open binary sensor."""
|
||||
return f"{self._door.device_id}_open"
|
||||
|
||||
@property
|
||||
def device_info(self):
|
||||
"""Return the device_info of the device."""
|
||||
return {
|
||||
"identifiers": {(DOMAIN, self._door.device_id)},
|
||||
"name": self._door.device_name,
|
||||
"manufacturer": DEFAULT_NAME,
|
||||
"sw_version": self._firmware_version,
|
||||
}
|
||||
|
||||
|
||||
class AugustDoorbellBinarySensor(BinarySensorDevice):
|
||||
"""Representation of an August binary sensor."""
|
||||
|
@ -152,6 +169,7 @@ class AugustDoorbellBinarySensor(BinarySensorDevice):
|
|||
self._doorbell = doorbell
|
||||
self._state = None
|
||||
self._available = False
|
||||
self._firmware_version = None
|
||||
|
||||
@property
|
||||
def available(self):
|
||||
|
@ -178,11 +196,21 @@ class AugustDoorbellBinarySensor(BinarySensorDevice):
|
|||
async_state_provider = SENSOR_TYPES_DOORBELL[self._sensor_type][
|
||||
SENSOR_STATE_PROVIDER
|
||||
]
|
||||
self._state = await async_state_provider(self._data, self._doorbell)
|
||||
detail = await self._data.async_get_doorbell_detail(self._doorbell.device_id)
|
||||
# The doorbell will go into standby mode when there is no motion
|
||||
# for a short while. It will wake by itself when needed so we need
|
||||
# to consider is available or we will not report motion or dings
|
||||
self._available = self._doorbell.is_online or self._doorbell.status == "standby"
|
||||
if self.device_class == DEVICE_CLASS_CONNECTIVITY:
|
||||
self._available = True
|
||||
else:
|
||||
self._available = detail is not None and (
|
||||
detail.is_online or detail.status == "standby"
|
||||
)
|
||||
|
||||
self._state = None
|
||||
if detail is not None:
|
||||
self._firmware_version = detail.firmware_version
|
||||
self._state = await async_state_provider(self._data, detail)
|
||||
|
||||
@property
|
||||
def unique_id(self) -> str:
|
||||
|
@ -191,3 +219,13 @@ class AugustDoorbellBinarySensor(BinarySensorDevice):
|
|||
f"{self._doorbell.device_id}_"
|
||||
f"{SENSOR_TYPES_DOORBELL[self._sensor_type][SENSOR_NAME].lower()}"
|
||||
)
|
||||
|
||||
@property
|
||||
def device_info(self):
|
||||
"""Return the device_info of the device."""
|
||||
return {
|
||||
"identifiers": {(DOMAIN, self._doorbell.device_id)},
|
||||
"name": self._doorbell.device_name,
|
||||
"manufacturer": "August",
|
||||
"sw_version": self._firmware_version,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue