Add template support
parent
fc8c26005c
commit
de68d3355a
|
@ -0,0 +1,58 @@
|
|||
"""
|
||||
homeassistant.util.template
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Template utility methods for rendering strings with HA data.
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
from jinja2.sandbox import SandboxedEnvironment
|
||||
|
||||
ENV = SandboxedEnvironment()
|
||||
|
||||
|
||||
def forgiving_round(value, precision):
|
||||
""" Rounding method that accepts strings. """
|
||||
try:
|
||||
return round(float(value), precision)
|
||||
except ValueError:
|
||||
# If value can't be converted to float
|
||||
return value
|
||||
|
||||
|
||||
ENV.filters['round'] = forgiving_round
|
||||
|
||||
|
||||
def render(hass, template):
|
||||
""" Render given template. """
|
||||
return ENV.from_string(template).render(
|
||||
states=AllStates(hass))
|
||||
|
||||
|
||||
class AllStates(object):
|
||||
""" Class to expose all HA states as attributes. """
|
||||
def __init__(self, hass):
|
||||
self._hass = hass
|
||||
|
||||
def __getattr__(self, name):
|
||||
return DomainStates(self._hass, name)
|
||||
|
||||
def __iter__(self):
|
||||
return iter(sorted(self._hass.states.all(),
|
||||
key=lambda state: state.entity_id))
|
||||
|
||||
|
||||
class DomainStates(object):
|
||||
""" Class to expose a specific HA domain as attributes. """
|
||||
|
||||
def __init__(self, hass, domain):
|
||||
self._hass = hass
|
||||
self._domain = domain
|
||||
|
||||
def __getattr__(self, name):
|
||||
return self._hass.states.get('{}.{}'.format(self._domain, name))
|
||||
|
||||
def __iter__(self):
|
||||
return iter(sorted(
|
||||
(state for state in self._hass.states.all()
|
||||
if state.domain == self._domain),
|
||||
key=lambda state: state.entity_id))
|
|
@ -0,0 +1,57 @@
|
|||
"""
|
||||
tests.test_util
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Tests Home Assistant util methods.
|
||||
"""
|
||||
# pylint: disable=too-many-public-methods
|
||||
import unittest
|
||||
import homeassistant.core as ha
|
||||
|
||||
from homeassistant.util import template
|
||||
|
||||
|
||||
class TestUtilTemplate(unittest.TestCase):
|
||||
|
||||
def setUp(self): # pylint: disable=invalid-name
|
||||
self.hass = ha.HomeAssistant()
|
||||
|
||||
def tearDown(self): # pylint: disable=invalid-name
|
||||
""" Stop down stuff we started. """
|
||||
self.hass.stop()
|
||||
|
||||
def test_referring_states_by_entity_id(self):
|
||||
self.hass.states.set('test.object', 'happy')
|
||||
self.assertEqual(
|
||||
'happy',
|
||||
template.render(self.hass, '{{ states.test.object.state }}'))
|
||||
|
||||
def test_iterating_all_states(self):
|
||||
self.hass.states.set('test.object', 'happy')
|
||||
self.hass.states.set('sensor.temperature', 10)
|
||||
|
||||
self.assertEqual(
|
||||
'10happy',
|
||||
template.render(
|
||||
self.hass,
|
||||
'{% for state in states %}{{ state.state }}{% endfor %}'))
|
||||
|
||||
def test_iterating_domain_states(self):
|
||||
self.hass.states.set('test.object', 'happy')
|
||||
self.hass.states.set('sensor.back_door', 'open')
|
||||
self.hass.states.set('sensor.temperature', 10)
|
||||
|
||||
self.assertEqual(
|
||||
'open10',
|
||||
template.render(
|
||||
self.hass,
|
||||
'{% for state in states.sensor %}{{ state.state }}{% endfor %}'))
|
||||
|
||||
def test_rounding_value(self):
|
||||
self.hass.states.set('sensor.temperature', 12.34)
|
||||
|
||||
self.assertEqual(
|
||||
'12.3',
|
||||
template.render(
|
||||
self.hass,
|
||||
'{{ states.sensor.temperature.state | round(1) }}'))
|
Loading…
Reference in New Issue