mirror of
https://github.com/home-assistant/core.git
synced 2025-07-27 07:07:28 +00:00
commit
75615bd92a
@ -82,7 +82,7 @@ class HassIOAuth(HassIOBaseAuth):
|
|||||||
data[ATTR_USERNAME], data[ATTR_PASSWORD]
|
data[ATTR_USERNAME], data[ATTR_PASSWORD]
|
||||||
)
|
)
|
||||||
except auth_ha.InvalidAuth:
|
except auth_ha.InvalidAuth:
|
||||||
raise HTTPUnauthorized() from None
|
raise HTTPNotFound() from None
|
||||||
|
|
||||||
return web.Response(status=HTTP_OK)
|
return web.Response(status=HTTP_OK)
|
||||||
|
|
||||||
|
@ -79,6 +79,9 @@ class KNXCover(KnxEntity, CoverEntity):
|
|||||||
@property
|
@property
|
||||||
def is_closed(self):
|
def is_closed(self):
|
||||||
"""Return if the cover is closed."""
|
"""Return if the cover is closed."""
|
||||||
|
# state shall be "unknown" when xknx travelcalculator is not initialized
|
||||||
|
if self._device.current_position() is None:
|
||||||
|
return None
|
||||||
return self._device.is_closed()
|
return self._device.is_closed()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -232,7 +232,7 @@ async def async_setup(hass, config):
|
|||||||
async def async_handle_toggle_service(light, call):
|
async def async_handle_toggle_service(light, call):
|
||||||
"""Handle toggling a light."""
|
"""Handle toggling a light."""
|
||||||
if light.is_on:
|
if light.is_on:
|
||||||
off_params = filter_turn_off_params(call.data)
|
off_params = filter_turn_off_params(call.data["params"])
|
||||||
await light.async_turn_off(**off_params)
|
await light.async_turn_off(**off_params)
|
||||||
else:
|
else:
|
||||||
await async_handle_light_on_service(light, call)
|
await async_handle_light_on_service(light, call)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"domain": "myq",
|
"domain": "myq",
|
||||||
"name": "MyQ",
|
"name": "MyQ",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/myq",
|
"documentation": "https://www.home-assistant.io/integrations/myq",
|
||||||
"requirements": ["pymyq==2.0.12"],
|
"requirements": ["pymyq==2.0.13"],
|
||||||
"codeowners": ["@bdraco"],
|
"codeowners": ["@bdraco"],
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"homekit": {
|
"homekit": {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""Constants used by Home Assistant components."""
|
"""Constants used by Home Assistant components."""
|
||||||
MAJOR_VERSION = 2021
|
MAJOR_VERSION = 2021
|
||||||
MINOR_VERSION = 1
|
MINOR_VERSION = 1
|
||||||
PATCH_VERSION = "0"
|
PATCH_VERSION = "1"
|
||||||
__short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}"
|
__short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}"
|
||||||
__version__ = f"{__short_version__}.{PATCH_VERSION}"
|
__version__ = f"{__short_version__}.{PATCH_VERSION}"
|
||||||
REQUIRED_PYTHON_VER = (3, 7, 1)
|
REQUIRED_PYTHON_VER = (3, 7, 1)
|
||||||
|
@ -62,11 +62,7 @@ from homeassistant.core import (
|
|||||||
callback,
|
callback,
|
||||||
)
|
)
|
||||||
from homeassistant.helpers import condition, config_validation as cv, service, template
|
from homeassistant.helpers import condition, config_validation as cv, service, template
|
||||||
from homeassistant.helpers.event import (
|
from homeassistant.helpers.event import async_call_later, async_track_template
|
||||||
TrackTemplate,
|
|
||||||
async_call_later,
|
|
||||||
async_track_template_result,
|
|
||||||
)
|
|
||||||
from homeassistant.helpers.script_variables import ScriptVariables
|
from homeassistant.helpers.script_variables import ScriptVariables
|
||||||
from homeassistant.helpers.trigger import (
|
from homeassistant.helpers.trigger import (
|
||||||
async_initialize_triggers,
|
async_initialize_triggers,
|
||||||
@ -359,7 +355,7 @@ class _ScriptRun:
|
|||||||
return
|
return
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def _async_script_wait(event, updates):
|
def async_script_wait(entity_id, from_s, to_s):
|
||||||
"""Handle script after template condition is true."""
|
"""Handle script after template condition is true."""
|
||||||
self._variables["wait"] = {
|
self._variables["wait"] = {
|
||||||
"remaining": to_context.remaining if to_context else delay,
|
"remaining": to_context.remaining if to_context else delay,
|
||||||
@ -368,12 +364,9 @@ class _ScriptRun:
|
|||||||
done.set()
|
done.set()
|
||||||
|
|
||||||
to_context = None
|
to_context = None
|
||||||
info = async_track_template_result(
|
unsub = async_track_template(
|
||||||
self._hass,
|
self._hass, wait_template, async_script_wait, self._variables
|
||||||
[TrackTemplate(wait_template, self._variables)],
|
|
||||||
_async_script_wait,
|
|
||||||
)
|
)
|
||||||
unsub = info.async_remove
|
|
||||||
|
|
||||||
self._changed()
|
self._changed()
|
||||||
done = asyncio.Event()
|
done = asyncio.Event()
|
||||||
|
@ -1536,7 +1536,7 @@ pymsteams==0.1.12
|
|||||||
pymusiccast==0.1.6
|
pymusiccast==0.1.6
|
||||||
|
|
||||||
# homeassistant.components.myq
|
# homeassistant.components.myq
|
||||||
pymyq==2.0.12
|
pymyq==2.0.13
|
||||||
|
|
||||||
# homeassistant.components.mysensors
|
# homeassistant.components.mysensors
|
||||||
pymysensors==0.18.0
|
pymysensors==0.18.0
|
||||||
|
@ -779,7 +779,7 @@ pymodbus==2.3.0
|
|||||||
pymonoprice==0.3
|
pymonoprice==0.3
|
||||||
|
|
||||||
# homeassistant.components.myq
|
# homeassistant.components.myq
|
||||||
pymyq==2.0.12
|
pymyq==2.0.13
|
||||||
|
|
||||||
# homeassistant.components.nut
|
# homeassistant.components.nut
|
||||||
pynut2==2.1.2
|
pynut2==2.1.2
|
||||||
|
@ -66,7 +66,7 @@ async def test_login_error(hass, hassio_client_supervisor):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Check we got right response
|
# Check we got right response
|
||||||
assert resp.status == 401
|
assert resp.status == 404
|
||||||
mock_login.assert_called_with("test", "123456")
|
mock_login.assert_called_with("test", "123456")
|
||||||
|
|
||||||
|
|
||||||
|
@ -336,6 +336,21 @@ async def test_services(hass, mock_light_profiles):
|
|||||||
light.ATTR_TRANSITION: prof_t,
|
light.ATTR_TRANSITION: prof_t,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
light.DOMAIN,
|
||||||
|
SERVICE_TOGGLE,
|
||||||
|
{
|
||||||
|
ATTR_ENTITY_ID: ent3.entity_id,
|
||||||
|
light.ATTR_TRANSITION: 4,
|
||||||
|
},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
_, data = ent3.last_call("turn_off")
|
||||||
|
assert data == {
|
||||||
|
light.ATTR_TRANSITION: 4,
|
||||||
|
}
|
||||||
|
|
||||||
# Test bad data
|
# Test bad data
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
light.DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ENTITY_MATCH_ALL}, blocking=True
|
light.DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ENTITY_MATCH_ALL}, blocking=True
|
||||||
|
@ -7,6 +7,7 @@ import logging
|
|||||||
from types import MappingProxyType
|
from types import MappingProxyType
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
|
from async_timeout import timeout
|
||||||
import pytest
|
import pytest
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
@ -544,6 +545,41 @@ async def test_wait_basic(hass, action_type):
|
|||||||
assert script_obj.last_action is None
|
assert script_obj.last_action is None
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("action_type", ["template", "trigger"])
|
||||||
|
async def test_wait_basic_times_out(hass, action_type):
|
||||||
|
"""Test wait actions times out when the action does not happen."""
|
||||||
|
wait_alias = "wait step"
|
||||||
|
action = {"alias": wait_alias}
|
||||||
|
if action_type == "template":
|
||||||
|
action["wait_template"] = "{{ states.switch.test.state == 'off' }}"
|
||||||
|
else:
|
||||||
|
action["wait_for_trigger"] = {
|
||||||
|
"platform": "state",
|
||||||
|
"entity_id": "switch.test",
|
||||||
|
"to": "off",
|
||||||
|
}
|
||||||
|
sequence = cv.SCRIPT_SCHEMA(action)
|
||||||
|
script_obj = script.Script(hass, sequence, "Test Name", "test_domain")
|
||||||
|
wait_started_flag = async_watch_for_action(script_obj, wait_alias)
|
||||||
|
timed_out = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
hass.states.async_set("switch.test", "on")
|
||||||
|
hass.async_create_task(script_obj.async_run(context=Context()))
|
||||||
|
await asyncio.wait_for(wait_started_flag.wait(), 1)
|
||||||
|
assert script_obj.is_running
|
||||||
|
assert script_obj.last_action == wait_alias
|
||||||
|
hass.states.async_set("switch.test", "not_on")
|
||||||
|
|
||||||
|
with timeout(0.1):
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
timed_out = True
|
||||||
|
await script_obj.async_stop()
|
||||||
|
|
||||||
|
assert timed_out
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("action_type", ["template", "trigger"])
|
@pytest.mark.parametrize("action_type", ["template", "trigger"])
|
||||||
async def test_multiple_runs_wait(hass, action_type):
|
async def test_multiple_runs_wait(hass, action_type):
|
||||||
"""Test multiple runs with wait in script."""
|
"""Test multiple runs with wait in script."""
|
||||||
@ -782,30 +818,53 @@ async def test_wait_template_variables_in(hass):
|
|||||||
|
|
||||||
async def test_wait_template_with_utcnow(hass):
|
async def test_wait_template_with_utcnow(hass):
|
||||||
"""Test the wait template with utcnow."""
|
"""Test the wait template with utcnow."""
|
||||||
sequence = cv.SCRIPT_SCHEMA({"wait_template": "{{ utcnow().hours == 12 }}"})
|
sequence = cv.SCRIPT_SCHEMA({"wait_template": "{{ utcnow().hour == 12 }}"})
|
||||||
script_obj = script.Script(hass, sequence, "Test Name", "test_domain")
|
script_obj = script.Script(hass, sequence, "Test Name", "test_domain")
|
||||||
wait_started_flag = async_watch_for_action(script_obj, "wait")
|
wait_started_flag = async_watch_for_action(script_obj, "wait")
|
||||||
start_time = dt_util.utcnow() + timedelta(hours=24)
|
start_time = dt_util.utcnow().replace(minute=1) + timedelta(hours=48)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
hass.async_create_task(script_obj.async_run(context=Context()))
|
hass.async_create_task(script_obj.async_run(context=Context()))
|
||||||
async_fire_time_changed(hass, start_time.replace(hour=5))
|
|
||||||
assert not script_obj.is_running
|
|
||||||
async_fire_time_changed(hass, start_time.replace(hour=12))
|
|
||||||
|
|
||||||
await asyncio.wait_for(wait_started_flag.wait(), 1)
|
await asyncio.wait_for(wait_started_flag.wait(), 1)
|
||||||
|
|
||||||
assert script_obj.is_running
|
assert script_obj.is_running
|
||||||
|
|
||||||
|
match_time = start_time.replace(hour=12)
|
||||||
|
with patch("homeassistant.util.dt.utcnow", return_value=match_time):
|
||||||
|
async_fire_time_changed(hass, match_time)
|
||||||
except (AssertionError, asyncio.TimeoutError):
|
except (AssertionError, asyncio.TimeoutError):
|
||||||
await script_obj.async_stop()
|
await script_obj.async_stop()
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
async_fire_time_changed(hass, start_time.replace(hour=3))
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert not script_obj.is_running
|
assert not script_obj.is_running
|
||||||
|
|
||||||
|
|
||||||
|
async def test_wait_template_with_utcnow_no_match(hass):
|
||||||
|
"""Test the wait template with utcnow that does not match."""
|
||||||
|
sequence = cv.SCRIPT_SCHEMA({"wait_template": "{{ utcnow().hour == 12 }}"})
|
||||||
|
script_obj = script.Script(hass, sequence, "Test Name", "test_domain")
|
||||||
|
wait_started_flag = async_watch_for_action(script_obj, "wait")
|
||||||
|
start_time = dt_util.utcnow().replace(minute=1) + timedelta(hours=48)
|
||||||
|
timed_out = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
hass.async_create_task(script_obj.async_run(context=Context()))
|
||||||
|
await asyncio.wait_for(wait_started_flag.wait(), 1)
|
||||||
|
assert script_obj.is_running
|
||||||
|
|
||||||
|
non_maching_time = start_time.replace(hour=3)
|
||||||
|
with patch("homeassistant.util.dt.utcnow", return_value=non_maching_time):
|
||||||
|
async_fire_time_changed(hass, non_maching_time)
|
||||||
|
|
||||||
|
with timeout(0.1):
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
timed_out = True
|
||||||
|
await script_obj.async_stop()
|
||||||
|
|
||||||
|
assert timed_out
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("mode", ["no_timeout", "timeout_finish", "timeout_not_finish"])
|
@pytest.mark.parametrize("mode", ["no_timeout", "timeout_finish", "timeout_not_finish"])
|
||||||
@pytest.mark.parametrize("action_type", ["template", "trigger"])
|
@pytest.mark.parametrize("action_type", ["template", "trigger"])
|
||||||
async def test_wait_variables_out(hass, mode, action_type):
|
async def test_wait_variables_out(hass, mode, action_type):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user