From 872b2f56ac5f3baf0a31c44e51e31a406cfb788d Mon Sep 17 00:00:00 2001 From: Aidan Timson Date: Mon, 15 Aug 2022 14:00:29 +0100 Subject: [PATCH 01/19] Update systembridgeconnector to 3.4.4 (#75362) Co-authored-by: Martin Hjelmare --- .../components/system_bridge/__init__.py | 18 +- .../components/system_bridge/config_flow.py | 32 ++- .../components/system_bridge/coordinator.py | 13 +- .../components/system_bridge/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- .../system_bridge/test_config_flow.py | 208 ++++++++++++------ 7 files changed, 183 insertions(+), 94 deletions(-) diff --git a/homeassistant/components/system_bridge/__init__.py b/homeassistant/components/system_bridge/__init__.py index 19bcc224a66..74be1faed40 100644 --- a/homeassistant/components/system_bridge/__init__.py +++ b/homeassistant/components/system_bridge/__init__.py @@ -10,6 +10,10 @@ from systembridgeconnector.exceptions import ( ConnectionClosedException, ConnectionErrorException, ) +from systembridgeconnector.models.keyboard_key import KeyboardKey +from systembridgeconnector.models.keyboard_text import KeyboardText +from systembridgeconnector.models.open_path import OpenPath +from systembridgeconnector.models.open_url import OpenUrl from systembridgeconnector.version import SUPPORTED_VERSION, Version import voluptuous as vol @@ -149,7 +153,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: coordinator: SystemBridgeDataUpdateCoordinator = hass.data[DOMAIN][ call.data[CONF_BRIDGE] ] - await coordinator.websocket_client.open_path(call.data[CONF_PATH]) + await coordinator.websocket_client.open_path( + OpenPath(path=call.data[CONF_PATH]) + ) async def handle_open_url(call: ServiceCall) -> None: """Handle the open url service call.""" @@ -157,21 +163,25 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: coordinator: SystemBridgeDataUpdateCoordinator = hass.data[DOMAIN][ call.data[CONF_BRIDGE] ] - await coordinator.websocket_client.open_url(call.data[CONF_URL]) + await coordinator.websocket_client.open_url(OpenUrl(url=call.data[CONF_URL])) async def handle_send_keypress(call: ServiceCall) -> None: """Handle the send_keypress service call.""" coordinator: SystemBridgeDataUpdateCoordinator = hass.data[DOMAIN][ call.data[CONF_BRIDGE] ] - await coordinator.websocket_client.keyboard_keypress(call.data[CONF_KEY]) + await coordinator.websocket_client.keyboard_keypress( + KeyboardKey(key=call.data[CONF_KEY]) + ) async def handle_send_text(call: ServiceCall) -> None: """Handle the send_keypress service call.""" coordinator: SystemBridgeDataUpdateCoordinator = hass.data[DOMAIN][ call.data[CONF_BRIDGE] ] - await coordinator.websocket_client.keyboard_text(call.data[CONF_TEXT]) + await coordinator.websocket_client.keyboard_text( + KeyboardText(text=call.data[CONF_TEXT]) + ) hass.services.async_register( DOMAIN, diff --git a/homeassistant/components/system_bridge/config_flow.py b/homeassistant/components/system_bridge/config_flow.py index 9d89cf83288..995df6391cc 100644 --- a/homeassistant/components/system_bridge/config_flow.py +++ b/homeassistant/components/system_bridge/config_flow.py @@ -7,12 +7,13 @@ import logging from typing import Any import async_timeout -from systembridgeconnector.const import EVENT_MODULE, EVENT_TYPE, TYPE_DATA_UPDATE from systembridgeconnector.exceptions import ( AuthenticationException, ConnectionClosedException, ConnectionErrorException, ) +from systembridgeconnector.models.get_data import GetData +from systembridgeconnector.models.system import System from systembridgeconnector.websocket_client import WebSocketClient import voluptuous as vol @@ -38,7 +39,7 @@ STEP_USER_DATA_SCHEMA = vol.Schema( ) -async def validate_input( +async def _validate_input( hass: HomeAssistant, data: dict[str, Any], ) -> dict[str, str]: @@ -56,15 +57,12 @@ async def validate_input( try: async with async_timeout.timeout(30): await websocket_client.connect(session=async_get_clientsession(hass)) - await websocket_client.get_data(["system"]) - while True: - message = await websocket_client.receive_message() - _LOGGER.debug("Message: %s", message) - if ( - message[EVENT_TYPE] == TYPE_DATA_UPDATE - and message[EVENT_MODULE] == "system" - ): - break + hass.async_create_task(websocket_client.listen()) + response = await websocket_client.get_data(GetData(modules=["system"])) + _LOGGER.debug("Got response: %s", response.json()) + if response.data is None or not isinstance(response.data, System): + raise CannotConnect("No data received") + system: System = response.data except AuthenticationException as exception: _LOGGER.warning( "Authentication error when connecting to %s: %s", data[CONF_HOST], exception @@ -81,14 +79,12 @@ async def validate_input( except asyncio.TimeoutError as exception: _LOGGER.warning("Timed out connecting to %s: %s", data[CONF_HOST], exception) raise CannotConnect from exception + except ValueError as exception: + raise CannotConnect from exception - _LOGGER.debug("%s Message: %s", TYPE_DATA_UPDATE, message) + _LOGGER.debug("Got System data: %s", system.json()) - if "uuid" not in message["data"]: - error = "No UUID in result!" - raise CannotConnect(error) - - return {"hostname": host, "uuid": message["data"]["uuid"]} + return {"hostname": host, "uuid": system.uuid} async def _async_get_info( @@ -98,7 +94,7 @@ async def _async_get_info( errors = {} try: - info = await validate_input(hass, user_input) + info = await _validate_input(hass, user_input) except CannotConnect: errors["base"] = "cannot_connect" except InvalidAuth: diff --git a/homeassistant/components/system_bridge/coordinator.py b/homeassistant/components/system_bridge/coordinator.py index 1719d951cf0..695dca44342 100644 --- a/homeassistant/components/system_bridge/coordinator.py +++ b/homeassistant/components/system_bridge/coordinator.py @@ -5,6 +5,7 @@ import asyncio from collections.abc import Callable from datetime import timedelta import logging +from typing import Any import async_timeout from pydantic import BaseModel # pylint: disable=no-name-in-module @@ -17,8 +18,10 @@ from systembridgeconnector.models.battery import Battery from systembridgeconnector.models.cpu import Cpu from systembridgeconnector.models.disk import Disk from systembridgeconnector.models.display import Display +from systembridgeconnector.models.get_data import GetData from systembridgeconnector.models.gpu import Gpu from systembridgeconnector.models.memory import Memory +from systembridgeconnector.models.register_data_listener import RegisterDataListener from systembridgeconnector.models.system import System from systembridgeconnector.websocket_client import WebSocketClient @@ -93,12 +96,14 @@ class SystemBridgeDataUpdateCoordinator( if not self.websocket_client.connected: await self._setup_websocket() - self.hass.async_create_task(self.websocket_client.get_data(modules)) + self.hass.async_create_task( + self.websocket_client.get_data(GetData(modules=modules)) + ) async def async_handle_module( self, module_name: str, - module, + module: Any, ) -> None: """Handle data from the WebSocket client.""" self.logger.debug("Set new data for: %s", module_name) @@ -174,7 +179,9 @@ class SystemBridgeDataUpdateCoordinator( self.hass.async_create_task(self._listen_for_data()) - await self.websocket_client.register_data_listener(MODULES) + await self.websocket_client.register_data_listener( + RegisterDataListener(modules=MODULES) + ) self.last_update_success = True self.async_update_listeners() diff --git a/homeassistant/components/system_bridge/manifest.json b/homeassistant/components/system_bridge/manifest.json index 4fb2201e2c7..7968b588814 100644 --- a/homeassistant/components/system_bridge/manifest.json +++ b/homeassistant/components/system_bridge/manifest.json @@ -3,7 +3,7 @@ "name": "System Bridge", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/system_bridge", - "requirements": ["systembridgeconnector==3.3.2"], + "requirements": ["systembridgeconnector==3.4.4"], "codeowners": ["@timmo001"], "zeroconf": ["_system-bridge._tcp.local."], "after_dependencies": ["zeroconf"], diff --git a/requirements_all.txt b/requirements_all.txt index 96be4dae1b1..bfd752843cb 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2281,7 +2281,7 @@ swisshydrodata==0.1.0 synology-srm==0.2.0 # homeassistant.components.system_bridge -systembridgeconnector==3.3.2 +systembridgeconnector==3.4.4 # homeassistant.components.tailscale tailscale==0.2.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 59b922c4ef1..1838b50232b 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1539,7 +1539,7 @@ sunwatcher==0.2.1 surepy==0.7.2 # homeassistant.components.system_bridge -systembridgeconnector==3.3.2 +systembridgeconnector==3.4.4 # homeassistant.components.tailscale tailscale==0.2.0 diff --git a/tests/components/system_bridge/test_config_flow.py b/tests/components/system_bridge/test_config_flow.py index 45131353550..d01ed9a3ff8 100644 --- a/tests/components/system_bridge/test_config_flow.py +++ b/tests/components/system_bridge/test_config_flow.py @@ -2,21 +2,14 @@ import asyncio from unittest.mock import patch -from systembridgeconnector.const import ( - EVENT_DATA, - EVENT_MESSAGE, - EVENT_MODULE, - EVENT_SUBTYPE, - EVENT_TYPE, - SUBTYPE_BAD_API_KEY, - TYPE_DATA_UPDATE, - TYPE_ERROR, -) +from systembridgeconnector.const import MODEL_SYSTEM, TYPE_DATA_UPDATE from systembridgeconnector.exceptions import ( AuthenticationException, ConnectionClosedException, ConnectionErrorException, ) +from systembridgeconnector.models.response import Response +from systembridgeconnector.models.system import LastUpdated, System from homeassistant import config_entries, data_entry_flow from homeassistant.components import zeroconf @@ -48,8 +41,8 @@ FIXTURE_ZEROCONF = zeroconf.ZeroconfServiceInfo( addresses=["1.1.1.1"], port=9170, hostname="test-bridge.local.", - type="_system-bridge._udp.local.", - name="System Bridge - test-bridge._system-bridge._udp.local.", + type="_system-bridge._tcp.local.", + name="System Bridge - test-bridge._system-bridge._tcp.local.", properties={ "address": "http://test-bridge:9170", "fqdn": "test-bridge", @@ -66,34 +59,70 @@ FIXTURE_ZEROCONF_BAD = zeroconf.ZeroconfServiceInfo( addresses=["1.1.1.1"], port=9170, hostname="test-bridge.local.", - type="_system-bridge._udp.local.", - name="System Bridge - test-bridge._system-bridge._udp.local.", + type="_system-bridge._tcp.local.", + name="System Bridge - test-bridge._system-bridge._tcp.local.", properties={ "something": "bad", }, ) -FIXTURE_DATA_SYSTEM = { - EVENT_TYPE: TYPE_DATA_UPDATE, - EVENT_MESSAGE: "Data changed", - EVENT_MODULE: "system", - EVENT_DATA: { - "uuid": FIXTURE_UUID, - }, -} -FIXTURE_DATA_SYSTEM_BAD = { - EVENT_TYPE: TYPE_DATA_UPDATE, - EVENT_MESSAGE: "Data changed", - EVENT_MODULE: "system", - EVENT_DATA: {}, -} +FIXTURE_SYSTEM = System( + id=FIXTURE_UUID, + boot_time=1, + fqdn="", + hostname="1.1.1.1", + ip_address_4="1.1.1.1", + mac_address=FIXTURE_MAC_ADDRESS, + platform="", + platform_version="", + uptime=1, + uuid=FIXTURE_UUID, + version="", + version_latest="", + version_newer_available=False, + last_updated=LastUpdated( + boot_time=1, + fqdn=1, + hostname=1, + ip_address_4=1, + mac_address=1, + platform=1, + platform_version=1, + uptime=1, + uuid=1, + version=1, + version_latest=1, + version_newer_available=1, + ), +) -FIXTURE_DATA_AUTH_ERROR = { - EVENT_TYPE: TYPE_ERROR, - EVENT_SUBTYPE: SUBTYPE_BAD_API_KEY, - EVENT_MESSAGE: "Invalid api-key", -} +FIXTURE_DATA_RESPONSE = Response( + id="1234", + type=TYPE_DATA_UPDATE, + subtype=None, + message="Data received", + module=MODEL_SYSTEM, + data=FIXTURE_SYSTEM, +) + +FIXTURE_DATA_RESPONSE_BAD = Response( + id="1234", + type=TYPE_DATA_UPDATE, + subtype=None, + message="Data received", + module=MODEL_SYSTEM, + data={}, +) + +FIXTURE_DATA_RESPONSE_BAD = Response( + id="1234", + type=TYPE_DATA_UPDATE, + subtype=None, + message="Data received", + module=MODEL_SYSTEM, + data={}, +) async def test_show_user_form(hass: HomeAssistant) -> None: @@ -117,9 +146,11 @@ async def test_user_flow(hass: HomeAssistant) -> None: with patch( "homeassistant.components.system_bridge.config_flow.WebSocketClient.connect" - ), patch("systembridgeconnector.websocket_client.WebSocketClient.get_data"), patch( - "systembridgeconnector.websocket_client.WebSocketClient.receive_message", - return_value=FIXTURE_DATA_SYSTEM, + ), patch( + "systembridgeconnector.websocket_client.WebSocketClient.get_data", + return_value=FIXTURE_DATA_RESPONSE, + ), patch( + "systembridgeconnector.websocket_client.WebSocketClient.listen" ), patch( "homeassistant.components.system_bridge.async_setup_entry", return_value=True, @@ -167,11 +198,13 @@ async def test_form_connection_closed_cannot_connect(hass: HomeAssistant) -> Non assert result["type"] == data_entry_flow.FlowResultType.FORM assert result["errors"] is None - with patch("systembridgeconnector.websocket_client.WebSocketClient.connect"), patch( - "systembridgeconnector.websocket_client.WebSocketClient.get_data" + with patch( + "homeassistant.components.system_bridge.config_flow.WebSocketClient.connect" ), patch( - "systembridgeconnector.websocket_client.WebSocketClient.receive_message", + "systembridgeconnector.websocket_client.WebSocketClient.get_data", side_effect=ConnectionClosedException, + ), patch( + "systembridgeconnector.websocket_client.WebSocketClient.listen", ): result2 = await hass.config_entries.flow.async_configure( result["flow_id"], FIXTURE_USER_INPUT @@ -192,11 +225,13 @@ async def test_form_timeout_cannot_connect(hass: HomeAssistant) -> None: assert result["type"] == data_entry_flow.FlowResultType.FORM assert result["errors"] is None - with patch("systembridgeconnector.websocket_client.WebSocketClient.connect"), patch( - "systembridgeconnector.websocket_client.WebSocketClient.get_data" + with patch( + "homeassistant.components.system_bridge.config_flow.WebSocketClient.connect" ), patch( - "systembridgeconnector.websocket_client.WebSocketClient.receive_message", + "systembridgeconnector.websocket_client.WebSocketClient.get_data", side_effect=asyncio.TimeoutError, + ), patch( + "systembridgeconnector.websocket_client.WebSocketClient.listen", ): result2 = await hass.config_entries.flow.async_configure( result["flow_id"], FIXTURE_USER_INPUT @@ -217,11 +252,13 @@ async def test_form_invalid_auth(hass: HomeAssistant) -> None: assert result["type"] == data_entry_flow.FlowResultType.FORM assert result["errors"] is None - with patch("systembridgeconnector.websocket_client.WebSocketClient.connect"), patch( - "systembridgeconnector.websocket_client.WebSocketClient.get_data" + with patch( + "homeassistant.components.system_bridge.config_flow.WebSocketClient.connect" ), patch( - "systembridgeconnector.websocket_client.WebSocketClient.receive_message", + "systembridgeconnector.websocket_client.WebSocketClient.get_data", side_effect=AuthenticationException, + ), patch( + "systembridgeconnector.websocket_client.WebSocketClient.listen", ): result2 = await hass.config_entries.flow.async_configure( result["flow_id"], FIXTURE_USER_INPUT @@ -242,11 +279,40 @@ async def test_form_uuid_error(hass: HomeAssistant) -> None: assert result["type"] == data_entry_flow.FlowResultType.FORM assert result["errors"] is None - with patch("systembridgeconnector.websocket_client.WebSocketClient.connect"), patch( - "systembridgeconnector.websocket_client.WebSocketClient.get_data" + with patch( + "homeassistant.components.system_bridge.config_flow.WebSocketClient.connect" ), patch( - "systembridgeconnector.websocket_client.WebSocketClient.receive_message", - return_value=FIXTURE_DATA_SYSTEM_BAD, + "systembridgeconnector.websocket_client.WebSocketClient.get_data", + side_effect=ValueError, + ), patch( + "systembridgeconnector.websocket_client.WebSocketClient.listen", + ): + result2 = await hass.config_entries.flow.async_configure( + result["flow_id"], FIXTURE_USER_INPUT + ) + await hass.async_block_till_done() + + assert result2["type"] == data_entry_flow.FlowResultType.FORM + assert result2["step_id"] == "user" + assert result2["errors"] == {"base": "cannot_connect"} + + +async def test_form_value_error(hass: HomeAssistant) -> None: + """Test we handle error from bad value.""" + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": config_entries.SOURCE_USER} + ) + + assert result["type"] == data_entry_flow.FlowResultType.FORM + assert result["errors"] is None + + with patch( + "homeassistant.components.system_bridge.config_flow.WebSocketClient.connect" + ), patch( + "systembridgeconnector.websocket_client.WebSocketClient.get_data", + return_value=FIXTURE_DATA_RESPONSE_BAD, + ), patch( + "systembridgeconnector.websocket_client.WebSocketClient.listen", ): result2 = await hass.config_entries.flow.async_configure( result["flow_id"], FIXTURE_USER_INPUT @@ -267,11 +333,13 @@ async def test_form_unknown_error(hass: HomeAssistant) -> None: assert result["type"] == data_entry_flow.FlowResultType.FORM assert result["errors"] is None - with patch("systembridgeconnector.websocket_client.WebSocketClient.connect"), patch( - "systembridgeconnector.websocket_client.WebSocketClient.get_data" + with patch( + "homeassistant.components.system_bridge.config_flow.WebSocketClient.connect" ), patch( - "systembridgeconnector.websocket_client.WebSocketClient.receive_message", + "systembridgeconnector.websocket_client.WebSocketClient.get_data", side_effect=Exception, + ), patch( + "systembridgeconnector.websocket_client.WebSocketClient.listen", ): result2 = await hass.config_entries.flow.async_configure( result["flow_id"], FIXTURE_USER_INPUT @@ -292,11 +360,13 @@ async def test_reauth_authorization_error(hass: HomeAssistant) -> None: assert result["type"] == data_entry_flow.FlowResultType.FORM assert result["step_id"] == "authenticate" - with patch("systembridgeconnector.websocket_client.WebSocketClient.connect"), patch( - "systembridgeconnector.websocket_client.WebSocketClient.get_data" + with patch( + "homeassistant.components.system_bridge.config_flow.WebSocketClient.connect" ), patch( - "systembridgeconnector.websocket_client.WebSocketClient.receive_message", + "systembridgeconnector.websocket_client.WebSocketClient.get_data", side_effect=AuthenticationException, + ), patch( + "systembridgeconnector.websocket_client.WebSocketClient.listen", ): result2 = await hass.config_entries.flow.async_configure( result["flow_id"], FIXTURE_AUTH_INPUT @@ -340,11 +410,13 @@ async def test_reauth_connection_closed_error(hass: HomeAssistant) -> None: assert result["type"] == data_entry_flow.FlowResultType.FORM assert result["step_id"] == "authenticate" - with patch("systembridgeconnector.websocket_client.WebSocketClient.connect"), patch( - "systembridgeconnector.websocket_client.WebSocketClient.get_data" + with patch( + "homeassistant.components.system_bridge.config_flow.WebSocketClient.connect" ), patch( - "systembridgeconnector.websocket_client.WebSocketClient.receive_message", + "systembridgeconnector.websocket_client.WebSocketClient.get_data", side_effect=ConnectionClosedException, + ), patch( + "systembridgeconnector.websocket_client.WebSocketClient.listen", ): result2 = await hass.config_entries.flow.async_configure( result["flow_id"], FIXTURE_AUTH_INPUT @@ -370,11 +442,13 @@ async def test_reauth_flow(hass: HomeAssistant) -> None: assert result["type"] == data_entry_flow.FlowResultType.FORM assert result["step_id"] == "authenticate" - with patch("systembridgeconnector.websocket_client.WebSocketClient.connect"), patch( - "systembridgeconnector.websocket_client.WebSocketClient.get_data" + with patch( + "homeassistant.components.system_bridge.config_flow.WebSocketClient.connect" ), patch( - "systembridgeconnector.websocket_client.WebSocketClient.receive_message", - return_value=FIXTURE_DATA_SYSTEM, + "systembridgeconnector.websocket_client.WebSocketClient.get_data", + return_value=FIXTURE_DATA_RESPONSE, + ), patch( + "systembridgeconnector.websocket_client.WebSocketClient.listen" ), patch( "homeassistant.components.system_bridge.async_setup_entry", return_value=True, @@ -402,11 +476,13 @@ async def test_zeroconf_flow(hass: HomeAssistant) -> None: assert result["type"] == data_entry_flow.FlowResultType.FORM assert not result["errors"] - with patch("systembridgeconnector.websocket_client.WebSocketClient.connect"), patch( - "systembridgeconnector.websocket_client.WebSocketClient.get_data" + with patch( + "homeassistant.components.system_bridge.config_flow.WebSocketClient.connect" ), patch( - "systembridgeconnector.websocket_client.WebSocketClient.receive_message", - return_value=FIXTURE_DATA_SYSTEM, + "systembridgeconnector.websocket_client.WebSocketClient.get_data", + return_value=FIXTURE_DATA_RESPONSE, + ), patch( + "systembridgeconnector.websocket_client.WebSocketClient.listen" ), patch( "homeassistant.components.system_bridge.async_setup_entry", return_value=True, From 972aad0e99d61189ce440a98a9fc551c54a119bd Mon Sep 17 00:00:00 2001 From: hansgoed Date: Mon, 15 Aug 2022 15:07:39 +0200 Subject: [PATCH 02/19] =?UTF-8?q?=F0=9F=90=9B=20Fix=20"The=20request=20con?= =?UTF-8?q?tent=20was=20malformed"=20error=20in=20home=5Fconnect=20(#76411?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/home_connect/__init__.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/home_connect/__init__.py b/homeassistant/components/home_connect/__init__.py index 6e664ad07e4..0fa14682f44 100644 --- a/homeassistant/components/home_connect/__init__.py +++ b/homeassistant/components/home_connect/__init__.py @@ -138,11 +138,18 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Execute calls to services taking a program.""" program = call.data[ATTR_PROGRAM] device_id = call.data[ATTR_DEVICE_ID] - options = { - ATTR_KEY: call.data.get(ATTR_KEY), - ATTR_VALUE: call.data.get(ATTR_VALUE), - ATTR_UNIT: call.data.get(ATTR_UNIT), - } + + options = [] + + option_key = call.data.get(ATTR_KEY) + if option_key is not None: + option = {ATTR_KEY: option_key, ATTR_VALUE: call.data[ATTR_VALUE]} + + option_unit = call.data.get(ATTR_UNIT) + if option_unit is not None: + option[ATTR_UNIT] = option_unit + + options.append(option) appliance = _get_appliance_by_device_id(hass, device_id) await hass.async_add_executor_job(getattr(appliance, method), program, options) From 666e938b14e3ee2856d048fb3587b015293a0890 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 11 Aug 2022 16:03:31 -1000 Subject: [PATCH 03/19] Bump pySwitchbot to 0.18.5 (#76640) --- homeassistant/components/switchbot/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/switchbot/manifest.json b/homeassistant/components/switchbot/manifest.json index b413b44d605..dd04829de15 100644 --- a/homeassistant/components/switchbot/manifest.json +++ b/homeassistant/components/switchbot/manifest.json @@ -2,7 +2,7 @@ "domain": "switchbot", "name": "SwitchBot", "documentation": "https://www.home-assistant.io/integrations/switchbot", - "requirements": ["PySwitchbot==0.18.4"], + "requirements": ["PySwitchbot==0.18.5"], "config_flow": true, "dependencies": ["bluetooth"], "codeowners": [ diff --git a/requirements_all.txt b/requirements_all.txt index bfd752843cb..4bd6175bdd5 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -37,7 +37,7 @@ PyRMVtransport==0.3.3 PySocks==1.7.1 # homeassistant.components.switchbot -PySwitchbot==0.18.4 +PySwitchbot==0.18.5 # homeassistant.components.transport_nsw PyTransportNSW==0.1.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 1838b50232b..7162289ec9f 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -33,7 +33,7 @@ PyRMVtransport==0.3.3 PySocks==1.7.1 # homeassistant.components.switchbot -PySwitchbot==0.18.4 +PySwitchbot==0.18.5 # homeassistant.components.transport_nsw PyTransportNSW==0.1.1 From 875de80b41f062ed435e41b9eefee2bc2f93eab1 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 12 Aug 2022 02:58:48 -1000 Subject: [PATCH 04/19] Bump pySwitchbot to 0.18.6 to fix disconnect race (#76656) --- homeassistant/components/switchbot/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/switchbot/manifest.json b/homeassistant/components/switchbot/manifest.json index dd04829de15..e26100108c9 100644 --- a/homeassistant/components/switchbot/manifest.json +++ b/homeassistant/components/switchbot/manifest.json @@ -2,7 +2,7 @@ "domain": "switchbot", "name": "SwitchBot", "documentation": "https://www.home-assistant.io/integrations/switchbot", - "requirements": ["PySwitchbot==0.18.5"], + "requirements": ["PySwitchbot==0.18.6"], "config_flow": true, "dependencies": ["bluetooth"], "codeowners": [ diff --git a/requirements_all.txt b/requirements_all.txt index 4bd6175bdd5..8a48eeb9c34 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -37,7 +37,7 @@ PyRMVtransport==0.3.3 PySocks==1.7.1 # homeassistant.components.switchbot -PySwitchbot==0.18.5 +PySwitchbot==0.18.6 # homeassistant.components.transport_nsw PyTransportNSW==0.1.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 7162289ec9f..9c521c7828f 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -33,7 +33,7 @@ PyRMVtransport==0.3.3 PySocks==1.7.1 # homeassistant.components.switchbot -PySwitchbot==0.18.5 +PySwitchbot==0.18.6 # homeassistant.components.transport_nsw PyTransportNSW==0.1.1 From d10e2336e2ab35e2ff29399c7279d1e33c0f85e7 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 14 Aug 2022 19:53:27 -1000 Subject: [PATCH 05/19] Bump pySwitchbot to 0.18.10 to handle empty data and disconnects (#76684) * Bump pySwitchbot to 0.18.7 to handle empty data Fixes #76621 * bump again * bump * bump for rssi on disconnect logging --- homeassistant/components/switchbot/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/switchbot/manifest.json b/homeassistant/components/switchbot/manifest.json index e26100108c9..e70f467ae74 100644 --- a/homeassistant/components/switchbot/manifest.json +++ b/homeassistant/components/switchbot/manifest.json @@ -2,7 +2,7 @@ "domain": "switchbot", "name": "SwitchBot", "documentation": "https://www.home-assistant.io/integrations/switchbot", - "requirements": ["PySwitchbot==0.18.6"], + "requirements": ["PySwitchbot==0.18.10"], "config_flow": true, "dependencies": ["bluetooth"], "codeowners": [ diff --git a/requirements_all.txt b/requirements_all.txt index 8a48eeb9c34..58e06048748 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -37,7 +37,7 @@ PyRMVtransport==0.3.3 PySocks==1.7.1 # homeassistant.components.switchbot -PySwitchbot==0.18.6 +PySwitchbot==0.18.10 # homeassistant.components.transport_nsw PyTransportNSW==0.1.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 9c521c7828f..bfaaa4e86bf 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -33,7 +33,7 @@ PyRMVtransport==0.3.3 PySocks==1.7.1 # homeassistant.components.switchbot -PySwitchbot==0.18.6 +PySwitchbot==0.18.10 # homeassistant.components.transport_nsw PyTransportNSW==0.1.1 From bd40d6f3321dc06ca201e4b85c719bd7bcb7b6d9 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Sat, 13 Aug 2022 06:02:32 -0700 Subject: [PATCH 06/19] Fix google calendar disabled entity handling (#76699) Fix google calendar disable entity handling --- homeassistant/components/google/calendar.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/google/calendar.py b/homeassistant/components/google/calendar.py index ca98b3da087..77ed922e511 100644 --- a/homeassistant/components/google/calendar.py +++ b/homeassistant/components/google/calendar.py @@ -192,7 +192,6 @@ async def async_setup_entry( calendar_id, data.get(CONF_SEARCH), ) - await coordinator.async_config_entry_first_refresh() entities.append( GoogleCalendarEntity( coordinator, @@ -342,6 +341,9 @@ class GoogleCalendarEntity(CoordinatorEntity, CalendarEntity): async def async_added_to_hass(self) -> None: """When entity is added to hass.""" await super().async_added_to_hass() + # We do not ask for an update with async_add_entities() + # because it will update disabled entities + await self.coordinator.async_request_refresh() self._apply_coordinator_update() async def async_get_events( From ef6285800f03735e4cebc7cb1cd1eb065c9facb7 Mon Sep 17 00:00:00 2001 From: starkillerOG Date: Sat, 13 Aug 2022 14:39:04 +0200 Subject: [PATCH 07/19] Motion Blinds fix OperationNotAllowed (#76712) fix OperationNotAllowed homeassistant.config_entries.OperationNotAllowed --- homeassistant/components/motion_blinds/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/motion_blinds/__init__.py b/homeassistant/components/motion_blinds/__init__.py index dfbc6ab74a7..a023fc05d14 100644 --- a/homeassistant/components/motion_blinds/__init__.py +++ b/homeassistant/components/motion_blinds/__init__.py @@ -121,8 +121,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: multicast_interface = entry.data.get(CONF_INTERFACE, DEFAULT_INTERFACE) wait_for_push = entry.options.get(CONF_WAIT_FOR_PUSH, DEFAULT_WAIT_FOR_PUSH) - entry.async_on_unload(entry.add_update_listener(update_listener)) - # Create multicast Listener async with setup_lock: if KEY_MULTICAST_LISTENER not in hass.data[DOMAIN]: @@ -213,6 +211,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) + entry.async_on_unload(entry.add_update_listener(update_listener)) + return True From 41faf9092a394c70bee416c8c1c1c85cad1660e1 Mon Sep 17 00:00:00 2001 From: Marvin Wichmann Date: Sun, 14 Aug 2022 06:31:39 +0200 Subject: [PATCH 08/19] =?UTF-8?q?Update=20xknx=20to=201.0.0=20=F0=9F=8E=89?= =?UTF-8?q?=20(#76734)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- homeassistant/components/knx/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/knx/manifest.json b/homeassistant/components/knx/manifest.json index 266eceaacee..0f9b6b4b95a 100644 --- a/homeassistant/components/knx/manifest.json +++ b/homeassistant/components/knx/manifest.json @@ -3,7 +3,7 @@ "name": "KNX", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/knx", - "requirements": ["xknx==0.22.1"], + "requirements": ["xknx==1.0.0"], "codeowners": ["@Julius2342", "@farmio", "@marvin-w"], "quality_scale": "platinum", "iot_class": "local_push", diff --git a/requirements_all.txt b/requirements_all.txt index 58e06048748..afbba9d6531 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2473,7 +2473,7 @@ xboxapi==2.0.1 xiaomi-ble==0.6.4 # homeassistant.components.knx -xknx==0.22.1 +xknx==1.0.0 # homeassistant.components.bluesound # homeassistant.components.fritz diff --git a/requirements_test_all.txt b/requirements_test_all.txt index bfaaa4e86bf..864c85d0e47 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1665,7 +1665,7 @@ xbox-webapi==2.0.11 xiaomi-ble==0.6.4 # homeassistant.components.knx -xknx==0.22.1 +xknx==1.0.0 # homeassistant.components.bluesound # homeassistant.components.fritz From 69ea07f29d1cae6b601bfd2638390e5ce665e6a1 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 13 Aug 2022 21:56:57 -1000 Subject: [PATCH 09/19] Bump aiohomekit to 1.2.10 (#76738) --- homeassistant/components/homekit_controller/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/homekit_controller/manifest.json b/homeassistant/components/homekit_controller/manifest.json index 4bd9a0b70f9..49635dd797c 100644 --- a/homeassistant/components/homekit_controller/manifest.json +++ b/homeassistant/components/homekit_controller/manifest.json @@ -3,7 +3,7 @@ "name": "HomeKit Controller", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/homekit_controller", - "requirements": ["aiohomekit==1.2.9"], + "requirements": ["aiohomekit==1.2.10"], "zeroconf": ["_hap._tcp.local.", "_hap._udp.local."], "bluetooth": [{ "manufacturer_id": 76, "manufacturer_data_start": [6] }], "dependencies": ["bluetooth", "zeroconf"], diff --git a/requirements_all.txt b/requirements_all.txt index afbba9d6531..f708004d979 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -168,7 +168,7 @@ aioguardian==2022.07.0 aioharmony==0.2.9 # homeassistant.components.homekit_controller -aiohomekit==1.2.9 +aiohomekit==1.2.10 # homeassistant.components.emulated_hue # homeassistant.components.http diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 864c85d0e47..684e8b44b49 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -152,7 +152,7 @@ aioguardian==2022.07.0 aioharmony==0.2.9 # homeassistant.components.homekit_controller -aiohomekit==1.2.9 +aiohomekit==1.2.10 # homeassistant.components.emulated_hue # homeassistant.components.http From 71a6128c65e634857260da30e97b9d6ed7bc8f54 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 14 Aug 2022 20:48:06 -1000 Subject: [PATCH 10/19] Fix bad data with inkbird bbq sensors (#76739) --- homeassistant/components/inkbird/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/inkbird/test_config_flow.py | 6 +++--- tests/components/inkbird/test_sensor.py | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/homeassistant/components/inkbird/manifest.json b/homeassistant/components/inkbird/manifest.json index b0ef08143c2..f65177ab6e2 100644 --- a/homeassistant/components/inkbird/manifest.json +++ b/homeassistant/components/inkbird/manifest.json @@ -10,7 +10,7 @@ { "local_name": "xBBQ*" }, { "local_name": "tps" } ], - "requirements": ["inkbird-ble==0.5.2"], + "requirements": ["inkbird-ble==0.5.5"], "dependencies": ["bluetooth"], "codeowners": ["@bdraco"], "iot_class": "local_push" diff --git a/requirements_all.txt b/requirements_all.txt index f708004d979..0b29516b23e 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -902,7 +902,7 @@ influxdb-client==1.24.0 influxdb==5.3.1 # homeassistant.components.inkbird -inkbird-ble==0.5.2 +inkbird-ble==0.5.5 # homeassistant.components.insteon insteon-frontend-home-assistant==0.2.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 684e8b44b49..81c79718e63 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -655,7 +655,7 @@ influxdb-client==1.24.0 influxdb==5.3.1 # homeassistant.components.inkbird -inkbird-ble==0.5.2 +inkbird-ble==0.5.5 # homeassistant.components.insteon insteon-frontend-home-assistant==0.2.0 diff --git a/tests/components/inkbird/test_config_flow.py b/tests/components/inkbird/test_config_flow.py index fe210f75f4b..4d9fbc65df7 100644 --- a/tests/components/inkbird/test_config_flow.py +++ b/tests/components/inkbird/test_config_flow.py @@ -25,7 +25,7 @@ async def test_async_step_bluetooth_valid_device(hass): result["flow_id"], user_input={} ) assert result2["type"] == FlowResultType.CREATE_ENTRY - assert result2["title"] == "iBBQ 6AADDD4CAC3D" + assert result2["title"] == "iBBQ AC3D" assert result2["data"] == {} assert result2["result"].unique_id == "4125DDBA-2774-4851-9889-6AADDD4CAC3D" @@ -69,7 +69,7 @@ async def test_async_step_user_with_found_devices(hass): user_input={"address": "61DE521B-F0BF-9F44-64D4-75BBE1738105"}, ) assert result2["type"] == FlowResultType.CREATE_ENTRY - assert result2["title"] == "IBS-TH 75BBE1738105" + assert result2["title"] == "IBS-TH 8105" assert result2["data"] == {} assert result2["result"].unique_id == "61DE521B-F0BF-9F44-64D4-75BBE1738105" @@ -184,7 +184,7 @@ async def test_async_step_user_takes_precedence_over_discovery(hass): user_input={"address": "61DE521B-F0BF-9F44-64D4-75BBE1738105"}, ) assert result2["type"] == FlowResultType.CREATE_ENTRY - assert result2["title"] == "IBS-TH 75BBE1738105" + assert result2["title"] == "IBS-TH 8105" assert result2["data"] == {} assert result2["result"].unique_id == "61DE521B-F0BF-9F44-64D4-75BBE1738105" diff --git a/tests/components/inkbird/test_sensor.py b/tests/components/inkbird/test_sensor.py index cafc22911c3..c54c6e3c242 100644 --- a/tests/components/inkbird/test_sensor.py +++ b/tests/components/inkbird/test_sensor.py @@ -39,10 +39,10 @@ async def test_sensors(hass): await hass.async_block_till_done() assert len(hass.states.async_all()) == 3 - temp_sensor = hass.states.get("sensor.ibs_th_75bbe1738105_battery") + temp_sensor = hass.states.get("sensor.ibs_th_8105_battery") temp_sensor_attribtes = temp_sensor.attributes assert temp_sensor.state == "87" - assert temp_sensor_attribtes[ATTR_FRIENDLY_NAME] == "IBS-TH 75BBE1738105 Battery" + assert temp_sensor_attribtes[ATTR_FRIENDLY_NAME] == "IBS-TH 8105 Battery" assert temp_sensor_attribtes[ATTR_UNIT_OF_MEASUREMENT] == "%" assert temp_sensor_attribtes[ATTR_STATE_CLASS] == "measurement" From ae99b53757e549979c5e9d3853217f192f0dd460 Mon Sep 17 00:00:00 2001 From: rikroe <42204099+rikroe@users.noreply.github.com> Date: Mon, 15 Aug 2022 13:55:23 +0200 Subject: [PATCH 11/19] Bump bimmer_connected to 0.10.2 (#76751) Co-authored-by: rikroe --- homeassistant/components/bmw_connected_drive/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/bmw_connected_drive/manifest.json b/homeassistant/components/bmw_connected_drive/manifest.json index 0381035a63e..f540176a837 100644 --- a/homeassistant/components/bmw_connected_drive/manifest.json +++ b/homeassistant/components/bmw_connected_drive/manifest.json @@ -2,7 +2,7 @@ "domain": "bmw_connected_drive", "name": "BMW Connected Drive", "documentation": "https://www.home-assistant.io/integrations/bmw_connected_drive", - "requirements": ["bimmer_connected==0.10.1"], + "requirements": ["bimmer_connected==0.10.2"], "codeowners": ["@gerard33", "@rikroe"], "config_flow": true, "iot_class": "cloud_polling", diff --git a/requirements_all.txt b/requirements_all.txt index 0b29516b23e..95f746a761e 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -399,7 +399,7 @@ beautifulsoup4==4.11.1 bellows==0.32.0 # homeassistant.components.bmw_connected_drive -bimmer_connected==0.10.1 +bimmer_connected==0.10.2 # homeassistant.components.bizkaibus bizkaibus==0.1.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 81c79718e63..2beb50a7b48 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -323,7 +323,7 @@ beautifulsoup4==4.11.1 bellows==0.32.0 # homeassistant.components.bmw_connected_drive -bimmer_connected==0.10.1 +bimmer_connected==0.10.2 # homeassistant.components.bluetooth bleak==0.15.1 From 30a5e396d3b1b2c713b0062840a980d8eb71c39b Mon Sep 17 00:00:00 2001 From: Marcel van der Veldt Date: Mon, 15 Aug 2022 11:23:38 +0200 Subject: [PATCH 12/19] Bump aiohue to 4.5.0 (#76757) --- homeassistant/components/hue/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/hue/manifest.json b/homeassistant/components/hue/manifest.json index b3dbe4df50a..3854b861c98 100644 --- a/homeassistant/components/hue/manifest.json +++ b/homeassistant/components/hue/manifest.json @@ -3,7 +3,7 @@ "name": "Philips Hue", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/hue", - "requirements": ["aiohue==4.4.2"], + "requirements": ["aiohue==4.5.0"], "ssdp": [ { "manufacturer": "Royal Philips Electronics", diff --git a/requirements_all.txt b/requirements_all.txt index 95f746a761e..109562ad0fd 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -175,7 +175,7 @@ aiohomekit==1.2.10 aiohttp_cors==0.7.0 # homeassistant.components.hue -aiohue==4.4.2 +aiohue==4.5.0 # homeassistant.components.imap aioimaplib==1.0.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 2beb50a7b48..15cb74f0bbe 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -159,7 +159,7 @@ aiohomekit==1.2.10 aiohttp_cors==0.7.0 # homeassistant.components.hue -aiohue==4.4.2 +aiohue==4.5.0 # homeassistant.components.apache_kafka aiokafka==0.7.2 From 70541eac616dc1f162885a5c9323dded38574b63 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 14 Aug 2022 20:48:28 -1000 Subject: [PATCH 13/19] Fix stale data with SensorPush sensors (#76771) --- homeassistant/components/sensorpush/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/sensorpush/manifest.json b/homeassistant/components/sensorpush/manifest.json index a5d900aaf3b..906b5c22f6b 100644 --- a/homeassistant/components/sensorpush/manifest.json +++ b/homeassistant/components/sensorpush/manifest.json @@ -8,7 +8,7 @@ "local_name": "SensorPush*" } ], - "requirements": ["sensorpush-ble==1.5.1"], + "requirements": ["sensorpush-ble==1.5.2"], "dependencies": ["bluetooth"], "codeowners": ["@bdraco"], "iot_class": "local_push" diff --git a/requirements_all.txt b/requirements_all.txt index 109562ad0fd..863460cc9e6 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2160,7 +2160,7 @@ sendgrid==6.8.2 sense_energy==0.10.4 # homeassistant.components.sensorpush -sensorpush-ble==1.5.1 +sensorpush-ble==1.5.2 # homeassistant.components.sentry sentry-sdk==1.8.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 15cb74f0bbe..4261d763b1e 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1451,7 +1451,7 @@ securetar==2022.2.0 sense_energy==0.10.4 # homeassistant.components.sensorpush -sensorpush-ble==1.5.1 +sensorpush-ble==1.5.2 # homeassistant.components.sentry sentry-sdk==1.8.0 From d91e9f7f988838f725acf6b81f3951128ddfa15d Mon Sep 17 00:00:00 2001 From: Frank <46161394+BraveChicken1@users.noreply.github.com> Date: Mon, 15 Aug 2022 10:44:14 +0200 Subject: [PATCH 14/19] Bump homeconnect to 0.7.2 (#76773) --- homeassistant/components/home_connect/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/home_connect/manifest.json b/homeassistant/components/home_connect/manifest.json index ca6e0f012ac..c9aa5d229b8 100644 --- a/homeassistant/components/home_connect/manifest.json +++ b/homeassistant/components/home_connect/manifest.json @@ -4,7 +4,7 @@ "documentation": "https://www.home-assistant.io/integrations/home_connect", "dependencies": ["application_credentials"], "codeowners": ["@DavidMStraub"], - "requirements": ["homeconnect==0.7.1"], + "requirements": ["homeconnect==0.7.2"], "config_flow": true, "iot_class": "cloud_push", "loggers": ["homeconnect"] diff --git a/requirements_all.txt b/requirements_all.txt index 863460cc9e6..fe4ecf42602 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -842,7 +842,7 @@ holidays==0.14.2 home-assistant-frontend==20220802.0 # homeassistant.components.home_connect -homeconnect==0.7.1 +homeconnect==0.7.2 # homeassistant.components.homematicip_cloud homematicip==1.0.7 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 4261d763b1e..484eb31144d 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -619,7 +619,7 @@ holidays==0.14.2 home-assistant-frontend==20220802.0 # homeassistant.components.home_connect -homeconnect==0.7.1 +homeconnect==0.7.2 # homeassistant.components.homematicip_cloud homematicip==1.0.7 From d14261829722c504001df135a148f8ee6d620422 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 14 Aug 2022 20:54:49 -1000 Subject: [PATCH 15/19] Bump aiohomekit to 1.2.11 (#76784) --- homeassistant/components/homekit_controller/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/homekit_controller/manifest.json b/homeassistant/components/homekit_controller/manifest.json index 49635dd797c..ece53d29406 100644 --- a/homeassistant/components/homekit_controller/manifest.json +++ b/homeassistant/components/homekit_controller/manifest.json @@ -3,7 +3,7 @@ "name": "HomeKit Controller", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/homekit_controller", - "requirements": ["aiohomekit==1.2.10"], + "requirements": ["aiohomekit==1.2.11"], "zeroconf": ["_hap._tcp.local.", "_hap._udp.local."], "bluetooth": [{ "manufacturer_id": 76, "manufacturer_data_start": [6] }], "dependencies": ["bluetooth", "zeroconf"], diff --git a/requirements_all.txt b/requirements_all.txt index fe4ecf42602..300ac05de84 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -168,7 +168,7 @@ aioguardian==2022.07.0 aioharmony==0.2.9 # homeassistant.components.homekit_controller -aiohomekit==1.2.10 +aiohomekit==1.2.11 # homeassistant.components.emulated_hue # homeassistant.components.http diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 484eb31144d..a069c31b87b 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -152,7 +152,7 @@ aioguardian==2022.07.0 aioharmony==0.2.9 # homeassistant.components.homekit_controller -aiohomekit==1.2.10 +aiohomekit==1.2.11 # homeassistant.components.emulated_hue # homeassistant.components.http From bae01f188ac4d387933df6a29b8d9f0e87b021c3 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 15 Aug 2022 10:19:37 -1000 Subject: [PATCH 16/19] Fix bluetooth callback registration not surviving a reload (#76817) --- .../components/bluetooth/__init__.py | 21 ++-- tests/components/bluetooth/test_init.py | 97 +++++++++++++++++++ 2 files changed, 110 insertions(+), 8 deletions(-) diff --git a/homeassistant/components/bluetooth/__init__.py b/homeassistant/components/bluetooth/__init__.py index 2d7b47b7552..f9c6a6aca15 100644 --- a/homeassistant/components/bluetooth/__init__.py +++ b/homeassistant/components/bluetooth/__init__.py @@ -358,13 +358,13 @@ class BluetoothManager: async with async_timeout.timeout(START_TIMEOUT): await self.scanner.start() # type: ignore[no-untyped-call] except InvalidMessageError as ex: - self._cancel_device_detected() + self._async_cancel_scanner_callback() _LOGGER.debug("Invalid DBus message received: %s", ex, exc_info=True) raise ConfigEntryNotReady( f"Invalid DBus message received: {ex}; try restarting `dbus`" ) from ex except BrokenPipeError as ex: - self._cancel_device_detected() + self._async_cancel_scanner_callback() _LOGGER.debug("DBus connection broken: %s", ex, exc_info=True) if is_docker_env(): raise ConfigEntryNotReady( @@ -374,7 +374,7 @@ class BluetoothManager: f"DBus connection broken: {ex}; try restarting `bluetooth` and `dbus`" ) from ex except FileNotFoundError as ex: - self._cancel_device_detected() + self._async_cancel_scanner_callback() _LOGGER.debug( "FileNotFoundError while starting bluetooth: %s", ex, exc_info=True ) @@ -386,12 +386,12 @@ class BluetoothManager: f"DBus service not found; make sure the DBus socket is available to Home Assistant: {ex}" ) from ex except asyncio.TimeoutError as ex: - self._cancel_device_detected() + self._async_cancel_scanner_callback() raise ConfigEntryNotReady( f"Timed out starting Bluetooth after {START_TIMEOUT} seconds" ) from ex except BleakError as ex: - self._cancel_device_detected() + self._async_cancel_scanner_callback() _LOGGER.debug("BleakError while starting bluetooth: %s", ex, exc_info=True) raise ConfigEntryNotReady(f"Failed to start Bluetooth: {ex}") from ex self.async_setup_unavailable_tracking() @@ -573,15 +573,20 @@ class BluetoothManager: self._cancel_stop = None await self.async_stop() + @hass_callback + def _async_cancel_scanner_callback(self) -> None: + """Cancel the scanner callback.""" + if self._cancel_device_detected: + self._cancel_device_detected() + self._cancel_device_detected = None + async def async_stop(self) -> None: """Stop bluetooth discovery.""" _LOGGER.debug("Stopping bluetooth discovery") if self._cancel_watchdog: self._cancel_watchdog() self._cancel_watchdog = None - if self._cancel_device_detected: - self._cancel_device_detected() - self._cancel_device_detected = None + self._async_cancel_scanner_callback() if self._cancel_unavailable_tracking: self._cancel_unavailable_tracking() self._cancel_unavailable_tracking = None diff --git a/tests/components/bluetooth/test_init.py b/tests/components/bluetooth/test_init.py index 9432be9f2e4..e69d7ba96e1 100644 --- a/tests/components/bluetooth/test_init.py +++ b/tests/components/bluetooth/test_init.py @@ -164,6 +164,43 @@ async def test_setup_and_retry_adapter_not_yet_available(hass, caplog): await hass.async_block_till_done() +async def test_no_race_during_manual_reload_in_retry_state(hass, caplog): + """Test we can successfully reload when the entry is in a retry state.""" + mock_bt = [] + with patch("homeassistant.components.bluetooth.HaBleakScanner.async_setup"), patch( + "homeassistant.components.bluetooth.HaBleakScanner.start", + side_effect=BleakError, + ), patch( + "homeassistant.components.bluetooth.async_get_bluetooth", return_value=mock_bt + ): + assert await async_setup_component( + hass, bluetooth.DOMAIN, {bluetooth.DOMAIN: {}} + ) + await hass.async_block_till_done() + hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED) + await hass.async_block_till_done() + + entry = hass.config_entries.async_entries(bluetooth.DOMAIN)[0] + + assert "Failed to start Bluetooth" in caplog.text + assert len(bluetooth.async_discovered_service_info(hass)) == 0 + assert entry.state == ConfigEntryState.SETUP_RETRY + + with patch( + "homeassistant.components.bluetooth.HaBleakScanner.start", + ): + await hass.config_entries.async_reload(entry.entry_id) + await hass.async_block_till_done() + + assert entry.state == ConfigEntryState.LOADED + + with patch( + "homeassistant.components.bluetooth.HaBleakScanner.stop", + ): + hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP) + await hass.async_block_till_done() + + async def test_calling_async_discovered_devices_no_bluetooth(hass, caplog): """Test we fail gracefully when asking for discovered devices and there is no blueooth.""" mock_bt = [] @@ -828,6 +865,66 @@ async def test_register_callback_by_address( assert service_info.manufacturer_id == 89 +async def test_register_callback_survives_reload( + hass, mock_bleak_scanner_start, enable_bluetooth +): + """Test registering a callback by address survives bluetooth being reloaded.""" + mock_bt = [] + callbacks = [] + + def _fake_subscriber( + service_info: BluetoothServiceInfo, change: BluetoothChange + ) -> None: + """Fake subscriber for the BleakScanner.""" + callbacks.append((service_info, change)) + + with patch( + "homeassistant.components.bluetooth.async_get_bluetooth", return_value=mock_bt + ): + assert await async_setup_component( + hass, bluetooth.DOMAIN, {bluetooth.DOMAIN: {}} + ) + await hass.async_block_till_done() + + hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED) + await hass.async_block_till_done() + + bluetooth.async_register_callback( + hass, + _fake_subscriber, + {"address": "44:44:33:11:23:45"}, + BluetoothScanningMode.ACTIVE, + ) + + assert len(mock_bleak_scanner_start.mock_calls) == 1 + + switchbot_device = BLEDevice("44:44:33:11:23:45", "wohand") + switchbot_adv = AdvertisementData( + local_name="wohand", + service_uuids=["cba20d00-224d-11e6-9fb8-0002a5d5c51b"], + manufacturer_data={89: b"\xd8.\xad\xcd\r\x85"}, + service_data={"00000d00-0000-1000-8000-00805f9b34fb": b"H\x10c"}, + ) + + _get_underlying_scanner()._callback(switchbot_device, switchbot_adv) + assert len(callbacks) == 1 + service_info: BluetoothServiceInfo = callbacks[0][0] + assert service_info.name == "wohand" + assert service_info.manufacturer == "Nordic Semiconductor ASA" + assert service_info.manufacturer_id == 89 + + entry = hass.config_entries.async_entries(bluetooth.DOMAIN)[0] + await hass.config_entries.async_reload(entry.entry_id) + await hass.async_block_till_done() + + _get_underlying_scanner()._callback(switchbot_device, switchbot_adv) + assert len(callbacks) == 2 + service_info: BluetoothServiceInfo = callbacks[1][0] + assert service_info.name == "wohand" + assert service_info.manufacturer == "Nordic Semiconductor ASA" + assert service_info.manufacturer_id == 89 + + async def test_process_advertisements_bail_on_good_advertisement( hass: HomeAssistant, mock_bleak_scanner_start, enable_bluetooth ): From bf88448ffda1a361be7d444c8c56c1d7b95ca7d6 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Mon, 15 Aug 2022 23:35:30 +0200 Subject: [PATCH 17/19] Correct referenced entities and devices for event triggers (#76818) --- .../components/automation/__init__.py | 8 +++-- tests/components/automation/test_init.py | 30 +++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/automation/__init__.py b/homeassistant/components/automation/__init__.py index c743e1f83fd..1914a837ba7 100644 --- a/homeassistant/components/automation/__init__.py +++ b/homeassistant/components/automation/__init__.py @@ -36,6 +36,7 @@ from homeassistant.core import ( HomeAssistant, callback, split_entity_id, + valid_entity_id, ) from homeassistant.exceptions import ( ConditionError, @@ -361,7 +362,7 @@ class AutomationEntity(ToggleEntity, RestoreEntity): referenced |= condition.async_extract_devices(conf) for conf in self._trigger_config: - referenced |= set(_trigger_extract_device(conf)) + referenced |= set(_trigger_extract_devices(conf)) self._referenced_devices = referenced return referenced @@ -763,7 +764,7 @@ async def _async_process_if(hass, name, config, p_config): @callback -def _trigger_extract_device(trigger_conf: dict) -> list[str]: +def _trigger_extract_devices(trigger_conf: dict) -> list[str]: """Extract devices from a trigger config.""" if trigger_conf[CONF_PLATFORM] == "device": return [trigger_conf[CONF_DEVICE_ID]] @@ -772,6 +773,7 @@ def _trigger_extract_device(trigger_conf: dict) -> list[str]: trigger_conf[CONF_PLATFORM] == "event" and CONF_EVENT_DATA in trigger_conf and CONF_DEVICE_ID in trigger_conf[CONF_EVENT_DATA] + and isinstance(trigger_conf[CONF_EVENT_DATA][CONF_DEVICE_ID], str) ): return [trigger_conf[CONF_EVENT_DATA][CONF_DEVICE_ID]] @@ -803,6 +805,8 @@ def _trigger_extract_entities(trigger_conf: dict) -> list[str]: trigger_conf[CONF_PLATFORM] == "event" and CONF_EVENT_DATA in trigger_conf and CONF_ENTITY_ID in trigger_conf[CONF_EVENT_DATA] + and isinstance(trigger_conf[CONF_EVENT_DATA][CONF_ENTITY_ID], str) + and valid_entity_id(trigger_conf[CONF_EVENT_DATA][CONF_ENTITY_ID]) ): return [trigger_conf[CONF_EVENT_DATA][CONF_ENTITY_ID]] diff --git a/tests/components/automation/test_init.py b/tests/components/automation/test_init.py index bcbcf382892..cef553653de 100644 --- a/tests/components/automation/test_init.py +++ b/tests/components/automation/test_init.py @@ -1103,6 +1103,24 @@ async def test_extraction_functions(hass): "event_type": "state_changed", "event_data": {"entity_id": "sensor.trigger_event"}, }, + # entity_id is a list of strings (not supported) + { + "platform": "event", + "event_type": "state_changed", + "event_data": {"entity_id": ["sensor.trigger_event2"]}, + }, + # entity_id is not a valid entity ID + { + "platform": "event", + "event_type": "state_changed", + "event_data": {"entity_id": "abc"}, + }, + # entity_id is not a string + { + "platform": "event", + "event_type": "state_changed", + "event_data": {"entity_id": 123}, + }, ], "condition": { "condition": "state", @@ -1151,6 +1169,18 @@ async def test_extraction_functions(hass): "event_type": "esphome.button_pressed", "event_data": {"device_id": "device-trigger-event"}, }, + # device_id is a list of strings (not supported) + { + "platform": "event", + "event_type": "esphome.button_pressed", + "event_data": {"device_id": ["device-trigger-event"]}, + }, + # device_id is not a string + { + "platform": "event", + "event_type": "esphome.button_pressed", + "event_data": {"device_id": 123}, + }, ], "condition": { "condition": "device", From f4a09455c0b9291f5c214755a52c1b7b0d4bcf1c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 15 Aug 2022 15:09:13 -1000 Subject: [PATCH 18/19] Fix lifx homekit discoveries not being ignorable or updating the IP (#76825) --- homeassistant/components/lifx/config_flow.py | 10 +++--- tests/components/lifx/test_config_flow.py | 33 +++++++++++++++----- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/homeassistant/components/lifx/config_flow.py b/homeassistant/components/lifx/config_flow.py index 30b42e640f8..deff53e06c6 100644 --- a/homeassistant/components/lifx/config_flow.py +++ b/homeassistant/components/lifx/config_flow.py @@ -119,18 +119,20 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): ) -> FlowResult: """Confirm discovery.""" assert self._discovered_device is not None + discovered = self._discovered_device _LOGGER.debug( "Confirming discovery: %s with serial %s", - self._discovered_device.label, + discovered.label, self.unique_id, ) if user_input is not None or self._async_discovered_pending_migration(): - return self._async_create_entry_from_device(self._discovered_device) + return self._async_create_entry_from_device(discovered) + self._abort_if_unique_id_configured(updates={CONF_HOST: discovered.ip_addr}) self._set_confirm_only() placeholders = { - "label": self._discovered_device.label, - "host": self._discovered_device.ip_addr, + "label": discovered.label, + "host": discovered.ip_addr, "serial": self.unique_id, } self.context["title_placeholders"] = placeholders diff --git a/tests/components/lifx/test_config_flow.py b/tests/components/lifx/test_config_flow.py index f007e9ee0e8..05bf29f43e5 100644 --- a/tests/components/lifx/test_config_flow.py +++ b/tests/components/lifx/test_config_flow.py @@ -466,21 +466,38 @@ async def test_discovered_by_dhcp_or_discovery_failed_to_get_device(hass, source assert result["reason"] == "cannot_connect" -async def test_discovered_by_dhcp_updates_ip(hass): +@pytest.mark.parametrize( + "source, data", + [ + ( + config_entries.SOURCE_DHCP, + dhcp.DhcpServiceInfo(ip=IP_ADDRESS, macaddress=MAC_ADDRESS, hostname=LABEL), + ), + ( + config_entries.SOURCE_HOMEKIT, + zeroconf.ZeroconfServiceInfo( + host=IP_ADDRESS, + addresses=[IP_ADDRESS], + hostname=LABEL, + name=LABEL, + port=None, + properties={zeroconf.ATTR_PROPERTIES_ID: "any"}, + type="mock_type", + ), + ), + ], +) +async def test_discovered_by_dhcp_or_homekit_updates_ip(hass, source, data): """Update host from dhcp.""" config_entry = MockConfigEntry( domain=DOMAIN, data={CONF_HOST: "127.0.0.2"}, unique_id=SERIAL ) config_entry.add_to_hass(hass) - with _patch_discovery(no_device=True), _patch_config_flow_try_connect( - no_device=True - ): + with _patch_discovery(), _patch_config_flow_try_connect(): result = await hass.config_entries.flow.async_init( DOMAIN, - context={"source": config_entries.SOURCE_DHCP}, - data=dhcp.DhcpServiceInfo( - ip=IP_ADDRESS, macaddress=MAC_ADDRESS, hostname=LABEL - ), + context={"source": source}, + data=data, ) await hass.async_block_till_done() assert result["type"] == RESULT_TYPE_ABORT From ec4ff824ada9a4a376449033757583a43c83c2ee Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 15 Aug 2022 21:09:58 -0400 Subject: [PATCH 19/19] Bumped version to 2022.8.5 --- homeassistant/const.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index e79c132519d..329c0e483dd 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -7,7 +7,7 @@ from .backports.enum import StrEnum MAJOR_VERSION: Final = 2022 MINOR_VERSION: Final = 8 -PATCH_VERSION: Final = "4" +PATCH_VERSION: Final = "5" __short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__: Final = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 9, 0) diff --git a/pyproject.toml b/pyproject.toml index 6c6b88feb4a..b42b0b91b58 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "homeassistant" -version = "2022.8.4" +version = "2022.8.5" license = {text = "Apache-2.0"} description = "Open-source home automation platform running on Python 3." readme = "README.rst"