194 lines
6.3 KiB
Python
194 lines
6.3 KiB
Python
"""Support for August binary sensors."""
|
|
import logging
|
|
from datetime import timedelta, datetime
|
|
|
|
from homeassistant.components.august import DATA_AUGUST
|
|
from homeassistant.components.binary_sensor import (BinarySensorDevice)
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
DEPENDENCIES = ['august']
|
|
|
|
SCAN_INTERVAL = timedelta(seconds=5)
|
|
|
|
|
|
def _retrieve_door_state(data, lock):
|
|
"""Get the latest state of the DoorSense sensor."""
|
|
return data.get_door_state(lock.device_id)
|
|
|
|
|
|
def _retrieve_online_state(data, doorbell):
|
|
"""Get the latest state of the sensor."""
|
|
detail = data.get_doorbell_detail(doorbell.device_id)
|
|
if detail is None:
|
|
return None
|
|
|
|
return detail.is_online
|
|
|
|
|
|
def _retrieve_motion_state(data, doorbell):
|
|
from august.activity import ActivityType
|
|
return _activity_time_based_state(data, doorbell,
|
|
[ActivityType.DOORBELL_MOTION,
|
|
ActivityType.DOORBELL_DING])
|
|
|
|
|
|
def _retrieve_ding_state(data, doorbell):
|
|
from august.activity import ActivityType
|
|
return _activity_time_based_state(data, doorbell,
|
|
[ActivityType.DOORBELL_DING])
|
|
|
|
|
|
def _activity_time_based_state(data, doorbell, activity_types):
|
|
"""Get the latest state of the sensor."""
|
|
latest = data.get_latest_device_activity(doorbell.device_id,
|
|
*activity_types)
|
|
|
|
if latest is not None:
|
|
start = latest.activity_start_time
|
|
end = latest.activity_end_time + timedelta(seconds=30)
|
|
return start <= datetime.now() <= end
|
|
return None
|
|
|
|
|
|
# Sensor types: Name, device_class, state_provider
|
|
SENSOR_TYPES_DOOR = {
|
|
'door_open': ['Open', 'door', _retrieve_door_state],
|
|
}
|
|
|
|
SENSOR_TYPES_DOORBELL = {
|
|
'doorbell_ding': ['Ding', 'occupancy', _retrieve_ding_state],
|
|
'doorbell_motion': ['Motion', 'motion', _retrieve_motion_state],
|
|
'doorbell_online': ['Online', 'connectivity', _retrieve_online_state],
|
|
}
|
|
|
|
|
|
def setup_platform(hass, config, add_entities, discovery_info=None):
|
|
"""Set up the August binary sensors."""
|
|
data = hass.data[DATA_AUGUST]
|
|
devices = []
|
|
|
|
from august.lock import LockDoorStatus
|
|
for door in data.locks:
|
|
for sensor_type in SENSOR_TYPES_DOOR:
|
|
state_provider = SENSOR_TYPES_DOOR[sensor_type][2]
|
|
if state_provider(data, door) is LockDoorStatus.UNKNOWN:
|
|
_LOGGER.debug(
|
|
"Not adding sensor class %s for lock %s ",
|
|
SENSOR_TYPES_DOOR[sensor_type][1], door.device_name
|
|
)
|
|
continue
|
|
|
|
_LOGGER.debug(
|
|
"Adding sensor class %s for %s",
|
|
SENSOR_TYPES_DOOR[sensor_type][1], door.device_name
|
|
)
|
|
devices.append(AugustDoorBinarySensor(data, sensor_type, door))
|
|
|
|
for doorbell in data.doorbells:
|
|
for sensor_type in SENSOR_TYPES_DOORBELL:
|
|
_LOGGER.debug("Adding doorbell sensor class %s for %s",
|
|
SENSOR_TYPES_DOORBELL[sensor_type][1],
|
|
doorbell.device_name)
|
|
devices.append(
|
|
AugustDoorbellBinarySensor(data, sensor_type,
|
|
doorbell)
|
|
)
|
|
|
|
add_entities(devices, True)
|
|
|
|
|
|
class AugustDoorBinarySensor(BinarySensorDevice):
|
|
"""Representation of an August Door binary sensor."""
|
|
|
|
def __init__(self, data, sensor_type, door):
|
|
"""Initialize the sensor."""
|
|
self._data = data
|
|
self._sensor_type = sensor_type
|
|
self._door = door
|
|
self._state = None
|
|
self._available = False
|
|
|
|
@property
|
|
def available(self):
|
|
"""Return the availability of this sensor."""
|
|
return self._available
|
|
|
|
@property
|
|
def is_on(self):
|
|
"""Return true if the binary sensor is on."""
|
|
return self._state
|
|
|
|
@property
|
|
def device_class(self):
|
|
"""Return the class of this device, from component DEVICE_CLASSES."""
|
|
return SENSOR_TYPES_DOOR[self._sensor_type][1]
|
|
|
|
@property
|
|
def name(self):
|
|
"""Return the name of the binary sensor."""
|
|
return "{} {}".format(self._door.device_name,
|
|
SENSOR_TYPES_DOOR[self._sensor_type][0])
|
|
|
|
def update(self):
|
|
"""Get the latest state of the sensor."""
|
|
state_provider = SENSOR_TYPES_DOOR[self._sensor_type][2]
|
|
self._state = state_provider(self._data, self._door)
|
|
self._available = self._state is not None
|
|
|
|
from august.lock import LockDoorStatus
|
|
self._state = self._state == LockDoorStatus.OPEN
|
|
|
|
@property
|
|
def unique_id(self) -> str:
|
|
"""Get the unique of the door open binary sensor."""
|
|
return '{:s}_{:s}'.format(self._door.device_id,
|
|
SENSOR_TYPES_DOOR[self._sensor_type][0]
|
|
.lower())
|
|
|
|
|
|
class AugustDoorbellBinarySensor(BinarySensorDevice):
|
|
"""Representation of an August binary sensor."""
|
|
|
|
def __init__(self, data, sensor_type, doorbell):
|
|
"""Initialize the sensor."""
|
|
self._data = data
|
|
self._sensor_type = sensor_type
|
|
self._doorbell = doorbell
|
|
self._state = None
|
|
self._available = False
|
|
|
|
@property
|
|
def available(self):
|
|
"""Return the availability of this sensor."""
|
|
return self._available
|
|
|
|
@property
|
|
def is_on(self):
|
|
"""Return true if the binary sensor is on."""
|
|
return self._state
|
|
|
|
@property
|
|
def device_class(self):
|
|
"""Return the class of this device, from component DEVICE_CLASSES."""
|
|
return SENSOR_TYPES_DOORBELL[self._sensor_type][1]
|
|
|
|
@property
|
|
def name(self):
|
|
"""Return the name of the binary sensor."""
|
|
return "{} {}".format(self._doorbell.device_name,
|
|
SENSOR_TYPES_DOORBELL[self._sensor_type][0])
|
|
|
|
def update(self):
|
|
"""Get the latest state of the sensor."""
|
|
state_provider = SENSOR_TYPES_DOORBELL[self._sensor_type][2]
|
|
self._state = state_provider(self._data, self._doorbell)
|
|
self._available = self._doorbell.is_online
|
|
|
|
@property
|
|
def unique_id(self) -> str:
|
|
"""Get the unique id of the doorbell sensor."""
|
|
return '{:s}_{:s}'.format(self._doorbell.device_id,
|
|
SENSOR_TYPES_DOORBELL[self._sensor_type][0]
|
|
.lower())
|