diff --git a/homeassistant/components/sensor/rest.py b/homeassistant/components/sensor/rest.py index f50113350da..4dcd036df5e 100644 --- a/homeassistant/components/sensor/rest.py +++ b/homeassistant/components/sensor/rest.py @@ -1,18 +1,17 @@ """ 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/ """ from datetime import timedelta -from json import loads import logging - import requests -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 +58,31 @@ 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 - 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 +106,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, 'N/A') + self._state = value # pylint: disable=too-few-public-methods @@ -164,7 +129,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 +153,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'