def test_states_function(self): self.hass.states.set('test.object', 'available') self.assertEqual( 'available', template.render(self.hass, '{{ states("test.object") }}')) self.assertEqual( 'unknown', template.render(self.hass, '{{ states("test.object2") }}'))
def notify_message(notify_service, call): """ Handle sending notification message service calls. """ message = call.data.get(ATTR_MESSAGE) if message is None: return title = template.render(hass, call.data.get(ATTR_TITLE, ATTR_TITLE_DEFAULT)) target = call.data.get(ATTR_TARGET) message = template.render(hass, message) notify_service.send_message(message, title=title, target=target)
def notify_message(notify_service, call): """ Handle sending notification message service calls. """ message = call.data.get(ATTR_MESSAGE) if message is None: return title = template.render( hass, call.data.get(ATTR_TITLE, ATTR_TITLE_DEFAULT)) target = call.data.get(ATTR_TARGET) message = template.render(hass, message) notify_service.send_message(message, title=title, target=target)
def test_is_state_attr(self): self.hass.states.set('test.object', 'available', {'mode': 'on'}) self.assertEqual( 'yes', template.render( self.hass, '{% if is_state_attr("test.object", "mode", "on") %}yes{% else %}no{% endif %}'))
def test_if_state_exists(self): self.hass.states.set('test.object', 'available') self.assertEqual( 'exists', template.render( self.hass, '{% if states.test.object %}exists{% else %}not exists{% endif %}'))
def if_action(hass, config): """ Wraps action method with state based condition. """ entity_id = config.get(CONF_ENTITY_ID) if entity_id is None: _LOGGER.error("Missing configuration key %s", CONF_ENTITY_ID) return None below = config.get(CONF_BELOW) above = config.get(CONF_ABOVE) value_template = config.get(CONF_VALUE_TEMPLATE) if below is None and above is None: _LOGGER.error("Missing configuration key." " One of %s or %s is required", CONF_BELOW, CONF_ABOVE) return None if value_template is not None: renderer = lambda value: template.render(hass, value_template, {'state': value}) else: renderer = lambda value: value.state def if_numeric_state(): """ Test numeric state condition. """ state = hass.states.get(entity_id) return state is not None and _in_range(above, below, renderer(state)) return if_numeric_state
def test_rounding_value(self): self.hass.states.set('sensor.temperature', 12.78) self.assertEqual( '12.8', template.render( self.hass, '{{ states.sensor.temperature.state | round(1) }}'))
def test_is_state(self): self.hass.states.set('test.object', 'available') self.assertEqual( 'yes', template.render( self.hass, '{% if is_state("test.object", "available") %}yes{% else %}no{% endif %}'))
def test_rounding_value2(self): self.hass.states.set('sensor.temperature', 12.78) self.assertEqual( '128', template.render( self.hass, '{{ states.sensor.temperature.state | multiply(10) | round }}'))
def test_if_state_exists(self): self.hass.states.set('test.object', 'available') self.assertEqual( 'exists', template.render( self.hass, '{% if states.test.object %}exists{% else %}not exists{% endif %}' ))
def test_is_state_attr(self): self.hass.states.set('test.object', 'available', {'mode': 'on'}) self.assertEqual( 'yes', template.render( self.hass, '{% if is_state_attr("test.object", "mode", "on") %}yes{% else %}no{% endif %}' ))
def test_is_state(self): self.hass.states.set('test.object', 'available') self.assertEqual( 'yes', template.render( self.hass, '{% if is_state("test.object", "available") %}yes{% else %}no{% endif %}' ))
def test_rounding_value2(self): self.hass.states.set('sensor.temperature', 12.78) self.assertEqual( '128', template.render( self.hass, '{{ states.sensor.temperature.state | multiply(10) | round }}') )
def _check_template(hass, value_template): """ Checks if result of template is true """ try: value = template.render(hass, value_template, {}) except TemplateError: _LOGGER.exception('Error parsing template') return False return value.lower() == 'true'
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 update(self): try: self._state = template.render(self.hass, self._template) except TemplateError as ex: self._state = STATE_ERROR if ex.args and ex.args[0].startswith( "UndefinedError: 'None' has no attribute"): # Common during HA startup - so just a warning _LOGGER.warning(ex) return _LOGGER.error(ex)
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 log_message(service): """ Handle sending notification message service calls. """ message = service.data.get(ATTR_MESSAGE) name = service.data.get(ATTR_NAME) domain = service.data.get(ATTR_DOMAIN, None) entity_id = service.data.get(ATTR_ENTITY_ID, None) if not message or not name: return message = template.render(hass, message) log_entry(hass, name, message, domain, entity_id)
def update(self): """ Updates the state from the template. """ try: self._value = template.render(self.hass, self._template) if not self.available: _LOGGER.error( "`%s` is not a switch state, setting %s to unavailable", self._value, self.entity_id) except TemplateError as ex: self._value = STATE_ERROR _LOGGER.error(ex)
def _handle_post_api_template(handler, path_match, data): """ Log user out. """ template_string = data.get('template', '') try: rendered = template.render(handler.server.hass, template_string) handler.send_response(HTTP_OK) handler.send_header(HTTP_HEADER_CONTENT_TYPE, CONTENT_TYPE_TEXT_PLAIN) handler.end_headers() handler.wfile.write(rendered.encode('utf-8')) except TemplateError as e: handler.write_json_message(str(e), HTTP_UNPROCESSABLE_ENTITY) return
def trigger(hass, config, action): """ Listen for state changes based on `config`. """ entity_id = config.get(CONF_ENTITY_ID) if entity_id is None: _LOGGER.error("Missing configuration key %s", CONF_ENTITY_ID) return False below = config.get(CONF_BELOW) above = config.get(CONF_ABOVE) value_template = config.get(CONF_VALUE_TEMPLATE) if below is None and above is None: _LOGGER.error("Missing configuration key." " One of %s or %s is required", CONF_BELOW, CONF_ABOVE) return False if value_template is not None: renderer = lambda value: template.render(hass, value_template, {'state': value}) else: renderer = lambda value: value.state # pylint: disable=unused-argument def state_automation_listener(entity, from_s, to_s): """ Listens for state changes and calls action. """ # Fire action if we go from outside range into range if _in_range(above, below, renderer(to_s)) and \ (from_s is None or not _in_range(above, below, renderer(from_s))): action() track_state_change( hass, entity_id, state_automation_listener) return True
def publish_service(call): """Handle MQTT publish service calls.""" msg_topic = call.data.get(ATTR_TOPIC) payload = call.data.get(ATTR_PAYLOAD) payload_template = call.data.get(ATTR_PAYLOAD_TEMPLATE) qos = call.data.get(ATTR_QOS, DEFAULT_QOS) retain = call.data.get(ATTR_RETAIN, DEFAULT_RETAIN) if payload is None: if payload_template is None: _LOGGER.error( "You must set either '%s' or '%s' to use this service", ATTR_PAYLOAD, ATTR_PAYLOAD_TEMPLATE) return try: payload = template.render(hass, payload_template) except template.jinja2.TemplateError as exc: _LOGGER.error( "Unable to publish to '%s': rendering payload template of " "'%s' failed because %s.", msg_topic, payload_template, exc) return if msg_topic is None or payload is None: return MQTT_CLIENT.publish(msg_topic, payload, qos, retain)
def _render(self, template_string): """ Render a response, adding data from intent if available. """ return template.render(self.hass, template_string, self.variables)
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 update(self): try: self._state = template.render(self.hass, self._template) except TemplateError as ex: self._state = STATE_ERROR _LOGGER.error(ex)
def _render(value): try: return template.render(hass, value_template, {'value': value}) except TemplateError: _LOGGER.exception('Error parsing value') return value
def test_passing_vars_as_keywords(self): self.assertEqual('127', template.render(self.hass, '{{ hello }}', hello=127))
def _renderer(hass, value_template, state): """Render state value.""" if value_template is None: return state.state return template.render(hass, value_template, {'state': state})
def test_passing_vars_as_vars(self): self.assertEqual( '127', template.render(self.hass, '{{ hello }}', {'hello': 127}))
def test_raise_exception_on_error(self): with self.assertRaises(TemplateError): template.render(self.hass, '{{ invalid_syntax')
def test_passing_vars_as_keywords(self): self.assertEqual( '127', template.render(self.hass, '{{ hello }}', hello=127))