def create_service(call):
        """Handle a create notification service call."""
        title = call.data.get(ATTR_TITLE)
        message = call.data.get(ATTR_MESSAGE)
        notification_id = call.data.get(ATTR_NOTIFICATION_ID)

        if notification_id is not None:
            entity_id = ENTITY_ID_FORMAT.format(slugify(notification_id))
        else:
            entity_id = generate_entity_id(ENTITY_ID_FORMAT,
                                           DEFAULT_OBJECT_ID,
                                           hass=hass)
        attr = {}
        if title is not None:
            try:
                title = template.render(hass, title)
            except TemplateError as ex:
                _LOGGER.error('Error rendering title %s: %s', title, ex)

            attr[ATTR_TITLE] = title

        try:
            message = template.render(hass, message)
        except TemplateError as ex:
            _LOGGER.error('Error rendering message %s: %s', message, ex)

        hass.states.set(entity_id, message, attr)
    def create_service(call):
        """Handle a create notification service call."""
        title = call.data.get(ATTR_TITLE)
        message = call.data.get(ATTR_MESSAGE)
        notification_id = call.data.get(ATTR_NOTIFICATION_ID)

        if notification_id is not None:
            entity_id = ENTITY_ID_FORMAT.format(slugify(notification_id))
        else:
            entity_id = generate_entity_id(ENTITY_ID_FORMAT, DEFAULT_OBJECT_ID,
                                           hass=hass)
        attr = {}
        if title is not None:
            try:
                title = template.render(hass, title)
            except TemplateError as ex:
                _LOGGER.error('Error rendering title %s: %s', title, ex)

            attr[ATTR_TITLE] = title

        try:
            message = template.render(hass, message)
        except TemplateError as ex:
            _LOGGER.error('Error rendering message %s: %s', message, ex)

        hass.states.set(entity_id, message, attr)
    def test_float(self):
        """."""
        self.hass.states.set("sensor.temperature", "12")

        self.assertEqual("12.0", template.render(self.hass, "{{ float(states.sensor.temperature.state) }}"))

        self.assertEqual("True", template.render(self.hass, "{{ float(states.sensor.temperature.state) > 11 }}"))
    def test_rounding_value_get_original_value_on_error(self):
        """."""
        self.assertEqual('None',
                         template.render(self.hass, '{{ None | round }}'))

        self.assertEqual(
            'no_number', template.render(self.hass,
                                         '{{ "no_number" | round }}'))
Example #5
0
 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 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) }}"))

        self.assertEqual(
            "128", template.render(self.hass, "{{ states.sensor.temperature.state | multiply(10) | round }}")
        )
    def test_distance_function_return_None_if_invalid_coord(self):
        """."""
        self.assertEqual("None", template.render(self.hass, '{{ distance("123", "abc") }}'))

        self.assertEqual("None", template.render(self.hass, '{{ distance("123") }}'))

        self.hass.states.set(
            "test.object_2", "happy", {"latitude": self.hass.config.latitude, "longitude": self.hass.config.longitude}
        )

        self.assertEqual("None", template.render(self.hass, '{{ distance("123", states.test_object_2) }}'))
Example #8
0
        def notify_message(notify_service, call):
            """Handle sending notification message service calls."""
            message = call.data[ATTR_MESSAGE]

            title = template.render(
                hass, call.data.get(ATTR_TITLE, ATTR_TITLE_DEFAULT))
            target = call.data.get(ATTR_TARGET)
            message = template.render(hass, message)
            data = call.data.get(ATTR_DATA)

            notify_service.send_message(message, title=title, target=target,
                                        data=data)
Example #9
0
        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)
Example #10
0
        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_rounding_value_get_original_value_on_error(self):
        self.assertEqual(
            'None',
            template.render(
                self.hass,
                '{{ None | round }}'
            ))

        self.assertEqual(
            'no_number',
            template.render(
                self.hass,
                '{{ "no_number" | round }}'
            ))
    def test_float(self):
        self.hass.states.set('sensor.temperature', '12')

        self.assertEqual(
            '12.0',
            template.render(
                self.hass,
                '{{ float(states.sensor.temperature.state) }}'))

        self.assertEqual(
            'True',
            template.render(
                self.hass,
                '{{ float(states.sensor.temperature.state) > 11 }}'))
Example #13
0
        def notify_message(notify_service, call):
            """Handle sending notification message service calls."""
            message = call.data[ATTR_MESSAGE]

            title = template.render(
                hass, call.data.get(ATTR_TITLE, ATTR_TITLE_DEFAULT))
            target = call.data.get(ATTR_TARGET)
            message = template.render(hass, message)
            data = call.data.get(ATTR_DATA)

            notify_service.send_message(message,
                                        title=title,
                                        target=target,
                                        data=data)
Example #14
0
    def test_float(self):
        """."""
        self.hass.states.set('sensor.temperature', '12')

        self.assertEqual(
            '12.0',
            template.render(self.hass,
                            '{{ float(states.sensor.temperature.state) }}'))

        self.assertEqual(
            'True',
            template.render(
                self.hass,
                '{{ float(states.sensor.temperature.state) > 11 }}'))
    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) }}'))

        self.assertEqual(
            '128',
            template.render(
                self.hass,
                '{{ states.sensor.temperature.state | multiply(10) | round }}'
            ))
Example #16
0
    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) }}'))

        self.assertEqual(
            '128',
            template.render(
                self.hass,
                '{{ states.sensor.temperature.state | multiply(10) | round }}')
        )
Example #17
0
        def notify_message(notify_service, call):
            """Handle sending notification message service calls."""
            message = call.data.get(ATTR_MESSAGE)

            if message is None:
                _LOGGER.error('Received call to %s without attribute %s',
                              call.service, ATTR_MESSAGE)
                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)
Example #18
0
    def test_distance_function_with_1_state_1_coord(self):
        """."""
        self.hass.states.set(
            "test.object_2", "happy", {"latitude": self.hass.config.latitude, "longitude": self.hass.config.longitude}
        )

        self.assertEqual(
            "187",
            template.render(self.hass, '{{ distance("32.87336", "-117.22943", states.test.object_2) ' "| round }}"),
        )

        self.assertEqual(
            "187",
            template.render(self.hass, '{{ distance(states.test.object_2, "32.87336", "-117.22943") ' "| round }}"),
        )
Example #19
0
        def notify_message(notify_service, call):
            """Handle sending notification message service calls."""
            message = call.data.get(ATTR_MESSAGE)

            if message is None:
                _LOGGER.error(
                    'Received call to %s without attribute %s',
                    call.service, ATTR_MESSAGE)
                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)
Example #20
0
def numeric_state(hass, entity, below=None, above=None, value_template=None,
                  variables=None):
    """Test a numeric state condition."""
    if isinstance(entity, str):
        entity = hass.states.get(entity)

    if entity is None:
        return False

    if value_template is None:
        value = entity.state
    else:
        variables = dict(variables or {})
        variables['state'] = entity
        try:
            value = render(hass, value_template, variables)
        except TemplateError as ex:
            _LOGGER.error(ex)
            return False

    try:
        value = float(value)
    except ValueError:
        _LOGGER.warning("Value cannot be processed as a number: %s", value)
        return False

    if below is not None and value > below:
        return False

    if above is not None and value < above:
        return False

    return True
Example #21
0
    def test_closest_function_to_coord(self):
        """."""
        self.hass.states.set(
            "test_domain.closest_home",
            "happy",
            {"latitude": self.hass.config.latitude + 0.1, "longitude": self.hass.config.longitude + 0.1},
        )

        self.hass.states.set(
            "test_domain.closest_zone",
            "happy",
            {"latitude": self.hass.config.latitude + 0.2, "longitude": self.hass.config.longitude + 0.2},
        )

        self.hass.states.set(
            "zone.far_away",
            "zoning",
            {"latitude": self.hass.config.latitude + 0.3, "longitude": self.hass.config.longitude + 0.3},
        )

        self.assertEqual(
            "test_domain.closest_zone",
            template.render(
                self.hass,
                '{{ closest("%s", %s, states.test_domain).entity_id }}'
                % (self.hass.config.latitude + 0.3, self.hass.config.longitude + 0.3),
            ),
        )
Example #22
0
    def test_closest_function_to_state(self):
        """."""
        self.hass.states.set(
            'test_domain.closest_home', 'happy', {
                'latitude': self.hass.config.latitude + 0.1,
                'longitude': self.hass.config.longitude + 0.1,
            })

        self.hass.states.set(
            'test_domain.closest_zone', 'happy', {
                'latitude': self.hass.config.latitude + 0.2,
                'longitude': self.hass.config.longitude + 0.2,
            })

        self.hass.states.set(
            'zone.far_away', 'zoning', {
                'latitude': self.hass.config.latitude + 0.3,
                'longitude': self.hass.config.longitude + 0.3,
            })

        self.assertEqual(
            'test_domain.closest_zone',
            template.render(
                self.hass, '{{ closest(states.zone.far_away, '
                'states.test_domain).entity_id }}'))
Example #23
0
def numeric_state(hass: HomeAssistant, entity, below=None, above=None,
                  value_template=None, variables=None):
    """Test a numeric state condition."""
    if isinstance(entity, str):
        entity = hass.states.get(entity)

    if entity is None:
        return False

    if value_template is None:
        value = entity.state
    else:
        variables = dict(variables or {})
        variables['state'] = entity
        try:
            value = render(hass, value_template, variables)
        except TemplateError as ex:
            _LOGGER.error("Template error: %s", ex)
            return False

    try:
        value = float(value)
    except ValueError:
        _LOGGER.warning("Value cannot be processed as a number: %s", value)
        return False

    if below is not None and value > below:
        return False

    if above is not None and value < above:
        return False

    return True
Example #24
0
    def test_closest_function_to_coord(self):
        """."""
        self.hass.states.set('test_domain.closest_home', 'happy', {
            'latitude': self.hass.config.latitude + 0.1,
            'longitude': self.hass.config.longitude + 0.1,
        })

        self.hass.states.set('test_domain.closest_zone', 'happy', {
            'latitude': self.hass.config.latitude + 0.2,
            'longitude': self.hass.config.longitude + 0.2,
        })

        self.hass.states.set('zone.far_away', 'zoning', {
            'latitude': self.hass.config.latitude + 0.3,
            'longitude': self.hass.config.longitude + 0.3,
        })

        self.assertEqual(
            'test_domain.closest_zone',
            template.render(
                self.hass,
                '{{ closest("%s", %s, states.test_domain).entity_id }}'
                % (self.hass.config.latitude + 0.3,
                   self.hass.config.longitude + 0.3))
        )
Example #25
0
 def test_distance_function_with_2_coords(self):
     self.assertEqual(
         '187',
         template.render(
             self.hass,
             '{{ distance("32.87336", "-117.22943", %s, %s) | round }}'
             % (self.hass.config.latitude, self.hass.config.longitude)))
Example #26
0
 def post(self, request):
     """Render a template."""
     try:
         return template.render(self.hass, request.json['template'],
                                request.json.get('variables'))
     except TemplateError as ex:
         return self.json_message('Error rendering template: {}'.format(ex),
                                  HTTP_BAD_REQUEST)
Example #27
0
 def post(self, request):
     """Render a template."""
     try:
         return template.render(self.hass, request.json['template'],
                                request.json.get('variables'))
     except TemplateError as ex:
         return self.json_message('Error rendering template: {}'.format(ex),
                                  HTTP_BAD_REQUEST)
Example #28
0
    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 %}")
        )
Example #29
0
    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 %}'))
Example #30
0
    def test_multiply(self):
        """."""
        tests = {None: 'None', 10: '100', '"abcd"': 'abcd'}

        for inp, out in tests.items():
            self.assertEqual(
                out,
                template.render(self.hass,
                                '{{ %s | multiply(10) | round }}' % inp))
Example #31
0
        def notify_message(notify_service, call):
            """Handle sending notification message service calls."""
            kwargs = {}
            message = call.data[ATTR_MESSAGE]
            title = call.data.get(ATTR_TITLE)

            if title:
                kwargs[ATTR_TITLE] = template.render(hass, title)

            if targets.get(call.service) is not None:
                kwargs[ATTR_TARGET] = targets[call.service]
            else:
                kwargs[ATTR_TARGET] = call.data.get(ATTR_TARGET)

            kwargs[ATTR_MESSAGE] = template.render(hass, message)
            kwargs[ATTR_DATA] = call.data.get(ATTR_DATA)

            notify_service.send_message(**kwargs)
Example #32
0
    def test_distance_function_return_None_if_invalid_coord(self):
        """."""
        self.assertEqual(
            'None', template.render(self.hass, '{{ distance("123", "abc") }}'))

        self.assertEqual('None',
                         template.render(self.hass, '{{ distance("123") }}'))

        self.hass.states.set(
            'test.object_2', 'happy', {
                'latitude': self.hass.config.latitude,
                'longitude': self.hass.config.longitude,
            })

        self.assertEqual(
            'None',
            template.render(self.hass,
                            '{{ distance("123", states.test_object_2) }}'))
Example #33
0
    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 %}
                """))
Example #34
0
    def log_message(service):
        """Handle sending notification message service calls."""
        message = service.data[ATTR_MESSAGE]
        name = service.data[ATTR_NAME]
        domain = service.data.get(ATTR_DOMAIN)
        entity_id = service.data.get(ATTR_ENTITY_ID)

        message = template.render(hass, message)
        log_entry(hass, name, message, domain, entity_id)
Example #35
0
    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 %}
                """))
Example #36
0
        def notify_message(notify_service, call):
            """Handle sending notification message service calls."""
            kwargs = {}
            message = call.data[ATTR_MESSAGE]
            title = call.data.get(ATTR_TITLE)

            if title:
                kwargs[ATTR_TITLE] = template.render(hass, title)

            if targets.get(call.service) is not None:
                kwargs[ATTR_TARGET] = targets[call.service]
            else:
                kwargs[ATTR_TARGET] = call.data.get(ATTR_TARGET)

            kwargs[ATTR_MESSAGE] = template.render(hass, message)
            kwargs[ATTR_DATA] = call.data.get(ATTR_DATA)

            notify_service.send_message(**kwargs)
Example #37
0
def template(hass, value_template, variables=None):
    """Test if template condition matches."""
    try:
        value = render(hass, value_template, variables)
    except TemplateError as ex:
        _LOGGER.error('Error duriong template condition: %s', ex)
        return False

    return value.lower() == 'true'
Example #38
0
    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_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 %}
                """))
Example #40
0
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_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_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 %}
                """))
Example #43
0
def template(hass, value_template, variables=None):
    """Test if template condition matches."""
    try:
        value = render(hass, value_template, variables)
    except TemplateError as ex:
        _LOGGER.error('Error duriong template condition: %s', ex)
        return False

    return value.lower() == 'true'
Example #44
0
    def test_closest_function_invalid_coordinates(self):
        """."""
        self.hass.states.set(
            "test_domain.closest_home",
            "happy",
            {"latitude": self.hass.config.latitude + 0.1, "longitude": self.hass.config.longitude + 0.1},
        )

        self.assertEqual("None", template.render(self.hass, '{{ closest("invalid", "coord", states) }}'))
Example #45
0
    def log_message(service):
        """Handle sending notification message service calls."""
        message = service.data[ATTR_MESSAGE]
        name = service.data[ATTR_NAME]
        domain = service.data.get(ATTR_DOMAIN)
        entity_id = service.data.get(ATTR_ENTITY_ID)

        message = template.render(hass, message)
        log_entry(hass, name, message, domain, entity_id)
Example #46
0
    def test_distance_function_return_None_if_invalid_state(self):
        """."""
        self.hass.states.set('test.object_2', 'happy', {
            'latitude': 10,
        })

        self.assertEqual(
            'None',
            template.render(self.hass,
                            '{{ distance(states.test.object_2) | round }}'))
Example #47
0
    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)
Example #48
0
    def test_closest_function_invalid_coordinates(self):
        self.hass.states.set('test_domain.closest_home', 'happy', {
            'latitude': self.hass.config.latitude + 0.1,
            'longitude': self.hass.config.longitude + 0.1,
        })

        self.assertEqual(
            'None',
            template.render(self.hass,
                            '{{ closest("invalid", "coord", states) }}'))
Example #49
0
    def test_distance_function_with_1_state(self):
        self.hass.states.set('test.object', 'happy', {
            'latitude': 32.87336,
            'longitude': -117.22943,
        })

        self.assertEqual(
            '187',
            template.render(
                self.hass, '{{ distance(states.test.object) | round }}'))
Example #50
0
    def test_closest_function_invalid_state(self):
        """."""
        self.hass.states.set(
            "test_domain.closest_home",
            "happy",
            {"latitude": self.hass.config.latitude + 0.1, "longitude": self.hass.config.longitude + 0.1},
        )

        for state in ("states.zone.non_existing", '"zone.non_existing"'):
            self.assertEqual("None", template.render(self.hass, "{{ closest(%s, states) }}" % state))
Example #51
0
    def test_distance_function_with_1_state_1_coord(self):
        self.hass.states.set('test.object_2', 'happy', {
            'latitude': self.hass.config.latitude,
            'longitude': self.hass.config.longitude,
        })

        self.assertEqual(
            '187',
            template.render(
                self.hass,
                '{{ distance("32.87336", "-117.22943", states.test.object_2) '
                '| round }}'))

        self.assertEqual(
            '187',
            template.render(
                self.hass,
                '{{ distance(states.test.object_2, "32.87336", "-117.22943") '
                '| round }}'))
Example #52
0
def call_from_config(hass, config, blocking=False):
    """Call a service based on a config hash."""
    validation_error = validate_service_call(config)
    if validation_error:
        _LOGGER.error(validation_error)
        return

    domain_service = (config[CONF_SERVICE] if CONF_SERVICE in config else
                      template.render(hass, config[CONF_SERVICE_TEMPLATE]))

    try:
        domain, service_name = domain_service.split('.', 1)
    except ValueError:
        _LOGGER.error('Invalid service specified: %s', domain_service)
        return

    service_data = config.get(CONF_SERVICE_DATA)

    if service_data is None:
        service_data = {}
    elif isinstance(service_data, dict):
        service_data = dict(service_data)
    else:
        _LOGGER.error("%s should be a dictionary", CONF_SERVICE_DATA)
        service_data = {}

    service_data_template = config.get(CONF_SERVICE_DATA_TEMPLATE)
    if service_data_template and isinstance(service_data_template, dict):
        for key, value in service_data_template.items():
            service_data[key] = template.render(hass, value)
    elif service_data_template:
        _LOGGER.error("%s should be a dictionary", CONF_SERVICE_DATA)

    entity_id = config.get(CONF_SERVICE_ENTITY_ID)
    if isinstance(entity_id, str):
        service_data[ATTR_ENTITY_ID] = [
            ent.strip() for ent in entity_id.split(",")
        ]
    elif entity_id is not None:
        service_data[ATTR_ENTITY_ID] = entity_id

    hass.services.call(domain, service_name, service_data, blocking)
Example #53
0
    def test_closest_function_invalid_state(self):
        self.hass.states.set('test_domain.closest_home', 'happy', {
            'latitude': self.hass.config.latitude + 0.1,
            'longitude': self.hass.config.longitude + 0.1,
        })

        for state in ('states.zone.non_existing', '"zone.non_existing"'):
            self.assertEqual(
                'None',
                template.render(
                    self.hass, '{{ closest(%s, states) }}' % state))
Example #54
0
    def test_timestamp_local(self):
        """Test the timestamps to local filter."""
        tests = {
            None: 'None',
            1469119144: '2016-07-21 16:39:04',
        }

        for inp, out in tests.items():
            self.assertEqual(
                out,
                template.render(self.hass, '{{ %s | timestamp_local }}' % inp))
Example #55
0
 def _data_template_creator(value):
     """Recursive template creator helper function."""
     if isinstance(value, list):
         for idx, element in enumerate(value):
             value[idx] = _data_template_creator(element)
         return value
     if isinstance(value, dict):
         for key, element in value.items():
             value[key] = _data_template_creator(element)
         return value
     return template.render(hass, value, variables)