Example #1
0
    def test_service_call(self):
        """Test service call with templating."""
        config = {
            "service": "{{ 'test_domain.test_service' }}",
            "entity_id": "hello.world",
            "data": {
                "hello": "{{ 'goodbye' }}",
                "effect": {
                    "value": "{{ 'complex' }}",
                    "simple": "simple"
                },
            },
            "data_template": {
                "list": ["{{ 'list' }}", "2"]
            },
            "target": {
                "area_id": "test-area-id",
                "entity_id": "will.be_overridden"
            },
        }

        service.call_from_config(self.hass, config)
        self.hass.block_till_done()

        assert dict(self.calls[0].data) == {
            "hello": "goodbye",
            "effect": {
                "value": "complex",
                "simple": "simple",
            },
            "list": ["list", "2"],
            "entity_id": ["hello.world"],
            "area_id": ["test-area-id"],
        }
Example #2
0
    def test_template_service_call(self):
        """Test service call with tempating."""
        config = {
            'service_template': '{{ \'test_domain.test_service\' }}',
            'entity_id': 'hello.world',
            'data_template': {
                'hello': '{{ \'goodbye\' }}',
                'data': {
                    'value': '{{ \'complex\' }}',
                    'simple': 'simple'
                },
                'list': ['{{ \'list\' }}', '2'],
            },
        }
        runs = []

        decor = service.service('test_domain', 'test_service')
        decor(lambda x, y: runs.append(y))

        service.call_from_config(self.hass, config)
        self.hass.pool.block_till_done()

        self.assertEqual('goodbye', runs[0].data['hello'])
        self.assertEqual('complex', runs[0].data['data']['value'])
        self.assertEqual('simple', runs[0].data['data']['simple'])
        self.assertEqual('list', runs[0].data['list'][0])
Example #3
0
def _handle_alexa(handler, path_match, data):
    """Handle Alexa."""
    _LOGGER.debug('Received Alexa request: %s', data)

    req = data.get('request')

    if req is None:
        _LOGGER.error('Received invalid data from Alexa: %s', data)
        handler.write_json_message(
            "Invalid value received for port", HTTP_UNPROCESSABLE_ENTITY)
        return

    req_type = req['type']

    if req_type == 'SessionEndedRequest':
        handler.send_response(HTTP_OK)
        handler.end_headers()
        return

    intent = req.get('intent')
    response = AlexaResponse(handler.server.hass, intent)

    if req_type == 'LaunchRequest':
        response.add_speech(
            SpeechType.plaintext,
            "Hello, and welcome to the future. How may I help?")
        handler.write_json(response.as_dict())
        return

    if req_type != 'IntentRequest':
        _LOGGER.warning('Received unsupported request: %s', req_type)
        return

    intent_name = intent['name']
    config = _CONFIG.get(intent_name)

    if config is None:
        _LOGGER.warning('Received unknown intent %s', intent_name)
        response.add_speech(
            SpeechType.plaintext,
            "This intent is not yet configured within Home Assistant.")
        handler.write_json(response.as_dict())
        return

    speech = config.get(CONF_SPEECH)
    card = config.get(CONF_CARD)
    action = config.get(CONF_ACTION)

    # pylint: disable=unsubscriptable-object
    if speech is not None:
        response.add_speech(SpeechType[speech['type']], speech['text'])

    if card is not None:
        response.add_card(CardType[card['type']], card['title'],
                          card['content'])

    if action is not None:
        call_from_config(handler.server.hass, action, True)

    handler.write_json(response.as_dict())
 def test_not_mutate_input(self):
     orig = {"service": "test_domain.test_service", "entity_id": "hello.world, sensor.beer", "data": {"hello": 1}}
     service.call_from_config(self.hass, orig)
     self.hass.pool.block_till_done()
     self.assertEqual(
         {"service": "test_domain.test_service", "entity_id": "hello.world, sensor.beer", "data": {"hello": 1}}, orig
     )
Example #5
0
    def _call_service(self,
                      service_name,
                      service_data=None,
                      allow_override=False):
        """Call either a specified or active child's service."""
        if service_data is None:
            service_data = {}

        if allow_override and service_name in self._cmds:
            call_from_config(self.hass,
                             self._cmds[service_name],
                             variables=service_data,
                             blocking=True)
            return

        active_child = self._child_state
        if active_child is None:
            # No child to call service on
            return

        service_data[ATTR_ENTITY_ID] = active_child.entity_id

        self.hass.services.call(DOMAIN,
                                service_name,
                                service_data,
                                blocking=True)
Example #6
0
def _handle_alexa(handler, path_match, data):
    """Handle Alexa."""
    _LOGGER.debug('Received Alexa request: %s', data)

    req = data.get('request')

    if req is None:
        _LOGGER.error('Received invalid data from Alexa: %s', data)
        handler.write_json_message("Invalid value received for port",
                                   HTTP_UNPROCESSABLE_ENTITY)
        return

    req_type = req['type']

    if req_type == 'SessionEndedRequest':
        handler.send_response(HTTP_OK)
        handler.end_headers()
        return

    intent = req.get('intent')
    response = AlexaResponse(handler.server.hass, intent)

    if req_type == 'LaunchRequest':
        response.add_speech(
            SpeechType.plaintext,
            "Hello, and welcome to the future. How may I help?")
        handler.write_json(response.as_dict())
        return

    if req_type != 'IntentRequest':
        _LOGGER.warning('Received unsupported request: %s', req_type)
        return

    intent_name = intent['name']
    config = _CONFIG.get(intent_name)

    if config is None:
        _LOGGER.warning('Received unknown intent %s', intent_name)
        response.add_speech(
            SpeechType.plaintext,
            "This intent is not yet configured within Home Assistant.")
        handler.write_json(response.as_dict())
        return

    speech = config.get(CONF_SPEECH)
    card = config.get(CONF_CARD)
    action = config.get(CONF_ACTION)

    # pylint: disable=unsubscriptable-object
    if speech is not None:
        response.add_speech(SpeechType[speech['type']], speech['text'])

    if card is not None:
        response.add_card(CardType[card['type']], card['title'],
                          card['content'])

    if action is not None:
        call_from_config(handler.server.hass, action, True)

    handler.write_json(response.as_dict())
Example #7
0
    def test_template_service_call(self):
        """Test service call with tempating."""
        config = {
            'service_template': '{{ \'test_domain.test_service\' }}',
            'entity_id': 'hello.world',
            'data_template': {
                'hello': '{{ \'goodbye\' }}',
                'data': {
                    'value': '{{ \'complex\' }}',
                    'simple': 'simple'
                },
                'list': ['{{ \'list\' }}', '2'],
            },
        }
        runs = []

        decor = service.service('test_domain', 'test_service')
        decor(lambda x, y: runs.append(y))

        service.call_from_config(self.hass, config)
        self.hass.block_till_done()

        self.assertEqual('goodbye', runs[0].data['hello'])
        self.assertEqual('complex', runs[0].data['data']['value'])
        self.assertEqual('simple', runs[0].data['data']['simple'])
        self.assertEqual('list', runs[0].data['list'][0])
 def test_split_entity_string(self):
     service.call_from_config(self.hass, {
         'service': 'test_domain.test_service',
         'entity_id': 'hello.world, sensor.beer'
     })
     self.hass.pool.block_till_done()
     self.assertEqual(['hello.world', 'sensor.beer'],
                      self.calls[-1].data.get('entity_id'))
Example #9
0
 def _call_service(self, action, variables):
     """Call the service specified in the action."""
     self.last_action = action.get(CONF_ALIAS, 'call service')
     self._log("Executing step %s" % self.last_action)
     service.call_from_config(self.hass,
                              action,
                              True,
                              variables,
                              validate_config=False)
Example #10
0
 def test_split_entity_string(self):
     """Test splitting of entity string."""
     service.call_from_config(self.hass, {
         'service': 'test_domain.test_service',
         'entity_id': 'hello.world, sensor.beer'
     })
     self.hass.block_till_done()
     self.assertEqual(['hello.world', 'sensor.beer'],
                      self.calls[-1].data.get('entity_id'))
Example #11
0
 def test_split_entity_string(self):
     """Test splitting of entity string."""
     service.call_from_config(self.hass, {
         'service': 'test_domain.test_service',
         'entity_id': 'hello.world, sensor.beer'
     })
     self.hass.block_till_done()
     assert ['hello.world', 'sensor.beer'] == \
         self.calls[-1].data.get('entity_id')
 def test_split_entity_string(self):
     """Test splitting of entity string."""
     service.call_from_config(
         self.hass,
         {
             "service": "test_domain.test_service",
             "entity_id": "hello.world, sensor.beer",
         },
     )
     self.hass.block_till_done()
     assert ["hello.world", "sensor.beer"] == self.calls[-1].data.get("entity_id")
Example #13
0
    def test_service_template_service_call(self):
        """Test legacy service_template call with templating."""
        config = {
            "service_template": "{{ 'test_domain.test_service' }}",
            "entity_id": "hello.world",
            "data": {"hello": "goodbye"},
        }

        service.call_from_config(self.hass, config)
        self.hass.block_till_done()

        assert self.calls[0].data["hello"] == "goodbye"
    def _call_service(self, service_name, service_data=None, allow_override=False):
        """Call either a specified or active child's service."""
        if service_data is None:
            service_data = {}

        if allow_override and service_name in self._cmds:
            call_from_config(self.hass, self._cmds[service_name], variables=service_data, blocking=True)
            return

        active_child = self._child_state
        service_data[ATTR_ENTITY_ID] = active_child.entity_id

        self.hass.services.call(DOMAIN, service_name, service_data, blocking=True)
Example #15
0
    def _call_service(self, action):
        """ Calls the service specified in the action. """
        # Backwards compatibility
        if CONF_SERVICE not in action and CONF_SERVICE_OLD in action:
            action[CONF_SERVICE] = action[CONF_SERVICE_OLD]

        if CONF_SERVICE_DATA not in action and CONF_SERVICE_DATA_OLD in action:
            action[CONF_SERVICE_DATA] = action[CONF_SERVICE_DATA_OLD]

        self._last_action = action.get(CONF_ALIAS, action[CONF_SERVICE])
        _LOGGER.info("Executing script %s step %s", self._name,
                     self._last_action)
        call_from_config(self.hass, action, True)
 def test_not_mutate_input(self):
     orig = {
         'service': 'test_domain.test_service',
         'entity_id': 'hello.world, sensor.beer',
         'data': {
             'hello': 1,
         },
     }
     service.call_from_config(self.hass, orig)
     self.hass.pool.block_till_done()
     self.assertEqual({
         'service': 'test_domain.test_service',
         'entity_id': 'hello.world, sensor.beer',
         'data': {
             'hello': 1,
         },
     }, orig)
Example #17
0
    def test_passing_variables_to_templates(self):
        """Test passing variables to templates."""
        config = {
            'service_template': '{{ var_service }}',
            'entity_id': 'hello.world',
            'data_template': {
                'hello': '{{ var_data }}',
            },
        }

        service.call_from_config(self.hass, config, variables={
            'var_service': 'test_domain.test_service',
            'var_data': 'goodbye',
        })
        self.hass.block_till_done()

        self.assertEqual('goodbye', self.calls[0].data['hello'])
    def test_not_mutate_input(self):
        """Test for immutable input."""
        config = cv.SERVICE_SCHEMA(
            {
                "service": "test_domain.test_service",
                "entity_id": "hello.world, sensor.beer",
                "data": {"hello": 1},
                "data_template": {"nested": {"value": "{{ 1 + 1 }}"}},
            }
        )
        orig = deepcopy(config)

        # Only change after call is each template getting hass attached
        template.attach(self.hass, orig)

        service.call_from_config(self.hass, config, validate_config=False)
        assert orig == config
Example #19
0
    def test_bad_template(self):
        """Test passing bad template."""
        config = {
            'service_template': '{{ var_service }}',
            'entity_id': 'hello.world',
            'data_template': {
                'hello': '{{ states + unknown_var }}'
            }
        }

        service.call_from_config(self.hass, config, variables={
            'var_service': 'test_domain.test_service',
            'var_data': 'goodbye',
        })
        self.hass.block_till_done()

        assert len(self.calls) == 0
Example #20
0
    def test_bad_template(self):
        """Test passing bad template."""
        config = {
            'service_template': '{{ var_service }}',
            'entity_id': 'hello.world',
            'data_template': {
                'hello': '{{ states + unknown_var }}'
            }
        }

        service.call_from_config(self.hass, config, variables={
            'var_service': 'test_domain.test_service',
            'var_data': 'goodbye',
        })
        self.hass.block_till_done()

        assert len(self.calls) == 0
Example #21
0
    def test_template_service_call(self):
        """Test service call with tempating."""
        config = {
            'service_template': '{{ \'test_domain.test_service\' }}',
            'entity_id': 'hello.world',
            'data_template': {
                'hello': '{{ \'goodbye\' }}',
            },
        }
        runs = []

        decor = service.service('test_domain', 'test_service')
        decor(lambda x, y: runs.append(y))

        service.call_from_config(self.hass, config)
        self.hass.pool.block_till_done()

        self.assertEqual('goodbye', runs[0].data['hello'])
Example #22
0
 def test_not_mutate_input(self):
     """Test for immutable input."""
     orig = {
         'service': 'test_domain.test_service',
         'entity_id': 'hello.world, sensor.beer',
         'data': {
             'hello': 1,
         },
     }
     service.call_from_config(self.hass, orig)
     self.hass.pool.block_till_done()
     self.assertEqual({
         'service': 'test_domain.test_service',
         'entity_id': 'hello.world, sensor.beer',
         'data': {
             'hello': 1,
         },
     }, orig)
    def test_passing_variables_to_templates(self):
        """Test passing variables to templates."""
        config = {
            "service_template": "{{ var_service }}",
            "entity_id": "hello.world",
            "data_template": {"hello": "{{ var_data }}"},
        }

        service.call_from_config(
            self.hass,
            config,
            variables={
                "var_service": "test_domain.test_service",
                "var_data": "goodbye",
            },
        )
        self.hass.block_till_done()

        assert "goodbye" == self.calls[0].data["hello"]
    def test_bad_template(self):
        """Test passing bad template."""
        config = {
            "service_template": "{{ var_service }}",
            "entity_id": "hello.world",
            "data_template": {"hello": "{{ states + unknown_var }}"},
        }

        service.call_from_config(
            self.hass,
            config,
            variables={
                "var_service": "test_domain.test_service",
                "var_data": "goodbye",
            },
        )
        self.hass.block_till_done()

        assert len(self.calls) == 0
    def test_template_service_call(self):
        """Test service call with templating."""
        config = {
            "service_template": "{{ 'test_domain.test_service' }}",
            "entity_id": "hello.world",
            "data_template": {
                "hello": "{{ 'goodbye' }}",
                "data": {"value": "{{ 'complex' }}", "simple": "simple"},
                "list": ["{{ 'list' }}", "2"],
            },
        }

        service.call_from_config(self.hass, config)
        self.hass.block_till_done()

        assert "goodbye" == self.calls[0].data["hello"]
        assert "complex" == self.calls[0].data["data"]["value"]
        assert "simple" == self.calls[0].data["data"]["simple"]
        assert "list" == self.calls[0].data["list"][0]
Example #26
0
    def test_not_mutate_input(self):
        """Test for immutable input."""
        config = cv.SERVICE_SCHEMA({
            'service': 'test_domain.test_service',
            'entity_id': 'hello.world, sensor.beer',
            'data': {
                'hello': 1,
            },
            'data_template': {
                'nested': {
                    'value': '{{ 1 + 1 }}'
                }
            }
        })
        orig = deepcopy(config)

        # Only change after call is each template getting hass attached
        template.attach(self.hass, orig)

        service.call_from_config(self.hass, config, validate_config=False)
        assert orig == config
Example #27
0
    def test_passing_variables_to_templates(self):
        """Test passing variables to templates."""
        config = {
            'service_template': '{{ var_service }}',
            'entity_id': 'hello.world',
            'data_template': {
                'hello': '{{ var_data }}',
            },
        }
        runs = []

        decor = service.service('test_domain', 'test_service')
        decor(lambda x, y: runs.append(y))

        service.call_from_config(self.hass, config, variables={
            'var_service': 'test_domain.test_service',
            'var_data': 'goodbye',
        })
        self.hass.pool.block_till_done()

        self.assertEqual('goodbye', runs[0].data['hello'])
    def test_not_mutate_input(self):
        """Test for immutable input."""
        config = cv.SERVICE_SCHEMA({
            'service': 'test_domain.test_service',
            'entity_id': 'hello.world, sensor.beer',
            'data': {
                'hello': 1,
            },
            'data_template': {
                'nested': {
                    'value': '{{ 1 + 1 }}'
                }
            }
        })
        orig = deepcopy(config)

        # Only change after call is each template getting hass attached
        template.attach(self.hass, orig)

        service.call_from_config(self.hass, config, validate_config=False)
        assert orig == config
    def test_template_service_call(self):
        """Test service call with tempating."""
        config = {
            'service_template': '{{ \'test_domain.test_service\' }}',
            'entity_id': 'hello.world',
            'data_template': {
                'hello': '{{ \'goodbye\' }}',
                'data': {
                    'value': '{{ \'complex\' }}',
                    'simple': 'simple'
                },
                'list': ['{{ \'list\' }}', '2'],
            },
        }

        service.call_from_config(self.hass, config)
        self.hass.block_till_done()

        self.assertEqual('goodbye', self.calls[0].data['hello'])
        self.assertEqual('complex', self.calls[0].data['data']['value'])
        self.assertEqual('simple', self.calls[0].data['data']['simple'])
        self.assertEqual('list', self.calls[0].data['list'][0])
Example #30
0
    def test_template_service_call(self):
        """Test service call with templating."""
        config = {
            'service_template': '{{ \'test_domain.test_service\' }}',
            'entity_id': 'hello.world',
            'data_template': {
                'hello': '{{ \'goodbye\' }}',
                'data': {
                    'value': '{{ \'complex\' }}',
                    'simple': 'simple'
                },
                'list': ['{{ \'list\' }}', '2'],
            },
        }

        service.call_from_config(self.hass, config)
        self.hass.block_till_done()

        assert 'goodbye' == self.calls[0].data['hello']
        assert 'complex' == self.calls[0].data['data']['value']
        assert 'simple' == self.calls[0].data['data']['simple']
        assert 'list' == self.calls[0].data['list'][0]
Example #31
0
    def test_fail_silently_if_no_service(self, mock_log):
        service.call_from_config(self.hass, None)
        self.assertEqual(1, mock_log.call_count)

        service.call_from_config(self.hass, {})
        self.assertEqual(2, mock_log.call_count)

        service.call_from_config(self.hass, {"service": "invalid"})
        self.assertEqual(3, mock_log.call_count)
Example #32
0
    def test_fail_silently_if_no_service(self, mock_log):
        service.call_from_config(self.hass, None)
        self.assertEqual(1, mock_log.call_count)

        service.call_from_config(self.hass, {})
        self.assertEqual(2, mock_log.call_count)

        service.call_from_config(self.hass, {'service': 'invalid'})
        self.assertEqual(3, mock_log.call_count)
    def test_fail_silently_if_no_service(self, mock_log):
        """Test failing if service is missing."""
        service.call_from_config(self.hass, None)
        assert 1 == mock_log.call_count

        service.call_from_config(self.hass, {})
        assert 2 == mock_log.call_count

        service.call_from_config(self.hass, {"service": "invalid"})
        assert 3 == mock_log.call_count
    def test_fail_silently_if_no_service(self, mock_log):
        """Test failling if service is missing."""
        service.call_from_config(self.hass, None)
        self.assertEqual(1, mock_log.call_count)

        service.call_from_config(self.hass, {})
        self.assertEqual(2, mock_log.call_count)

        service.call_from_config(self.hass, {
            'service': 'invalid'
        })
        self.assertEqual(3, mock_log.call_count)
Example #35
0
    def test_fail_silently_if_no_service(self, mock_log):
        """Test failing if service is missing."""
        service.call_from_config(self.hass, None)
        assert 1 == mock_log.call_count

        service.call_from_config(self.hass, {})
        assert 2 == mock_log.call_count

        service.call_from_config(self.hass, {
            'service': 'invalid'
        })
        assert 3 == mock_log.call_count
Example #36
0
 def turn_off(self, **kwargs):
     """ Fires the off action. """
     call_from_config(self.hass, self._off_action, True)
Example #37
0
    def action():
        """Action to be executed."""
        _LOGGER.info('Executing %s', name)
        logbook.log_entry(hass, name, 'has been triggered', DOMAIN)

        call_from_config(hass, config)
Example #38
0
 def turn_on(self, **kwargs):
     """Fire the on action."""
     call_from_config(self.hass, self._on_action, True)
Example #39
0
    def test_service_call(self):
        """Test service call with templating."""
        config = {
            "service": "{{ 'test_domain.test_service' }}",
            "entity_id": "hello.world",
            "data": {
                "hello": "{{ 'goodbye' }}",
                "effect": {
                    "value": "{{ 'complex' }}",
                    "simple": "simple"
                },
            },
            "data_template": {
                "list": ["{{ 'list' }}", "2"]
            },
            "target": {
                "area_id": "test-area-id",
                "entity_id": "will.be_overridden"
            },
        }

        service.call_from_config(self.hass, config)
        self.hass.block_till_done()

        assert dict(self.calls[0].data) == {
            "hello": "goodbye",
            "effect": {
                "value": "complex",
                "simple": "simple",
            },
            "list": ["list", "2"],
            "entity_id": ["hello.world"],
            "area_id": ["test-area-id"],
        }

        config = {
            "service": "{{ 'test_domain.test_service' }}",
            "target": {
                "area_id": ["area-42", "{{ 'area-51' }}"],
                "device_id": ["abcdef", "{{ 'fedcba' }}"],
                "entity_id": ["light.static", "{{ 'light.dynamic' }}"],
            },
        }

        service.call_from_config(self.hass, config)
        self.hass.block_till_done()

        assert dict(self.calls[1].data) == {
            "area_id": ["area-42", "area-51"],
            "device_id": ["abcdef", "fedcba"],
            "entity_id": ["light.static", "light.dynamic"],
        }

        config = {
            "service": "{{ 'test_domain.test_service' }}",
            "target": "{{ var_target }}",
        }

        service.call_from_config(
            self.hass,
            config,
            variables={
                "var_target": {
                    "entity_id": "light.static",
                    "area_id": ["area-42", "area-51"],
                },
            },
        )

        service.call_from_config(self.hass, config)
        self.hass.block_till_done()

        assert dict(self.calls[2].data) == {
            "area_id": ["area-42", "area-51"],
            "entity_id": ["light.static"],
        }
Example #40
0
 def _call_service(self, action, variables):
     """Call the service specified in the action."""
     self.last_action = action.get(CONF_ALIAS, 'call service')
     self._log("Executing step %s" % self.last_action)
     service.call_from_config(self.hass, action, True, variables,
                              validate_config=False)
Example #41
0
 def call(self, action):
     if action not in self.actions:
         return
     call_from_config(self.hass, self.actions[action], blocking=True)
Example #42
0
    def action():
        """Action to be executed."""
        _LOGGER.info('Executing %s', name)
        logbook.log_entry(hass, name, 'has been triggered', DOMAIN)

        call_from_config(hass, config)
Example #43
0
 def turn_off(self, **kwargs):
     """Fire the off action."""
     call_from_config(self.hass, self._off_action, True)
Example #44
0
 def _call_service(self, action):
     """Call the service specified in the action."""
     self._last_action = action.get(CONF_ALIAS, 'call service')
     _LOGGER.info("Executing script %s step %s", self._name,
                  self._last_action)
     call_from_config(self.hass, action, True)
Example #45
0
 def _call_service(self, action):
     """Call the service specified in the action."""
     self._last_action = action.get(CONF_ALIAS, 'call service')
     _LOGGER.info("Executing script %s step %s", self._name,
                  self._last_action)
     call_from_config(self.hass, action, True)
Example #46
0
 def turn_on(self, **kwargs):
     """Fires the on action."""
     call_from_config(self.hass, self._on_action, True)
Example #47
0
 def test_split_entity_string(self):
     service.call_from_config(
         self.hass, {"service": "test_domain.test_service", "entity_id": "hello.world, sensor.beer"}
     )
     self.hass.pool.block_till_done()
     self.assertEqual(["hello.world", "sensor.beer"], self.calls[-1].data.get("entity_id"))