From 1c5411101878c886cf9cced53b9b0c9d6652e465 Mon Sep 17 00:00:00 2001 From: Philip Lundrigan Date: Fri, 11 Dec 2015 15:19:49 -0700 Subject: [PATCH 1/3] Add template support to rest sensor --- homeassistant/components/sensor/rest.py | 74 +++++++++---------------- 1 file changed, 26 insertions(+), 48 deletions(-) diff --git a/homeassistant/components/sensor/rest.py b/homeassistant/components/sensor/rest.py index f50113350da..041a656a5ba 100644 --- a/homeassistant/components/sensor/rest.py +++ b/homeassistant/components/sensor/rest.py @@ -7,12 +7,12 @@ For more details about this platform, please refer to the documentation at https://home-assistant.io/components/sensor.rest/ """ from datetime import timedelta -from json import loads import logging - import requests +import jinja2.exceptions -from homeassistant.util import Throttle +from homeassistant.const import CONF_VALUE_TEMPLATE +from homeassistant.util import template, Throttle from homeassistant.helpers.entity import Entity _LOGGER = logging.getLogger(__name__) @@ -59,57 +59,43 @@ def setup_platform(hass, config, add_devices, discovery_info=None): 'Please check the URL in the configuration file.') return False - try: - data = loads(response.text) - except ValueError: - _LOGGER.error('No valid JSON in the response in: %s', data) - return False - - try: - RestSensor.extract_value(data, config.get('variable')) - except KeyError: - _LOGGER.error('Variable "%s" not found in response: "%s"', - config.get('variable'), data) - return False + value_template = config.get(CONF_VALUE_TEMPLATE) + data = response.text + if value_template is not None: + try: + template.render_with_possible_json_value(hass, + value_template, + data) + except jinja2.exceptions.UndefinedError: + _LOGGER.error('Template "%s" not found in response: "%s"', + value_template, data) + return False if use_get: rest = RestDataGet(resource, verify_ssl) elif use_post: rest = RestDataPost(resource, payload, verify_ssl) - add_devices([RestSensor(rest, + add_devices([RestSensor(hass, + rest, config.get('name', DEFAULT_NAME), - config.get('variable'), config.get('unit_of_measurement'), - config.get('correction_factor', None), - config.get('decimal_places', None))]) + config.get(CONF_VALUE_TEMPLATE))]) # pylint: disable=too-many-arguments class RestSensor(Entity): """ Implements a REST sensor. """ - def __init__(self, rest, name, variable, unit_of_measurement, corr_factor, - decimal_places): + def __init__(self, hass, rest, name, unit_of_measurement, value_template): + self._hass = hass self.rest = rest self._name = name - self._variable = variable self._state = 'n/a' self._unit_of_measurement = unit_of_measurement - self._corr_factor = corr_factor - self._decimal_places = decimal_places + self._value_template = value_template self.update() - @classmethod - def extract_value(cls, data, variable): - """ Extracts the value using a key name or a path. """ - if isinstance(variable, list): - for variable_item in variable: - data = data[variable_item] - return data - else: - return data[variable] - @property def name(self): """ The name of the sensor. """ @@ -133,18 +119,10 @@ class RestSensor(Entity): if 'error' in value: self._state = value['error'] else: - try: - if value is not None: - value = RestSensor.extract_value(value, 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) - self._state = value - except ValueError: - self._state = RestSensor.extract_value(value, self._variable) + if self._value_template is not None: + value = template.render_with_possible_json_value( + self._hass, self._value_template, value) + self._state = value # pylint: disable=too-few-public-methods @@ -164,7 +142,7 @@ class RestDataGet(object): verify=self._verify_ssl) if 'error' in self.data: del self.data['error'] - self.data = response.json() + self.data = response.text except requests.exceptions.ConnectionError: _LOGGER.error("No route to resource/endpoint.") self.data['error'] = 'N/A' @@ -188,7 +166,7 @@ class RestDataPost(object): timeout=10, verify=self._verify_ssl) if 'error' in self.data: del self.data['error'] - self.data = response.json() + self.data = response.text except requests.exceptions.ConnectionError: _LOGGER.error("No route to resource/endpoint.") self.data['error'] = 'N/A' From a84ff14b00b69230d8e2ba9a115c8e621db4cc74 Mon Sep 17 00:00:00 2001 From: Philip Lundrigan Date: Sat, 12 Dec 2015 13:34:21 -0700 Subject: [PATCH 2/3] Remove exception handling for templates It is now handled in the layers below --- homeassistant/components/sensor/rest.py | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/homeassistant/components/sensor/rest.py b/homeassistant/components/sensor/rest.py index 041a656a5ba..f824f022966 100644 --- a/homeassistant/components/sensor/rest.py +++ b/homeassistant/components/sensor/rest.py @@ -9,7 +9,6 @@ https://home-assistant.io/components/sensor.rest/ from datetime import timedelta import logging import requests -import jinja2.exceptions from homeassistant.const import CONF_VALUE_TEMPLATE from homeassistant.util import template, Throttle @@ -59,18 +58,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None): 'Please check the URL in the configuration file.') return False - value_template = config.get(CONF_VALUE_TEMPLATE) - data = response.text - if value_template is not None: - try: - template.render_with_possible_json_value(hass, - value_template, - data) - except jinja2.exceptions.UndefinedError: - _LOGGER.error('Template "%s" not found in response: "%s"', - value_template, data) - return False - if use_get: rest = RestDataGet(resource, verify_ssl) elif use_post: @@ -121,7 +108,7 @@ class RestSensor(Entity): else: if self._value_template is not None: value = template.render_with_possible_json_value( - self._hass, self._value_template, value) + self._hass, self._value_template, value, 'N/A') self._state = value From 27e3e72211805fd44a3af2d255c10a75aa7bc60b Mon Sep 17 00:00:00 2001 From: Philip Lundrigan Date: Sat, 12 Dec 2015 14:19:00 -0700 Subject: [PATCH 3/3] Change description of rest sensor --- homeassistant/components/sensor/rest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/sensor/rest.py b/homeassistant/components/sensor/rest.py index f824f022966..4dcd036df5e 100644 --- a/homeassistant/components/sensor/rest.py +++ b/homeassistant/components/sensor/rest.py @@ -1,7 +1,7 @@ """ homeassistant.components.sensor.rest ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The rest sensor will consume JSON responses sent by an exposed REST API. +The rest sensor will consume responses sent by an exposed REST API. For more details about this platform, please refer to the documentation at https://home-assistant.io/components/sensor.rest/