From 065f4b7c20d7cf1da468c4227337be94b8527e40 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 20 Nov 2015 23:39:39 +0100 Subject: [PATCH 1/2] Add binary sensor for aREST --- .../components/binary_sensor/arest.py | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 homeassistant/components/binary_sensor/arest.py diff --git a/homeassistant/components/binary_sensor/arest.py b/homeassistant/components/binary_sensor/arest.py new file mode 100644 index 00000000000..3077fe40bdb --- /dev/null +++ b/homeassistant/components/binary_sensor/arest.py @@ -0,0 +1,106 @@ +""" +homeassistant.components.binary_sensor.arest +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The arest sensor will consume an exposed aREST API of a device. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/binary_sensor.arest/ +""" +import logging +import requests +from datetime import timedelta + +from homeassistant.util import Throttle +from homeassistant.components.binary_sensor import BinarySensorDevice + +_LOGGER = logging.getLogger(__name__) + +# Return cached results if last scan was less then this time ago +MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=30) + +CONF_RESOURCE = 'resource' +CONF_PIN = 'pin' + + +def setup_platform(hass, config, add_devices, discovery_info=None): + """ Get the aREST binary sensor. """ + + resource = config.get(CONF_RESOURCE) + pin = config.get(CONF_PIN) + + if None in (resource, pin): + _LOGGER.error('Not all required config keys present: %s', + ', '.join((CONF_RESOURCE, CONF_PIN))) + return False + + try: + response = requests.get(resource, timeout=10).json() + except requests.exceptions.MissingSchema: + _LOGGER.error('Missing resource or schema in configuration. ' + 'Add http:// to your URL.') + return False + except requests.exceptions.ConnectionError: + _LOGGER.error('No route to device at %s. ' + 'Please check the IP address in the configuration file.', + resource) + return False + + arest = ArestData(resource, pin) + + add_devices([ArestBinarySensor(arest, + resource, + config.get('name', response['name']), + pin)]) + + +# pylint: disable=too-many-instance-attributes, too-many-arguments +class ArestBinarySensor(BinarySensorDevice): + """ Implements an aREST binary sensor for a pin. """ + + def __init__(self, arest, resource, name, pin): + self.arest = arest + self._resource = resource + self._name = name + self._pin = pin + self.update() + + if self._pin is not None: + request = requests.get('{}/mode/{}/i'.format + (self._resource, self._pin), timeout=10) + if request.status_code is not 200: + _LOGGER.error("Can't set mode. Is device offline?") + + @property + def name(self): + """ The name of the binary sensor. """ + return self._name + + @property + def is_on(self): + """ True if the binary sensor is on. """ + return bool(self.arest.data.get('state')) + + def update(self): + """ Gets the latest data from aREST API. """ + self.arest.update() + + +# pylint: disable=too-few-public-methods +class ArestData(object): + """ Class for handling the data retrieval for pins. """ + + def __init__(self, resource, pin): + self._resource = resource + self._pin = pin + self.data = {} + + @Throttle(MIN_TIME_BETWEEN_UPDATES) + def update(self): + """ Gets the latest data from aREST device. """ + try: + response = requests.get('{}/digital/{}'.format( + self._resource, self._pin), timeout=10) + self.data = {'state': response.json()['return_value']} + except requests.exceptions.ConnectionError: + _LOGGER.error("No route to device '%s'. Is device offline?", + self._resource) From b4ee3f73b46aed0f36bc660db80487869c739863 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 20 Nov 2015 23:47:49 +0100 Subject: [PATCH 2/2] Add aREST binary sensor and fix ordering --- .coveragerc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.coveragerc b/.coveragerc index f19e37d00a1..07d4a8dd4bc 100644 --- a/.coveragerc +++ b/.coveragerc @@ -29,7 +29,7 @@ omit = homeassistant/components/rfxtrx.py homeassistant/components/*/rfxtrx.py - homeassistant/components/ifttt.py + homeassistant/components/binary_sensor/arest.py homeassistant/components/browser.py homeassistant/components/camera/* homeassistant/components/device_tracker/actiontec.py @@ -48,6 +48,7 @@ omit = homeassistant/components/device_tracker/snmp.py homeassistant/components/discovery.py homeassistant/components/downloader.py + homeassistant/components/ifttt.py homeassistant/components/keyboard.py homeassistant/components/light/hue.py homeassistant/components/light/mqtt.py @@ -84,7 +85,6 @@ omit = homeassistant/components/sensor/glances.py homeassistant/components/sensor/mysensors.py homeassistant/components/sensor/openweathermap.py - homeassistant/components/switch/orvibo.py homeassistant/components/sensor/rest.py homeassistant/components/sensor/rpi_gpio.py homeassistant/components/sensor/sabnzbd.py @@ -98,6 +98,7 @@ omit = homeassistant/components/switch/command_switch.py homeassistant/components/switch/edimax.py homeassistant/components/switch/hikvisioncam.py + homeassistant/components/switch/orvibo.py homeassistant/components/switch/rest.py homeassistant/components/switch/rpi_gpio.py homeassistant/components/switch/transmission.py