From 6738085391bb3b84c6705ffe275b284322166a7d Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Fri, 20 Jun 2025 10:54:11 -0500 Subject: [PATCH 1/7] Minor clean up missed in previous PR (#147229) --- homeassistant/components/assist_satellite/__init__.py | 2 +- homeassistant/components/assist_satellite/entity.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/homeassistant/components/assist_satellite/__init__.py b/homeassistant/components/assist_satellite/__init__.py index f1f38f343f9af..6bfbdfb33a8c1 100644 --- a/homeassistant/components/assist_satellite/__init__.py +++ b/homeassistant/components/assist_satellite/__init__.py @@ -133,7 +133,7 @@ async def handle_ask_question(call: ServiceCall) -> dict[str, Any]: service_func=handle_ask_question, schema=vol.All( { - vol.Required(ATTR_ENTITY_ID): cv.entity_id, + vol.Required(ATTR_ENTITY_ID): cv.entity_domain(DOMAIN), vol.Optional("question"): str, vol.Optional("question_media_id"): str, vol.Optional("preannounce"): bool, diff --git a/homeassistant/components/assist_satellite/entity.py b/homeassistant/components/assist_satellite/entity.py index d32bad2c8241a..e7a10ef63f67a 100644 --- a/homeassistant/components/assist_satellite/entity.py +++ b/homeassistant/components/assist_satellite/entity.py @@ -138,7 +138,6 @@ class AssistSatelliteEntity(entity.Entity): _is_announcing = False _extra_system_prompt: str | None = None _wake_word_intercept_future: asyncio.Future[str | None] | None = None - _stt_intercept_future: asyncio.Future[str | None] | None = None _attr_tts_options: dict[str, Any] | None = None _pipeline_task: asyncio.Task | None = None _ask_question_future: asyncio.Future[str | None] | None = None From 9346c584c381d826260a55f6a8891d7e5f35da86 Mon Sep 17 00:00:00 2001 From: Manu <4445816+tr4nt0r@users.noreply.github.com> Date: Fri, 20 Jun 2025 18:42:47 +0200 Subject: [PATCH 2/7] Add reconfigure flow to ntfy integration (#143743) --- homeassistant/components/ntfy/config_flow.py | 115 +++++++++ .../components/ntfy/quality_scale.yaml | 2 +- homeassistant/components/ntfy/strings.json | 31 ++- tests/components/ntfy/test_config_flow.py | 233 ++++++++++++++++++ 4 files changed, 378 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/ntfy/config_flow.py b/homeassistant/components/ntfy/config_flow.py index 04a6730aa733f..ed8d56820c220 100644 --- a/homeassistant/components/ntfy/config_flow.py +++ b/homeassistant/components/ntfy/config_flow.py @@ -90,6 +90,24 @@ } ) +STEP_RECONFIGURE_DATA_SCHEMA = vol.Schema( + { + vol.Exclusive(CONF_USERNAME, ATTR_CREDENTIALS): TextSelector( + TextSelectorConfig( + type=TextSelectorType.TEXT, + autocomplete="username", + ), + ), + vol.Optional(CONF_PASSWORD, default=""): TextSelector( + TextSelectorConfig( + type=TextSelectorType.PASSWORD, + autocomplete="current-password", + ), + ), + vol.Exclusive(CONF_TOKEN, ATTR_CREDENTIALS): str, + } +) + STEP_USER_TOPIC_SCHEMA = vol.Schema( { vol.Required(CONF_TOPIC): str, @@ -244,6 +262,103 @@ async def async_step_reauth_confirm( description_placeholders={CONF_USERNAME: entry.data[CONF_USERNAME]}, ) + async def async_step_reconfigure( + self, user_input: dict[str, Any] | None = None + ) -> ConfigFlowResult: + """Handle reconfigure flow for ntfy.""" + errors: dict[str, str] = {} + + entry = self._get_reconfigure_entry() + + if user_input is not None: + session = async_get_clientsession(self.hass) + if token := user_input.get(CONF_TOKEN): + ntfy = Ntfy( + entry.data[CONF_URL], + session, + token=user_input[CONF_TOKEN], + ) + else: + ntfy = Ntfy( + entry.data[CONF_URL], + session, + username=user_input.get(CONF_USERNAME, entry.data[CONF_USERNAME]), + password=user_input[CONF_PASSWORD], + ) + + try: + account = await ntfy.account() + if not token: + token = (await ntfy.generate_token("Home Assistant")).token + except NtfyUnauthorizedAuthenticationError: + errors["base"] = "invalid_auth" + except NtfyHTTPError as e: + _LOGGER.debug("Error %s: %s [%s]", e.code, e.error, e.link) + errors["base"] = "cannot_connect" + except NtfyException: + errors["base"] = "cannot_connect" + except Exception: + _LOGGER.exception("Unexpected exception") + errors["base"] = "unknown" + else: + if entry.data[CONF_USERNAME]: + if entry.data[CONF_USERNAME] != account.username: + return self.async_abort( + reason="account_mismatch", + description_placeholders={ + CONF_USERNAME: entry.data[CONF_USERNAME], + "wrong_username": account.username, + }, + ) + + return self.async_update_reload_and_abort( + entry, + data_updates={CONF_TOKEN: token}, + ) + self._async_abort_entries_match( + { + CONF_URL: entry.data[CONF_URL], + CONF_USERNAME: account.username, + } + ) + return self.async_update_reload_and_abort( + entry, + data_updates={ + CONF_USERNAME: account.username, + CONF_TOKEN: token, + }, + ) + if entry.data[CONF_USERNAME]: + return self.async_show_form( + step_id="reconfigure_user", + data_schema=self.add_suggested_values_to_schema( + data_schema=STEP_REAUTH_DATA_SCHEMA, + suggested_values=user_input, + ), + errors=errors, + description_placeholders={ + CONF_NAME: entry.title, + CONF_USERNAME: entry.data[CONF_USERNAME], + }, + ) + + return self.async_show_form( + step_id="reconfigure", + data_schema=self.add_suggested_values_to_schema( + data_schema=STEP_RECONFIGURE_DATA_SCHEMA, + suggested_values=user_input, + ), + errors=errors, + description_placeholders={CONF_NAME: entry.title}, + ) + + async def async_step_reconfigure_user( + self, user_input: dict[str, Any] | None = None + ) -> ConfigFlowResult: + """Handle reconfigure flow for authenticated ntfy entry.""" + + return await self.async_step_reconfigure(user_input) + class TopicSubentryFlowHandler(ConfigSubentryFlow): """Handle subentry flow for adding and modifying a topic.""" diff --git a/homeassistant/components/ntfy/quality_scale.yaml b/homeassistant/components/ntfy/quality_scale.yaml index 0d075f0014bb4..43a96135baf38 100644 --- a/homeassistant/components/ntfy/quality_scale.yaml +++ b/homeassistant/components/ntfy/quality_scale.yaml @@ -72,7 +72,7 @@ rules: comment: the notify entity uses the device name as entity name, no translation required exception-translations: done icon-translations: done - reconfiguration-flow: todo + reconfiguration-flow: done repair-issues: status: exempt comment: the integration has no repairs diff --git a/homeassistant/components/ntfy/strings.json b/homeassistant/components/ntfy/strings.json index 13704d960be6f..cef662d6f2f76 100644 --- a/homeassistant/components/ntfy/strings.json +++ b/homeassistant/components/ntfy/strings.json @@ -39,7 +39,33 @@ }, "data_description": { "password": "Enter the password corresponding to the aforementioned username to automatically create an access token", - "token": "Enter a new access token. To create a new access token navigate to Account → Access tokens and click create access token" + "token": "Enter a new access token. To create a new access token navigate to Account → Access tokens and select 'Create access token'" + } + }, + "reconfigure": { + "title": "Configuration for {name}", + "description": "You can either log in with your **ntfy** username and password, and Home Assistant will automatically create an access token to authenticate with **ntfy**, or you can provide an access token directly", + "data": { + "username": "[%key:common::config_flow::data::username%]", + "password": "[%key:common::config_flow::data::password%]", + "token": "[%key:common::config_flow::data::access_token%]" + }, + "data_description": { + "username": "[%key:component::ntfy::config::step::user::sections::auth::data_description::username%]", + "password": "[%key:component::ntfy::config::step::user::sections::auth::data_description::password%]", + "token": "Enter a new or existing access token. To create a new access token navigate to Account → Access tokens and select 'Create access token'" + } + }, + "reconfigure_user": { + "title": "[%key:component::ntfy::config::step::reconfigure::title%]", + "description": "Enter the password for **{username}** below. Home Assistant will automatically create a new access token to authenticate with **ntfy**. You can also directly provide a valid access token", + "data": { + "password": "[%key:common::config_flow::data::password%]", + "token": "[%key:common::config_flow::data::access_token%]" + }, + "data_description": { + "password": "[%key:component::ntfy::config::step::reauth_confirm::data_description::password%]", + "token": "[%key:component::ntfy::config::step::reconfigure::data_description::token%]" } } }, @@ -51,7 +77,8 @@ "abort": { "already_configured": "[%key:common::config_flow::abort::already_configured_service%]", "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]", - "account_mismatch": "The provided access token corresponds to the account {wrong_username}. Please re-authenticate with the account **{username}**" + "account_mismatch": "The provided access token corresponds to the account {wrong_username}. Please re-authenticate with the account **{username}**", + "reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]" } }, "config_subentries": { diff --git a/tests/components/ntfy/test_config_flow.py b/tests/components/ntfy/test_config_flow.py index 2d3656536a915..48909552e086f 100644 --- a/tests/components/ntfy/test_config_flow.py +++ b/tests/components/ntfy/test_config_flow.py @@ -498,3 +498,236 @@ async def test_flow_reauth_account_mismatch( assert result["type"] is FlowResultType.ABORT assert result["reason"] == "account_mismatch" + + +@pytest.mark.parametrize( + ("entry_data", "user_input", "step_id"), + [ + ( + {CONF_USERNAME: None, CONF_TOKEN: None}, + {CONF_USERNAME: "username", CONF_PASSWORD: "password"}, + "reconfigure", + ), + ( + {CONF_USERNAME: "username", CONF_TOKEN: "oldtoken"}, + {CONF_TOKEN: "newtoken"}, + "reconfigure_user", + ), + ], +) +async def test_flow_reconfigure( + hass: HomeAssistant, + mock_aiontfy: AsyncMock, + entry_data: dict[str, str | None], + user_input: dict[str, str], + step_id: str, +) -> None: + """Test reconfigure flow.""" + config_entry = MockConfigEntry( + domain=DOMAIN, + title="ntfy.sh", + data={ + CONF_URL: "https://ntfy.sh/", + **entry_data, + }, + ) + mock_aiontfy.generate_token.return_value = AccountTokenResponse( + token="newtoken", last_access=datetime.now() + ) + config_entry.add_to_hass(hass) + result = await config_entry.start_reconfigure_flow(hass) + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == step_id + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + user_input, + ) + + await hass.async_block_till_done() + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "reconfigure_successful" + assert config_entry.data[CONF_USERNAME] == "username" + assert config_entry.data[CONF_TOKEN] == "newtoken" + + assert len(hass.config_entries.async_entries()) == 1 + + +@pytest.mark.parametrize( + ("entry_data", "step_id"), + [ + ({CONF_USERNAME: None, CONF_TOKEN: None}, "reconfigure"), + ({CONF_USERNAME: "username", CONF_TOKEN: "oldtoken"}, "reconfigure_user"), + ], +) +@pytest.mark.usefixtures("mock_aiontfy") +async def test_flow_reconfigure_token( + hass: HomeAssistant, + entry_data: dict[str, Any], + step_id: str, +) -> None: + """Test reconfigure flow with access token.""" + config_entry = MockConfigEntry( + domain=DOMAIN, + title="ntfy.sh", + data={ + CONF_URL: "https://ntfy.sh/", + **entry_data, + }, + ) + + config_entry.add_to_hass(hass) + result = await config_entry.start_reconfigure_flow(hass) + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == step_id + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + {CONF_TOKEN: "access_token"}, + ) + + await hass.async_block_till_done() + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "reconfigure_successful" + assert config_entry.data[CONF_USERNAME] == "username" + assert config_entry.data[CONF_TOKEN] == "access_token" + + assert len(hass.config_entries.async_entries()) == 1 + + +@pytest.mark.parametrize( + ("exception", "error"), + [ + ( + NtfyHTTPError(418001, 418, "I'm a teapot", ""), + "cannot_connect", + ), + ( + NtfyUnauthorizedAuthenticationError( + 40101, + 401, + "unauthorized", + "https://ntfy.sh/docs/publish/#authentication", + ), + "invalid_auth", + ), + (NtfyException, "cannot_connect"), + (TypeError, "unknown"), + ], +) +async def test_flow_reconfigure_errors( + hass: HomeAssistant, + mock_aiontfy: AsyncMock, + exception: Exception, + error: str, +) -> None: + """Test reconfigure flow errors.""" + config_entry = MockConfigEntry( + domain=DOMAIN, + title="ntfy.sh", + data={ + CONF_URL: "https://ntfy.sh/", + CONF_USERNAME: None, + CONF_TOKEN: None, + }, + ) + mock_aiontfy.generate_token.return_value = AccountTokenResponse( + token="newtoken", last_access=datetime.now() + ) + mock_aiontfy.account.side_effect = exception + + config_entry.add_to_hass(hass) + result = await config_entry.start_reconfigure_flow(hass) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "reconfigure" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + {CONF_USERNAME: "username", CONF_PASSWORD: "password"}, + ) + + await hass.async_block_till_done() + + assert result["type"] is FlowResultType.FORM + assert result["errors"] == {"base": error} + + mock_aiontfy.account.side_effect = None + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + {CONF_USERNAME: "username", CONF_PASSWORD: "password"}, + ) + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "reconfigure_successful" + assert config_entry.data[CONF_USERNAME] == "username" + assert config_entry.data[CONF_TOKEN] == "newtoken" + + assert len(hass.config_entries.async_entries()) == 1 + + +@pytest.mark.usefixtures("mock_aiontfy") +async def test_flow_reconfigure_already_configured( + hass: HomeAssistant, + config_entry: MockConfigEntry, +) -> None: + """Test reconfigure flow already configured.""" + other_config_entry = MockConfigEntry( + domain=DOMAIN, + title="ntfy.sh", + data={ + CONF_URL: "https://ntfy.sh/", + CONF_USERNAME: "username", + }, + ) + other_config_entry.add_to_hass(hass) + + config_entry.add_to_hass(hass) + result = await config_entry.start_reconfigure_flow(hass) + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "reconfigure" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + {CONF_USERNAME: "username", CONF_PASSWORD: "password"}, + ) + + await hass.async_block_till_done() + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "already_configured" + + assert len(hass.config_entries.async_entries()) == 2 + + +@pytest.mark.usefixtures("mock_aiontfy") +async def test_flow_reconfigure_account_mismatch( + hass: HomeAssistant, +) -> None: + """Test reconfigure flow account mismatch.""" + config_entry = MockConfigEntry( + domain=DOMAIN, + title="ntfy.sh", + data={ + CONF_URL: "https://ntfy.sh/", + CONF_USERNAME: "wrong_username", + CONF_TOKEN: "oldtoken", + }, + ) + config_entry.add_to_hass(hass) + result = await config_entry.start_reconfigure_flow(hass) + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "reconfigure_user" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + {CONF_TOKEN: "newtoken"}, + ) + + await hass.async_block_till_done() + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "account_mismatch" From 95f292c43d8d5ee485f99c74d6fda717890b0c57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20Diego=20Rodr=C3=ADguez=20Royo?= Date: Fri, 20 Jun 2025 19:27:29 +0200 Subject: [PATCH 3/7] Bump aiohomeconnect to 0.18.1 (#147236) --- 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 5e296ba18ac74..8ced21ecba523 100644 --- a/homeassistant/components/home_connect/manifest.json +++ b/homeassistant/components/home_connect/manifest.json @@ -22,6 +22,6 @@ "iot_class": "cloud_push", "loggers": ["aiohomeconnect"], "quality_scale": "platinum", - "requirements": ["aiohomeconnect==0.18.0"], + "requirements": ["aiohomeconnect==0.18.1"], "zeroconf": ["_homeconnect._tcp.local."] } diff --git a/requirements_all.txt b/requirements_all.txt index 90e902ed8c787..6d1d834a8e750 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -265,7 +265,7 @@ aioharmony==0.5.2 aiohasupervisor==0.3.1 # homeassistant.components.home_connect -aiohomeconnect==0.18.0 +aiohomeconnect==0.18.1 # homeassistant.components.homekit_controller aiohomekit==3.2.15 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 633d6904fc7c4..3ad1ef1ed8797 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -250,7 +250,7 @@ aioharmony==0.5.2 aiohasupervisor==0.3.1 # homeassistant.components.home_connect -aiohomeconnect==0.18.0 +aiohomeconnect==0.18.1 # homeassistant.components.homekit_controller aiohomekit==3.2.15 From 435c08685d1fecb6b196bf1f6c4cf7e1042c2412 Mon Sep 17 00:00:00 2001 From: Robert Resch Date: Fri, 20 Jun 2025 20:22:33 +0200 Subject: [PATCH 4/7] Bump deebot-client to 13.4.0 (#147221) --- homeassistant/components/ecovacs/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/ecovacs/manifest.json b/homeassistant/components/ecovacs/manifest.json index 8a7388da7353a..97739f698d954 100644 --- a/homeassistant/components/ecovacs/manifest.json +++ b/homeassistant/components/ecovacs/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/ecovacs", "iot_class": "cloud_push", "loggers": ["sleekxmppfs", "sucks", "deebot_client"], - "requirements": ["py-sucks==0.9.11", "deebot-client==13.3.0"] + "requirements": ["py-sucks==0.9.11", "deebot-client==13.4.0"] } diff --git a/requirements_all.txt b/requirements_all.txt index 6d1d834a8e750..a1fa1694dd6e2 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -765,7 +765,7 @@ decora-wifi==1.4 # decora==0.6 # homeassistant.components.ecovacs -deebot-client==13.3.0 +deebot-client==13.4.0 # homeassistant.components.ihc # homeassistant.components.namecheapdns diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 3ad1ef1ed8797..492978d900065 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -665,7 +665,7 @@ debugpy==1.8.14 # decora==0.6 # homeassistant.components.ecovacs -deebot-client==13.3.0 +deebot-client==13.4.0 # homeassistant.components.ihc # homeassistant.components.namecheapdns From 65f897793d184231fa41031b956d73c1ad42775d Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Fri, 20 Jun 2025 14:18:03 -0500 Subject: [PATCH 5/7] Use string instead of boolean for voice event (#147244) Use string instead of bool --- homeassistant/components/esphome/assist_satellite.py | 6 +++--- tests/components/esphome/test_assist_satellite.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/esphome/assist_satellite.py b/homeassistant/components/esphome/assist_satellite.py index fdeadd7feb1d5..f63671654004c 100644 --- a/homeassistant/components/esphome/assist_satellite.py +++ b/homeassistant/components/esphome/assist_satellite.py @@ -285,9 +285,9 @@ def on_pipeline_event(self, event: PipelineEvent) -> None: data_to_send = {"text": event.data["stt_output"]["text"]} elif event_type == VoiceAssistantEventType.VOICE_ASSISTANT_INTENT_PROGRESS: data_to_send = { - "tts_start_streaming": bool( - event.data and event.data.get("tts_start_streaming") - ), + "tts_start_streaming": "1" + if (event.data and event.data.get("tts_start_streaming")) + else "0", } elif event_type == VoiceAssistantEventType.VOICE_ASSISTANT_INTENT_END: assert event.data is not None diff --git a/tests/components/esphome/test_assist_satellite.py b/tests/components/esphome/test_assist_satellite.py index 71977f0285ca5..3acdc1f20291d 100644 --- a/tests/components/esphome/test_assist_satellite.py +++ b/tests/components/esphome/test_assist_satellite.py @@ -243,12 +243,12 @@ async def async_pipeline_from_audio_stream(*args, device_id, **kwargs): event_callback( PipelineEvent( type=PipelineEventType.INTENT_PROGRESS, - data={"tts_start_streaming": True}, + data={"tts_start_streaming": "1"}, ) ) assert mock_client.send_voice_assistant_event.call_args_list[-1].args == ( VoiceAssistantEventType.VOICE_ASSISTANT_INTENT_PROGRESS, - {"tts_start_streaming": True}, + {"tts_start_streaming": "1"}, ) event_callback( From ace18e540b797ce1088bddeb01ad69b27085a55e Mon Sep 17 00:00:00 2001 From: Noah Husby <32528627+noahhusby@users.noreply.github.com> Date: Fri, 20 Jun 2025 15:59:59 -0400 Subject: [PATCH 6/7] Bump aiorussound to 4.6.1 (#147233) --- homeassistant/components/russound_rio/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/russound_rio/manifest.json b/homeassistant/components/russound_rio/manifest.json index 30b9205f439ef..a74a1887836f5 100644 --- a/homeassistant/components/russound_rio/manifest.json +++ b/homeassistant/components/russound_rio/manifest.json @@ -7,6 +7,6 @@ "iot_class": "local_push", "loggers": ["aiorussound"], "quality_scale": "silver", - "requirements": ["aiorussound==4.6.0"], + "requirements": ["aiorussound==4.6.1"], "zeroconf": ["_rio._tcp.local."] } diff --git a/requirements_all.txt b/requirements_all.txt index a1fa1694dd6e2..4eca8e12383d9 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -369,7 +369,7 @@ aioridwell==2024.01.0 aioruckus==0.42 # homeassistant.components.russound_rio -aiorussound==4.6.0 +aiorussound==4.6.1 # homeassistant.components.ruuvi_gateway aioruuvigateway==0.1.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 492978d900065..c63e4f2f551cc 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -351,7 +351,7 @@ aioridwell==2024.01.0 aioruckus==0.42 # homeassistant.components.russound_rio -aiorussound==4.6.0 +aiorussound==4.6.1 # homeassistant.components.ruuvi_gateway aioruuvigateway==0.1.0 From 9bcd74c44946f80d48e214338c634f62db6530ed Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Fri, 20 Jun 2025 15:39:22 -0500 Subject: [PATCH 7/7] Change async_supports_streaming_input to an instance method (#147245) --- homeassistant/components/tts/entity.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/tts/entity.py b/homeassistant/components/tts/entity.py index 2c3fd446d2f64..dc6f22570fc79 100644 --- a/homeassistant/components/tts/entity.py +++ b/homeassistant/components/tts/entity.py @@ -89,11 +89,11 @@ def default_options(self) -> Mapping[str, Any] | None: """Return a mapping with the default options.""" return self._attr_default_options - @classmethod - def async_supports_streaming_input(cls) -> bool: + def async_supports_streaming_input(self) -> bool: """Return if the TTS engine supports streaming input.""" return ( - cls.async_stream_tts_audio is not TextToSpeechEntity.async_stream_tts_audio + self.__class__.async_stream_tts_audio + is not TextToSpeechEntity.async_stream_tts_audio ) @callback