Merge pull request #44982 from home-assistant/rc

2021.1.1
This commit is contained in:
Paulus Schoutsen 2021-01-09 16:02:54 +01:00 committed by GitHub
commit 75615bd92a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 97 additions and 27 deletions

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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": {

View File

@ -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)

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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")

View File

@ -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

View File

@ -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):