Merge pull request #732 from philipbl/sensor_template

Add template support for rest sensor
This commit is contained in:
Paulus Schoutsen 2015-12-12 13:26:15 -08:00
commit 01c4038dec

View File

@ -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'