Beispiel #1
0
async def test_repeat_conditional(hass, condition):
    """Test repeat action w/ while option."""
    event = "test_event"
    events = async_capture_events(hass, event)
    count = 3

    sequence = {
        "repeat": {
            "sequence": [
                {
                    "event": event,
                    "event_data_template": {
                        "first": "{{ repeat.first }}",
                        "index": "{{ repeat.index }}",
                    },
                },
                {"wait_template": "{{ is_state('sensor.test', 'next') }}"},
                {"wait_template": "{{ not is_state('sensor.test', 'next') }}"},
            ],
        }
    }
    if condition == "while":
        sequence["repeat"]["while"] = {
            "condition": "template",
            "value_template": "{{ not is_state('sensor.test', 'done') }}",
        }
    else:
        sequence["repeat"]["until"] = {
            "condition": "template",
            "value_template": "{{ is_state('sensor.test', 'done') }}",
        }
    script_obj = script.Script(hass, cv.SCRIPT_SCHEMA(sequence))

    wait_started = async_watch_for_action(script_obj, "wait")
    hass.states.async_set("sensor.test", "1")

    hass.async_create_task(script_obj.async_run())
    try:
        for index in range(2, count + 1):
            await asyncio.wait_for(wait_started.wait(), 1)
            wait_started.clear()
            hass.states.async_set("sensor.test", "next")
            await asyncio.wait_for(wait_started.wait(), 1)
            wait_started.clear()
            hass.states.async_set("sensor.test", index)
        await asyncio.wait_for(wait_started.wait(), 1)
        hass.states.async_set("sensor.test", "next")
        await asyncio.wait_for(wait_started.wait(), 1)
        wait_started.clear()
        hass.states.async_set("sensor.test", "done")
        await asyncio.wait_for(hass.async_block_till_done(), 1)
    except asyncio.TimeoutError:
        await script_obj.async_stop()
        raise

    assert len(events) == count
    for index, event in enumerate(events):
        assert event.data.get("first") == str(index == 0)
        assert event.data.get("index") == str(index + 1)
Beispiel #2
0
async def test_script_mode_1(hass, caplog, script_mode, expectation, messages):
    """Test overlapping runs with script_mode='ignore'."""
    event = "test_event"
    events = async_capture_events(hass, event)
    sequence = cv.SCRIPT_SCHEMA([
        {
            "event": event,
            "event_data": {
                "value": 1
            }
        },
        {
            "wait_template": "{{ states.switch.test.state == 'off' }}"
        },
        {
            "event": event,
            "event_data": {
                "value": 2
            }
        },
    ])
    logger = logging.getLogger("TEST")
    script_obj = script.Script(hass,
                               sequence,
                               script_mode=script_mode,
                               logger=logger)
    wait_started_flag = async_watch_for_action(script_obj, "wait")

    try:
        hass.states.async_set("switch.test", "on")
        hass.async_create_task(script_obj.async_run())
        await asyncio.wait_for(wait_started_flag.wait(), 1)

        assert script_obj.is_running
        assert len(events) == 1
        assert events[0].data["value"] == 1

        # Start second run of script while first run is suspended in wait_template.

        with expectation:
            await script_obj.async_run()

        assert script_obj.is_running
        assert all(
            any(rec.levelname == "INFO" and rec.name == "TEST"
                and message in rec.message for rec in caplog.records)
            for message in messages)
    except (AssertionError, asyncio.TimeoutError):
        await script_obj.async_stop()
        raise
    else:
        hass.states.async_set("switch.test", "off")
        await hass.async_block_till_done()

        assert not script_obj.is_running
        assert len(events) == 2
        assert events[1].data["value"] == 2
Beispiel #3
0
async def test_multiple_runs_delay(hass, mock_timeout, script_mode):
    """Test multiple runs with delay in script."""
    event = "test_event"
    events = async_capture_events(hass, event)
    delay = timedelta(seconds=5)
    sequence = cv.SCRIPT_SCHEMA([
        {
            "event": event,
            "event_data": {
                "value": 1
            }
        },
        {
            "delay": delay
        },
        {
            "event": event,
            "event_data": {
                "value": 2
            }
        },
    ])
    script_obj = script.Script(hass, sequence, script_mode=script_mode)
    delay_started_flag = async_watch_for_action(script_obj, "delay")

    try:
        hass.async_create_task(script_obj.async_run())
        await asyncio.wait_for(delay_started_flag.wait(), 1)

        assert script_obj.is_running
        assert len(events) == 1
        assert events[-1].data["value"] == 1
    except (AssertionError, asyncio.TimeoutError):
        await script_obj.async_stop()
        raise
    else:
        # Start second run of script while first run is in a delay.
        if script_mode == "legacy":
            await script_obj.async_run()
        else:
            script_obj.sequence[1]["alias"] = "delay run 2"
            delay_started_flag = async_watch_for_action(
                script_obj, "delay run 2")
            hass.async_create_task(script_obj.async_run())
            await asyncio.wait_for(delay_started_flag.wait(), 1)
        async_fire_time_changed(hass, dt_util.utcnow() + delay)
        await hass.async_block_till_done()

        assert not script_obj.is_running
        if script_mode == "legacy":
            assert len(events) == 2
        else:
            assert len(events) == 4
            assert events[-3].data["value"] == 1
            assert events[-2].data["value"] == 2
        assert events[-1].data["value"] == 2
Beispiel #4
0
    def __init__(self, hass, intents):
        """Initialize Alexa view."""
        super().__init__(hass)

        for name, intent in intents.items():
            if CONF_ACTION in intent:
                intent[CONF_ACTION] = script.Script(
                    hass, intent[CONF_ACTION], "Alexa intent {}".format(name))

        self.intents = intents
Beispiel #5
0
def _get_action(hass, config, name):
    """Return an action based on a configuration."""
    script_obj = script.Script(hass, config, name)

    def action(variables=None):
        """Action to be executed."""
        _LOGGER.info('Executing %s', name)
        logbook.log_entry(hass, name, 'has been triggered', DOMAIN)
        script_obj.run(variables)

    return action
Beispiel #6
0
async def async_setup(hass, config):
    """Activate Alexa component."""
    intents = copy.deepcopy(config[DOMAIN])
    template.attach(hass, intents)

    for intent_type, conf in intents.items():
        if CONF_ACTION in conf:
            conf[CONF_ACTION] = script.Script(hass, conf[CONF_ACTION],
                                              f"Intent Script {intent_type}")
        intent.async_register(hass, ScriptIntentHandler(intent_type, conf))

    return True
Beispiel #7
0
async def test_propagate_error_service_not_found(hass, script_mode):
    """Test that a script aborts when a service is not found."""
    event = "test_event"
    events = async_capture_events(hass, event)
    sequence = cv.SCRIPT_SCHEMA([{"service": "test.script"}, {"event": event}])
    script_obj = script.Script(hass, sequence, script_mode=script_mode)

    with pytest.raises(exceptions.ServiceNotFound):
        await script_obj.async_run()

    assert len(events) == 0
    assert not script_obj.is_running
Beispiel #8
0
    def __init__(self, hass, intents):
        """Initialize the intent handler."""
        self.hass = hass
        intents = copy.deepcopy(intents)
        template.attach(hass, intents)

        for name, intent in intents.items():
            if CONF_ACTION in intent:
                intent[CONF_ACTION] = script.Script(
                    hass, intent[CONF_ACTION], "Snips intent {}".format(name))

        self.intents = intents
Beispiel #9
0
def _async_get_action(hass, config, name):
    """Return an action based on a configuration."""
    script_obj = script.Script(hass, config, name)

    async def action(entity_id, variables, context):
        """Execute an action."""
        _LOGGER.info('Executing %s', name)
        hass.components.logbook.async_log_entry(name, 'has been triggered',
                                                DOMAIN, entity_id)
        await script_obj.async_run(variables, context)

    return action
Beispiel #10
0
async def test_multiple_runs_wait_template(hass, script_mode):
    """Test multiple runs with wait_template in script."""
    event = "test_event"
    events = async_capture_events(hass, event)
    sequence = cv.SCRIPT_SCHEMA([
        {
            "event": event,
            "event_data": {
                "value": 1
            }
        },
        {
            "wait_template": "{{ states.switch.test.state == 'off' }}"
        },
        {
            "event": event,
            "event_data": {
                "value": 2
            }
        },
    ])
    script_obj = script.Script(hass, sequence, script_mode=script_mode)
    wait_started_flag = async_watch_for_action(script_obj, "wait")

    try:
        hass.states.async_set("switch.test", "on")
        hass.async_create_task(script_obj.async_run())
        await asyncio.wait_for(wait_started_flag.wait(), 1)

        assert script_obj.is_running
        assert len(events) == 1
        assert events[-1].data["value"] == 1
    except (AssertionError, asyncio.TimeoutError):
        await script_obj.async_stop()
        raise
    else:
        # Start second run of script while first run is in wait_template.
        if script_mode == "legacy":
            await script_obj.async_run()
        else:
            hass.async_create_task(script_obj.async_run())
        hass.states.async_set("switch.test", "off")
        await hass.async_block_till_done()

        assert not script_obj.is_running
        if script_mode == "legacy":
            assert len(events) == 2
        else:
            assert len(events) == 4
            assert events[-3].data["value"] == 1
            assert events[-2].data["value"] == 2
        assert events[-1].data["value"] == 2
Beispiel #11
0
def _async_get_action(hass, config, name):
    """Return an action based on a configuration."""
    script_obj = script.Script(hass, config, name)

    @asyncio.coroutine
    def action(entity_id, variables):
        """Action to be executed."""
        _LOGGER.info('Executing %s', name)
        logbook.async_log_entry(hass, name, 'has been triggered', DOMAIN,
                                entity_id)
        yield from script_obj.async_run(variables)

    return action
Beispiel #12
0
async def test_passing_variables_to_script(hass):
    """Test if we can pass variables to script."""
    calls = []

    @callback
    def record_call(service):
        """Add recorded event to set."""
        calls.append(service)

    hass.services.async_register("test", "script", record_call)

    script_obj = script.Script(
        hass,
        cv.SCRIPT_SCHEMA([
            {
                "service": "test.script",
                "data_template": {
                    "hello": "{{ greeting }}"
                },
            },
            {
                "delay": "{{ delay_period }}"
            },
            {
                "service": "test.script",
                "data_template": {
                    "hello": "{{ greeting2 }}"
                },
            },
        ]),
    )

    await script_obj.async_run({
        "greeting": "world",
        "greeting2": "universe",
        "delay_period": "00:00:05"
    })

    await hass.async_block_till_done()

    assert script_obj.is_running
    assert len(calls) == 1
    assert calls[-1].data["hello"] == "world"

    future = dt_util.utcnow() + timedelta(seconds=5)
    async_fire_time_changed(hass, future)
    await hass.async_block_till_done()

    assert not script_obj.is_running
    assert len(calls) == 2
    assert calls[-1].data["hello"] == "universe"
Beispiel #13
0
def setup(hass, config):
    """Activate Alexa component."""
    intents = config[DOMAIN].get(CONF_INTENTS, {})

    for name, intent in intents.items():
        if CONF_ACTION in intent:
            intent[CONF_ACTION] = script.Script(hass, intent[CONF_ACTION],
                                                "Alexa intent {}".format(name))

    _CONFIG.update(intents)

    hass.http.register_path('POST', API_ENDPOINT, _handle_alexa, True)

    return True
Beispiel #14
0
async def test_calling_service_basic(hass):
    """Test the calling of a service."""
    context = Context()
    calls = async_mock_service(hass, "test", "script")

    sequence = cv.SCRIPT_SCHEMA({"service": "test.script", "data": {"hello": "world"}})
    script_obj = script.Script(hass, sequence)

    await script_obj.async_run(context=context)
    await hass.async_block_till_done()

    assert len(calls) == 1
    assert calls[0].context is context
    assert calls[0].data.get("hello") == "world"
Beispiel #15
0
async def test_activating_scene(hass):
    """Test the activation of a scene."""
    context = Context()
    calls = async_mock_service(hass, scene.DOMAIN, SERVICE_TURN_ON)

    sequence = cv.SCRIPT_SCHEMA({"scene": "scene.hello"})
    script_obj = script.Script(hass, sequence)

    await script_obj.async_run(context=context)
    await hass.async_block_till_done()

    assert len(calls) == 1
    assert calls[0].context is context
    assert calls[0].data.get(ATTR_ENTITY_ID) == "scene.hello"
    def __init__(self,hass,intents):
        super().__init__()

        _LOGGER.debug("DingdongIntentsView init ")

        self.hass = hass
        intents = copy.deepcopy(intents)
        template.attach(hass, intents)

        for name, intent in intents.items():
            if CONF_ACTION in intent:
                intent[CONF_ACTION] = script.Script(hass,intent[CONF_ACTION],"DingDong {}".format(name))

        self.intents = intents
Beispiel #17
0
async def test_last_triggered(hass, script_mode):
    """Test the last_triggered."""
    event = "test_event"
    sequence = cv.SCRIPT_SCHEMA({"event": event})
    script_obj = script.Script(hass, sequence, script_mode=script_mode)

    assert script_obj.last_triggered is None

    time = dt_util.utcnow()
    with mock.patch("homeassistant.helpers.script.utcnow", return_value=time):
        await script_obj.async_run()
        await hass.async_block_till_done()

    assert script_obj.last_triggered == time
Beispiel #18
0
    def __init__(self, hass, intents):
        """Initialize API.AI view."""
        super().__init__()

        self.hass = hass
        intents = copy.deepcopy(intents)
        template.attach(hass, intents)

        for name, intent in intents.items():
            if CONF_ACTION in intent:
                intent[CONF_ACTION] = script.Script(
                    hass, intent[CONF_ACTION], "Apiai intent {}".format(name))

        self.intents = intents
Beispiel #19
0
async def test_wait_template_cancel(hass):
    """Test the wait template cancel action."""
    event = "test_event"
    events = []
    wait_alias = "wait step"

    @callback
    def record_event(event):
        """Add recorded event to set."""
        events.append(event)

    hass.bus.async_listen(event, record_event)

    hass.states.async_set("switch.test", "on")

    script_obj = script.Script(
        hass,
        cv.SCRIPT_SCHEMA([
            {
                "event": event
            },
            {
                "wait_template": "{{states.switch.test.state == 'off'}}",
                "alias": wait_alias,
            },
            {
                "event": event
            },
        ]),
    )

    await script_obj.async_run()
    await hass.async_block_till_done()

    assert script_obj.is_running
    assert script_obj.can_cancel
    assert script_obj.last_action == wait_alias
    assert len(events) == 1

    script_obj.async_stop()

    assert not script_obj.is_running
    assert len(events) == 1

    hass.states.async_set("switch.test", "off")
    await hass.async_block_till_done()

    assert not script_obj.is_running
    assert len(events) == 1
Beispiel #20
0
async def test_script_mode_single(hass, caplog):
    """Test overlapping runs with max_runs = 1."""
    event = "test_event"
    events = async_capture_events(hass, event)
    sequence = cv.SCRIPT_SCHEMA([
        {
            "event": event,
            "event_data": {
                "value": 1
            }
        },
        {
            "wait_template": "{{ states.switch.test.state == 'off' }}"
        },
        {
            "event": event,
            "event_data": {
                "value": 2
            }
        },
    ])
    script_obj = script.Script(hass, sequence)
    wait_started_flag = async_watch_for_action(script_obj, "wait")

    try:
        hass.states.async_set("switch.test", "on")
        hass.async_create_task(script_obj.async_run())
        await asyncio.wait_for(wait_started_flag.wait(), 1)

        assert script_obj.is_running
        assert len(events) == 1
        assert events[0].data["value"] == 1

        # Start second run of script while first run is suspended in wait_template.

        await script_obj.async_run()

        assert "Already running" in caplog.text
        assert script_obj.is_running
    except (AssertionError, asyncio.TimeoutError):
        await script_obj.async_stop()
        raise
    else:
        hass.states.async_set("switch.test", "off")
        await hass.async_block_till_done()

        assert not script_obj.is_running
        assert len(events) == 2
        assert events[1].data["value"] == 2
Beispiel #21
0
def _async_get_action(hass, config, name):
    """Return an action based on a configuration."""
    script_obj = script.Script(hass, config, name)

    async def action(entity_id, variables, context):
        """Execute an action."""
        _LOGGER.info("Executing %s", name)

        try:
            await script_obj.async_run(variables, context)
        except Exception as err:  # pylint: disable=broad-except
            script_obj.async_log_exception(
                _LOGGER, f"Error while executing automation {entity_id}", err)

    return action
Beispiel #22
0
async def test_firing_event_basic(hass):
    """Test the firing of events."""
    event = "test_event"
    context = Context()
    events = async_capture_events(hass, event)

    sequence = cv.SCRIPT_SCHEMA({"event": event, "event_data": {"hello": "world"}})
    script_obj = script.Script(hass, sequence)

    await script_obj.async_run(context=context)
    await hass.async_block_till_done()

    assert len(events) == 1
    assert events[0].context is context
    assert events[0].data.get("hello") == "world"
Beispiel #23
0
async def test_multiple_runs_repeat_choose(hass, caplog, action):
    """Test parallel runs with repeat & choose actions & max_runs > default."""
    max_runs = script.DEFAULT_MAX + 1
    script_obj = script.Script(
        hass, cv.SCRIPT_SCHEMA(action), script_mode="parallel", max_runs=max_runs
    )

    events = async_capture_events(hass, "abc")
    for _ in range(max_runs):
        hass.async_create_task(script_obj.async_run())
    await hass.async_block_till_done()

    assert "WARNING" not in caplog.text
    assert "ERROR" not in caplog.text
    assert len(events) == max_runs
Beispiel #24
0
async def test_delay(hass):
    """Test the delay."""
    event = "test_event"
    events = []
    context = Context()
    delay_alias = "delay step"

    @callback
    def record_event(event):
        """Add recorded event to set."""
        events.append(event)

    hass.bus.async_listen(event, record_event)

    script_obj = script.Script(
        hass,
        cv.SCRIPT_SCHEMA([
            {
                "event": event
            },
            {
                "delay": {
                    "seconds": 5
                },
                "alias": delay_alias
            },
            {
                "event": event
            },
        ]),
    )

    await script_obj.async_run(context=context)
    await hass.async_block_till_done()

    assert script_obj.is_running
    assert script_obj.can_cancel
    assert script_obj.last_action == delay_alias
    assert len(events) == 1

    future = dt_util.utcnow() + timedelta(seconds=5)
    async_fire_time_changed(hass, future)
    await hass.async_block_till_done()

    assert not script_obj.is_running
    assert len(events) == 2
    assert events[0].context is context
    assert events[1].context is context
Beispiel #25
0
async def test_propagate_error_invalid_service_data(hass):
    """Test that a script aborts when we send invalid service data."""
    event = "test_event"
    events = async_capture_events(hass, event)
    calls = async_mock_service(hass, "test", "script", vol.Schema({"text": str}))
    sequence = cv.SCRIPT_SCHEMA(
        [{"service": "test.script", "data": {"text": 1}}, {"event": event}]
    )
    script_obj = script.Script(hass, sequence)

    with pytest.raises(vol.Invalid):
        await script_obj.async_run()

    assert len(events) == 0
    assert len(calls) == 0
    assert not script_obj.is_running
Beispiel #26
0
def _async_get_action(hass, sequence, button):
    """Return an action based on a configuration."""
    script_obj = script.Script(hass, sequence, button)

    async def action(entity_id):
        """Execute an action."""
        _LOGGER.info('Executing %s "%s" button', entity_id, button)

        try:
            await script_obj.async_run()
        except Exception as err:  # pylint: disable=broad-except
            script_obj.async_log_exception(
                _LOGGER,
                'Error while executing button action {} on {}'.format(button, entity_id), err)

    return action
Beispiel #27
0
async def test_referenced_entities():
    """Test referenced entities."""
    script_obj = script.Script(
        None,
        cv.SCRIPT_SCHEMA([
            {
                "service": "test.script",
                "data": {
                    "entity_id": "light.service_not_list"
                },
            },
            {
                "service": "test.script",
                "data": {
                    "entity_id": ["light.service_list"]
                },
            },
            {
                "condition": "state",
                "entity_id": "sensor.condition",
                "state": "100",
            },
            {
                "service": "test.script",
                "data": {
                    "without": "entity_id"
                }
            },
            {
                "scene": "scene.hello"
            },
            {
                "event": "test_event"
            },
            {
                "delay": "{{ delay_period }}"
            },
        ]),
    )
    assert script_obj.referenced_entities == {
        "light.service_not_list",
        "light.service_list",
        "sensor.condition",
        "scene.hello",
    }
    # Test we cache results.
    assert script_obj.referenced_entities is script_obj.referenced_entities
Beispiel #28
0
async def test_wait_template_timeout_continue(hass):
    """Test the wait template with continuing the script."""
    event = "test_event"
    events = []
    wait_alias = "wait step"

    @callback
    def record_event(event):
        """Add recorded event to set."""
        events.append(event)

    hass.bus.async_listen(event, record_event)

    hass.states.async_set("switch.test", "on")

    script_obj = script.Script(
        hass,
        cv.SCRIPT_SCHEMA([
            {
                "event": event
            },
            {
                "wait_template": "{{states.switch.test.state == 'off'}}",
                "timeout": 5,
                "continue_on_timeout": True,
                "alias": wait_alias,
            },
            {
                "event": event
            },
        ]),
    )

    await script_obj.async_run()
    await hass.async_block_till_done()

    assert script_obj.is_running
    assert script_obj.can_cancel
    assert script_obj.last_action == wait_alias
    assert len(events) == 1

    future = dt_util.utcnow() + timedelta(seconds=5)
    async_fire_time_changed(hass, future)
    await hass.async_block_till_done()

    assert not script_obj.is_running
    assert len(events) == 2
Beispiel #29
0
    def test_passing_variables_to_script(self):
        """Test if we can pass variables to script."""
        calls = []

        @callback
        def record_call(service):
            """Add recorded event to set."""
            calls.append(service)

        self.hass.services.register('test', 'script', record_call)

        script_obj = script.Script(
            self.hass,
            cv.SCRIPT_SCHEMA([{
                'service': 'test.script',
                'data_template': {
                    'hello': '{{ greeting }}',
                },
            }, {
                'delay': '{{ delay_period }}'
            }, {
                'service': 'test.script',
                'data_template': {
                    'hello': '{{ greeting2 }}',
                },
            }]))

        script_obj.run({
            'greeting': 'world',
            'greeting2': 'universe',
            'delay_period': '00:00:05'
        })

        self.hass.block_till_done()

        assert script_obj.is_running
        assert len(calls) == 1
        assert calls[-1].data['hello'] == 'world'

        future = dt_util.utcnow() + timedelta(seconds=5)
        fire_time_changed(self.hass, future)
        self.hass.block_till_done()

        assert not script_obj.is_running
        assert len(calls) == 2
        assert calls[-1].data['hello'] == 'universe'
Beispiel #30
0
async def test_update_logger(hass, caplog):
    """Test updating logger."""
    sequence = cv.SCRIPT_SCHEMA({"event": "test_event"})
    script_obj = script.Script(hass, sequence)

    await script_obj.async_run()
    await hass.async_block_till_done()

    assert script.__name__ in caplog.text

    log_name = "testing.123"
    script_obj.update_logger(logging.getLogger(log_name))

    await script_obj.async_run()
    await hass.async_block_till_done()

    assert log_name in caplog.text