diff --git a/.coveragerc b/.coveragerc index b0d6a40c7f7..4649f175606 100644 --- a/.coveragerc +++ b/.coveragerc @@ -605,6 +605,7 @@ omit = homeassistant/components/simplepush/notify.py homeassistant/components/simplisafe/__init__.py homeassistant/components/simplisafe/alarm_control_panel.py + homeassistant/components/simplisafe/lock.py homeassistant/components/simulated/sensor.py homeassistant/components/sisyphus/* homeassistant/components/sky_hub/device_tracker.py diff --git a/homeassistant/components/simplisafe/__init__.py b/homeassistant/components/simplisafe/__init__.py index 2514c5e9ed9..d57e7b83fa4 100644 --- a/homeassistant/components/simplisafe/__init__.py +++ b/homeassistant/components/simplisafe/__init__.py @@ -154,11 +154,10 @@ async def async_setup_entry(hass, config_entry): await simplisafe.async_update() hass.data[DOMAIN][DATA_CLIENT][config_entry.entry_id] = simplisafe - hass.async_create_task( - hass.config_entries.async_forward_entry_setup( - config_entry, "alarm_control_panel" + for component in ("alarm_control_panel", "lock"): + hass.async_create_task( + hass.config_entries.async_forward_entry_setup(config_entry, component) ) - ) async def refresh(event_time): """Refresh data from the SimpliSafe account.""" @@ -199,7 +198,12 @@ async def async_setup_entry(hass, config_entry): async def async_unload_entry(hass, entry): """Unload a SimpliSafe config entry.""" - await hass.config_entries.async_forward_entry_unload(entry, "alarm_control_panel") + tasks = [ + hass.config_entries.async_forward_entry_unload(entry, component) + for component in ("alarm_control_panel", "lock") + ] + + await asyncio.gather(*tasks) hass.data[DOMAIN][DATA_CLIENT].pop(entry.entry_id) remove_listener = hass.data[DOMAIN][DATA_LISTENER].pop(entry.entry_id) diff --git a/homeassistant/components/simplisafe/lock.py b/homeassistant/components/simplisafe/lock.py new file mode 100644 index 00000000000..10c5d310e73 --- /dev/null +++ b/homeassistant/components/simplisafe/lock.py @@ -0,0 +1,72 @@ +"""Support for SimpliSafe locks.""" +import logging + +from simplipy.lock import LockStates + +from homeassistant.components.lock import LockDevice +from homeassistant.const import STATE_LOCKED, STATE_UNKNOWN, STATE_UNLOCKED + +from . import SimpliSafeEntity +from .const import DATA_CLIENT, DOMAIN + +_LOGGER = logging.getLogger(__name__) + +ATTR_LOCK_LOW_BATTERY = "lock_low_battery" +ATTR_JAMMED = "jammed" +ATTR_PIN_PAD_LOW_BATTERY = "pin_pad_low_battery" + +STATE_MAP = { + LockStates.locked: STATE_LOCKED, + LockStates.unknown: STATE_UNKNOWN, + LockStates.unlocked: STATE_UNLOCKED, +} + + +async def async_setup_entry(hass, entry, async_add_entities): + """Set up SimpliSafe locks based on a config entry.""" + simplisafe = hass.data[DOMAIN][DATA_CLIENT][entry.entry_id] + async_add_entities( + [ + SimpliSafeLock(system, lock) + for system in simplisafe.systems.values() + for lock in system.locks.values() + ] + ) + + +class SimpliSafeLock(SimpliSafeEntity, LockDevice): + """Define a SimpliSafe lock.""" + + def __init__(self, system, lock): + """Initialize.""" + super().__init__(system, lock.name, serial=lock.serial) + self._lock = lock + + @property + def is_locked(self): + """Return true if the lock is locked.""" + return STATE_MAP.get(self._lock.state) == STATE_LOCKED + + async def async_lock(self, **kwargs): + """Lock the lock.""" + await self._lock.lock() + + async def async_unlock(self, **kwargs): + """Unlock the lock.""" + await self._lock.unlock() + + async def async_update(self): + """Update lock status.""" + if self._lock.offline or self._lock.disabled: + self._online = False + return + + self._online = True + + self._attrs.update( + { + ATTR_LOCK_LOW_BATTERY: self._lock.lock_low_battery, + ATTR_JAMMED: self._lock.state == LockStates.jammed, + ATTR_PIN_PAD_LOW_BATTERY: self._lock.pin_pad_low_battery, + } + ) diff --git a/homeassistant/components/simplisafe/manifest.json b/homeassistant/components/simplisafe/manifest.json index 254e947ed25..61a16f8aa44 100644 --- a/homeassistant/components/simplisafe/manifest.json +++ b/homeassistant/components/simplisafe/manifest.json @@ -4,7 +4,7 @@ "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/simplisafe", "requirements": [ - "simplisafe-python==5.1.0" + "simplisafe-python==5.2.0" ], "dependencies": [], "codeowners": [ diff --git a/requirements_all.txt b/requirements_all.txt index d9f830fb5ee..c10b9b46621 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1769,7 +1769,7 @@ shodan==1.19.0 simplepush==1.1.4 # homeassistant.components.simplisafe -simplisafe-python==5.1.0 +simplisafe-python==5.2.0 # homeassistant.components.sisyphus sisyphus-control==2.2.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 221995b0ac6..80c0a5cd33f 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -546,7 +546,7 @@ rxv==0.6.0 samsungctl[websocket]==0.7.1 # homeassistant.components.simplisafe -simplisafe-python==5.1.0 +simplisafe-python==5.2.0 # homeassistant.components.sleepiq sleepyq==0.7