From 9fa0de86005716817931482dcd12cf53433bd0c5 Mon Sep 17 00:00:00 2001 From: mvn23 Date: Fri, 5 Mar 2021 20:22:40 +0100 Subject: [PATCH 01/11] Update pyotgw to 1.1b1 (#47446) --- homeassistant/components/opentherm_gw/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/opentherm_gw/manifest.json b/homeassistant/components/opentherm_gw/manifest.json index 066cee61c05..baa02dc3f46 100644 --- a/homeassistant/components/opentherm_gw/manifest.json +++ b/homeassistant/components/opentherm_gw/manifest.json @@ -2,7 +2,7 @@ "domain": "opentherm_gw", "name": "OpenTherm Gateway", "documentation": "https://www.home-assistant.io/integrations/opentherm_gw", - "requirements": ["pyotgw==1.0b1"], + "requirements": ["pyotgw==1.1b1"], "codeowners": ["@mvn23"], "config_flow": true } diff --git a/requirements_all.txt b/requirements_all.txt index 5d69ddd65bd..86a8a705a5f 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1603,7 +1603,7 @@ pyoppleio==1.0.5 pyota==2.0.5 # homeassistant.components.opentherm_gw -pyotgw==1.0b1 +pyotgw==1.1b1 # homeassistant.auth.mfa_modules.notify # homeassistant.auth.mfa_modules.totp diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 5fdf5100605..fb684893daf 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -851,7 +851,7 @@ pyopenuv==1.0.9 pyopnsense==0.2.0 # homeassistant.components.opentherm_gw -pyotgw==1.0b1 +pyotgw==1.1b1 # homeassistant.auth.mfa_modules.notify # homeassistant.auth.mfa_modules.totp From f99ef25f8801ac5bcc1295d99f5988b7c3d23f6f Mon Sep 17 00:00:00 2001 From: Tobias Sauerwein Date: Fri, 5 Mar 2021 21:41:55 +0100 Subject: [PATCH 02/11] Fix issue at Netatmo startup (#47452) --- homeassistant/components/netatmo/camera.py | 48 ++++++++++--------- homeassistant/components/netatmo/climate.py | 8 +++- .../components/netatmo/data_handler.py | 6 ++- homeassistant/components/netatmo/light.py | 9 ++-- homeassistant/components/netatmo/sensor.py | 18 ++++++- 5 files changed, 56 insertions(+), 33 deletions(-) diff --git a/homeassistant/components/netatmo/camera.py b/homeassistant/components/netatmo/camera.py index 6e55b884d4d..5163c9582b0 100644 --- a/homeassistant/components/netatmo/camera.py +++ b/homeassistant/components/netatmo/camera.py @@ -7,6 +7,7 @@ import voluptuous as vol from homeassistant.components.camera import SUPPORT_STREAM, Camera from homeassistant.core import callback +from homeassistant.exceptions import PlatformNotReady from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.helpers.dispatcher import async_dispatcher_connect @@ -49,15 +50,17 @@ async def async_setup_entry(hass, entry, async_add_entities): data_handler = hass.data[DOMAIN][entry.entry_id][DATA_HANDLER] + await data_handler.register_data_class( + CAMERA_DATA_CLASS_NAME, CAMERA_DATA_CLASS_NAME, None + ) + + if CAMERA_DATA_CLASS_NAME not in data_handler.data: + raise PlatformNotReady + async def get_entities(): """Retrieve Netatmo entities.""" - await data_handler.register_data_class( - CAMERA_DATA_CLASS_NAME, CAMERA_DATA_CLASS_NAME, None - ) - data = data_handler.data - - if not data.get(CAMERA_DATA_CLASS_NAME): + if not data_handler.data.get(CAMERA_DATA_CLASS_NAME): return [] data_class = data_handler.data[CAMERA_DATA_CLASS_NAME] @@ -94,24 +97,25 @@ async def async_setup_entry(hass, entry, async_add_entities): async_add_entities(await get_entities(), True) + await data_handler.unregister_data_class(CAMERA_DATA_CLASS_NAME, None) + platform = entity_platform.current_platform.get() - if data_handler.data[CAMERA_DATA_CLASS_NAME] is not None: - platform.async_register_entity_service( - SERVICE_SET_PERSONS_HOME, - {vol.Required(ATTR_PERSONS): vol.All(cv.ensure_list, [cv.string])}, - "_service_set_persons_home", - ) - platform.async_register_entity_service( - SERVICE_SET_PERSON_AWAY, - {vol.Optional(ATTR_PERSON): cv.string}, - "_service_set_person_away", - ) - platform.async_register_entity_service( - SERVICE_SET_CAMERA_LIGHT, - {vol.Required(ATTR_CAMERA_LIGHT_MODE): vol.In(CAMERA_LIGHT_MODES)}, - "_service_set_camera_light", - ) + platform.async_register_entity_service( + SERVICE_SET_PERSONS_HOME, + {vol.Required(ATTR_PERSONS): vol.All(cv.ensure_list, [cv.string])}, + "_service_set_persons_home", + ) + platform.async_register_entity_service( + SERVICE_SET_PERSON_AWAY, + {vol.Optional(ATTR_PERSON): cv.string}, + "_service_set_person_away", + ) + platform.async_register_entity_service( + SERVICE_SET_CAMERA_LIGHT, + {vol.Required(ATTR_CAMERA_LIGHT_MODE): vol.In(CAMERA_LIGHT_MODES)}, + "_service_set_camera_light", + ) class NetatmoCamera(NetatmoBase, Camera): diff --git a/homeassistant/components/netatmo/climate.py b/homeassistant/components/netatmo/climate.py index a53f7f9fb08..d12ee9263db 100644 --- a/homeassistant/components/netatmo/climate.py +++ b/homeassistant/components/netatmo/climate.py @@ -25,6 +25,7 @@ from homeassistant.const import ( TEMP_CELSIUS, ) from homeassistant.core import callback +from homeassistant.exceptions import PlatformNotReady from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.helpers.device_registry import async_get_registry from homeassistant.helpers.dispatcher import async_dispatcher_connect @@ -81,6 +82,7 @@ NETATMO_MAP_PRESET = { STATE_NETATMO_AWAY: PRESET_AWAY, STATE_NETATMO_OFF: STATE_NETATMO_OFF, STATE_NETATMO_MANUAL: STATE_NETATMO_MANUAL, + STATE_NETATMO_HOME: PRESET_SCHEDULE, } HVAC_MAP_NETATMO = { @@ -111,8 +113,8 @@ async def async_setup_entry(hass, entry, async_add_entities): ) home_data = data_handler.data.get(HOMEDATA_DATA_CLASS_NAME) - if not home_data: - return + if HOMEDATA_DATA_CLASS_NAME not in data_handler.data: + raise PlatformNotReady async def get_entities(): """Retrieve Netatmo entities.""" @@ -151,6 +153,8 @@ async def async_setup_entry(hass, entry, async_add_entities): async_add_entities(await get_entities(), True) + await data_handler.unregister_data_class(HOMEDATA_DATA_CLASS_NAME, None) + platform = entity_platform.current_platform.get() if home_data is not None: diff --git a/homeassistant/components/netatmo/data_handler.py b/homeassistant/components/netatmo/data_handler.py index 9bc4b197f1b..be0120bd1a0 100644 --- a/homeassistant/components/netatmo/data_handler.py +++ b/homeassistant/components/netatmo/data_handler.py @@ -129,7 +129,11 @@ class NetatmoDataHandler: if update_callback: update_callback() - except (pyatmo.NoDevice, pyatmo.ApiError) as err: + except pyatmo.NoDevice as err: + _LOGGER.debug(err) + self.data[data_class_entry] = None + + except pyatmo.ApiError as err: _LOGGER.debug(err) async def register_data_class( diff --git a/homeassistant/components/netatmo/light.py b/homeassistant/components/netatmo/light.py index dc8bf3f1fc8..eed12f048c8 100644 --- a/homeassistant/components/netatmo/light.py +++ b/homeassistant/components/netatmo/light.py @@ -31,18 +31,15 @@ async def async_setup_entry(hass, entry, async_add_entities): data_handler = hass.data[DOMAIN][entry.entry_id][DATA_HANDLER] + if CAMERA_DATA_CLASS_NAME not in data_handler.data: + raise PlatformNotReady + async def get_entities(): """Retrieve Netatmo entities.""" - await data_handler.register_data_class( - CAMERA_DATA_CLASS_NAME, CAMERA_DATA_CLASS_NAME, None - ) entities = [] all_cameras = [] - if CAMERA_DATA_CLASS_NAME not in data_handler.data: - raise PlatformNotReady - try: for home in data_handler.data[CAMERA_DATA_CLASS_NAME].cameras.values(): for camera in home.values(): diff --git a/homeassistant/components/netatmo/sensor.py b/homeassistant/components/netatmo/sensor.py index f8484444818..9176b670bea 100644 --- a/homeassistant/components/netatmo/sensor.py +++ b/homeassistant/components/netatmo/sensor.py @@ -20,6 +20,7 @@ from homeassistant.const import ( TEMP_CELSIUS, ) from homeassistant.core import HomeAssistant, callback +from homeassistant.exceptions import PlatformNotReady from homeassistant.helpers.device_registry import async_entries_for_config_entry from homeassistant.helpers.dispatcher import ( async_dispatcher_connect, @@ -129,14 +130,25 @@ async def async_setup_entry(hass, entry, async_add_entities): """Set up the Netatmo weather and homecoach platform.""" data_handler = hass.data[DOMAIN][entry.entry_id][DATA_HANDLER] + await data_handler.register_data_class( + WEATHERSTATION_DATA_CLASS_NAME, WEATHERSTATION_DATA_CLASS_NAME, None + ) + await data_handler.register_data_class( + HOMECOACH_DATA_CLASS_NAME, HOMECOACH_DATA_CLASS_NAME, None + ) + async def find_entities(data_class_name): """Find all entities.""" - await data_handler.register_data_class(data_class_name, data_class_name, None) + if data_class_name not in data_handler.data: + raise PlatformNotReady all_module_infos = {} data = data_handler.data - if not data.get(data_class_name): + if data_class_name not in data: + return [] + + if data[data_class_name] is None: return [] data_class = data[data_class_name] @@ -174,6 +186,8 @@ async def async_setup_entry(hass, entry, async_add_entities): NetatmoSensor(data_handler, data_class_name, module, condition) ) + await data_handler.unregister_data_class(data_class_name, None) + return entities for data_class_name in [ From d11da43551bed2beeeec057a141edf2777094034 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Fri, 5 Mar 2021 18:43:26 +0100 Subject: [PATCH 03/11] Fix Hue scene overriding Hue default transition times (#47454) --- homeassistant/components/hue/bridge.py | 7 ++----- homeassistant/components/hue/const.py | 2 -- tests/components/hue/test_bridge.py | 1 + 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/hue/bridge.py b/homeassistant/components/hue/bridge.py index 201e9f3a546..dc9b56fcdfe 100644 --- a/homeassistant/components/hue/bridge.py +++ b/homeassistant/components/hue/bridge.py @@ -19,7 +19,6 @@ from .const import ( CONF_ALLOW_UNREACHABLE, DEFAULT_ALLOW_HUE_GROUPS, DEFAULT_ALLOW_UNREACHABLE, - DEFAULT_SCENE_TRANSITION, LOGGER, ) from .errors import AuthenticationRequired, CannotConnect @@ -34,9 +33,7 @@ SCENE_SCHEMA = vol.Schema( { vol.Required(ATTR_GROUP_NAME): cv.string, vol.Required(ATTR_SCENE_NAME): cv.string, - vol.Optional( - ATTR_TRANSITION, default=DEFAULT_SCENE_TRANSITION - ): cv.positive_int, + vol.Optional(ATTR_TRANSITION): cv.positive_int, } ) # How long should we sleep if the hub is busy @@ -209,7 +206,7 @@ class HueBridge: """Service to call directly into bridge to set scenes.""" group_name = call.data[ATTR_GROUP_NAME] scene_name = call.data[ATTR_SCENE_NAME] - transition = call.data.get(ATTR_TRANSITION, DEFAULT_SCENE_TRANSITION) + transition = call.data.get(ATTR_TRANSITION) group = next( (group for group in self.api.groups.values() if group.name == group_name), diff --git a/homeassistant/components/hue/const.py b/homeassistant/components/hue/const.py index b782ce70193..8d01617073b 100644 --- a/homeassistant/components/hue/const.py +++ b/homeassistant/components/hue/const.py @@ -14,8 +14,6 @@ DEFAULT_ALLOW_UNREACHABLE = False CONF_ALLOW_HUE_GROUPS = "allow_hue_groups" DEFAULT_ALLOW_HUE_GROUPS = False -DEFAULT_SCENE_TRANSITION = 4 - GROUP_TYPE_LIGHT_GROUP = "LightGroup" GROUP_TYPE_ROOM = "Room" GROUP_TYPE_LUMINAIRE = "Luminaire" diff --git a/tests/components/hue/test_bridge.py b/tests/components/hue/test_bridge.py index 29bc2acf03a..093f6356b09 100644 --- a/tests/components/hue/test_bridge.py +++ b/tests/components/hue/test_bridge.py @@ -189,6 +189,7 @@ async def test_hue_activate_scene(hass, mock_api): assert len(mock_api.mock_requests) == 3 assert mock_api.mock_requests[2]["json"]["scene"] == "scene_1" + assert "transitiontime" not in mock_api.mock_requests[2]["json"] assert mock_api.mock_requests[2]["path"] == "groups/group_1/action" From a4369fc352f776e55ab0b5e57e11d492cacd9d98 Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Fri, 5 Mar 2021 18:42:20 +0100 Subject: [PATCH 04/11] Bump version with fix for v1 (#47458) --- homeassistant/components/philips_js/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/philips_js/manifest.json b/homeassistant/components/philips_js/manifest.json index e1e1fa69b6b..9ed1cedbf05 100644 --- a/homeassistant/components/philips_js/manifest.json +++ b/homeassistant/components/philips_js/manifest.json @@ -3,7 +3,7 @@ "name": "Philips TV", "documentation": "https://www.home-assistant.io/integrations/philips_js", "requirements": [ - "ha-philipsjs==2.3.0" + "ha-philipsjs==2.3.1" ], "codeowners": [ "@elupus" diff --git a/requirements_all.txt b/requirements_all.txt index 86a8a705a5f..ba0cb7e2314 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -721,7 +721,7 @@ guppy3==3.1.0 ha-ffmpeg==3.0.2 # homeassistant.components.philips_js -ha-philipsjs==2.3.0 +ha-philipsjs==2.3.1 # homeassistant.components.habitica habitipy==0.2.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index fb684893daf..1e2c7ff0fb1 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -382,7 +382,7 @@ guppy3==3.1.0 ha-ffmpeg==3.0.2 # homeassistant.components.philips_js -ha-philipsjs==2.3.0 +ha-philipsjs==2.3.1 # homeassistant.components.habitica habitipy==0.2.0 From ddc6cd6da125119e58283a895dfaf58b806f6e57 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Fri, 5 Mar 2021 18:42:08 +0100 Subject: [PATCH 05/11] Update frontend to 20210302.5 (#47462) --- homeassistant/components/frontend/manifest.json | 2 +- homeassistant/package_constraints.txt | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/frontend/manifest.json b/homeassistant/components/frontend/manifest.json index a5b4c6f10d5..8093c65d91a 100644 --- a/homeassistant/components/frontend/manifest.json +++ b/homeassistant/components/frontend/manifest.json @@ -3,7 +3,7 @@ "name": "Home Assistant Frontend", "documentation": "https://www.home-assistant.io/integrations/frontend", "requirements": [ - "home-assistant-frontend==20210302.4" + "home-assistant-frontend==20210302.5" ], "dependencies": [ "api", diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index 919b53f64ed..0586b956f39 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -15,7 +15,7 @@ defusedxml==0.6.0 distro==1.5.0 emoji==1.2.0 hass-nabucasa==0.41.0 -home-assistant-frontend==20210302.4 +home-assistant-frontend==20210302.5 httpx==0.16.1 jinja2>=2.11.3 netdisco==2.8.2 diff --git a/requirements_all.txt b/requirements_all.txt index ba0cb7e2314..def728244f5 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -763,7 +763,7 @@ hole==0.5.1 holidays==0.10.5.2 # homeassistant.components.frontend -home-assistant-frontend==20210302.4 +home-assistant-frontend==20210302.5 # homeassistant.components.zwave homeassistant-pyozw==0.1.10 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 1e2c7ff0fb1..58885bf07e7 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -412,7 +412,7 @@ hole==0.5.1 holidays==0.10.5.2 # homeassistant.components.frontend -home-assistant-frontend==20210302.4 +home-assistant-frontend==20210302.5 # homeassistant.components.zwave homeassistant-pyozw==0.1.10 From 6c45a7d53329076a47b6c3bb36838d084fb5a7aa Mon Sep 17 00:00:00 2001 From: functionpointer Date: Fri, 5 Mar 2021 20:21:24 +0100 Subject: [PATCH 06/11] Use conn_made callback in MySensors (#47463) --- homeassistant/components/mysensors/const.py | 1 - homeassistant/components/mysensors/gateway.py | 40 ++++++++----------- homeassistant/components/mysensors/handler.py | 23 +---------- 3 files changed, 17 insertions(+), 47 deletions(-) diff --git a/homeassistant/components/mysensors/const.py b/homeassistant/components/mysensors/const.py index 66bee128d4d..9116009d7b1 100644 --- a/homeassistant/components/mysensors/const.py +++ b/homeassistant/components/mysensors/const.py @@ -29,7 +29,6 @@ CONF_GATEWAY_TYPE_ALL: List[str] = [ DOMAIN: str = "mysensors" -MYSENSORS_GATEWAY_READY: str = "mysensors_gateway_ready_{}" MYSENSORS_GATEWAY_START_TASK: str = "mysensors_gateway_start_task_{}" MYSENSORS_GATEWAYS: str = "mysensors_gateways" PLATFORM: str = "platform" diff --git a/homeassistant/components/mysensors/gateway.py b/homeassistant/components/mysensors/gateway.py index 4267ba5cbb3..b6797cafb37 100644 --- a/homeassistant/components/mysensors/gateway.py +++ b/homeassistant/components/mysensors/gateway.py @@ -26,7 +26,6 @@ from .const import ( CONF_TOPIC_OUT_PREFIX, CONF_VERSION, DOMAIN, - MYSENSORS_GATEWAY_READY, MYSENSORS_GATEWAY_START_TASK, MYSENSORS_GATEWAYS, GatewayId, @@ -36,7 +35,7 @@ from .helpers import discover_mysensors_platform, validate_child, validate_node _LOGGER = logging.getLogger(__name__) -GATEWAY_READY_TIMEOUT = 15.0 +GATEWAY_READY_TIMEOUT = 20.0 MQTT_COMPONENT = "mqtt" @@ -64,24 +63,16 @@ async def try_connect(hass: HomeAssistantType, user_input: Dict[str, str]) -> bo if user_input[CONF_DEVICE] == MQTT_COMPONENT: return True # dont validate mqtt. mqtt gateways dont send ready messages :( try: - gateway_ready = asyncio.Future() + gateway_ready = asyncio.Event() - def gateway_ready_callback(msg): - msg_type = msg.gateway.const.MessageType(msg.type) - _LOGGER.debug("Received MySensors msg type %s: %s", msg_type.name, msg) - if msg_type.name != "internal": - return - internal = msg.gateway.const.Internal(msg.sub_type) - if internal.name != "I_GATEWAY_READY": - return - _LOGGER.debug("Received gateway ready") - gateway_ready.set_result(True) + def on_conn_made(_: BaseAsyncGateway) -> None: + gateway_ready.set() gateway: Optional[BaseAsyncGateway] = await _get_gateway( hass, device=user_input[CONF_DEVICE], version=user_input[CONF_VERSION], - event_callback=gateway_ready_callback, + event_callback=lambda _: None, persistence_file=None, baud_rate=user_input.get(CONF_BAUD_RATE), tcp_port=user_input.get(CONF_TCP_PORT), @@ -92,12 +83,13 @@ async def try_connect(hass: HomeAssistantType, user_input: Dict[str, str]) -> bo ) if gateway is None: return False + gateway.on_conn_made = on_conn_made connect_task = None try: connect_task = asyncio.create_task(gateway.start()) - with async_timeout.timeout(20): - await gateway_ready + with async_timeout.timeout(GATEWAY_READY_TIMEOUT): + await gateway_ready.wait() return True except asyncio.TimeoutError: _LOGGER.info("Try gateway connect failed with timeout") @@ -280,6 +272,12 @@ async def _gw_start( hass: HomeAssistantType, entry: ConfigEntry, gateway: BaseAsyncGateway ): """Start the gateway.""" + gateway_ready = asyncio.Event() + + def gateway_connected(_: BaseAsyncGateway): + gateway_ready.set() + + gateway.on_conn_made = gateway_connected # Don't use hass.async_create_task to avoid holding up setup indefinitely. hass.data[DOMAIN][ MYSENSORS_GATEWAY_START_TASK.format(entry.entry_id) @@ -294,21 +292,15 @@ async def _gw_start( if entry.data[CONF_DEVICE] == MQTT_COMPONENT: # Gatways connected via mqtt doesn't send gateway ready message. return - gateway_ready = asyncio.Future() - gateway_ready_key = MYSENSORS_GATEWAY_READY.format(entry.entry_id) - hass.data[DOMAIN][gateway_ready_key] = gateway_ready - try: with async_timeout.timeout(GATEWAY_READY_TIMEOUT): - await gateway_ready + await gateway_ready.wait() except asyncio.TimeoutError: _LOGGER.warning( - "Gateway %s not ready after %s secs so continuing with setup", + "Gateway %s not connected after %s secs so continuing with setup", entry.data[CONF_DEVICE], GATEWAY_READY_TIMEOUT, ) - finally: - hass.data[DOMAIN].pop(gateway_ready_key, None) def _gw_callback_factory( diff --git a/homeassistant/components/mysensors/handler.py b/homeassistant/components/mysensors/handler.py index 10165a171e0..a47c9174b23 100644 --- a/homeassistant/components/mysensors/handler.py +++ b/homeassistant/components/mysensors/handler.py @@ -8,14 +8,7 @@ from homeassistant.helpers.dispatcher import async_dispatcher_send from homeassistant.helpers.typing import HomeAssistantType from homeassistant.util import decorator -from .const import ( - CHILD_CALLBACK, - DOMAIN, - MYSENSORS_GATEWAY_READY, - NODE_CALLBACK, - DevId, - GatewayId, -) +from .const import CHILD_CALLBACK, NODE_CALLBACK, DevId, GatewayId from .device import get_mysensors_devices from .helpers import discover_mysensors_platform, validate_set_msg @@ -75,20 +68,6 @@ async def handle_sketch_version( _handle_node_update(hass, gateway_id, msg) -@HANDLERS.register("I_GATEWAY_READY") -async def handle_gateway_ready( - hass: HomeAssistantType, gateway_id: GatewayId, msg: Message -) -> None: - """Handle an internal gateway ready message. - - Set asyncio future result if gateway is ready. - """ - gateway_ready = hass.data[DOMAIN].get(MYSENSORS_GATEWAY_READY.format(gateway_id)) - if gateway_ready is None or gateway_ready.cancelled(): - return - gateway_ready.set_result(True) - - @callback def _handle_child_update( hass: HomeAssistantType, gateway_id: GatewayId, validated: Dict[str, List[DevId]] From 65859b41073643364bdf6830ff44b93d46a7707e Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Fri, 5 Mar 2021 12:41:36 -0500 Subject: [PATCH 07/11] Bump zwave-js-server-python to 0.21.1 (#47464) --- homeassistant/components/zwave_js/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/zwave_js/manifest.json b/homeassistant/components/zwave_js/manifest.json index 2a6f036fa80..de0f2cc0a6f 100644 --- a/homeassistant/components/zwave_js/manifest.json +++ b/homeassistant/components/zwave_js/manifest.json @@ -3,7 +3,7 @@ "name": "Z-Wave JS", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/zwave_js", - "requirements": ["zwave-js-server-python==0.21.0"], + "requirements": ["zwave-js-server-python==0.21.1"], "codeowners": ["@home-assistant/z-wave"], "dependencies": ["http", "websocket_api"] } diff --git a/requirements_all.txt b/requirements_all.txt index def728244f5..ea34186457a 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2397,4 +2397,4 @@ zigpy==0.32.0 zm-py==0.5.2 # homeassistant.components.zwave_js -zwave-js-server-python==0.21.0 +zwave-js-server-python==0.21.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 58885bf07e7..360fd281434 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1234,4 +1234,4 @@ zigpy-znp==0.4.0 zigpy==0.32.0 # homeassistant.components.zwave_js -zwave-js-server-python==0.21.0 +zwave-js-server-python==0.21.1 From 90e0801c1bb70d7cca05daf219b6a1f2d9bf807a Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 5 Mar 2021 15:34:18 -0800 Subject: [PATCH 08/11] Raise error instead of crashing when template passed to call service target (#47467) --- .../components/websocket_api/commands.py | 16 +++++--- .../components/websocket_api/test_commands.py | 40 +++++++++++-------- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/homeassistant/components/websocket_api/commands.py b/homeassistant/components/websocket_api/commands.py index ddd7548cd68..53531cf9ba9 100644 --- a/homeassistant/components/websocket_api/commands.py +++ b/homeassistant/components/websocket_api/commands.py @@ -13,10 +13,9 @@ from homeassistant.exceptions import ( TemplateError, Unauthorized, ) -from homeassistant.helpers import config_validation as cv, entity +from homeassistant.helpers import config_validation as cv, entity, template from homeassistant.helpers.event import TrackTemplate, async_track_template_result from homeassistant.helpers.service import async_get_all_descriptions -from homeassistant.helpers.template import Template from homeassistant.loader import IntegrationNotFound, async_get_integration from . import const, decorators, messages @@ -132,6 +131,11 @@ async def handle_call_service(hass, connection, msg): if msg["domain"] == HASS_DOMAIN and msg["service"] in ["restart", "stop"]: blocking = False + # We do not support templates. + target = msg.get("target") + if template.is_complex(target): + raise vol.Invalid("Templates are not supported here") + try: context = connection.context(msg) await hass.services.async_call( @@ -140,7 +144,7 @@ async def handle_call_service(hass, connection, msg): msg.get("service_data"), blocking, context, - target=msg.get("target"), + target=target, ) connection.send_message( messages.result_message(msg["id"], {"context": context}) @@ -256,14 +260,14 @@ def handle_ping(hass, connection, msg): async def handle_render_template(hass, connection, msg): """Handle render_template command.""" template_str = msg["template"] - template = Template(template_str, hass) + template_obj = template.Template(template_str, hass) variables = msg.get("variables") timeout = msg.get("timeout") info = None if timeout: try: - timed_out = await template.async_render_will_timeout(timeout) + timed_out = await template_obj.async_render_will_timeout(timeout) except TemplateError as ex: connection.send_error(msg["id"], const.ERR_TEMPLATE_ERROR, str(ex)) return @@ -294,7 +298,7 @@ async def handle_render_template(hass, connection, msg): try: info = async_track_template_result( hass, - [TrackTemplate(template, variables)], + [TrackTemplate(template_obj, variables)], _template_listener, raise_on_template_error=True, ) diff --git a/tests/components/websocket_api/test_commands.py b/tests/components/websocket_api/test_commands.py index 1f7abc42c4e..f596db63c5e 100644 --- a/tests/components/websocket_api/test_commands.py +++ b/tests/components/websocket_api/test_commands.py @@ -21,13 +21,7 @@ from tests.common import MockEntity, MockEntityPlatform, async_mock_service async def test_call_service(hass, websocket_client): """Test call service command.""" - calls = [] - - @callback - def service_call(call): - calls.append(call) - - hass.services.async_register("domain_test", "test_service", service_call) + calls = async_mock_service(hass, "domain_test", "test_service") await websocket_client.send_json( { @@ -54,13 +48,7 @@ async def test_call_service(hass, websocket_client): async def test_call_service_target(hass, websocket_client): """Test call service command with target.""" - calls = [] - - @callback - def service_call(call): - calls.append(call) - - hass.services.async_register("domain_test", "test_service", service_call) + calls = async_mock_service(hass, "domain_test", "test_service") await websocket_client.send_json( { @@ -93,6 +81,28 @@ async def test_call_service_target(hass, websocket_client): } +async def test_call_service_target_template(hass, websocket_client): + """Test call service command with target does not allow template.""" + await websocket_client.send_json( + { + "id": 5, + "type": "call_service", + "domain": "domain_test", + "service": "test_service", + "service_data": {"hello": "world"}, + "target": { + "entity_id": "{{ 1 }}", + }, + } + ) + + msg = await websocket_client.receive_json() + assert msg["id"] == 5 + assert msg["type"] == const.TYPE_RESULT + assert not msg["success"] + assert msg["error"]["code"] == const.ERR_INVALID_FORMAT + + async def test_call_service_not_found(hass, websocket_client): """Test call service command.""" await websocket_client.send_json( @@ -232,7 +242,6 @@ async def test_call_service_error(hass, websocket_client): ) msg = await websocket_client.receive_json() - print(msg) assert msg["id"] == 5 assert msg["type"] == const.TYPE_RESULT assert msg["success"] is False @@ -249,7 +258,6 @@ async def test_call_service_error(hass, websocket_client): ) msg = await websocket_client.receive_json() - print(msg) assert msg["id"] == 6 assert msg["type"] == const.TYPE_RESULT assert msg["success"] is False From 55c1b67de496460c73fbc2b5604bd313381a3c54 Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Fri, 5 Mar 2021 14:57:06 -0500 Subject: [PATCH 09/11] Update zwave_js.refresh_value service description (#47469) --- homeassistant/components/zwave_js/services.yaml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/zwave_js/services.yaml b/homeassistant/components/zwave_js/services.yaml index 8e6d907fc96..7277f540d76 100644 --- a/homeassistant/components/zwave_js/services.yaml +++ b/homeassistant/components/zwave_js/services.yaml @@ -70,10 +70,15 @@ set_config_parameter: refresh_value: name: Refresh value(s) of a Z-Wave entity description: Force update value(s) for a Z-Wave entity - target: - entity: - integration: zwave_js fields: + entity_id: + name: Entity + description: Entity whose value(s) should be refreshed + required: true + example: sensor.family_room_motion + selector: + entity: + integration: zwave_js refresh_all_values: name: Refresh all values? description: Whether to refresh all values (true) or just the primary value (false) From ef79d24a8c0d8f4a1eab92a39a6c54ead647dcbb Mon Sep 17 00:00:00 2001 From: Phil Bruckner Date: Fri, 5 Mar 2021 17:05:36 -0600 Subject: [PATCH 10/11] Bump amcrest package version to 1.7.1 (#47483) --- homeassistant/components/amcrest/manifest.json | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/amcrest/manifest.json b/homeassistant/components/amcrest/manifest.json index 0b6fbbdc09a..0b7a59edb79 100644 --- a/homeassistant/components/amcrest/manifest.json +++ b/homeassistant/components/amcrest/manifest.json @@ -2,7 +2,7 @@ "domain": "amcrest", "name": "Amcrest", "documentation": "https://www.home-assistant.io/integrations/amcrest", - "requirements": ["amcrest==1.7.0"], + "requirements": ["amcrest==1.7.1"], "dependencies": ["ffmpeg"], "codeowners": ["@pnbruckner"] } diff --git a/requirements_all.txt b/requirements_all.txt index ea34186457a..33d2ee7aad6 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -245,7 +245,7 @@ alpha_vantage==2.3.1 ambiclimate==0.2.1 # homeassistant.components.amcrest -amcrest==1.7.0 +amcrest==1.7.1 # homeassistant.components.androidtv androidtv[async]==0.0.57 From 939da2403f27d1b050d6b1bbd255a3e4f09fd267 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 5 Mar 2021 23:38:27 +0000 Subject: [PATCH 11/11] Bumped version to 2021.3.2 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index e454f3ab09d..015a347a5e3 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 2021 MINOR_VERSION = 3 -PATCH_VERSION = "1" +PATCH_VERSION = "2" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER = (3, 8, 0)