From c2be7bc842f7dc90676fb1c5799eaea4fd9724a9 Mon Sep 17 00:00:00 2001 From: Anubhaw Arya Date: Sun, 19 Mar 2017 18:04:49 -0700 Subject: [PATCH 1/2] Integration with lockitron --- .coveragerc | 1 + homeassistant/components/lock/lockitron.py | 99 ++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 homeassistant/components/lock/lockitron.py diff --git a/.coveragerc b/.coveragerc index fac7edfa42b81..c6bf3d197ae4d 100644 --- a/.coveragerc +++ b/.coveragerc @@ -235,6 +235,7 @@ omit = homeassistant/components/light/zengge.py homeassistant/components/lirc.py homeassistant/components/lock/nuki.py + homeassistant/components/lock/lockitron.py homeassistant/components/media_player/anthemav.py homeassistant/components/media_player/apple_tv.py homeassistant/components/media_player/aquostv.py diff --git a/homeassistant/components/lock/lockitron.py b/homeassistant/components/lock/lockitron.py new file mode 100644 index 0000000000000..e9a560c68f9dc --- /dev/null +++ b/homeassistant/components/lock/lockitron.py @@ -0,0 +1,99 @@ +""" +Lockitron lock platform. + +For more details about this platform, please refer to the documentation +https://home-assistant.io/components/lockitron/ +""" +import logging + +import requests +import voluptuous as vol + +import homeassistant.helpers.config_validation as cv +from homeassistant.components.lock import LockDevice, PLATFORM_SCHEMA +from homeassistant.const import CONF_ACCESS_TOKEN, CONF_ID + +_LOGGER = logging.getLogger(__name__) + +DOMAIN = 'lockitron' + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_ACCESS_TOKEN): cv.string, + vol.Required(CONF_ID): cv.string +}) +BASE_URL = 'https://api.lockitron.com' +API_STATE_URL = BASE_URL + '/v2/locks/{}?access_token={}' +API_ACTION_URL = BASE_URL + '/v2/locks/{}?access_token={}&state={}' + + +# pylint: disable=unused-argument +def setup_platform(hass, config, add_devices, discovery_info=None): + """Setup the Lockitron platform.""" + access_token = config.get(CONF_ACCESS_TOKEN) + device_id = config.get(CONF_ID) + response = requests.get(API_STATE_URL.format(device_id, access_token)) + if response.status_code == 200: + add_devices([Lockitron(response.json()['state'], access_token, + device_id)]) + else: + _LOGGER.error('Error retrieving lock status during init: %s', + response.text) + + +class Lockitron(LockDevice): + """Representation of a Lockitron lock.""" + + LOCK_STATE = 'lock' + UNLOCK_STATE = 'unlock' + + def __init__(self, state, access_token, device_id): + """Initialize the lock.""" + self._state = state + self.access_token = access_token + self.device_id = device_id + + @property + def should_poll(self): + """Return True since we need to poll for the lock's new status.""" + return True + + @property + def name(self): + """Return the name of the device.""" + return DOMAIN + + @property + def is_locked(self): + """Return True if the lock is currently locked, else False.""" + return self._state == Lockitron.LOCK_STATE + + def lock(self, **kwargs): + """Lock the device.""" + self._state = self.do_change_request(Lockitron.LOCK_STATE) + self.update_ha_state() + + def unlock(self, **kwargs): + """Unlock the device.""" + self._state = self.do_change_request(Lockitron.UNLOCK_STATE) + self.update_ha_state() + + def update(self): + """Update the internal state of the device.""" + response = requests \ + .get(API_STATE_URL.format(self.device_id, self.access_token)) + if response.status_code == 200: + self._state = response.json()['state'] + else: + _LOGGER.error('Error retrieving lock status: %s', response.text) + + def do_change_request(self, requested_state): + """Execute the change request and pull out the new state.""" + response = requests.put( + API_ACTION_URL.format(self.device_id, self.access_token, + requested_state)) + if response.status_code == 200: + return response.json()['state'] + else: + _LOGGER.error('Error setting lock state: %s\n%s', + requested_state, response.text) + return self._state From a3a6c98ff2c570b7e67164cd363b9929335c37e9 Mon Sep 17 00:00:00 2001 From: Anubhaw Arya Date: Tue, 28 Mar 2017 19:14:21 -0700 Subject: [PATCH 2/2] Let super class deal with polling and updating --- homeassistant/components/lock/lockitron.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/homeassistant/components/lock/lockitron.py b/homeassistant/components/lock/lockitron.py index e9a560c68f9dc..86821711fd207 100644 --- a/homeassistant/components/lock/lockitron.py +++ b/homeassistant/components/lock/lockitron.py @@ -52,11 +52,6 @@ def __init__(self, state, access_token, device_id): self.access_token = access_token self.device_id = device_id - @property - def should_poll(self): - """Return True since we need to poll for the lock's new status.""" - return True - @property def name(self): """Return the name of the device.""" @@ -70,12 +65,10 @@ def is_locked(self): def lock(self, **kwargs): """Lock the device.""" self._state = self.do_change_request(Lockitron.LOCK_STATE) - self.update_ha_state() def unlock(self, **kwargs): """Unlock the device.""" self._state = self.do_change_request(Lockitron.UNLOCK_STATE) - self.update_ha_state() def update(self): """Update the internal state of the device."""