Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion homeassistant/components/assist_satellite/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 0 additions & 1 deletion homeassistant/components/assist_satellite/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/ecovacs/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
}
6 changes: 3 additions & 3 deletions homeassistant/components/esphome/assist_satellite.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/home_connect/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -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."]
}
115 changes: 115 additions & 0 deletions homeassistant/components/ntfy/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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."""
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/ntfy/quality_scale.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
31 changes: 29 additions & 2 deletions homeassistant/components/ntfy/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -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%]"
}
}
},
Expand All @@ -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": {
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/russound_rio/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -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."]
}
6 changes: 3 additions & 3 deletions homeassistant/components/tts/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions requirements_all.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions requirements_test_all.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions tests/components/esphome/test_assist_satellite.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Loading
Loading