From f45848477043d933119180e1229b841372b86240 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Thu, 10 Dec 2015 11:11:35 +0100 Subject: [PATCH 1/7] Add sensor for Dweet.io --- homeassistant/components/sensor/dweet.py | 119 +++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 homeassistant/components/sensor/dweet.py diff --git a/homeassistant/components/sensor/dweet.py b/homeassistant/components/sensor/dweet.py new file mode 100644 index 00000000000..346ecaf6457 --- /dev/null +++ b/homeassistant/components/sensor/dweet.py @@ -0,0 +1,119 @@ +""" +homeassistant.components.sensor.dweet +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Displays values from Dweet.io.. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/sensor.dweet/ +""" +from datetime import timedelta +import logging + +import homeassistant.util as util +from homeassistant.util import Throttle +from homeassistant.helpers.entity import Entity +from homeassistant.const import STATE_UNKNOWN + +_LOGGER = logging.getLogger(__name__) + +DEFAULT_NAME = 'Dweet.io Sensor' +CONF_DEVICE = 'device' + +# Return cached results if last scan was less then this time ago +MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=60) + + +# pylint: disable=unused-variable +def setup_platform(hass, config, add_devices, discovery_info=None): + """ Setup the Dweet sensor. """ + + import dweepy + + device = config.get('device') + + if device is None: + _LOGGER.error('Not all required config keys present: %s', + ', '.join(CONF_DEVICE)) + return False + + try: + dweepy.get_latest_dweet_for(device) + except dweepy.DweepyError: + _LOGGER.error("Device/thing '%s' could not be found", device) + return False + + dweet = DweetData(device) + + add_devices([DweetSensor(dweet, + config.get('name', DEFAULT_NAME), + config.get('variable'), + config.get('unit_of_measurement'), + config.get('correction_factor', None), + config.get('decimal_places', None))]) + + +class DweetSensor(Entity): + """ Implements a Dweet sensor. """ + + def __init__(self, dweet, name, variable, unit_of_measurement, corr_factor, + decimal_places): + self.dweet = dweet + self._name = name + self._variable = variable + self._state = STATE_UNKNOWN + self._unit_of_measurement = unit_of_measurement + self._corr_factor = corr_factor + self._decimal_places = decimal_places + self.update() + + @property + def name(self): + """ The name of the sensor. """ + return self._name + + @property + def unit_of_measurement(self): + """ Unit the value is expressed in. """ + return self._unit_of_measurement + + @property + def state(self): + """ Returns the state. """ + values = self.dweet.data + + if values is not None: + value = util.extract_value_json(values[0]['content'], + self._variable) + if self._corr_factor is not None: + value = float(value) * float(self._corr_factor) + if self._decimal_places is not None: + value = round(value, self._decimal_places) + if self._decimal_places == 0: + value = int(value) + return value + else: + return STATE_UNKNOWN + + def update(self): + """ Gets the latest data from REST API. """ + self.dweet.update() + + +# pylint: disable=too-few-public-methods +class DweetData(object): + """ Class for handling the data retrieval. """ + + def __init__(self, device): + self._device = device + self.data = dict() + + @Throttle(MIN_TIME_BETWEEN_UPDATES) + def update(self): + """ Gets the latest data from Dweet.io. """ + import dweepy + + try: + self.data = dweepy.get_latest_dweet_for(self._device) + except dweepy.DweepyError: + _LOGGER.error("Device '%s' could not be found", self._device) + self.data = None From 64e3db2444d6c3822deb98666920f14c206eed2f Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Thu, 10 Dec 2015 11:12:06 +0100 Subject: [PATCH 2/7] Add dweet sensor --- .coveragerc | 1 + 1 file changed, 1 insertion(+) diff --git a/.coveragerc b/.coveragerc index 993f8c9533b..44093131cfd 100644 --- a/.coveragerc +++ b/.coveragerc @@ -84,6 +84,7 @@ omit = homeassistant/components/sensor/command_sensor.py homeassistant/components/sensor/cpuspeed.py homeassistant/components/sensor/dht.py + homeassistant/components/sensor/dweet.py homeassistant/components/sensor/efergy.py homeassistant/components/sensor/forecast.py homeassistant/components/sensor/glances.py From 4286e116f3d661bcc86c3c8041e216a5d35af733 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Thu, 10 Dec 2015 11:13:59 +0100 Subject: [PATCH 3/7] Add requirement --- homeassistant/components/sensor/dweet.py | 1 + 1 file changed, 1 insertion(+) diff --git a/homeassistant/components/sensor/dweet.py b/homeassistant/components/sensor/dweet.py index 346ecaf6457..124036d298e 100644 --- a/homeassistant/components/sensor/dweet.py +++ b/homeassistant/components/sensor/dweet.py @@ -15,6 +15,7 @@ from homeassistant.helpers.entity import Entity from homeassistant.const import STATE_UNKNOWN _LOGGER = logging.getLogger(__name__) +REQUIREMENTS = ['dweepy==0.2.0'] DEFAULT_NAME = 'Dweet.io Sensor' CONF_DEVICE = 'device' From 1d017beb934bf584780a29c71784dcb658a5c3fa Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sat, 12 Dec 2015 21:56:47 +0100 Subject: [PATCH 4/7] Use templating --- homeassistant/components/sensor/dweet.py | 54 ++++++++++++------------ 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/homeassistant/components/sensor/dweet.py b/homeassistant/components/sensor/dweet.py index 124036d298e..422012bec2c 100644 --- a/homeassistant/components/sensor/dweet.py +++ b/homeassistant/components/sensor/dweet.py @@ -1,18 +1,19 @@ """ homeassistant.components.sensor.dweet ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Displays values from Dweet.io.. +Displays values from Dweet.io. For more details about this platform, please refer to the documentation at https://home-assistant.io/components/sensor.dweet/ """ from datetime import timedelta import logging +import json -import homeassistant.util as util from homeassistant.util import Throttle +from homeassistant.util import template from homeassistant.helpers.entity import Entity -from homeassistant.const import STATE_UNKNOWN +from homeassistant.const import (STATE_UNKNOWN, CONF_VALUE_TEMPLATE) _LOGGER = logging.getLogger(__name__) REQUIREMENTS = ['dweepy==0.2.0'] @@ -24,47 +25,51 @@ CONF_DEVICE = 'device' MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=60) -# pylint: disable=unused-variable +# pylint: disable=unused-variable, too-many-function-args def setup_platform(hass, config, add_devices, discovery_info=None): """ Setup the Dweet sensor. """ - import dweepy device = config.get('device') + value_template = config.get(CONF_VALUE_TEMPLATE) - if device is None: + if None in (device, value_template): _LOGGER.error('Not all required config keys present: %s', - ', '.join(CONF_DEVICE)) + ', '.join(CONF_DEVICE, CONF_VALUE_TEMPLATE)) return False try: - dweepy.get_latest_dweet_for(device) + content = json.dumps(dweepy.get_latest_dweet_for(device)[0]['content']) except dweepy.DweepyError: _LOGGER.error("Device/thing '%s' could not be found", device) return False + if template.render_with_possible_json_value(hass, + value_template, + content) is '': + _LOGGER.error("'%s' was not found", value_template) + return False + dweet = DweetData(device) - add_devices([DweetSensor(dweet, + add_devices([DweetSensor(hass, + dweet, config.get('name', DEFAULT_NAME), - config.get('variable'), - config.get('unit_of_measurement'), - config.get('correction_factor', None), - config.get('decimal_places', None))]) + value_template, + config.get('unit_of_measurement'))]) +# pylint: disable=too-many-arguments class DweetSensor(Entity): """ Implements a Dweet sensor. """ - def __init__(self, dweet, name, variable, unit_of_measurement, corr_factor, - decimal_places): + def __init__(self, hass, dweet, name, value_template, unit_of_measurement): + self.hass = hass self.dweet = dweet self._name = name - self._variable = variable + self._value_template = value_template self._state = STATE_UNKNOWN self._unit_of_measurement = unit_of_measurement - self._corr_factor = corr_factor - self._decimal_places = decimal_places self.update() @property @@ -80,17 +85,10 @@ class DweetSensor(Entity): @property def state(self): """ Returns the state. """ - values = self.dweet.data - + values = json.dumps(self.dweet.data[0]['content']) if values is not None: - value = util.extract_value_json(values[0]['content'], - self._variable) - if self._corr_factor is not None: - value = float(value) * float(self._corr_factor) - if self._decimal_places is not None: - value = round(value, self._decimal_places) - if self._decimal_places == 0: - value = int(value) + value = template.render_with_possible_json_value( + self.hass, self._value_template, values) return value else: return STATE_UNKNOWN From 27c5c1cb9f59d40c339fb30037172f8d9079d03f Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sat, 12 Dec 2015 22:58:08 +0100 Subject: [PATCH 5/7] Add dweepy --- requirements_all.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/requirements_all.txt b/requirements_all.txt index 5db0a85cee4..78234e8fb52 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -177,3 +177,6 @@ pydispatcher==2.0.5 # homeassistant.components.heatmiser heatmiserV3==0.9.1 + +# homeassistant.components.seansor.dweet +dweepy==0.2.0 From ed9b75756aa950296048a76d633b40922537ee58 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sun, 13 Dec 2015 01:00:12 +0100 Subject: [PATCH 6/7] Catch error state --- homeassistant/components/sensor/dweet.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/sensor/dweet.py b/homeassistant/components/sensor/dweet.py index 422012bec2c..8aa55c847cf 100644 --- a/homeassistant/components/sensor/dweet.py +++ b/homeassistant/components/sensor/dweet.py @@ -85,13 +85,13 @@ class DweetSensor(Entity): @property def state(self): """ Returns the state. """ - values = json.dumps(self.dweet.data[0]['content']) - if values is not None: + if self.dweet.data is None: + return STATE_UNKNOWN + else: + values = json.dumps(self.dweet.data[0]['content']) value = template.render_with_possible_json_value( self.hass, self._value_template, values) return value - else: - return STATE_UNKNOWN def update(self): """ Gets the latest data from REST API. """ @@ -104,7 +104,7 @@ class DweetData(object): def __init__(self, device): self._device = device - self.data = dict() + self.data = None @Throttle(MIN_TIME_BETWEEN_UPDATES) def update(self): From 649ce7befbade134db3c56b93eccc4ad9d02ab24 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sun, 13 Dec 2015 01:00:34 +0100 Subject: [PATCH 7/7] Fix typo --- requirements_all.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_all.txt b/requirements_all.txt index 78234e8fb52..d26029d909f 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -178,5 +178,5 @@ pydispatcher==2.0.5 # homeassistant.components.heatmiser heatmiserV3==0.9.1 -# homeassistant.components.seansor.dweet +# homeassistant.components.sensor.dweet dweepy==0.2.0