From e2c1a38d87a729e1933ab9acfe5881f17145f280 Mon Sep 17 00:00:00 2001 From: Daniel Rozycki Date: Sun, 18 Aug 2024 05:24:44 -0700 Subject: [PATCH 01/36] Skip NextBus update if integration is still loading (#123564) * Skip NextBus update if integration is still loading Fixes a race between the loading thread and update thread leading to an unrecoverable error * Use async_at_started * Use local copy of _route_stops to avoid NextBus race condition * Update homeassistant/components/nextbus/coordinator.py --------- Co-authored-by: Joost Lekkerkerker --- homeassistant/components/nextbus/coordinator.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/nextbus/coordinator.py b/homeassistant/components/nextbus/coordinator.py index 6c438f6f8080..781742e4c08a 100644 --- a/homeassistant/components/nextbus/coordinator.py +++ b/homeassistant/components/nextbus/coordinator.py @@ -50,13 +50,15 @@ class NextBusDataUpdateCoordinator(DataUpdateCoordinator): async def _async_update_data(self) -> dict[str, Any]: """Fetch data from NextBus.""" - self.logger.debug("Updating data from API. Routes: %s", str(self._route_stops)) + + _route_stops = set(self._route_stops) + self.logger.debug("Updating data from API. Routes: %s", str(_route_stops)) def _update_data() -> dict: """Fetch data from NextBus.""" self.logger.debug("Updating data from API (executor)") predictions: dict[RouteStop, dict[str, Any]] = {} - for route_stop in self._route_stops: + for route_stop in _route_stops: prediction_results: list[dict[str, Any]] = [] try: prediction_results = self.client.predictions_for_stop( From dc967e2ef2a3283fc5da80e92ae92bc635ce35cc Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 12 Aug 2024 15:40:35 -0500 Subject: [PATCH 02/36] Bump yalexs to 6.5.0 (#123739) --- homeassistant/components/august/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/august/manifest.json b/homeassistant/components/august/manifest.json index 293c94c96299..5a911eee5e50 100644 --- a/homeassistant/components/august/manifest.json +++ b/homeassistant/components/august/manifest.json @@ -28,5 +28,5 @@ "documentation": "https://www.home-assistant.io/integrations/august", "iot_class": "cloud_push", "loggers": ["pubnub", "yalexs"], - "requirements": ["yalexs==6.4.3", "yalexs-ble==2.4.3"] + "requirements": ["yalexs==6.5.0", "yalexs-ble==2.4.3"] } diff --git a/requirements_all.txt b/requirements_all.txt index 735997d32086..43ca454e28eb 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2959,7 +2959,7 @@ yalesmartalarmclient==0.3.9 yalexs-ble==2.4.3 # homeassistant.components.august -yalexs==6.4.3 +yalexs==6.5.0 # homeassistant.components.yeelight yeelight==0.7.14 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 757f8ccf4051..897c1ddd1fe1 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -2336,7 +2336,7 @@ yalesmartalarmclient==0.3.9 yalexs-ble==2.4.3 # homeassistant.components.august -yalexs==6.4.3 +yalexs==6.5.0 # homeassistant.components.yeelight yeelight==0.7.14 From 80df582ebdd40ad4a67461c9dded654a5290dfa3 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 13 Aug 2024 14:06:38 -0500 Subject: [PATCH 03/36] Bump yalexs to 8.0.2 (#123817) --- homeassistant/components/august/config_flow.py | 2 +- homeassistant/components/august/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/august/mocks.py | 2 +- tests/components/august/test_config_flow.py | 2 +- tests/components/august/test_gateway.py | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/august/config_flow.py b/homeassistant/components/august/config_flow.py index 18c15ad61a18..3523a4f7c392 100644 --- a/homeassistant/components/august/config_flow.py +++ b/homeassistant/components/august/config_flow.py @@ -8,7 +8,7 @@ from typing import Any import aiohttp import voluptuous as vol -from yalexs.authenticator import ValidationResult +from yalexs.authenticator_common import ValidationResult from yalexs.const import BRANDS, DEFAULT_BRAND from yalexs.manager.exceptions import CannotConnect, InvalidAuth, RequireValidation diff --git a/homeassistant/components/august/manifest.json b/homeassistant/components/august/manifest.json index 5a911eee5e50..13035d68dfec 100644 --- a/homeassistant/components/august/manifest.json +++ b/homeassistant/components/august/manifest.json @@ -28,5 +28,5 @@ "documentation": "https://www.home-assistant.io/integrations/august", "iot_class": "cloud_push", "loggers": ["pubnub", "yalexs"], - "requirements": ["yalexs==6.5.0", "yalexs-ble==2.4.3"] + "requirements": ["yalexs==8.0.2", "yalexs-ble==2.4.3"] } diff --git a/requirements_all.txt b/requirements_all.txt index 43ca454e28eb..367170f8706d 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2959,7 +2959,7 @@ yalesmartalarmclient==0.3.9 yalexs-ble==2.4.3 # homeassistant.components.august -yalexs==6.5.0 +yalexs==8.0.2 # homeassistant.components.yeelight yeelight==0.7.14 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 897c1ddd1fe1..837ec134197e 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -2336,7 +2336,7 @@ yalesmartalarmclient==0.3.9 yalexs-ble==2.4.3 # homeassistant.components.august -yalexs==6.5.0 +yalexs==8.0.2 # homeassistant.components.yeelight yeelight==0.7.14 diff --git a/tests/components/august/mocks.py b/tests/components/august/mocks.py index 30be50e75c9d..a0f5b55a6071 100644 --- a/tests/components/august/mocks.py +++ b/tests/components/august/mocks.py @@ -25,7 +25,7 @@ from yalexs.activity import ( DoorOperationActivity, LockOperationActivity, ) -from yalexs.authenticator import AuthenticationState +from yalexs.authenticator_common import AuthenticationState from yalexs.const import Brand from yalexs.doorbell import Doorbell, DoorbellDetail from yalexs.lock import Lock, LockDetail diff --git a/tests/components/august/test_config_flow.py b/tests/components/august/test_config_flow.py index aec08864c650..fdebb8d5c463 100644 --- a/tests/components/august/test_config_flow.py +++ b/tests/components/august/test_config_flow.py @@ -2,7 +2,7 @@ from unittest.mock import patch -from yalexs.authenticator import ValidationResult +from yalexs.authenticator_common import ValidationResult from yalexs.manager.exceptions import CannotConnect, InvalidAuth, RequireValidation from homeassistant import config_entries diff --git a/tests/components/august/test_gateway.py b/tests/components/august/test_gateway.py index e605fd74f0a3..74266397ed53 100644 --- a/tests/components/august/test_gateway.py +++ b/tests/components/august/test_gateway.py @@ -50,5 +50,5 @@ async def _patched_refresh_access_token( ) await august_gateway.async_refresh_access_token_if_needed() refresh_access_token_mock.assert_called() - assert august_gateway.access_token == new_token + assert await august_gateway.async_get_access_token() == new_token assert august_gateway.authentication.access_token_expires == new_token_expire_time From 3484ab3c0cbb510816cf797807ce6031204e8edb Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 19 Aug 2024 19:13:35 -0500 Subject: [PATCH 04/36] Bump aioshelly to 11.2.4 (#124080) --- homeassistant/components/shelly/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/shelly/manifest.json b/homeassistant/components/shelly/manifest.json index c742b45632cc..da3bbc4bb6ed 100644 --- a/homeassistant/components/shelly/manifest.json +++ b/homeassistant/components/shelly/manifest.json @@ -9,7 +9,7 @@ "iot_class": "local_push", "loggers": ["aioshelly"], "quality_scale": "platinum", - "requirements": ["aioshelly==11.2.0"], + "requirements": ["aioshelly==11.2.4"], "zeroconf": [ { "type": "_http._tcp.local.", diff --git a/requirements_all.txt b/requirements_all.txt index 367170f8706d..664e56695c4d 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -359,7 +359,7 @@ aioruuvigateway==0.1.0 aiosenz==1.0.0 # homeassistant.components.shelly -aioshelly==11.2.0 +aioshelly==11.2.4 # homeassistant.components.skybell aioskybell==22.7.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 837ec134197e..f2e82dc9baea 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -341,7 +341,7 @@ aioruuvigateway==0.1.0 aiosenz==1.0.0 # homeassistant.components.shelly -aioshelly==11.2.0 +aioshelly==11.2.4 # homeassistant.components.skybell aioskybell==22.7.0 From d1f09ecd0c0214e4292b964cd50ae30015351984 Mon Sep 17 00:00:00 2001 From: cdnninja Date: Sun, 18 Aug 2024 07:36:03 -0600 Subject: [PATCH 05/36] Add Alt Core300s model to vesync integration (#124091) --- homeassistant/components/vesync/const.py | 1 + 1 file changed, 1 insertion(+) diff --git a/homeassistant/components/vesync/const.py b/homeassistant/components/vesync/const.py index 483ab89b02e0..54fc21d2659a 100644 --- a/homeassistant/components/vesync/const.py +++ b/homeassistant/components/vesync/const.py @@ -40,6 +40,7 @@ SKU_TO_BASE_DEVICE = { "LAP-C202S-WUSR": "Core200S", # Alt ID Model Core200S "Core300S": "Core300S", "LAP-C301S-WJP": "Core300S", # Alt ID Model Core300S + "LAP-C301S-WAAA": "Core300S", # Alt ID Model Core300S "Core400S": "Core400S", "LAP-C401S-WJP": "Core400S", # Alt ID Model Core400S "LAP-C401S-WUSR": "Core400S", # Alt ID Model Core400S From 0fcdc3c200c8231fb24ecd0f5cf9e097f93d6ceb Mon Sep 17 00:00:00 2001 From: Artem Draft Date: Sat, 17 Aug 2024 17:30:26 +0300 Subject: [PATCH 06/36] Bump pybravia to 0.3.4 (#124113) --- homeassistant/components/braviatv/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/braviatv/manifest.json b/homeassistant/components/braviatv/manifest.json index 5a0a9def0ae7..a445a34cfcd2 100644 --- a/homeassistant/components/braviatv/manifest.json +++ b/homeassistant/components/braviatv/manifest.json @@ -7,7 +7,7 @@ "integration_type": "device", "iot_class": "local_polling", "loggers": ["pybravia"], - "requirements": ["pybravia==0.3.3"], + "requirements": ["pybravia==0.3.4"], "ssdp": [ { "st": "urn:schemas-sony-com:service:ScalarWebAPI:1", diff --git a/requirements_all.txt b/requirements_all.txt index 664e56695c4d..64a531b31564 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1759,7 +1759,7 @@ pyblu==0.4.0 pybotvac==0.0.25 # homeassistant.components.braviatv -pybravia==0.3.3 +pybravia==0.3.4 # homeassistant.components.nissan_leaf pycarwings2==2.14 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index f2e82dc9baea..85c211978f9c 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1421,7 +1421,7 @@ pyblu==0.4.0 pybotvac==0.0.25 # homeassistant.components.braviatv -pybravia==0.3.3 +pybravia==0.3.4 # homeassistant.components.cloudflare pycfdns==3.0.0 From 157a61845b70793a8278818a8e5a7e1bebe66308 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 17 Aug 2024 10:32:58 -0500 Subject: [PATCH 07/36] Bump aiohomekit to 3.2.3 (#124115) --- 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 007153aceafa..b2b215a98b9a 100644 --- a/homeassistant/components/homekit_controller/manifest.json +++ b/homeassistant/components/homekit_controller/manifest.json @@ -14,6 +14,6 @@ "documentation": "https://www.home-assistant.io/integrations/homekit_controller", "iot_class": "local_push", "loggers": ["aiohomekit", "commentjson"], - "requirements": ["aiohomekit==3.2.2"], + "requirements": ["aiohomekit==3.2.3"], "zeroconf": ["_hap._tcp.local.", "_hap._udp.local."] } diff --git a/requirements_all.txt b/requirements_all.txt index 64a531b31564..a88075818c19 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -255,7 +255,7 @@ aioguardian==2022.07.0 aioharmony==0.2.10 # homeassistant.components.homekit_controller -aiohomekit==3.2.2 +aiohomekit==3.2.3 # homeassistant.components.hue aiohue==4.7.2 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 85c211978f9c..fadcabbb82cf 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -240,7 +240,7 @@ aioguardian==2022.07.0 aioharmony==0.2.10 # homeassistant.components.homekit_controller -aiohomekit==3.2.2 +aiohomekit==3.2.3 # homeassistant.components.hue aiohue==4.7.2 From f89e8e6ceb3c92e3acb0ebeb2fe86c7a5c0d82d1 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Sat, 17 Aug 2024 12:11:19 -0700 Subject: [PATCH 08/36] Bump nest to 4.0.7 to increase subscriber deadline (#124131) Bump nest to 4.0.7 --- homeassistant/components/nest/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/nest/manifest.json b/homeassistant/components/nest/manifest.json index fbe5ddb65346..3472fa64e8fc 100644 --- a/homeassistant/components/nest/manifest.json +++ b/homeassistant/components/nest/manifest.json @@ -20,5 +20,5 @@ "iot_class": "cloud_push", "loggers": ["google_nest_sdm"], "quality_scale": "platinum", - "requirements": ["google-nest-sdm==4.0.6"] + "requirements": ["google-nest-sdm==4.0.7"] } diff --git a/requirements_all.txt b/requirements_all.txt index a88075818c19..84e2baa39ae4 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -989,7 +989,7 @@ google-cloud-texttospeech==2.16.3 google-generativeai==0.6.0 # homeassistant.components.nest -google-nest-sdm==4.0.6 +google-nest-sdm==4.0.7 # homeassistant.components.google_travel_time googlemaps==2.5.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index fadcabbb82cf..ed59051cf3f0 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -833,7 +833,7 @@ google-cloud-pubsub==2.13.11 google-generativeai==0.6.0 # homeassistant.components.nest -google-nest-sdm==4.0.6 +google-nest-sdm==4.0.7 # homeassistant.components.google_travel_time googlemaps==2.5.1 From 22bb3e5477ff49ef2f95491325308dcbc23237ae Mon Sep 17 00:00:00 2001 From: MarkGodwin <10632972+MarkGodwin@users.noreply.github.com> Date: Sun, 18 Aug 2024 13:23:47 +0100 Subject: [PATCH 09/36] Bump tplink-omada-api to 1.4.2 (#124136) Fix for bad pre-registered clients --- homeassistant/components/tplink_omada/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/tplink_omada/manifest.json b/homeassistant/components/tplink_omada/manifest.json index 9544470d7a9f..6bde656dc302 100644 --- a/homeassistant/components/tplink_omada/manifest.json +++ b/homeassistant/components/tplink_omada/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/tplink_omada", "integration_type": "hub", "iot_class": "local_polling", - "requirements": ["tplink-omada-client==1.3.12"] + "requirements": ["tplink-omada-client==1.4.2"] } diff --git a/requirements_all.txt b/requirements_all.txt index 84e2baa39ae4..1d7c14235e23 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2792,7 +2792,7 @@ total-connect-client==2024.5 tp-connected==0.0.4 # homeassistant.components.tplink_omada -tplink-omada-client==1.3.12 +tplink-omada-client==1.4.2 # homeassistant.components.transmission transmission-rpc==7.0.3 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index ed59051cf3f0..5fd713da9cb7 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -2190,7 +2190,7 @@ toonapi==0.3.0 total-connect-client==2024.5 # homeassistant.components.tplink_omada -tplink-omada-client==1.3.12 +tplink-omada-client==1.4.2 # homeassistant.components.transmission transmission-rpc==7.0.3 From e80dc521759ae0ad74956ad30443309d241885e8 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 18 Aug 2024 08:39:56 -0500 Subject: [PATCH 10/36] Bump aiohttp to 3.10.4 (#124137) changelog: https://github.com/aio-libs/aiohttp/compare/v3.10.3...v3.10.4 --- homeassistant/package_constraints.txt | 2 +- pyproject.toml | 2 +- requirements.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index e87307e13d28..1d909111657d 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -4,7 +4,7 @@ aiodhcpwatcher==1.0.2 aiodiscover==2.1.0 aiodns==3.2.0 aiohttp-fast-zlib==0.1.1 -aiohttp==3.10.3 +aiohttp==3.10.4 aiohttp_cors==0.7.0 aiozoneinfo==0.2.1 astral==2.2 diff --git a/pyproject.toml b/pyproject.toml index 9bc294b2d0fb..4df72b9b47ff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,7 +24,7 @@ classifiers = [ requires-python = ">=3.12.0" dependencies = [ "aiodns==3.2.0", - "aiohttp==3.10.3", + "aiohttp==3.10.4", "aiohttp_cors==0.7.0", "aiohttp-fast-zlib==0.1.1", "aiozoneinfo==0.2.1", diff --git a/requirements.txt b/requirements.txt index 7a4b0bd6d099..39801bdeb919 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ # Home Assistant Core aiodns==3.2.0 -aiohttp==3.10.3 +aiohttp==3.10.4 aiohttp_cors==0.7.0 aiohttp-fast-zlib==0.1.1 aiozoneinfo==0.2.1 From 45b44f8a592f70db87a45c6abeac137b6836e2e9 Mon Sep 17 00:00:00 2001 From: Christopher Maio Date: Sun, 25 Aug 2024 09:05:13 -0400 Subject: [PATCH 11/36] Update Matter light transition blocklist to include GE Cync Undercabinet Lights (#124138) --- homeassistant/components/matter/light.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/homeassistant/components/matter/light.py b/homeassistant/components/matter/light.py index 6e9019c46fa8..58ef8081fa9a 100644 --- a/homeassistant/components/matter/light.py +++ b/homeassistant/components/matter/light.py @@ -60,6 +60,8 @@ TRANSITION_BLOCKLIST = ( (4456, 1011, "1.0.0", "2.00.00"), (4488, 260, "1.0", "1.0.0"), (4488, 514, "1.0", "1.0.0"), + (4921, 42, "1.0", "1.01.060"), + (4921, 43, "1.0", "1.01.060"), (4999, 24875, "1.0", "27.0"), (4999, 25057, "1.0", "27.0"), (5009, 514, "1.0", "1.0.0"), From 129035967b9563089690d542799edb26c1d87e3a Mon Sep 17 00:00:00 2001 From: Shay Levy Date: Sun, 18 Aug 2024 18:35:02 +0300 Subject: [PATCH 12/36] Shelly RPC - do not stop BLE scanner if a sleeping device (#124147) --- .../components/shelly/coordinator.py | 3 ++- tests/components/shelly/test_coordinator.py | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/shelly/coordinator.py b/homeassistant/components/shelly/coordinator.py index 50140e1890d8..2710565f9601 100644 --- a/homeassistant/components/shelly/coordinator.py +++ b/homeassistant/components/shelly/coordinator.py @@ -711,7 +711,8 @@ class ShellyRpcCoordinator(ShellyCoordinatorBase[RpcDevice]): """Shutdown the coordinator.""" if self.device.connected: try: - await async_stop_scanner(self.device) + if not self.sleep_period: + await async_stop_scanner(self.device) await super().shutdown() except InvalidAuthError: self.entry.async_start_reauth(self.hass) diff --git a/tests/components/shelly/test_coordinator.py b/tests/components/shelly/test_coordinator.py index d3494c094f98..1140c93775b1 100644 --- a/tests/components/shelly/test_coordinator.py +++ b/tests/components/shelly/test_coordinator.py @@ -854,6 +854,27 @@ async def test_rpc_runs_connected_events_when_initialized( assert call.script_list() in mock_rpc_device.mock_calls +async def test_rpc_sleeping_device_unload_ignore_ble_scanner( + hass: HomeAssistant, + mock_rpc_device: Mock, + monkeypatch: pytest.MonkeyPatch, +) -> None: + """Test RPC sleeping device does not stop ble scanner on unload.""" + monkeypatch.setattr(mock_rpc_device, "connected", True) + entry = await init_integration(hass, 2, sleep_period=1000) + + # Make device online + mock_rpc_device.mock_online() + await hass.async_block_till_done(wait_background_tasks=True) + + # Unload + await hass.config_entries.async_unload(entry.entry_id) + await hass.async_block_till_done() + + # BLE script list is called during stop ble scanner + assert call.script_list() not in mock_rpc_device.mock_calls + + async def test_block_sleeping_device_connection_error( hass: HomeAssistant, device_registry: dr.DeviceRegistry, From b7d8f3d005db033bb1f03aeebd7a24f0c0b5088d Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 22 Aug 2024 08:14:45 -0500 Subject: [PATCH 13/36] Fix shelly available check when device is not initialized (#124182) * Fix shelly available check when device is not initialized available needs to check for device.initialized or if the device is sleepy as calls to status will raise NotInitialized which results in many unretrieved exceptions while writing state fixes ``` 2024-08-18 09:33:03.757 ERROR (MainThread) [homeassistant] Error doing job: Task exception was never retrieved (None) Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 258, in _handle_refresh_interval await self._async_refresh(log_failures=True, scheduled=True) File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 453, in _async_refresh self.async_update_listeners() File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 168, in async_update_listeners update_callback() File "/config/custom_components/shelly/entity.py", line 374, in _update_callback self.async_write_ha_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1005, in async_write_ha_state self._async_write_ha_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1130, in _async_write_ha_state self.__async_calculate_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1067, in __async_calculate_state state = self._stringify_state(available) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1011, in _stringify_state if (state := self.state) is None: ^^^^^^^^^^ File "/usr/src/homeassistant/homeassistant/components/binary_sensor/__init__.py", line 293, in state if (is_on := self.is_on) is None: ^^^^^^^^^^ File "/config/custom_components/shelly/binary_sensor.py", line 331, in is_on return bool(self.attribute_value) ^^^^^^^^^^^^^^^^^^^^ File "/config/custom_components/shelly/entity.py", line 545, in attribute_value self._last_value = self.sub_status ^^^^^^^^^^^^^^^ File "/config/custom_components/shelly/entity.py", line 534, in sub_status return self.status[self.entity_description.sub_key] ^^^^^^^^^^^ File "/config/custom_components/shelly/entity.py", line 364, in status return cast(dict, self.coordinator.device.status[self.key]) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/site-packages/aioshelly/rpc_device/device.py", line 390, in status raise NotInitialized aioshelly.exceptions.NotInitialized ``` * tweak * cover * fix * cover * fixes --- .../components/shelly/coordinator.py | 3 ++ homeassistant/components/shelly/entity.py | 8 +++++ tests/components/shelly/test_sensor.py | 34 ++++++++++++++++++- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/shelly/coordinator.py b/homeassistant/components/shelly/coordinator.py index 2710565f9601..6286e5157271 100644 --- a/homeassistant/components/shelly/coordinator.py +++ b/homeassistant/components/shelly/coordinator.py @@ -682,6 +682,7 @@ class ShellyRpcCoordinator(ShellyCoordinatorBase[RpcDevice]): self.entry.async_create_background_task( self.hass, self._async_connected(), "rpc device init", eager_start=True ) + # Make sure entities are marked available self.async_set_updated_data(None) elif update_type is RpcUpdateType.DISCONNECTED: self.entry.async_create_background_task( @@ -690,6 +691,8 @@ class ShellyRpcCoordinator(ShellyCoordinatorBase[RpcDevice]): "rpc device disconnected", eager_start=True, ) + # Make sure entities are marked as unavailable + self.async_set_updated_data(None) elif update_type is RpcUpdateType.STATUS: self.async_set_updated_data(None) if self.sleep_period: diff --git a/homeassistant/components/shelly/entity.py b/homeassistant/components/shelly/entity.py index 5bf8a4113778..980a39feaba9 100644 --- a/homeassistant/components/shelly/entity.py +++ b/homeassistant/components/shelly/entity.py @@ -358,6 +358,14 @@ class ShellyRpcEntity(CoordinatorEntity[ShellyRpcCoordinator]): self._attr_unique_id = f"{coordinator.mac}-{key}" self._attr_name = get_rpc_entity_name(coordinator.device, key) + @property + def available(self) -> bool: + """Check if device is available and initialized or sleepy.""" + coordinator = self.coordinator + return super().available and ( + coordinator.device.initialized or bool(coordinator.sleep_period) + ) + @property def status(self) -> dict: """Device status by entity key.""" diff --git a/tests/components/shelly/test_sensor.py b/tests/components/shelly/test_sensor.py index a39123a6722a..2da82a5da875 100644 --- a/tests/components/shelly/test_sensor.py +++ b/tests/components/shelly/test_sensor.py @@ -43,7 +43,7 @@ from . import ( register_entity, ) -from tests.common import mock_restore_cache_with_extra_data +from tests.common import async_fire_time_changed, mock_restore_cache_with_extra_data RELAY_BLOCK_ID = 0 SENSOR_BLOCK_ID = 3 @@ -1189,3 +1189,35 @@ async def test_rpc_remove_enum_virtual_sensor_when_orphaned( entry = entity_registry.async_get(entity_id) assert not entry + + +async def test_rpc_device_sensor_goes_unavailable_on_disconnect( + hass: HomeAssistant, + mock_rpc_device: Mock, + monkeypatch: pytest.MonkeyPatch, + freezer: FrozenDateTimeFactory, + caplog: pytest.LogCaptureFixture, +) -> None: + """Test RPC device with sensor goes unavailable on disconnect.""" + await init_integration(hass, 2) + temp_sensor_state = hass.states.get("sensor.test_name_temperature") + assert temp_sensor_state is not None + assert temp_sensor_state.state != STATE_UNAVAILABLE + monkeypatch.setattr(mock_rpc_device, "connected", False) + monkeypatch.setattr(mock_rpc_device, "initialized", False) + mock_rpc_device.mock_disconnected() + await hass.async_block_till_done() + temp_sensor_state = hass.states.get("sensor.test_name_temperature") + assert temp_sensor_state.state == STATE_UNAVAILABLE + + freezer.tick(60) + async_fire_time_changed(hass) + await hass.async_block_till_done() + assert "NotInitialized" not in caplog.text + + monkeypatch.setattr(mock_rpc_device, "connected", True) + monkeypatch.setattr(mock_rpc_device, "initialized", True) + mock_rpc_device.mock_initialized() + await hass.async_block_till_done() + temp_sensor_state = hass.states.get("sensor.test_name_temperature") + assert temp_sensor_state.state != STATE_UNAVAILABLE From a857f603c82b21d745aa3de654d1a4da61085bc0 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Mon, 19 Aug 2024 10:20:58 +0200 Subject: [PATCH 14/36] Bump pyhomeworks to 1.1.2 (#124199) --- homeassistant/components/homeworks/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/homeworks/manifest.json b/homeassistant/components/homeworks/manifest.json index a399e0a98e72..011c301d00dc 100644 --- a/homeassistant/components/homeworks/manifest.json +++ b/homeassistant/components/homeworks/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/homeworks", "iot_class": "local_push", "loggers": ["pyhomeworks"], - "requirements": ["pyhomeworks==1.1.1"] + "requirements": ["pyhomeworks==1.1.2"] } diff --git a/requirements_all.txt b/requirements_all.txt index 1d7c14235e23..e65c4d4c0397 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1912,7 +1912,7 @@ pyhiveapi==0.5.16 pyhomematic==0.1.77 # homeassistant.components.homeworks -pyhomeworks==1.1.1 +pyhomeworks==1.1.2 # homeassistant.components.ialarm pyialarm==2.2.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 5fd713da9cb7..7cc3aabdf4ff 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1523,7 +1523,7 @@ pyhiveapi==0.5.16 pyhomematic==0.1.77 # homeassistant.components.homeworks -pyhomeworks==1.1.1 +pyhomeworks==1.1.2 # homeassistant.components.ialarm pyialarm==2.2.0 From 1f466702662e0b2bd541aaa06aa5464f28dab2b8 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 19 Aug 2024 15:40:32 -0500 Subject: [PATCH 15/36] Bump aiohttp to 3.10.5 (#124254) --- homeassistant/package_constraints.txt | 2 +- pyproject.toml | 2 +- requirements.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index 1d909111657d..432e213d2673 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -4,7 +4,7 @@ aiodhcpwatcher==1.0.2 aiodiscover==2.1.0 aiodns==3.2.0 aiohttp-fast-zlib==0.1.1 -aiohttp==3.10.4 +aiohttp==3.10.5 aiohttp_cors==0.7.0 aiozoneinfo==0.2.1 astral==2.2 diff --git a/pyproject.toml b/pyproject.toml index 4df72b9b47ff..c2b167bbbd71 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,7 +24,7 @@ classifiers = [ requires-python = ">=3.12.0" dependencies = [ "aiodns==3.2.0", - "aiohttp==3.10.4", + "aiohttp==3.10.5", "aiohttp_cors==0.7.0", "aiohttp-fast-zlib==0.1.1", "aiozoneinfo==0.2.1", diff --git a/requirements.txt b/requirements.txt index 39801bdeb919..9af81e775eee 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ # Home Assistant Core aiodns==3.2.0 -aiohttp==3.10.4 +aiohttp==3.10.5 aiohttp_cors==0.7.0 aiohttp-fast-zlib==0.1.1 aiozoneinfo==0.2.1 From 524e09b45eb1f63f5e9b9282724645eff04fd864 Mon Sep 17 00:00:00 2001 From: Matthias Alphart Date: Sat, 24 Aug 2024 06:48:02 +0200 Subject: [PATCH 16/36] Update xknx to 3.1.1 (#124257) --- 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 9ecf687d6b9d..b7efd14fa2a2 100644 --- a/homeassistant/components/knx/manifest.json +++ b/homeassistant/components/knx/manifest.json @@ -11,7 +11,7 @@ "loggers": ["xknx", "xknxproject"], "quality_scale": "platinum", "requirements": [ - "xknx==3.1.0", + "xknx==3.1.1", "xknxproject==3.7.1", "knx-frontend==2024.8.9.225351" ], diff --git a/requirements_all.txt b/requirements_all.txt index e65c4d4c0397..f260f2eed36e 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2936,7 +2936,7 @@ xbox-webapi==2.0.11 xiaomi-ble==0.30.2 # homeassistant.components.knx -xknx==3.1.0 +xknx==3.1.1 # homeassistant.components.knx xknxproject==3.7.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 7cc3aabdf4ff..94d224d5e622 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -2316,7 +2316,7 @@ xbox-webapi==2.0.11 xiaomi-ble==0.30.2 # homeassistant.components.knx -xknx==3.1.0 +xknx==3.1.1 # homeassistant.components.knx xknxproject==3.7.1 From 5a73b636e35e551fcfef089b96818c8a9040c344 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Tue, 20 Aug 2024 00:51:44 -0700 Subject: [PATCH 17/36] Bump python-roborock to 2.6.0 (#124268) --- homeassistant/components/roborock/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/roborock/manifest.json b/homeassistant/components/roborock/manifest.json index 7a80a9083e94..3bb3b9b2046f 100644 --- a/homeassistant/components/roborock/manifest.json +++ b/homeassistant/components/roborock/manifest.json @@ -7,7 +7,7 @@ "iot_class": "local_polling", "loggers": ["roborock"], "requirements": [ - "python-roborock==2.5.0", + "python-roborock==2.6.0", "vacuum-map-parser-roborock==0.1.2" ] } diff --git a/requirements_all.txt b/requirements_all.txt index f260f2eed36e..2cf52a82ac5c 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2341,7 +2341,7 @@ python-rabbitair==0.0.8 python-ripple-api==0.0.3 # homeassistant.components.roborock -python-roborock==2.5.0 +python-roborock==2.6.0 # homeassistant.components.smarttub python-smarttub==0.0.36 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 94d224d5e622..eebb7d7c1335 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1850,7 +1850,7 @@ python-picnic-api==1.1.0 python-rabbitair==0.0.8 # homeassistant.components.roborock -python-roborock==2.5.0 +python-roborock==2.6.0 # homeassistant.components.smarttub python-smarttub==0.0.36 From 5a8045d1fbad645e26992b19d4018b9b2eaee48f Mon Sep 17 00:00:00 2001 From: Marcel van der Veldt Date: Sun, 25 Aug 2024 15:06:16 +0200 Subject: [PATCH 18/36] Prevent KeyError when Matter device sends invalid value for StartUpOnOff (#124280) --- homeassistant/components/matter/select.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/matter/select.py b/homeassistant/components/matter/select.py index 4a9ef3780d1c..b46cad53123f 100644 --- a/homeassistant/components/matter/select.py +++ b/homeassistant/components/matter/select.py @@ -229,12 +229,12 @@ DISCOVERY_SCHEMAS = [ entity_category=EntityCategory.CONFIG, translation_key="startup_on_off", options=["On", "Off", "Toggle", "Previous"], - measurement_to_ha=lambda x: { + measurement_to_ha=lambda x: { # pylint: disable=unnecessary-lambda 0: "Off", 1: "On", 2: "Toggle", None: "Previous", - }[x], + }.get(x), ha_to_native_value=lambda x: { "Off": 0, "On": 1, From 769c7f1ea35ed14944f1f1974c9efbfdfc0fc522 Mon Sep 17 00:00:00 2001 From: Joost Lekkerkerker Date: Sat, 24 Aug 2024 07:20:00 +0200 Subject: [PATCH 19/36] Don't abort airgradient user flow if flow in progress (#124300) --- .../components/airgradient/config_flow.py | 4 ++- .../airgradient/test_config_flow.py | 29 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/airgradient/config_flow.py b/homeassistant/components/airgradient/config_flow.py index 93cd0be61c45..70fa8a1755bf 100644 --- a/homeassistant/components/airgradient/config_flow.py +++ b/homeassistant/components/airgradient/config_flow.py @@ -92,7 +92,9 @@ class AirGradientConfigFlow(ConfigFlow, domain=DOMAIN): except AirGradientError: errors["base"] = "cannot_connect" else: - await self.async_set_unique_id(current_measures.serial_number) + await self.async_set_unique_id( + current_measures.serial_number, raise_on_progress=False + ) self._abort_if_unique_id_configured() await self.set_configuration_source() return self.async_create_entry( diff --git a/tests/components/airgradient/test_config_flow.py b/tests/components/airgradient/test_config_flow.py index 222ac5d04af1..8730b18676fd 100644 --- a/tests/components/airgradient/test_config_flow.py +++ b/tests/components/airgradient/test_config_flow.py @@ -253,3 +253,32 @@ async def test_zeroconf_flow_abort_old_firmware(hass: HomeAssistant) -> None: ) assert result["type"] is FlowResultType.ABORT assert result["reason"] == "invalid_version" + + +async def test_user_flow_works_discovery( + hass: HomeAssistant, + mock_new_airgradient_client: AsyncMock, + mock_setup_entry: AsyncMock, +) -> None: + """Test user flow can continue after discovery happened.""" + await hass.config_entries.flow.async_init( + DOMAIN, + context={"source": SOURCE_ZEROCONF}, + data=ZEROCONF_DISCOVERY, + ) + result = await hass.config_entries.flow.async_init( + DOMAIN, + context={"source": SOURCE_USER}, + ) + assert len(hass.config_entries.flow.async_progress(DOMAIN)) == 2 + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "user" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + {CONF_HOST: "10.0.0.131"}, + ) + assert result["type"] is FlowResultType.CREATE_ENTRY + + # Verify the discovery flow was aborted + assert not hass.config_entries.flow.async_progress(DOMAIN) From 70a58a0bb00ee0fa61f28dcf3c3a7b3e3fe7a7e4 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 20 Aug 2024 11:38:29 -0500 Subject: [PATCH 20/36] Bump yalexs to 8.1.2 (#124303) --- homeassistant/components/august/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/august/manifest.json b/homeassistant/components/august/manifest.json index 13035d68dfec..5d7b253e9525 100644 --- a/homeassistant/components/august/manifest.json +++ b/homeassistant/components/august/manifest.json @@ -28,5 +28,5 @@ "documentation": "https://www.home-assistant.io/integrations/august", "iot_class": "cloud_push", "loggers": ["pubnub", "yalexs"], - "requirements": ["yalexs==8.0.2", "yalexs-ble==2.4.3"] + "requirements": ["yalexs==8.1.2", "yalexs-ble==2.4.3"] } diff --git a/requirements_all.txt b/requirements_all.txt index 2cf52a82ac5c..a09e7820a83c 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2959,7 +2959,7 @@ yalesmartalarmclient==0.3.9 yalexs-ble==2.4.3 # homeassistant.components.august -yalexs==8.0.2 +yalexs==8.1.2 # homeassistant.components.yeelight yeelight==0.7.14 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index eebb7d7c1335..943a69901f79 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -2336,7 +2336,7 @@ yalesmartalarmclient==0.3.9 yalexs-ble==2.4.3 # homeassistant.components.august -yalexs==8.0.2 +yalexs==8.1.2 # homeassistant.components.yeelight yeelight==0.7.14 From 236fa8e2384031cb24ce20991632484597426a8b Mon Sep 17 00:00:00 2001 From: G Johansson Date: Sun, 18 Aug 2024 20:05:41 +0200 Subject: [PATCH 21/36] Bump python-holidays to 0.54 (#124170) --- homeassistant/components/holiday/manifest.json | 2 +- homeassistant/components/workday/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/holiday/manifest.json b/homeassistant/components/holiday/manifest.json index ebe472d7f0ef..0a714815ae3e 100644 --- a/homeassistant/components/holiday/manifest.json +++ b/homeassistant/components/holiday/manifest.json @@ -5,5 +5,5 @@ "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/holiday", "iot_class": "local_polling", - "requirements": ["holidays==0.53", "babel==2.15.0"] + "requirements": ["holidays==0.54", "babel==2.15.0"] } diff --git a/homeassistant/components/workday/manifest.json b/homeassistant/components/workday/manifest.json index 69df8080fa5b..133c82454bc7 100644 --- a/homeassistant/components/workday/manifest.json +++ b/homeassistant/components/workday/manifest.json @@ -7,5 +7,5 @@ "iot_class": "local_polling", "loggers": ["holidays"], "quality_scale": "internal", - "requirements": ["holidays==0.53"] + "requirements": ["holidays==0.54"] } diff --git a/requirements_all.txt b/requirements_all.txt index a09e7820a83c..db41a5ed5a06 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1096,7 +1096,7 @@ hole==0.8.0 # homeassistant.components.holiday # homeassistant.components.workday -holidays==0.53 +holidays==0.54 # homeassistant.components.frontend home-assistant-frontend==20240809.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 943a69901f79..b62084a586d2 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -916,7 +916,7 @@ hole==0.8.0 # homeassistant.components.holiday # homeassistant.components.workday -holidays==0.53 +holidays==0.54 # homeassistant.components.frontend home-assistant-frontend==20240809.0 From e5a64a1e0a1d107dcf1da2b3bdf0142c29dfae44 Mon Sep 17 00:00:00 2001 From: G Johansson Date: Thu, 22 Aug 2024 07:59:21 +0200 Subject: [PATCH 22/36] Bump python-holidays to 0.55 (#124314) --- homeassistant/components/holiday/manifest.json | 2 +- homeassistant/components/workday/binary_sensor.py | 4 ++-- homeassistant/components/workday/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/holiday/manifest.json b/homeassistant/components/holiday/manifest.json index 0a714815ae3e..0a3064450d46 100644 --- a/homeassistant/components/holiday/manifest.json +++ b/homeassistant/components/holiday/manifest.json @@ -5,5 +5,5 @@ "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/holiday", "iot_class": "local_polling", - "requirements": ["holidays==0.54", "babel==2.15.0"] + "requirements": ["holidays==0.55", "babel==2.15.0"] } diff --git a/homeassistant/components/workday/binary_sensor.py b/homeassistant/components/workday/binary_sensor.py index 4635b2209a69..33c2e249024a 100644 --- a/homeassistant/components/workday/binary_sensor.py +++ b/homeassistant/components/workday/binary_sensor.py @@ -92,7 +92,7 @@ def _get_obj_holidays( subdiv=province, years=year, language=language, - categories=set_categories, # type: ignore[arg-type] + categories=set_categories, ) if (supported_languages := obj_holidays.supported_languages) and language == "en": for lang in supported_languages: @@ -102,7 +102,7 @@ def _get_obj_holidays( subdiv=province, years=year, language=lang, - categories=set_categories, # type: ignore[arg-type] + categories=set_categories, ) LOGGER.debug("Changing language from %s to %s", language, lang) return obj_holidays diff --git a/homeassistant/components/workday/manifest.json b/homeassistant/components/workday/manifest.json index 133c82454bc7..fafa870d00ab 100644 --- a/homeassistant/components/workday/manifest.json +++ b/homeassistant/components/workday/manifest.json @@ -7,5 +7,5 @@ "iot_class": "local_polling", "loggers": ["holidays"], "quality_scale": "internal", - "requirements": ["holidays==0.54"] + "requirements": ["holidays==0.55"] } diff --git a/requirements_all.txt b/requirements_all.txt index db41a5ed5a06..cf9bff559168 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1096,7 +1096,7 @@ hole==0.8.0 # homeassistant.components.holiday # homeassistant.components.workday -holidays==0.54 +holidays==0.55 # homeassistant.components.frontend home-assistant-frontend==20240809.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index b62084a586d2..992a19e41e49 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -916,7 +916,7 @@ hole==0.8.0 # homeassistant.components.holiday # homeassistant.components.workday -holidays==0.54 +holidays==0.55 # homeassistant.components.frontend home-assistant-frontend==20240809.0 From 667af10017caaf033727df6ee865a106f0b5ef48 Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Tue, 20 Aug 2024 09:45:16 -0700 Subject: [PATCH 23/36] Add missing strings for riemann options flow (#124317) --- homeassistant/components/integration/strings.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/integration/strings.json b/homeassistant/components/integration/strings.json index 55d4df1b45e6..6186521aa1b7 100644 --- a/homeassistant/components/integration/strings.json +++ b/homeassistant/components/integration/strings.json @@ -31,12 +31,14 @@ "round": "[%key:component::integration::config::step::user::data::round%]", "source": "[%key:component::integration::config::step::user::data::source%]", "unit_prefix": "[%key:component::integration::config::step::user::data::unit_prefix%]", - "unit_time": "[%key:component::integration::config::step::user::data::unit_time%]" + "unit_time": "[%key:component::integration::config::step::user::data::unit_time%]", + "max_sub_interval": "[%key:component::integration::config::step::user::data::max_sub_interval%]" }, "data_description": { "round": "[%key:component::integration::config::step::user::data_description::round%]", "unit_prefix": "[%key:component::integration::config::step::user::data_description::unit_prefix%]", - "unit_time": "[%key:component::integration::config::step::user::data_description::unit_time%]" + "unit_time": "[%key:component::integration::config::step::user::data_description::unit_time%]", + "max_sub_interval": "[%key:component::integration::config::step::user::data_description::max_sub_interval%]" } } } From 8f4af4f7c2e513e7468e5d465aa3f3c41f5fc65f Mon Sep 17 00:00:00 2001 From: Pete Sage <76050312+PeteRager@users.noreply.github.com> Date: Wed, 21 Aug 2024 15:05:09 -0400 Subject: [PATCH 24/36] Fix Spotify Media Browsing fails for new config entries (#124368) * initial commit * tests * tests * update tests * update tests * update tests --- .../components/spotify/browse_media.py | 11 +- tests/components/spotify/conftest.py | 128 ++++++++++ .../spotify/snapshots/test_media_browser.ambr | 236 ++++++++++++++++++ .../components/spotify/test_media_browser.py | 61 +++++ 4 files changed, 434 insertions(+), 2 deletions(-) create mode 100644 tests/components/spotify/conftest.py create mode 100644 tests/components/spotify/snapshots/test_media_browser.ambr create mode 100644 tests/components/spotify/test_media_browser.py diff --git a/homeassistant/components/spotify/browse_media.py b/homeassistant/components/spotify/browse_media.py index cff7cae5ebdd..abcb6df62053 100644 --- a/homeassistant/components/spotify/browse_media.py +++ b/homeassistant/components/spotify/browse_media.py @@ -172,10 +172,17 @@ async def async_browse_media( # Check for config entry specifier, and extract Spotify URI parsed_url = yarl.URL(media_content_id) + host = parsed_url.host if ( - parsed_url.host is None - or (entry := hass.config_entries.async_get_entry(parsed_url.host)) is None + host is None + # config entry ids can be upper or lower case. Yarl always returns host + # names in lower case, so we need to look for the config entry in both + or ( + entry := hass.config_entries.async_get_entry(host) + or hass.config_entries.async_get_entry(host.upper()) + ) + is None or not isinstance(entry.runtime_data, HomeAssistantSpotifyData) ): raise BrowseError("Invalid Spotify account specified") diff --git a/tests/components/spotify/conftest.py b/tests/components/spotify/conftest.py new file mode 100644 index 000000000000..3f248b545294 --- /dev/null +++ b/tests/components/spotify/conftest.py @@ -0,0 +1,128 @@ +"""Common test fixtures.""" + +from collections.abc import Generator +from typing import Any +from unittest.mock import MagicMock, patch + +import pytest + +from homeassistant.components.application_credentials import ( + ClientCredential, + async_import_client_credential, +) +from homeassistant.components.spotify import DOMAIN +from homeassistant.core import HomeAssistant +from homeassistant.setup import async_setup_component + +from tests.common import MockConfigEntry + + +@pytest.fixture +def mock_config_entry_1() -> MockConfigEntry: + """Mock a config entry with an upper case entry id.""" + return MockConfigEntry( + domain=DOMAIN, + title="spotify_1", + data={ + "auth_implementation": "spotify_c95e4090d4d3438b922331e7428f8171", + "token": { + "access_token": "AccessToken", + "token_type": "Bearer", + "expires_in": 3600, + "refresh_token": "RefreshToken", + "scope": "playlist-read-private ...", + "expires_at": 1724198975.8829377, + }, + "id": "32oesphrnacjcf7vw5bf6odx3oiu", + "name": "spotify_account_1", + }, + unique_id="84fce612f5b8", + entry_id="01J5TX5A0FF6G5V0QJX6HBC94T", + ) + + +@pytest.fixture +def mock_config_entry_2() -> MockConfigEntry: + """Mock a config entry with a lower case entry id.""" + return MockConfigEntry( + domain=DOMAIN, + title="spotify_2", + data={ + "auth_implementation": "spotify_c95e4090d4d3438b922331e7428f8171", + "token": { + "access_token": "AccessToken", + "token_type": "Bearer", + "expires_in": 3600, + "refresh_token": "RefreshToken", + "scope": "playlist-read-private ...", + "expires_at": 1724198975.8829377, + }, + "id": "55oesphrnacjcf7vw5bf6odx3oiu", + "name": "spotify_account_2", + }, + unique_id="99fce612f5b8", + entry_id="32oesphrnacjcf7vw5bf6odx3", + ) + + +@pytest.fixture +def spotify_playlists() -> dict[str, Any]: + """Mock the return from getting a list of playlists.""" + return { + "href": "https://api.spotify.com/v1/users/31oesphrnacjcf7vw5bf6odx3oiu/playlists?offset=0&limit=48", + "limit": 48, + "next": None, + "offset": 0, + "previous": None, + "total": 1, + "items": [ + { + "collaborative": False, + "description": "", + "id": "unique_identifier_00", + "name": "Playlist1", + "type": "playlist", + "uri": "spotify:playlist:unique_identifier_00", + } + ], + } + + +@pytest.fixture +def spotify_mock(spotify_playlists: dict[str, Any]) -> Generator[MagicMock]: + """Mock the Spotify API.""" + with patch("homeassistant.components.spotify.Spotify") as spotify_mock: + mock = MagicMock() + mock.current_user_playlists.return_value = spotify_playlists + spotify_mock.return_value = mock + yield spotify_mock + + +@pytest.fixture +async def spotify_setup( + hass: HomeAssistant, + spotify_mock: MagicMock, + mock_config_entry_1: MockConfigEntry, + mock_config_entry_2: MockConfigEntry, +): + """Set up the spotify integration.""" + with patch( + "homeassistant.components.spotify.OAuth2Session.async_ensure_token_valid" + ): + await async_setup_component(hass, "application_credentials", {}) + await hass.async_block_till_done() + await async_import_client_credential( + hass, + DOMAIN, + ClientCredential("CLIENT_ID", "CLIENT_SECRET"), + "spotify_c95e4090d4d3438b922331e7428f8171", + ) + await hass.async_block_till_done() + mock_config_entry_1.add_to_hass(hass) + await hass.config_entries.async_setup(mock_config_entry_1.entry_id) + mock_config_entry_2.add_to_hass(hass) + await hass.config_entries.async_setup(mock_config_entry_2.entry_id) + await hass.async_block_till_done(wait_background_tasks=True) + await async_setup_component(hass, DOMAIN, {}) + await hass.async_block_till_done(wait_background_tasks=True) + yield diff --git a/tests/components/spotify/snapshots/test_media_browser.ambr b/tests/components/spotify/snapshots/test_media_browser.ambr new file mode 100644 index 000000000000..4236fcb2e799 --- /dev/null +++ b/tests/components/spotify/snapshots/test_media_browser.ambr @@ -0,0 +1,236 @@ +# serializer version: 1 +# name: test_browse_media_categories + dict({ + 'can_expand': True, + 'can_play': False, + 'children': list([ + dict({ + 'can_expand': True, + 'can_play': False, + 'children_media_class': , + 'media_class': , + 'media_content_id': 'spotify://01j5tx5a0ff6g5v0qjx6hbc94t/current_user_playlists', + 'media_content_type': 'spotify://current_user_playlists', + 'thumbnail': None, + 'title': 'Playlists', + }), + dict({ + 'can_expand': True, + 'can_play': False, + 'children_media_class': , + 'media_class': , + 'media_content_id': 'spotify://01j5tx5a0ff6g5v0qjx6hbc94t/current_user_followed_artists', + 'media_content_type': 'spotify://current_user_followed_artists', + 'thumbnail': None, + 'title': 'Artists', + }), + dict({ + 'can_expand': True, + 'can_play': False, + 'children_media_class': , + 'media_class': , + 'media_content_id': 'spotify://01j5tx5a0ff6g5v0qjx6hbc94t/current_user_saved_albums', + 'media_content_type': 'spotify://current_user_saved_albums', + 'thumbnail': None, + 'title': 'Albums', + }), + dict({ + 'can_expand': True, + 'can_play': False, + 'children_media_class': , + 'media_class': , + 'media_content_id': 'spotify://01j5tx5a0ff6g5v0qjx6hbc94t/current_user_saved_tracks', + 'media_content_type': 'spotify://current_user_saved_tracks', + 'thumbnail': None, + 'title': 'Tracks', + }), + dict({ + 'can_expand': True, + 'can_play': False, + 'children_media_class': , + 'media_class': , + 'media_content_id': 'spotify://01j5tx5a0ff6g5v0qjx6hbc94t/current_user_saved_shows', + 'media_content_type': 'spotify://current_user_saved_shows', + 'thumbnail': None, + 'title': 'Podcasts', + }), + dict({ + 'can_expand': True, + 'can_play': False, + 'children_media_class': , + 'media_class': , + 'media_content_id': 'spotify://01j5tx5a0ff6g5v0qjx6hbc94t/current_user_recently_played', + 'media_content_type': 'spotify://current_user_recently_played', + 'thumbnail': None, + 'title': 'Recently played', + }), + dict({ + 'can_expand': True, + 'can_play': False, + 'children_media_class': , + 'media_class': , + 'media_content_id': 'spotify://01j5tx5a0ff6g5v0qjx6hbc94t/current_user_top_artists', + 'media_content_type': 'spotify://current_user_top_artists', + 'thumbnail': None, + 'title': 'Top Artists', + }), + dict({ + 'can_expand': True, + 'can_play': False, + 'children_media_class': , + 'media_class': , + 'media_content_id': 'spotify://01j5tx5a0ff6g5v0qjx6hbc94t/current_user_top_tracks', + 'media_content_type': 'spotify://current_user_top_tracks', + 'thumbnail': None, + 'title': 'Top Tracks', + }), + dict({ + 'can_expand': True, + 'can_play': False, + 'children_media_class': , + 'media_class': , + 'media_content_id': 'spotify://01j5tx5a0ff6g5v0qjx6hbc94t/categories', + 'media_content_type': 'spotify://categories', + 'thumbnail': None, + 'title': 'Categories', + }), + dict({ + 'can_expand': True, + 'can_play': False, + 'children_media_class': , + 'media_class': , + 'media_content_id': 'spotify://01j5tx5a0ff6g5v0qjx6hbc94t/featured_playlists', + 'media_content_type': 'spotify://featured_playlists', + 'thumbnail': None, + 'title': 'Featured Playlists', + }), + dict({ + 'can_expand': True, + 'can_play': False, + 'children_media_class': , + 'media_class': , + 'media_content_id': 'spotify://01j5tx5a0ff6g5v0qjx6hbc94t/new_releases', + 'media_content_type': 'spotify://new_releases', + 'thumbnail': None, + 'title': 'New Releases', + }), + ]), + 'children_media_class': , + 'media_class': , + 'media_content_id': 'spotify://01j5tx5a0ff6g5v0qjx6hbc94t/library', + 'media_content_type': 'spotify://library', + 'not_shown': 0, + 'thumbnail': None, + 'title': 'Media Library', + }) +# --- +# name: test_browse_media_playlists + dict({ + 'can_expand': True, + 'can_play': False, + 'children': list([ + dict({ + 'can_expand': True, + 'can_play': True, + 'children_media_class': , + 'media_class': , + 'media_content_id': 'spotify://01j5tx5a0ff6g5v0qjx6hbc94t/spotify:playlist:unique_identifier_00', + 'media_content_type': 'spotify://playlist', + 'thumbnail': None, + 'title': 'Playlist1', + }), + ]), + 'children_media_class': , + 'media_class': , + 'media_content_id': 'spotify://01j5tx5a0ff6g5v0qjx6hbc94t/current_user_playlists', + 'media_content_type': 'spotify://current_user_playlists', + 'not_shown': 0, + 'thumbnail': None, + 'title': 'Playlists', + }) +# --- +# name: test_browse_media_playlists[01J5TX5A0FF6G5V0QJX6HBC94T] + dict({ + 'can_expand': True, + 'can_play': False, + 'children': list([ + dict({ + 'can_expand': True, + 'can_play': True, + 'children_media_class': , + 'media_class': , + 'media_content_id': 'spotify://01j5tx5a0ff6g5v0qjx6hbc94t/spotify:playlist:unique_identifier_00', + 'media_content_type': 'spotify://playlist', + 'thumbnail': None, + 'title': 'Playlist1', + }), + ]), + 'children_media_class': , + 'media_class': , + 'media_content_id': 'spotify://01j5tx5a0ff6g5v0qjx6hbc94t/current_user_playlists', + 'media_content_type': 'spotify://current_user_playlists', + 'not_shown': 0, + 'thumbnail': None, + 'title': 'Playlists', + }) +# --- +# name: test_browse_media_playlists[32oesphrnacjcf7vw5bf6odx3] + dict({ + 'can_expand': True, + 'can_play': False, + 'children': list([ + dict({ + 'can_expand': True, + 'can_play': True, + 'children_media_class': , + 'media_class': , + 'media_content_id': 'spotify://32oesphrnacjcf7vw5bf6odx3/spotify:playlist:unique_identifier_00', + 'media_content_type': 'spotify://playlist', + 'thumbnail': None, + 'title': 'Playlist1', + }), + ]), + 'children_media_class': , + 'media_class': , + 'media_content_id': 'spotify://32oesphrnacjcf7vw5bf6odx3/current_user_playlists', + 'media_content_type': 'spotify://current_user_playlists', + 'not_shown': 0, + 'thumbnail': None, + 'title': 'Playlists', + }) +# --- +# name: test_browse_media_root + dict({ + 'can_expand': True, + 'can_play': False, + 'children': list([ + dict({ + 'can_expand': True, + 'can_play': False, + 'children_media_class': None, + 'media_class': , + 'media_content_id': 'spotify://01J5TX5A0FF6G5V0QJX6HBC94T', + 'media_content_type': 'spotify://library', + 'thumbnail': 'https://brands.home-assistant.io/_/spotify/logo.png', + 'title': 'spotify_1', + }), + dict({ + 'can_expand': True, + 'can_play': False, + 'children_media_class': None, + 'media_class': , + 'media_content_id': 'spotify://32oesphrnacjcf7vw5bf6odx3', + 'media_content_type': 'spotify://library', + 'thumbnail': 'https://brands.home-assistant.io/_/spotify/logo.png', + 'title': 'spotify_2', + }), + ]), + 'children_media_class': , + 'media_class': , + 'media_content_id': 'spotify://', + 'media_content_type': 'spotify', + 'not_shown': 0, + 'thumbnail': 'https://brands.home-assistant.io/_/spotify/logo.png', + 'title': 'Spotify', + }) +# --- diff --git a/tests/components/spotify/test_media_browser.py b/tests/components/spotify/test_media_browser.py new file mode 100644 index 000000000000..2b47aed9ee3e --- /dev/null +++ b/tests/components/spotify/test_media_browser.py @@ -0,0 +1,61 @@ +"""Test the media browser interface.""" + +import pytest +from syrupy import SnapshotAssertion + +from homeassistant.components.spotify import DOMAIN +from homeassistant.components.spotify.browse_media import async_browse_media +from homeassistant.core import HomeAssistant +from homeassistant.setup import async_setup_component + +from tests.common import MockConfigEntry + + +async def setup_integration(hass: HomeAssistant, config_entry: MockConfigEntry) -> None: + """Fixture for setting up the component.""" + config_entry.add_to_hass(hass) + + await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done(wait_background_tasks=True) + await async_setup_component(hass, DOMAIN, {}) + await hass.async_block_till_done(wait_background_tasks=True) + + +async def test_browse_media_root( + hass: HomeAssistant, + snapshot: SnapshotAssertion, + spotify_setup, +) -> None: + """Test browsing the root.""" + response = await async_browse_media(hass, None, None) + assert response.as_dict() == snapshot + + +async def test_browse_media_categories( + hass: HomeAssistant, + snapshot: SnapshotAssertion, + spotify_setup, +) -> None: + """Test browsing categories.""" + response = await async_browse_media( + hass, "spotify://library", "spotify://01J5TX5A0FF6G5V0QJX6HBC94T" + ) + assert response.as_dict() == snapshot + + +@pytest.mark.parametrize( + ("config_entry_id"), [("01J5TX5A0FF6G5V0QJX6HBC94T"), ("32oesphrnacjcf7vw5bf6odx3")] +) +async def test_browse_media_playlists( + hass: HomeAssistant, + snapshot: SnapshotAssertion, + config_entry_id: str, + spotify_setup, +) -> None: + """Test browsing playlists for the two config entries.""" + response = await async_browse_media( + hass, + "spotify://current_user_playlists", + f"spotify://{config_entry_id}/current_user_playlists", + ) + assert response.as_dict() == snapshot From 102528e5d3ccd057db27296f1c6e9671f9e69cfb Mon Sep 17 00:00:00 2001 From: Angel Nunez Mencias Date: Wed, 21 Aug 2024 21:14:03 +0200 Subject: [PATCH 25/36] update ttn_client - fix crash with SenseCAP devices (#124370) update ttn_client --- homeassistant/components/thethingsnetwork/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/thethingsnetwork/manifest.json b/homeassistant/components/thethingsnetwork/manifest.json index c39b2b7c421a..8d826750e39e 100644 --- a/homeassistant/components/thethingsnetwork/manifest.json +++ b/homeassistant/components/thethingsnetwork/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/thethingsnetwork", "integration_type": "hub", "iot_class": "cloud_polling", - "requirements": ["ttn_client==1.1.0"] + "requirements": ["ttn_client==1.2.0"] } diff --git a/requirements_all.txt b/requirements_all.txt index cf9bff559168..74a0ad2d881a 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2801,7 +2801,7 @@ transmission-rpc==7.0.3 ttls==1.8.3 # homeassistant.components.thethingsnetwork -ttn_client==1.1.0 +ttn_client==1.2.0 # homeassistant.components.tuya tuya-device-sharing-sdk==0.1.9 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 992a19e41e49..da6b9d92a78c 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -2199,7 +2199,7 @@ transmission-rpc==7.0.3 ttls==1.8.3 # homeassistant.components.thethingsnetwork -ttn_client==1.1.0 +ttn_client==1.2.0 # homeassistant.components.tuya tuya-device-sharing-sdk==0.1.9 From 03c7f2cf5b4005103666e0cb2de0e9024a01fef9 Mon Sep 17 00:00:00 2001 From: Penny Wood Date: Thu, 22 Aug 2024 21:39:09 +0800 Subject: [PATCH 26/36] Add supported features for iZone (#124416) * Fix for #123462 * Set outside of constructor --- homeassistant/components/izone/climate.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/homeassistant/components/izone/climate.py b/homeassistant/components/izone/climate.py index 3a1279a9bd43..617cdc730cc0 100644 --- a/homeassistant/components/izone/climate.py +++ b/homeassistant/components/izone/climate.py @@ -441,6 +441,9 @@ class ZoneDevice(ClimateEntity): _attr_name = None _attr_temperature_unit = UnitOfTemperature.CELSIUS _attr_target_temperature_step = 0.5 + _attr_supported_features = ( + ClimateEntityFeature.TURN_OFF | ClimateEntityFeature.TURN_ON + ) def __init__(self, controller: ControllerDevice, zone: Zone) -> None: """Initialise ZoneDevice.""" From a128e2e4fce43db67e26f432dbb159ec6fd2378f Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 22 Aug 2024 14:46:54 -0500 Subject: [PATCH 27/36] Bump yalexs to 8.1.4 (#124425) changelog: https://github.com/bdraco/yalexs/compare/v8.1.2...v8.1.4 --- homeassistant/components/august/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/august/manifest.json b/homeassistant/components/august/manifest.json index 5d7b253e9525..7e73e55e6ba9 100644 --- a/homeassistant/components/august/manifest.json +++ b/homeassistant/components/august/manifest.json @@ -28,5 +28,5 @@ "documentation": "https://www.home-assistant.io/integrations/august", "iot_class": "cloud_push", "loggers": ["pubnub", "yalexs"], - "requirements": ["yalexs==8.1.2", "yalexs-ble==2.4.3"] + "requirements": ["yalexs==8.1.4", "yalexs-ble==2.4.3"] } diff --git a/requirements_all.txt b/requirements_all.txt index 74a0ad2d881a..504f81e032b6 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2959,7 +2959,7 @@ yalesmartalarmclient==0.3.9 yalexs-ble==2.4.3 # homeassistant.components.august -yalexs==8.1.2 +yalexs==8.1.4 # homeassistant.components.yeelight yeelight==0.7.14 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index da6b9d92a78c..39db339241e6 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -2336,7 +2336,7 @@ yalesmartalarmclient==0.3.9 yalexs-ble==2.4.3 # homeassistant.components.august -yalexs==8.1.2 +yalexs==8.1.4 # homeassistant.components.yeelight yeelight==0.7.14 From fa914b2811f91c841c17d2d4e4742d280528ac97 Mon Sep 17 00:00:00 2001 From: Ino Dekker Date: Fri, 23 Aug 2024 13:43:17 +0200 Subject: [PATCH 28/36] Bump aiohue to version 4.7.3 (#124436) --- homeassistant/components/hue/manifest.json | 2 +- homeassistant/components/hue/v2/hue_event.py | 6 +++--- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/hue/fixtures/v2_resources.json | 12 +++++++++--- 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/hue/manifest.json b/homeassistant/components/hue/manifest.json index 71aabd4c2043..dbd9b5119771 100644 --- a/homeassistant/components/hue/manifest.json +++ b/homeassistant/components/hue/manifest.json @@ -11,6 +11,6 @@ "iot_class": "local_push", "loggers": ["aiohue"], "quality_scale": "platinum", - "requirements": ["aiohue==4.7.2"], + "requirements": ["aiohue==4.7.3"], "zeroconf": ["_hue._tcp.local."] } diff --git a/homeassistant/components/hue/v2/hue_event.py b/homeassistant/components/hue/v2/hue_event.py index b286a11aade2..2eace5139afb 100644 --- a/homeassistant/components/hue/v2/hue_event.py +++ b/homeassistant/components/hue/v2/hue_event.py @@ -80,9 +80,9 @@ async def async_setup_hue_events(bridge: HueBridge): CONF_DEVICE_ID: device.id, # type: ignore[union-attr] CONF_UNIQUE_ID: hue_resource.id, CONF_TYPE: hue_resource.relative_rotary.rotary_report.action.value, - CONF_SUBTYPE: hue_resource.relative_rotary.last_event.rotation.direction.value, - CONF_DURATION: hue_resource.relative_rotary.last_event.rotation.duration, - CONF_STEPS: hue_resource.relative_rotary.last_event.rotation.steps, + CONF_SUBTYPE: hue_resource.relative_rotary.rotary_report.rotation.direction.value, + CONF_DURATION: hue_resource.relative_rotary.rotary_report.rotation.duration, + CONF_STEPS: hue_resource.relative_rotary.rotary_report.rotation.steps, } hass.bus.async_fire(ATTR_HUE_EVENT, data) diff --git a/requirements_all.txt b/requirements_all.txt index 504f81e032b6..011601ba3e6a 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -258,7 +258,7 @@ aioharmony==0.2.10 aiohomekit==3.2.3 # homeassistant.components.hue -aiohue==4.7.2 +aiohue==4.7.3 # homeassistant.components.imap aioimaplib==1.1.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 39db339241e6..6c272c5e9e05 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -243,7 +243,7 @@ aioharmony==0.2.10 aiohomekit==3.2.3 # homeassistant.components.hue -aiohue==4.7.2 +aiohue==4.7.3 # homeassistant.components.imap aioimaplib==1.1.0 diff --git a/tests/components/hue/fixtures/v2_resources.json b/tests/components/hue/fixtures/v2_resources.json index 980086d09888..3d718f24c505 100644 --- a/tests/components/hue/fixtures/v2_resources.json +++ b/tests/components/hue/fixtures/v2_resources.json @@ -1288,7 +1288,9 @@ }, { "button": { - "last_event": "short_release" + "button_report": { + "event": "short_release" + } }, "id": "c658d3d8-a013-4b81-8ac6-78b248537e70", "id_v1": "/sensors/50", @@ -1327,7 +1329,9 @@ }, { "button": { - "last_event": "short_release" + "button_report": { + "event": "short_release" + } }, "id": "7f1ab9f6-cc2b-4b40-9011-65e2af153f75", "id_v1": "/sensors/10", @@ -1366,7 +1370,9 @@ }, { "button": { - "last_event": "short_release" + "button_report": { + "event": "short_release" + } }, "id": "31cffcda-efc2-401f-a152-e10db3eed232", "id_v1": "/sensors/5", From 5f275a6b9c9adf1d2916483870e63f06a98d9292 Mon Sep 17 00:00:00 2001 From: Joost Lekkerkerker Date: Sat, 24 Aug 2024 07:04:50 +0200 Subject: [PATCH 29/36] Don't raise WLED user flow unique_id check (#124481) --- homeassistant/components/wled/config_flow.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/wled/config_flow.py b/homeassistant/components/wled/config_flow.py index 7853ad2101e3..2798e0d46d1a 100644 --- a/homeassistant/components/wled/config_flow.py +++ b/homeassistant/components/wled/config_flow.py @@ -46,7 +46,9 @@ class WLEDFlowHandler(ConfigFlow, domain=DOMAIN): except WLEDConnectionError: errors["base"] = "cannot_connect" else: - await self.async_set_unique_id(device.info.mac_address) + await self.async_set_unique_id( + device.info.mac_address, raise_on_progress=False + ) self._abort_if_unique_id_configured( updates={CONF_HOST: user_input[CONF_HOST]} ) @@ -56,8 +58,6 @@ class WLEDFlowHandler(ConfigFlow, domain=DOMAIN): CONF_HOST: user_input[CONF_HOST], }, ) - else: - user_input = {} return self.async_show_form( step_id="user", From 2db362ab3df3144337c744d7772ba2ae8ba59af1 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 23 Aug 2024 12:23:05 -0500 Subject: [PATCH 30/36] Bump yalexs to 8.3.3 (#124492) * Bump yalexs to 8.2.0 changelog: https://github.com/bdraco/yalexs/compare/v8.1.4...v8.2.0 * bump to 8.3.1 * bump * one more bump to ensure we do not hit the ratelimit/shutdown cleanly * empty commit to restart ci since close/open did not work in flight --- homeassistant/components/august/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/august/conftest.py | 8 ++++++++ 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/august/manifest.json b/homeassistant/components/august/manifest.json index 7e73e55e6ba9..49c23dac660f 100644 --- a/homeassistant/components/august/manifest.json +++ b/homeassistant/components/august/manifest.json @@ -28,5 +28,5 @@ "documentation": "https://www.home-assistant.io/integrations/august", "iot_class": "cloud_push", "loggers": ["pubnub", "yalexs"], - "requirements": ["yalexs==8.1.4", "yalexs-ble==2.4.3"] + "requirements": ["yalexs==8.3.3", "yalexs-ble==2.4.3"] } diff --git a/requirements_all.txt b/requirements_all.txt index 011601ba3e6a..b1a919a0c9b8 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2959,7 +2959,7 @@ yalesmartalarmclient==0.3.9 yalexs-ble==2.4.3 # homeassistant.components.august -yalexs==8.1.4 +yalexs==8.3.3 # homeassistant.components.yeelight yeelight==0.7.14 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 6c272c5e9e05..383bc52ae1e0 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -2336,7 +2336,7 @@ yalesmartalarmclient==0.3.9 yalexs-ble==2.4.3 # homeassistant.components.august -yalexs==8.1.4 +yalexs==8.3.3 # homeassistant.components.yeelight yeelight==0.7.14 diff --git a/tests/components/august/conftest.py b/tests/components/august/conftest.py index 052cde7d2a27..78cb2cdad890 100644 --- a/tests/components/august/conftest.py +++ b/tests/components/august/conftest.py @@ -3,6 +3,7 @@ from unittest.mock import patch import pytest +from yalexs.manager.ratelimit import _RateLimitChecker @pytest.fixture(name="mock_discovery", autouse=True) @@ -12,3 +13,10 @@ def mock_discovery_fixture(): "homeassistant.components.august.data.discovery_flow.async_create_flow" ) as mock_discovery: yield mock_discovery + + +@pytest.fixture(name="disable_ratelimit_checks", autouse=True) +def disable_ratelimit_checks_fixture(): + """Disable rate limit checks.""" + with patch.object(_RateLimitChecker, "register_wakeup"): + yield From b294a92ad2d463e003a7df06c796575b953242ec Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 24 Aug 2024 01:44:12 -0500 Subject: [PATCH 31/36] Bump yalexs to 8.4.0 (#124520) --- homeassistant/components/august/config_flow.py | 6 +++--- homeassistant/components/august/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/august/config_flow.py b/homeassistant/components/august/config_flow.py index 3523a4f7c392..2a1a20a9dc4d 100644 --- a/homeassistant/components/august/config_flow.py +++ b/homeassistant/components/august/config_flow.py @@ -9,7 +9,7 @@ from typing import Any import aiohttp import voluptuous as vol from yalexs.authenticator_common import ValidationResult -from yalexs.const import BRANDS, DEFAULT_BRAND +from yalexs.const import BRANDS_WITHOUT_OAUTH, DEFAULT_BRAND from yalexs.manager.exceptions import CannotConnect, InvalidAuth, RequireValidation from homeassistant.config_entries import ConfigFlow, ConfigFlowResult @@ -118,7 +118,7 @@ class AugustConfigFlow(ConfigFlow, domain=DOMAIN): vol.Required( CONF_BRAND, default=self._user_auth_details.get(CONF_BRAND, DEFAULT_BRAND), - ): vol.In(BRANDS), + ): vol.In(BRANDS_WITHOUT_OAUTH), vol.Required( CONF_LOGIN_METHOD, default=self._user_auth_details.get( @@ -208,7 +208,7 @@ class AugustConfigFlow(ConfigFlow, domain=DOMAIN): vol.Required( CONF_BRAND, default=self._user_auth_details.get(CONF_BRAND, DEFAULT_BRAND), - ): vol.In(BRANDS), + ): vol.In(BRANDS_WITHOUT_OAUTH), vol.Required(CONF_PASSWORD): str, } ), diff --git a/homeassistant/components/august/manifest.json b/homeassistant/components/august/manifest.json index 49c23dac660f..abe9dc707c39 100644 --- a/homeassistant/components/august/manifest.json +++ b/homeassistant/components/august/manifest.json @@ -28,5 +28,5 @@ "documentation": "https://www.home-assistant.io/integrations/august", "iot_class": "cloud_push", "loggers": ["pubnub", "yalexs"], - "requirements": ["yalexs==8.3.3", "yalexs-ble==2.4.3"] + "requirements": ["yalexs==8.4.0", "yalexs-ble==2.4.3"] } diff --git a/requirements_all.txt b/requirements_all.txt index b1a919a0c9b8..d6f7c866360c 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2959,7 +2959,7 @@ yalesmartalarmclient==0.3.9 yalexs-ble==2.4.3 # homeassistant.components.august -yalexs==8.3.3 +yalexs==8.4.0 # homeassistant.components.yeelight yeelight==0.7.14 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 383bc52ae1e0..f035cebac786 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -2336,7 +2336,7 @@ yalesmartalarmclient==0.3.9 yalexs-ble==2.4.3 # homeassistant.components.august -yalexs==8.3.3 +yalexs==8.4.0 # homeassistant.components.yeelight yeelight==0.7.14 From 1bdf9d657e1183a67be4ade412f5164bd3cfd353 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 25 Aug 2024 01:16:20 -1000 Subject: [PATCH 32/36] Bump yalexs to 8.4.1 (#124553) changelog: https://github.com/bdraco/yalexs/compare/v8.4.0...v8.4.1 --- homeassistant/components/august/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/august/manifest.json b/homeassistant/components/august/manifest.json index abe9dc707c39..e0739aadff0c 100644 --- a/homeassistant/components/august/manifest.json +++ b/homeassistant/components/august/manifest.json @@ -28,5 +28,5 @@ "documentation": "https://www.home-assistant.io/integrations/august", "iot_class": "cloud_push", "loggers": ["pubnub", "yalexs"], - "requirements": ["yalexs==8.4.0", "yalexs-ble==2.4.3"] + "requirements": ["yalexs==8.4.1", "yalexs-ble==2.4.3"] } diff --git a/requirements_all.txt b/requirements_all.txt index d6f7c866360c..48fed02cd53c 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2959,7 +2959,7 @@ yalesmartalarmclient==0.3.9 yalexs-ble==2.4.3 # homeassistant.components.august -yalexs==8.4.0 +yalexs==8.4.1 # homeassistant.components.yeelight yeelight==0.7.14 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index f035cebac786..5df5a0836c73 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -2336,7 +2336,7 @@ yalesmartalarmclient==0.3.9 yalexs-ble==2.4.3 # homeassistant.components.august -yalexs==8.4.0 +yalexs==8.4.1 # homeassistant.components.yeelight yeelight==0.7.14 From a45c1a39148c4f5e949bf8de5026c32b27db60ab Mon Sep 17 00:00:00 2001 From: "Mr. Bubbles" Date: Sun, 25 Aug 2024 15:15:47 +0200 Subject: [PATCH 33/36] Fix missing id in Habitica completed todos API response (#124565) * Fix missing id in completed todos API response * Copy id only if none * Update homeassistant/components/habitica/coordinator.py Co-authored-by: Paulus Schoutsen --------- Co-authored-by: Paulus Schoutsen --- .../components/habitica/coordinator.py | 9 +++++- tests/components/habitica/test_init.py | 28 +++++++++---------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/homeassistant/components/habitica/coordinator.py b/homeassistant/components/habitica/coordinator.py index 9d0ebe651e3f..1b17eee63522 100644 --- a/homeassistant/components/habitica/coordinator.py +++ b/homeassistant/components/habitica/coordinator.py @@ -49,7 +49,14 @@ class HabiticaDataUpdateCoordinator(DataUpdateCoordinator[HabiticaData]): try: user_response = await self.api.user.get() tasks_response = await self.api.tasks.user.get() - tasks_response.extend(await self.api.tasks.user.get(type="completedTodos")) + tasks_response.extend( + [ + {"id": task["_id"], **task} + for task in await self.api.tasks.user.get(type="completedTodos") + if task.get("_id") + ] + ) + except ClientResponseError as error: raise UpdateFailed(f"Error communicating with API: {error}") from error diff --git a/tests/components/habitica/test_init.py b/tests/components/habitica/test_init.py index 31c3a1fae39f..4c2b1e2aae61 100644 --- a/tests/components/habitica/test_init.py +++ b/tests/components/habitica/test_init.py @@ -73,7 +73,20 @@ def common_requests(aioclient_mock: AiohttpClientMocker) -> AiohttpClientMocker: } }, ) - + aioclient_mock.get( + "https://habitica.com/api/v3/tasks/user?type=completedTodos", + json={ + "data": [ + { + "text": "this is a mock todo #5", + "id": 5, + "_id": 5, + "type": "todo", + "completed": True, + } + ] + }, + ) aioclient_mock.get( "https://habitica.com/api/v3/tasks/user", json={ @@ -88,19 +101,6 @@ def common_requests(aioclient_mock: AiohttpClientMocker) -> AiohttpClientMocker: ] }, ) - aioclient_mock.get( - "https://habitica.com/api/v3/tasks/user?type=completedTodos", - json={ - "data": [ - { - "text": "this is a mock todo #5", - "id": 5, - "type": "todo", - "completed": True, - } - ] - }, - ) aioclient_mock.post( "https://habitica.com/api/v3/tasks/user", From b34c90b1893a582b950c58ead23cfa96eeac01a0 Mon Sep 17 00:00:00 2001 From: Jan Bouwhuis Date: Sun, 25 Aug 2024 15:09:08 +0200 Subject: [PATCH 34/36] Only support remote activity on Alexa if feature is set and at least one feature is in the activity_list (#124567) Only support remote activity on Alexa if feaure is set and at least one feature is in the activity_list --- homeassistant/components/alexa/entities.py | 9 +++++--- tests/components/alexa/test_capabilities.py | 24 +++++++++++++++++---- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/alexa/entities.py b/homeassistant/components/alexa/entities.py index 8bba4ed24689..ca7b389a0f1b 100644 --- a/homeassistant/components/alexa/entities.py +++ b/homeassistant/components/alexa/entities.py @@ -661,9 +661,12 @@ class RemoteCapabilities(AlexaEntity): def interfaces(self) -> Generator[AlexaCapability]: """Yield the supported interfaces.""" yield AlexaPowerController(self.entity) - yield AlexaModeController( - self.entity, instance=f"{remote.DOMAIN}.{remote.ATTR_ACTIVITY}" - ) + supported = self.entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0) + activities = self.entity.attributes.get(remote.ATTR_ACTIVITY_LIST) or [] + if activities and supported & remote.RemoteEntityFeature.ACTIVITY: + yield AlexaModeController( + self.entity, instance=f"{remote.DOMAIN}.{remote.ATTR_ACTIVITY}" + ) yield AlexaEndpointHealth(self.hass, self.entity) yield Alexa(self.entity) diff --git a/tests/components/alexa/test_capabilities.py b/tests/components/alexa/test_capabilities.py index 162149f095b6..b56d8054d7b9 100644 --- a/tests/components/alexa/test_capabilities.py +++ b/tests/components/alexa/test_capabilities.py @@ -70,6 +70,7 @@ async def test_discovery_remote( { "current_activity": current_activity, "activity_list": activity_list, + "supported_features": 4, }, ) msg = await smart_home.async_handle_message(hass, get_default_config(hass), request) @@ -790,22 +791,37 @@ async def test_report_remote_activity(hass: HomeAssistant) -> None: hass.states.async_set( "remote.unknown", "on", - {"current_activity": "UNKNOWN"}, + { + "current_activity": "UNKNOWN", + "supported_features": 4, + }, ) hass.states.async_set( "remote.tv", "on", - {"current_activity": "TV", "activity_list": ["TV", "MUSIC", "DVD"]}, + { + "current_activity": "TV", + "activity_list": ["TV", "MUSIC", "DVD"], + "supported_features": 4, + }, ) hass.states.async_set( "remote.music", "on", - {"current_activity": "MUSIC", "activity_list": ["TV", "MUSIC", "DVD"]}, + { + "current_activity": "MUSIC", + "activity_list": ["TV", "MUSIC", "DVD"], + "supported_features": 4, + }, ) hass.states.async_set( "remote.dvd", "on", - {"current_activity": "DVD", "activity_list": ["TV", "MUSIC", "DVD"]}, + { + "current_activity": "DVD", + "activity_list": ["TV", "MUSIC", "DVD"], + "supported_features": 4, + }, ) properties = await reported_properties(hass, "remote#unknown") From 18efd84a357aa806f4f82e710ac0d89d6df08bb3 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 25 Aug 2024 13:26:00 +0000 Subject: [PATCH 35/36] Bump version to 2024.8.3 --- 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 39df0486e066..2a06c24843a9 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -24,7 +24,7 @@ if TYPE_CHECKING: APPLICATION_NAME: Final = "HomeAssistant" MAJOR_VERSION: Final = 2024 MINOR_VERSION: Final = 8 -PATCH_VERSION: Final = "2" +PATCH_VERSION: Final = "3" __short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__: Final = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 12, 0) diff --git a/pyproject.toml b/pyproject.toml index c2b167bbbd71..437aea9f0971 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "homeassistant" -version = "2024.8.2" +version = "2024.8.3" license = {text = "Apache-2.0"} description = "Open-source home automation platform running on Python 3." readme = "README.rst" From 2d5289e7dd2c1cde5c4af6052a0880983d7cacc4 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 17 Aug 2024 10:10:45 -0500 Subject: [PATCH 36/36] Revert "Exclude aiohappyeyeballs from license check" (#124116) --- script/licenses.py | 1 - 1 file changed, 1 deletion(-) diff --git a/script/licenses.py b/script/licenses.py index 659f8cb8dcc4..9c584e7f4fcb 100644 --- a/script/licenses.py +++ b/script/licenses.py @@ -124,7 +124,6 @@ EXCEPTIONS = { "PyXiaomiGateway", # https://github.com/Danielhiversen/PyXiaomiGateway/pull/201 "aiocomelit", # https://github.com/chemelli74/aiocomelit/pull/138 "aioecowitt", # https://github.com/home-assistant-libs/aioecowitt/pull/180 - "aiohappyeyeballs", # Python-2.0.1 "aioopenexchangerates", # https://github.com/MartinHjelmare/aioopenexchangerates/pull/94 "aiooui", # https://github.com/Bluetooth-Devices/aiooui/pull/8 "aioruuvigateway", # https://github.com/akx/aioruuvigateway/pull/6