mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-14 12:56:37 +00:00
20241127.5 (#23178)
This commit is contained in:
commit
8c5862e4ce
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "home-assistant-frontend"
|
||||
version = "20241127.4"
|
||||
version = "20241127.5"
|
||||
license = {text = "Apache-2.0"}
|
||||
description = "The Home Assistant frontend"
|
||||
readme = "README.md"
|
||||
|
@ -18,6 +18,7 @@ export class HaMdSelect extends MdFilledSelect {
|
||||
--md-sys-color-on-surface: var(--input-ink-color);
|
||||
|
||||
--md-sys-color-surface-container: var(--input-fill-color);
|
||||
--md-sys-color-on-secondary-container: var(--primary-text-color);
|
||||
--md-sys-color-secondary-container: var(--input-fill-color);
|
||||
--md-menu-container-color: var(--card-background-color);
|
||||
}
|
||||
|
@ -682,19 +682,27 @@ const tryDescribeTrigger = (
|
||||
|
||||
// Conversation Trigger
|
||||
if (trigger.trigger === "conversation") {
|
||||
if (!trigger.command) {
|
||||
if (!trigger.command || !trigger.command.length) {
|
||||
return hass.localize(
|
||||
`${triggerTranslationBaseKey}.conversation.description.empty`
|
||||
);
|
||||
}
|
||||
|
||||
const commands = ensureArray(trigger.command);
|
||||
|
||||
if (commands.length === 1) {
|
||||
return hass.localize(
|
||||
`${triggerTranslationBaseKey}.conversation.description.single`,
|
||||
{
|
||||
sentence: commands[0],
|
||||
}
|
||||
);
|
||||
}
|
||||
return hass.localize(
|
||||
`${triggerTranslationBaseKey}.conversation.description.full`,
|
||||
`${triggerTranslationBaseKey}.conversation.description.multiple`,
|
||||
{
|
||||
sentence: formatListWithOrs(
|
||||
hass.locale,
|
||||
ensureArray(trigger.command).map((cmd) => `'${cmd}'`)
|
||||
),
|
||||
sentence: commands[0],
|
||||
count: commands.length - 1,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -486,6 +486,11 @@ const tryDescribeAction = <T extends ActionType>(
|
||||
|
||||
if (actionType === "set_conversation_response") {
|
||||
const config = action as SetConversationResponseAction;
|
||||
if (isTemplate(config.set_conversation_response)) {
|
||||
return hass.localize(
|
||||
`${actionTranslationBaseKey}.set_conversation_response.description.template`
|
||||
);
|
||||
}
|
||||
return hass.localize(
|
||||
`${actionTranslationBaseKey}.set_conversation_response.description.full`,
|
||||
{ response: config.set_conversation_response }
|
||||
|
@ -18,7 +18,11 @@ export class CloudStepIntro extends LitElement {
|
||||
src=${`/static/images/logo_nabu_casa${this.hass.themes?.darkMode ? "_dark" : ""}.png`}
|
||||
alt="Nabu Casa logo"
|
||||
/>
|
||||
<h1>The power of Home Assistant Cloud</h1>
|
||||
<h1>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.cloud.title"
|
||||
)}
|
||||
</h1>
|
||||
<div class="features">
|
||||
<div class="feature speech">
|
||||
<div class="logos">
|
||||
@ -45,12 +49,15 @@ export class CloudStepIntro extends LitElement {
|
||||
</div>
|
||||
</div>
|
||||
<h2>
|
||||
Remote access
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.assistants.cloud.features.remote_access.title"
|
||||
)}
|
||||
<span class="no-wrap"></span>
|
||||
</h2>
|
||||
<p>
|
||||
Secure remote access to your system while supporting the
|
||||
development of Home Assistant.
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.assistants.cloud.features.remote_access.text"
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<div class="feature">
|
||||
@ -101,7 +108,9 @@ export class CloudStepIntro extends LitElement {
|
||||
</ha-button>
|
||||
</a>
|
||||
<ha-button unelevated @click=${this._signUp}
|
||||
>Try 1 month for free</ha-button
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.cloud.register.headline"
|
||||
)}</ha-button
|
||||
>
|
||||
</div>`;
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ export class CloudStepSignin extends LitElement {
|
||||
src=${`/static/images/logo_nabu_casa${this.hass.themes?.darkMode ? "_dark" : ""}.png`}
|
||||
alt="Nabu Casa logo"
|
||||
/>
|
||||
<h1>Sign in</h1>
|
||||
<h1>${this.hass.localize("ui.panel.config.cloud.login.sign_in")}</h1>
|
||||
${this._error
|
||||
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
|
||||
: ""}
|
||||
@ -73,7 +73,9 @@ export class CloudStepSignin extends LitElement {
|
||||
unelevated
|
||||
@click=${this._handleLogin}
|
||||
.disabled=${this._requestInProgress}
|
||||
>Sign in</ha-button
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.cloud.login.sign_in"
|
||||
)}</ha-button
|
||||
>
|
||||
</div>`;
|
||||
}
|
||||
|
@ -40,14 +40,18 @@ export class CloudStepSignup extends LitElement {
|
||||
src=${`/static/images/logo_nabu_casa${this.hass.themes?.darkMode ? "_dark" : ""}.png`}
|
||||
alt="Nabu Casa logo"
|
||||
/>
|
||||
<h1>Sign up</h1>
|
||||
<h1>
|
||||
${this.hass.localize("ui.panel.config.cloud.register.create_account")}
|
||||
</h1>
|
||||
${this._error
|
||||
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
|
||||
: ""}
|
||||
${this._state === "VERIFY"
|
||||
? html`<p>
|
||||
Check the email we just sent to ${this._email} and click the
|
||||
confirmation link to continue.
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.register.confirm_email",
|
||||
{ email: this._email }
|
||||
)}
|
||||
</p>`
|
||||
: html`<ha-textfield
|
||||
autofocus
|
||||
@ -86,23 +90,29 @@ export class CloudStepSignup extends LitElement {
|
||||
? html`<ha-button
|
||||
@click=${this._handleResendVerifyEmail}
|
||||
.disabled=${this._requestInProgress}
|
||||
>Send the email again</ha-button
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.cloud.register.resend_confirm_email"
|
||||
)}</ha-button
|
||||
><ha-button
|
||||
unelevated
|
||||
@click=${this._login}
|
||||
.disabled=${this._requestInProgress}
|
||||
>I clicked the link</ha-button
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.cloud.register.clicked_confirm"
|
||||
)}</ha-button
|
||||
>`
|
||||
: html`<ha-button
|
||||
@click=${this._signIn}
|
||||
.disabled=${this._requestInProgress}
|
||||
>Sign in</ha-button
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.cloud.login.sign_in"
|
||||
)}</ha-button
|
||||
>
|
||||
<ha-button
|
||||
unelevated
|
||||
@click=${this._handleRegister}
|
||||
.disabled=${this._requestInProgress}
|
||||
>Next</ha-button
|
||||
>${this.hass.localize("ui.common.next")}</ha-button
|
||||
>`}
|
||||
</div>`;
|
||||
}
|
||||
|
@ -145,7 +145,9 @@ export class HaVoiceAssistantSetupDialog extends LitElement {
|
||||
@click=${this._goToNextStep}
|
||||
class="skip-btn"
|
||||
slot="actionItems"
|
||||
>Skip</ha-button
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.skip"
|
||||
)}</ha-button
|
||||
>`
|
||||
: nothing}
|
||||
</ha-dialog-header>
|
||||
@ -164,7 +166,9 @@ export class HaVoiceAssistantSetupDialog extends LitElement {
|
||||
)}
|
||||
></ha-voice-assistant-setup-step-update>`
|
||||
: assistEntityState?.state === UNAVAILABLE
|
||||
? html`Your voice assistant is not available.`
|
||||
? this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.not_available"
|
||||
)
|
||||
: this._step === STEP.CHECK
|
||||
? html`<ha-voice-assistant-setup-step-check
|
||||
.hass=${this.hass}
|
||||
|
@ -21,10 +21,15 @@ export class HaVoiceAssistantSetupStepArea extends LitElement {
|
||||
src="/static/images/voice-assistant/area.png"
|
||||
alt="Casita Home Assistant logo"
|
||||
/>
|
||||
<h1>Select area</h1>
|
||||
<h1>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.area.title"
|
||||
)}
|
||||
</h1>
|
||||
<p class="secondary">
|
||||
When you voice assistant knows where it is, it can better control the
|
||||
devices around it.
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.area.secondary"
|
||||
)}
|
||||
</p>
|
||||
<ha-area-picker
|
||||
.hass=${this.hass}
|
||||
@ -32,14 +37,20 @@ export class HaVoiceAssistantSetupStepArea extends LitElement {
|
||||
></ha-area-picker>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<ha-button @click=${this._setArea} unelevated>Next</ha-button>
|
||||
<ha-button @click=${this._setArea} unelevated
|
||||
>${this.hass.localize("ui.common.next")}</ha-button
|
||||
>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
private async _setArea() {
|
||||
const area = this.shadowRoot!.querySelector("ha-area-picker")!.value;
|
||||
if (!area) {
|
||||
showAlertDialog(this, { text: "Please select an area" });
|
||||
showAlertDialog(this, {
|
||||
text: this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.area.no_selection"
|
||||
),
|
||||
});
|
||||
return;
|
||||
}
|
||||
await updateDeviceRegistryEntry(this.hass, this.deviceId, {
|
||||
|
@ -1,14 +1,13 @@
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import "../../components/ha-md-list";
|
||||
import "../../components/ha-md-list-item";
|
||||
import type { AssistSatelliteConfiguration } from "../../data/assist_satellite";
|
||||
import { setWakeWords } from "../../data/assist_satellite";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import { STEP } from "./voice-assistant-setup-dialog";
|
||||
import { AssistantSetupStyles } from "./styles";
|
||||
import "../../components/ha-md-list";
|
||||
import "../../components/ha-md-list-item";
|
||||
import { formatLanguageCode } from "../../common/language/format_language";
|
||||
import { STEP } from "./voice-assistant-setup-dialog";
|
||||
|
||||
@customElement("ha-voice-assistant-setup-step-change-wake-word")
|
||||
export class HaVoiceAssistantSetupStepChangeWakeWord extends LitElement {
|
||||
@ -25,11 +24,15 @@ export class HaVoiceAssistantSetupStepChangeWakeWord extends LitElement {
|
||||
src="/static/images/voice-assistant/change-wake-word.png"
|
||||
alt="Casita Home Assistant logo"
|
||||
/>
|
||||
<h1>Change wake word</h1>
|
||||
<h1>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.change_wake_word.title"
|
||||
)}
|
||||
</h1>
|
||||
<p class="secondary">
|
||||
Some wake words are better for
|
||||
${formatLanguageCode(this.hass.locale.language, this.hass.locale)} and
|
||||
voice than others. Please try them out.
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.change_wake_word.secondary"
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<ha-md-list>
|
||||
|
@ -40,11 +40,15 @@ export class HaVoiceAssistantSetupStepCheck extends LitElement {
|
||||
src="/static/images/voice-assistant/error.png"
|
||||
alt="Casita Home Assistant error logo"
|
||||
/>
|
||||
<h1>The voice assistant is unable to connect to Home Assistant</h1>
|
||||
<h1>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.check.failed_title"
|
||||
)}
|
||||
</h1>
|
||||
<p class="secondary">
|
||||
To play audio, the voice assistant device has to connect to Home
|
||||
Assistant to fetch the files. Our test shows that the device is
|
||||
unable to reach the Home Assistant server.
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.check.failed_secondary"
|
||||
)}
|
||||
</p>
|
||||
<div class="footer">
|
||||
<a
|
||||
@ -52,18 +56,31 @@ export class HaVoiceAssistantSetupStepCheck extends LitElement {
|
||||
this.hass,
|
||||
"/voice_control/troubleshooting/#i-dont-get-a-voice-response"
|
||||
)}
|
||||
><ha-button>Help me</ha-button></a
|
||||
><ha-button
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.check.help"
|
||||
)}</ha-button
|
||||
></a
|
||||
>
|
||||
<ha-button @click=${this._testConnection}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.check.retry"
|
||||
)}</ha-button
|
||||
>
|
||||
<ha-button @click=${this._testConnection}>Retry</ha-button>
|
||||
</div>`
|
||||
: html`<img
|
||||
src="/static/images/voice-assistant/hi.png"
|
||||
alt="Casita Home Assistant hi logo"
|
||||
/>
|
||||
<h1>Hi</h1>
|
||||
<h1>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.check.title"
|
||||
)}
|
||||
</h1>
|
||||
<p class="secondary">
|
||||
Over the next couple steps we're going to personalize your voice
|
||||
assistant.
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.check.secondary"
|
||||
)}
|
||||
</p>
|
||||
|
||||
${this._showLoader
|
||||
|
@ -11,7 +11,11 @@ import {
|
||||
listAssistPipelines,
|
||||
} from "../../data/assist_pipeline";
|
||||
import type { AssistSatelliteConfiguration } from "../../data/assist_satellite";
|
||||
import { createConfigFlow, handleConfigFlowStep } from "../../data/config_flow";
|
||||
import {
|
||||
createConfigFlow,
|
||||
fetchConfigFlowInProgress,
|
||||
handleConfigFlowStep,
|
||||
} from "../../data/config_flow";
|
||||
import type { EntityRegistryDisplayEntry } from "../../data/entity_registry";
|
||||
import {
|
||||
fetchHassioAddonsInfo,
|
||||
@ -50,9 +54,15 @@ export class HaVoiceAssistantSetupStepLocal extends LitElement {
|
||||
src="/static/images/voice-assistant/update.png"
|
||||
alt="Casita Home Assistant loading logo"
|
||||
/>
|
||||
<h1>Installing add-ons</h1>
|
||||
<h1>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.local.title"
|
||||
)}
|
||||
</h1>
|
||||
<p>
|
||||
The Whisper and Piper add-ons are being installed and configured.
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.local.secondary"
|
||||
)}
|
||||
</p>
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
<p>
|
||||
@ -63,13 +73,20 @@ export class HaVoiceAssistantSetupStepLocal extends LitElement {
|
||||
src="/static/images/voice-assistant/error.png"
|
||||
alt="Casita Home Assistant error logo"
|
||||
/>
|
||||
<h1>Failed to install add-ons</h1>
|
||||
<h1>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.local.failed_title"
|
||||
)}
|
||||
</h1>
|
||||
<p>${this._error}</p>
|
||||
<p>
|
||||
We could not automatically install a local TTS and STT provider
|
||||
for you. Read the documentation to learn how to install them.
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.local.failed_secondary"
|
||||
)}
|
||||
</p>
|
||||
<ha-button @click=${this._prevStep}>Go back</ha-button>
|
||||
<ha-button @click=${this._prevStep}
|
||||
>${this.hass.localize("ui.common.back")}</ha-button
|
||||
>
|
||||
<a
|
||||
href=${documentationUrl(
|
||||
this.hass,
|
||||
@ -80,7 +97,9 @@ export class HaVoiceAssistantSetupStepLocal extends LitElement {
|
||||
>
|
||||
<ha-button>
|
||||
<ha-svg-icon .path=${mdiOpenInNew} slot="icon"></ha-svg-icon>
|
||||
Learn more</ha-button
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.common.learn_more"
|
||||
)}</ha-button
|
||||
>
|
||||
</a>`
|
||||
: this._state === "NOT_SUPPORTED"
|
||||
@ -88,13 +107,19 @@ export class HaVoiceAssistantSetupStepLocal extends LitElement {
|
||||
src="/static/images/voice-assistant/error.png"
|
||||
alt="Casita Home Assistant error logo"
|
||||
/>
|
||||
<h1>Installation of add-ons is not supported on your system</h1>
|
||||
<h1>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.local.not_supported_title"
|
||||
)}
|
||||
</h1>
|
||||
<p>
|
||||
Your system is not supported to automatically install a local
|
||||
TTS and STT provider. Learn how to set up local TTS and STT
|
||||
providers in the documentation.
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.local.not_supported_secondary"
|
||||
)}
|
||||
</p>
|
||||
<ha-button @click=${this._prevStep}>Go back</ha-button>
|
||||
<ha-button @click=${this._prevStep}
|
||||
>${this.hass.localize("ui.common.back")}</ha-button
|
||||
>
|
||||
<a
|
||||
href=${documentationUrl(
|
||||
this.hass,
|
||||
@ -108,7 +133,9 @@ export class HaVoiceAssistantSetupStepLocal extends LitElement {
|
||||
.path=${mdiOpenInNew}
|
||||
slot="icon"
|
||||
></ha-svg-icon>
|
||||
Learn more</ha-button
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.common.learn_more"
|
||||
)}</ha-button
|
||||
>
|
||||
</a>`
|
||||
: nothing}
|
||||
@ -151,29 +178,43 @@ export class HaVoiceAssistantSetupStepLocal extends LitElement {
|
||||
const piper = addons.find((addon) => addon.slug === "core_piper");
|
||||
if (!this._localTts.length) {
|
||||
if (!piper) {
|
||||
this._detailState = "Installing Piper add-on";
|
||||
this._detailState = this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.local.state.installing_piper"
|
||||
);
|
||||
await installHassioAddon(this.hass, "core_piper");
|
||||
}
|
||||
if (!piper || piper.state !== "started") {
|
||||
this._detailState = "Starting Piper add-on";
|
||||
this._detailState = this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.local.state.starting_piper"
|
||||
);
|
||||
await startHassioAddon(this.hass, "core_piper");
|
||||
}
|
||||
this._detailState = "Setting up Piper";
|
||||
this._detailState = this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.local.state.setup_piper"
|
||||
);
|
||||
await this._setupConfigEntry("piper");
|
||||
}
|
||||
if (!this._localStt.length) {
|
||||
if (!whisper) {
|
||||
this._detailState = "Installing Whisper add-on";
|
||||
this._detailState = this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.local.state.installing_whisper"
|
||||
);
|
||||
await installHassioAddon(this.hass, "core_whisper");
|
||||
}
|
||||
if (!whisper || whisper.state !== "started") {
|
||||
this._detailState = "Starting Whisper add-on";
|
||||
this._detailState = this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.local.state.starting_whisper"
|
||||
);
|
||||
await startHassioAddon(this.hass, "core_whisper");
|
||||
}
|
||||
this._detailState = "Setting up Whisper";
|
||||
this._detailState = this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.local.state.setup_whisper"
|
||||
);
|
||||
await this._setupConfigEntry("whisper");
|
||||
}
|
||||
this._detailState = "Creating assistant";
|
||||
this._detailState = this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.local.state.creating_pipeline"
|
||||
);
|
||||
await this._findEntitiesAndCreatePipeline();
|
||||
} catch (e: any) {
|
||||
this._state = "ERROR";
|
||||
@ -194,6 +235,35 @@ export class HaVoiceAssistantSetupStepLocal extends LitElement {
|
||||
}
|
||||
|
||||
private async _setupConfigEntry(addon: string) {
|
||||
const configFlow = await this._findConfigFlowInProgress(addon);
|
||||
|
||||
if (configFlow) {
|
||||
const step = await handleConfigFlowStep(
|
||||
this.hass,
|
||||
configFlow.flow_id,
|
||||
{}
|
||||
);
|
||||
if (step.type === "create_entry") {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
return this._createConfigEntry(addon);
|
||||
}
|
||||
|
||||
private async _findConfigFlowInProgress(addon: string) {
|
||||
const configFlows = await fetchConfigFlowInProgress(this.hass.connection);
|
||||
|
||||
return configFlows.find(
|
||||
(flow) =>
|
||||
flow.handler === "wyoming" &&
|
||||
flow.context.source === "hassio" &&
|
||||
(flow.context.configuration_url.includes(`core_${addon}`) ||
|
||||
flow.context.title_placeholders.title.toLowerCase().includes(addon))
|
||||
);
|
||||
}
|
||||
|
||||
private async _createConfigEntry(addon: string) {
|
||||
const configFlow = await createConfigFlow(this.hass, "wyoming");
|
||||
const step = await handleConfigFlowStep(this.hass, configFlow.flow_id, {
|
||||
host: `core-${addon}`,
|
||||
@ -201,7 +271,7 @@ export class HaVoiceAssistantSetupStepLocal extends LitElement {
|
||||
});
|
||||
if (step.type !== "create_entry") {
|
||||
throw new Error(
|
||||
`Failed to create entry for ${addon}${"errors" in step ? `: ${step.errors.base}` : ""}`
|
||||
`${this.hass.localize("ui.panel.config.voice_assistants.satellite_wizard.local.errors.failed_create_entry", { addon })}${"errors" in step ? `: ${step.errors.base}` : ""}`
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -289,7 +359,9 @@ export class HaVoiceAssistantSetupStepLocal extends LitElement {
|
||||
)
|
||||
).providers.find((provider) => provider.engine_id === sttEntityId);
|
||||
|
||||
let pipelineName = "Local Assistant";
|
||||
let pipelineName = this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.local.local_pipeline"
|
||||
);
|
||||
let i = 1;
|
||||
while (
|
||||
pipelines.pipelines.find(
|
||||
@ -297,7 +369,7 @@ export class HaVoiceAssistantSetupStepLocal extends LitElement {
|
||||
(pipeline) => pipeline.name === pipelineName
|
||||
)
|
||||
) {
|
||||
pipelineName = `Local Assistant ${i}`;
|
||||
pipelineName = `${this.hass.localize("ui.panel.config.voice_assistants.satellite_wizard.local.local_pipeline")} ${i}`;
|
||||
i++;
|
||||
}
|
||||
|
||||
@ -320,7 +392,11 @@ export class HaVoiceAssistantSetupStepLocal extends LitElement {
|
||||
this._findLocalEntities();
|
||||
if (!this._localTts?.length || !this._localStt?.length) {
|
||||
if (tryNo > 3) {
|
||||
throw new Error("Could not find local TTS and STT entities");
|
||||
throw new Error(
|
||||
this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.local.errors.could_not_find_entities"
|
||||
)
|
||||
);
|
||||
}
|
||||
await new Promise<void>((resolve) => {
|
||||
setTimeout(resolve, 2000);
|
||||
|
@ -14,9 +14,9 @@ import { fetchCloudStatus } from "../../data/cloud";
|
||||
import { listSTTEngines } from "../../data/stt";
|
||||
import { listTTSEngines, listTTSVoices } from "../../data/tts";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import { documentationUrl } from "../../util/documentation-url";
|
||||
import { AssistantSetupStyles } from "./styles";
|
||||
import { STEP } from "./voice-assistant-setup-dialog";
|
||||
import { documentationUrl } from "../../util/documentation-url";
|
||||
|
||||
@customElement("ha-voice-assistant-setup-step-pipeline")
|
||||
export class HaVoiceAssistantSetupStepPipeline extends LitElement {
|
||||
@ -69,10 +69,15 @@ export class HaVoiceAssistantSetupStepPipeline extends LitElement {
|
||||
}
|
||||
|
||||
return html`<div class="content">
|
||||
<h1>What hardware do you want to use?</h1>
|
||||
<h1>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.pipeline.title"
|
||||
)}
|
||||
</h1>
|
||||
<p class="secondary">
|
||||
How quickly your assistant responds depends on the power of the
|
||||
hardware.
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.pipeline.secondary"
|
||||
)}
|
||||
</p>
|
||||
<div class="container">
|
||||
<div class="messages-container cloud">
|
||||
@ -80,7 +85,12 @@ export class HaVoiceAssistantSetupStepPipeline extends LitElement {
|
||||
${!this._showFirst ? "…" : "Turn on the lights in the bedroom"}
|
||||
</div>
|
||||
${this._showFirst
|
||||
? html`<div class="timing user">0.2 seconds</div>`
|
||||
? html`<div class="timing user">
|
||||
0.2
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.pipeline.seconds"
|
||||
)}
|
||||
</div>`
|
||||
: nothing}
|
||||
${this._showFirst
|
||||
? html` <div class="message hass ${this._showSecond ? "show" : ""}">
|
||||
@ -88,12 +98,23 @@ export class HaVoiceAssistantSetupStepPipeline extends LitElement {
|
||||
</div>`
|
||||
: nothing}
|
||||
${this._showSecond
|
||||
? html`<div class="timing hass">0.4 seconds</div>`
|
||||
? html`<div class="timing hass">
|
||||
0.4
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.pipeline.seconds"
|
||||
)}
|
||||
</div>`
|
||||
: nothing}
|
||||
</div>
|
||||
<h2>Home Assistant Cloud</h2>
|
||||
<p>Ideal if you don't have a powerful system at home.</p>
|
||||
<ha-button @click=${this._setupCloud} unelevated>Learn more</ha-button>
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.pipeline.cloud.description"
|
||||
)}
|
||||
</p>
|
||||
<ha-button @click=${this._setupCloud} unelevated
|
||||
>${this.hass.localize("ui.panel.config.common.learn_more")}</ha-button
|
||||
>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="messages-container rpi">
|
||||
@ -101,7 +122,12 @@ export class HaVoiceAssistantSetupStepPipeline extends LitElement {
|
||||
${!this._showThird ? "…" : "Turn on the lights in the bedroom"}
|
||||
</div>
|
||||
${this._showThird
|
||||
? html`<div class="timing user">3 seconds</div>`
|
||||
? html`<div class="timing user">
|
||||
3
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.pipeline.seconds"
|
||||
)}
|
||||
</div>`
|
||||
: nothing}
|
||||
${this._showThird
|
||||
? html`<div class="message hass ${this._showFourth ? "show" : ""}">
|
||||
@ -109,13 +135,23 @@ export class HaVoiceAssistantSetupStepPipeline extends LitElement {
|
||||
</div>`
|
||||
: nothing}
|
||||
${this._showFourth
|
||||
? html`<div class="timing hass">5 seconds</div>`
|
||||
? html`<div class="timing hass">
|
||||
5
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.pipeline.seconds"
|
||||
)}
|
||||
</div>`
|
||||
: nothing}
|
||||
</div>
|
||||
<h2>Do-it-yourself</h2>
|
||||
<h2>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.pipeline.local.title"
|
||||
)}
|
||||
</h2>
|
||||
<p>
|
||||
Install add-ons or containers to run it on your own system. Powerful
|
||||
hardware is needed for fast responses.
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.pipeline.local.description"
|
||||
)}
|
||||
</p>
|
||||
<div class="row">
|
||||
<a
|
||||
@ -128,11 +164,15 @@ export class HaVoiceAssistantSetupStepPipeline extends LitElement {
|
||||
>
|
||||
<ha-button>
|
||||
<ha-svg-icon .path=${mdiOpenInNew} slot="icon"></ha-svg-icon>
|
||||
Learn more</ha-button
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.common.learn_more"
|
||||
)}</ha-button
|
||||
>
|
||||
</a>
|
||||
<ha-button @click=${this._setupLocal} unelevated
|
||||
>Setup with add-ons</ha-button
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.pipeline.local.setup"
|
||||
)}</ha-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -72,10 +72,15 @@ export class HaVoiceAssistantSetupStepSuccess extends LitElement {
|
||||
src="/static/images/voice-assistant/heart.png"
|
||||
alt="Casita Home Assistant logo"
|
||||
/>
|
||||
<h1>Ready to Assist!</h1>
|
||||
<h1>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.success.title"
|
||||
)}
|
||||
</h1>
|
||||
<p class="secondary">
|
||||
Make any final customizations here. You can always change these in the
|
||||
Voice Assistants section of the settings page.
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.success.secondary"
|
||||
)}
|
||||
</p>
|
||||
<div class="rows">
|
||||
${this.assistConfiguration &&
|
||||
|
@ -72,12 +72,17 @@ export class HaVoiceAssistantSetupStepUpdate extends LitElement {
|
||||
<h1>
|
||||
${stateObj &&
|
||||
(stateObj.state === "unavailable" || updateIsInstalling(stateObj))
|
||||
? "Updating your voice assistant"
|
||||
: "Checking for updates"}
|
||||
? this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.update.title"
|
||||
)
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.update.checking"
|
||||
)}
|
||||
</h1>
|
||||
<p class="secondary">
|
||||
We are making sure you have the latest and greatest version of your
|
||||
voice assistant. This may take a few minutes.
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.update.secondary"
|
||||
)}
|
||||
</p>
|
||||
<ha-circular-progress
|
||||
.value=${progressIsNumeric
|
||||
|
@ -92,34 +92,55 @@ export class HaVoiceAssistantSetupStepWakeWord extends LitElement {
|
||||
? html`
|
||||
<img src="/static/images/voice-assistant/sleep.png" alt="Casita Home Assistant logo"/>
|
||||
<h1>
|
||||
Say “${this._activeWakeWord(this.assistConfiguration)}” to wake the
|
||||
device up
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.wake_word.title",
|
||||
{ wakeword: this._activeWakeWord(this.assistConfiguration) }
|
||||
)}
|
||||
</h1>
|
||||
<p class="secondary">Setup will continue once the device is awake.</p>
|
||||
<p class="secondary">${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.wake_word.secondary"
|
||||
)}</p>
|
||||
</div>`
|
||||
: html`<img
|
||||
src="/static/images/voice-assistant/ok-nabu.png"
|
||||
alt="Casita Home Assistant logo"
|
||||
/>
|
||||
<h1>
|
||||
Say “${this._activeWakeWord(this.assistConfiguration)}” again
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.wake_word.title_2",
|
||||
{ wakeword: this._activeWakeWord(this.assistConfiguration) }
|
||||
)}
|
||||
</h1>
|
||||
<p class="secondary">
|
||||
To make sure the wake word works for you.
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.wake_word.secondary_2"
|
||||
)}
|
||||
</p>`}
|
||||
${this._timedout
|
||||
? html`<ha-alert alert-type="warning"
|
||||
>We have not heard the wake word, is your device muted?</ha-alert
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.wake_word.time_out"
|
||||
)}</ha-alert
|
||||
>`
|
||||
: this._muteSwitchEntity &&
|
||||
this.hass.states[this._muteSwitchEntity].state === "on"
|
||||
? html`<ha-alert alert-type="warning" title="Your device is muted"
|
||||
>Please unmute your device to continue.</ha-alert
|
||||
? html`<ha-alert
|
||||
alert-type="warning"
|
||||
.title=${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.wake_word.muted"
|
||||
)}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.wake_word.muted_description"
|
||||
)}</ha-alert
|
||||
>`
|
||||
: nothing}
|
||||
</div>
|
||||
<div class="footer centered">
|
||||
<ha-button @click=${this._changeWakeWord}>Change wake word</ha-button>
|
||||
<ha-button @click=${this._changeWakeWord}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.satellite_wizard.wake_word.change_wake_word"
|
||||
)}</ha-button
|
||||
>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import "../card-features/hui-alarm-modes-card-feature";
|
||||
import "../card-features/hui-climate-fan-modes-card-feature";
|
||||
import "../card-features/hui-climate-swing-modes-card-feature";
|
||||
import "../card-features/hui-climate-swing-horizontal-modes-card-feature";
|
||||
import "../card-features/hui-climate-hvac-modes-card-feature";
|
||||
import "../card-features/hui-climate-preset-modes-card-feature";
|
||||
import "../card-features/hui-cover-open-close-card-feature";
|
||||
|
@ -2771,6 +2771,10 @@
|
||||
"speech": {
|
||||
"title": "Amazing speech options for Assist",
|
||||
"text": "Bring personality to your home by having it speak to you using our neural-network powered speech-to-text and text-to-speech services."
|
||||
},
|
||||
"remote_access": {
|
||||
"title": "Remote access",
|
||||
"text": " Secure remote access to your system while supporting the development of Home Assistant."
|
||||
}
|
||||
},
|
||||
"and_more": "And more",
|
||||
@ -2824,6 +2828,83 @@
|
||||
"expose_to": "to {assistants}",
|
||||
"expose_entities": "Expose {count} {count, plural,\n one {entity}\n other {entities}\n}"
|
||||
}
|
||||
},
|
||||
"satellite_wizard": {
|
||||
"skip": "Skip",
|
||||
"not_available": "Your voice assistant is not available.",
|
||||
"update": {
|
||||
"title": "Updating",
|
||||
"checking": "Checking for updates",
|
||||
"secondary": "We are making sure you have the latest updates. This may take a few minutes."
|
||||
},
|
||||
"check": {
|
||||
"title": "Hello!",
|
||||
"secondary": "Over the next couple steps we're going to personalize your voice assistant.",
|
||||
"failed_title": "The voice assistant is unable to connect to Home Assistant",
|
||||
"failed_secondary": "To play audio, the voice assistant device has to connect to Home Assistant to fetch the files. Our test shows that the device is unable to reach the Home Assistant server.",
|
||||
"help": "Help me",
|
||||
"retry": "Retry"
|
||||
},
|
||||
"wake_word": {
|
||||
"title": "Say ''{wakeword}'' to wake the device up",
|
||||
"secondary": "Setup will continue once the device is awake.",
|
||||
"title_2": "Say ''{wakeword}'' again",
|
||||
"secondary_2": "To make sure the wake word works for you.",
|
||||
"change_wake_word": "Change wake word",
|
||||
"time_out": "We have not heard the wake word, is your device muted?",
|
||||
"muted": "Your device is muted",
|
||||
"muted_description": "Please unmute your device to continue."
|
||||
},
|
||||
"change_wake_word": {
|
||||
"title": "Change wake word",
|
||||
"secondary": "These are the phrases you can use to wake your device and have it start listening for commands."
|
||||
},
|
||||
"area": {
|
||||
"title": "Select area",
|
||||
"secondary": "When your voice assistant knows where it is, it can better control the devices around it. This allows you to control devices in the room with short commands, like 'turn on the lights'",
|
||||
"no_selection": "Please select an area"
|
||||
},
|
||||
"pipeline": {
|
||||
"title": "What hardware do you want to use?",
|
||||
"secondary": "How quickly your assistant responds depends on the power of the hardware.",
|
||||
"seconds": "seconds",
|
||||
"cloud": {
|
||||
"description": "Ideal if you don't have a powerful system at home."
|
||||
},
|
||||
"local": { "title": "", "description": "", "setup": "" }
|
||||
},
|
||||
"cloud": {
|
||||
"title": "The power of Home Assistant Cloud",
|
||||
"register": {
|
||||
"confirm_email": "Confirm email"
|
||||
}
|
||||
},
|
||||
"local": {
|
||||
"title": "Installing add-ons",
|
||||
"secondary": "The Whisper and Piper add-ons are being installed and configured based on your hardware.",
|
||||
"failed_title": "Failed to install add-ons",
|
||||
"failed_secondary": "We were unable to install the Whisper and Piper add-ons automatically for you. Read the documentation to learn how to install them.",
|
||||
"not_supported_title": "Installation of add-ons is not supported on your system",
|
||||
"not_supported_secondary": "Your system is not supported to automatically install a local TTS and STT provider. Learn how to set up local TTS and STT providers in the documentation.",
|
||||
"local_pipeline": "Local Assistant",
|
||||
"state": {
|
||||
"installing_piper": "Installing Piper add-on",
|
||||
"starting_piper": "Starting Piper add-on",
|
||||
"setup_piper": "Setting up Piper",
|
||||
"installing_whisper": "Installing Whisper add-on",
|
||||
"starting_whisper": "Starting Whisper add-on",
|
||||
"setup_whisper": "Setting up Whisper",
|
||||
"creating_pipeline": "Creating assistant"
|
||||
},
|
||||
"errors": {
|
||||
"failed_create_entry": "Failed to create entry for {addon}",
|
||||
"could_not_find_entities": "Could not find local TTS and STT entities"
|
||||
}
|
||||
},
|
||||
"success": {
|
||||
"title": "Ready to Assist!",
|
||||
"secondary": "Make any final customizations here. You can always change these in the Voice Assistants section of the settings page."
|
||||
}
|
||||
}
|
||||
},
|
||||
"automation": {
|
||||
@ -3124,7 +3205,8 @@
|
||||
"description": {
|
||||
"picker": "When Assist matches a sentence from a voice assistant.",
|
||||
"empty": "When a sentence is said",
|
||||
"full": "When the sentence {sentence} is said"
|
||||
"single": "When the sentence ''{sentence}'' is said",
|
||||
"multiple": "When the sentence ''{sentence}'' or {count, plural,\n one {another}\n other {{count} others}\n} are said"
|
||||
}
|
||||
},
|
||||
"tag": {
|
||||
@ -3598,7 +3680,8 @@
|
||||
"label": "Set conversation response",
|
||||
"description": {
|
||||
"picker": "Set response of conversation if automation was triggered by conversation trigger.",
|
||||
"full": "Set response of conversation to {response}"
|
||||
"template": "Set response of conversation to a template",
|
||||
"full": "Set response of conversation to ''{response}''"
|
||||
}
|
||||
},
|
||||
"unknown": {
|
||||
@ -3965,6 +4048,8 @@
|
||||
"password_error_msg": "Passwords are at least 8 characters",
|
||||
"start_trial": "Start trial",
|
||||
"resend_confirm_email": "Resend confirmation email",
|
||||
"clicked_confirm": "I clicked the confirmation link",
|
||||
"confirm_email": "Check the email we just sent to {email} and click the confirmation link to continue.",
|
||||
"account_created": "Account created! Check your email for instructions on how to activate your account."
|
||||
},
|
||||
"account": {
|
||||
|
Loading…
x
Reference in New Issue
Block a user