Add template support to rest sensor

This commit is contained in:
Philip Lundrigan 2015-12-11 15:19:49 -07:00
parent 13b0d2afa3
commit 1c54111018

View File

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