216 lines
6.5 KiB
Python
216 lines
6.5 KiB
Python
"""Support for Wink locks."""
|
|
import logging
|
|
|
|
import pywink
|
|
import voluptuous as vol
|
|
|
|
from homeassistant.components.lock import LockEntity
|
|
from homeassistant.const import (
|
|
ATTR_CODE,
|
|
ATTR_ENTITY_ID,
|
|
ATTR_MODE,
|
|
ATTR_NAME,
|
|
STATE_UNKNOWN,
|
|
)
|
|
import homeassistant.helpers.config_validation as cv
|
|
|
|
from . import DOMAIN, WinkDevice
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
SERVICE_SET_VACATION_MODE = "set_lock_vacation_mode"
|
|
SERVICE_SET_ALARM_MODE = "set_lock_alarm_mode"
|
|
SERVICE_SET_ALARM_SENSITIVITY = "set_lock_alarm_sensitivity"
|
|
SERVICE_SET_ALARM_STATE = "set_lock_alarm_state"
|
|
SERVICE_SET_BEEPER_STATE = "set_lock_beeper_state"
|
|
SERVICE_ADD_KEY = "add_new_lock_key_code"
|
|
|
|
ATTR_ENABLED = "enabled"
|
|
ATTR_SENSITIVITY = "sensitivity"
|
|
|
|
ALARM_SENSITIVITY_MAP = {
|
|
"low": 0.2,
|
|
"medium_low": 0.4,
|
|
"medium": 0.6,
|
|
"medium_high": 0.8,
|
|
"high": 1.0,
|
|
}
|
|
|
|
ALARM_MODES_MAP = {
|
|
"activity": "alert",
|
|
"forced_entry": "forced_entry",
|
|
"tamper": "tamper",
|
|
}
|
|
|
|
SET_ENABLED_SCHEMA = vol.Schema(
|
|
{vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, vol.Required(ATTR_ENABLED): cv.string}
|
|
)
|
|
|
|
SET_SENSITIVITY_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Optional(ATTR_ENTITY_ID): cv.entity_ids,
|
|
vol.Required(ATTR_SENSITIVITY): vol.In(ALARM_SENSITIVITY_MAP),
|
|
}
|
|
)
|
|
|
|
SET_ALARM_MODES_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Optional(ATTR_ENTITY_ID): cv.entity_ids,
|
|
vol.Required(ATTR_MODE): vol.In(ALARM_MODES_MAP),
|
|
}
|
|
)
|
|
|
|
ADD_KEY_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Optional(ATTR_ENTITY_ID): cv.entity_ids,
|
|
vol.Required(ATTR_NAME): cv.string,
|
|
vol.Required(ATTR_CODE): cv.positive_int,
|
|
}
|
|
)
|
|
|
|
|
|
def setup_platform(hass, config, add_entities, discovery_info=None):
|
|
"""Set up the Wink platform."""
|
|
|
|
for lock in pywink.get_locks():
|
|
_id = lock.object_id() + lock.name()
|
|
if _id not in hass.data[DOMAIN]["unique_ids"]:
|
|
add_entities([WinkLockDevice(lock, hass)])
|
|
|
|
def service_handle(service):
|
|
"""Handle for services."""
|
|
entity_ids = service.data.get("entity_id")
|
|
all_locks = hass.data[DOMAIN]["entities"]["lock"]
|
|
locks_to_set = []
|
|
if entity_ids is None:
|
|
locks_to_set = all_locks
|
|
else:
|
|
for lock in all_locks:
|
|
if lock.entity_id in entity_ids:
|
|
locks_to_set.append(lock)
|
|
|
|
for lock in locks_to_set:
|
|
if service.service == SERVICE_SET_VACATION_MODE:
|
|
lock.set_vacation_mode(service.data.get(ATTR_ENABLED))
|
|
elif service.service == SERVICE_SET_ALARM_STATE:
|
|
lock.set_alarm_state(service.data.get(ATTR_ENABLED))
|
|
elif service.service == SERVICE_SET_BEEPER_STATE:
|
|
lock.set_beeper_state(service.data.get(ATTR_ENABLED))
|
|
elif service.service == SERVICE_SET_ALARM_MODE:
|
|
lock.set_alarm_mode(service.data.get(ATTR_MODE))
|
|
elif service.service == SERVICE_SET_ALARM_SENSITIVITY:
|
|
lock.set_alarm_sensitivity(service.data.get(ATTR_SENSITIVITY))
|
|
elif service.service == SERVICE_ADD_KEY:
|
|
name = service.data.get(ATTR_NAME)
|
|
code = service.data.get(ATTR_CODE)
|
|
lock.add_new_key(code, name)
|
|
|
|
hass.services.register(
|
|
DOMAIN, SERVICE_SET_VACATION_MODE, service_handle, schema=SET_ENABLED_SCHEMA
|
|
)
|
|
|
|
hass.services.register(
|
|
DOMAIN, SERVICE_SET_ALARM_STATE, service_handle, schema=SET_ENABLED_SCHEMA
|
|
)
|
|
|
|
hass.services.register(
|
|
DOMAIN, SERVICE_SET_BEEPER_STATE, service_handle, schema=SET_ENABLED_SCHEMA
|
|
)
|
|
|
|
hass.services.register(
|
|
DOMAIN, SERVICE_SET_ALARM_MODE, service_handle, schema=SET_ALARM_MODES_SCHEMA
|
|
)
|
|
|
|
hass.services.register(
|
|
DOMAIN,
|
|
SERVICE_SET_ALARM_SENSITIVITY,
|
|
service_handle,
|
|
schema=SET_SENSITIVITY_SCHEMA,
|
|
)
|
|
|
|
hass.services.register(
|
|
DOMAIN, SERVICE_ADD_KEY, service_handle, schema=ADD_KEY_SCHEMA
|
|
)
|
|
|
|
|
|
class WinkLockDevice(WinkDevice, LockEntity):
|
|
"""Representation of a Wink lock."""
|
|
|
|
async def async_added_to_hass(self):
|
|
"""Call when entity is added to hass."""
|
|
self.hass.data[DOMAIN]["entities"]["lock"].append(self)
|
|
|
|
@property
|
|
def is_locked(self):
|
|
"""Return true if device is locked."""
|
|
return self.wink.state()
|
|
|
|
def lock(self, **kwargs):
|
|
"""Lock the device."""
|
|
self.wink.set_state(True)
|
|
|
|
def unlock(self, **kwargs):
|
|
"""Unlock the device."""
|
|
self.wink.set_state(False)
|
|
|
|
def set_alarm_state(self, enabled):
|
|
"""Set lock's alarm state."""
|
|
self.wink.set_alarm_state(enabled)
|
|
|
|
def set_vacation_mode(self, enabled):
|
|
"""Set lock's vacation mode."""
|
|
self.wink.set_vacation_mode(enabled)
|
|
|
|
def set_beeper_state(self, enabled):
|
|
"""Set lock's beeper mode."""
|
|
self.wink.set_beeper_mode(enabled)
|
|
|
|
def add_new_key(self, code, name):
|
|
"""Add a new user key code."""
|
|
self.wink.add_new_key(code, name)
|
|
|
|
def set_alarm_sensitivity(self, sensitivity):
|
|
"""
|
|
Set lock's alarm sensitivity.
|
|
|
|
Valid sensitivities:
|
|
0.2, 0.4, 0.6, 0.8, 1.0
|
|
"""
|
|
self.wink.set_alarm_sensitivity(sensitivity)
|
|
|
|
def set_alarm_mode(self, mode):
|
|
"""
|
|
Set lock's alarm mode.
|
|
|
|
Valid modes:
|
|
alert - Beep when lock is locked or unlocked
|
|
tamper - 15 sec alarm when lock is disturbed when locked
|
|
forced_entry - 3 min alarm when significant force applied
|
|
to door when locked.
|
|
"""
|
|
self.wink.set_alarm_mode(mode)
|
|
|
|
@property
|
|
def device_state_attributes(self):
|
|
"""Return the state attributes."""
|
|
super_attrs = super().device_state_attributes
|
|
sensitivity = dict_value_to_key(
|
|
ALARM_SENSITIVITY_MAP, self.wink.alarm_sensitivity()
|
|
)
|
|
super_attrs["alarm_sensitivity"] = sensitivity
|
|
super_attrs["vacation_mode"] = self.wink.vacation_mode_enabled()
|
|
super_attrs["beeper_mode"] = self.wink.beeper_enabled()
|
|
super_attrs["auto_lock"] = self.wink.auto_lock_enabled()
|
|
alarm_mode = dict_value_to_key(ALARM_MODES_MAP, self.wink.alarm_mode())
|
|
super_attrs["alarm_mode"] = alarm_mode
|
|
super_attrs["alarm_enabled"] = self.wink.alarm_enabled()
|
|
return super_attrs
|
|
|
|
|
|
def dict_value_to_key(dict_map, comp_value):
|
|
"""Return the key that has the provided value."""
|
|
for key, value in dict_map.items():
|
|
if value == comp_value:
|
|
return key
|
|
return STATE_UNKNOWN
|