mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
Add wake word to assist pipeline settings (#18019)
* Add wake word to assist pipeline settings * Update assist-pipeline-detail-wakeword.ts * Add icon for wake word domain * format state * implement `wake_word/info` command
This commit is contained in:
parent
2a8d98307e
commit
c567a61dd7
@ -15,6 +15,7 @@ import {
|
|||||||
mdiCalendarClock,
|
mdiCalendarClock,
|
||||||
mdiCarCoolantLevel,
|
mdiCarCoolantLevel,
|
||||||
mdiCash,
|
mdiCash,
|
||||||
|
mdiChatSleep,
|
||||||
mdiClock,
|
mdiClock,
|
||||||
mdiCloudUpload,
|
mdiCloudUpload,
|
||||||
mdiCog,
|
mdiCog,
|
||||||
@ -124,6 +125,7 @@ export const FIXED_DOMAIN_ICONS = {
|
|||||||
tts: mdiSpeakerMessage,
|
tts: mdiSpeakerMessage,
|
||||||
updater: mdiCloudUpload,
|
updater: mdiCloudUpload,
|
||||||
vacuum: mdiRobotVacuum,
|
vacuum: mdiRobotVacuum,
|
||||||
|
wake_word: mdiChatSleep,
|
||||||
zone: mdiMapMarkerRadius,
|
zone: mdiMapMarkerRadius,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -193,6 +193,7 @@ export const computeStateDisplayFromEntityAttributes = (
|
|||||||
"scene",
|
"scene",
|
||||||
"stt",
|
"stt",
|
||||||
"tts",
|
"tts",
|
||||||
|
"wake_word",
|
||||||
].includes(domain) ||
|
].includes(domain) ||
|
||||||
(domain === "sensor" && attributes.device_class === "timestamp")
|
(domain === "sensor" && attributes.device_class === "timestamp")
|
||||||
) {
|
) {
|
||||||
|
@ -14,6 +14,8 @@ export interface AssistPipeline {
|
|||||||
tts_engine: string | null;
|
tts_engine: string | null;
|
||||||
tts_language: string | null;
|
tts_language: string | null;
|
||||||
tts_voice: string | null;
|
tts_voice: string | null;
|
||||||
|
wake_word_entity: string | null;
|
||||||
|
wake_word_id: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AssistPipelineMutableParams {
|
export interface AssistPipelineMutableParams {
|
||||||
@ -26,6 +28,8 @@ export interface AssistPipelineMutableParams {
|
|||||||
tts_engine: string | null;
|
tts_engine: string | null;
|
||||||
tts_language: string | null;
|
tts_language: string | null;
|
||||||
tts_voice: string | null;
|
tts_voice: string | null;
|
||||||
|
wake_word_entity: string | null;
|
||||||
|
wake_word_id: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface assistRunListing {
|
export interface assistRunListing {
|
||||||
|
12
src/data/wake_word.ts
Normal file
12
src/data/wake_word.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import type { HomeAssistant } from "../types";
|
||||||
|
|
||||||
|
export interface WakeWord {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const fetchWakeWordInfo = (hass: HomeAssistant, entity_id: string) =>
|
||||||
|
hass.callWS<{ wake_words: WakeWord[] }>({
|
||||||
|
type: "wake_word/info",
|
||||||
|
entity_id,
|
||||||
|
});
|
@ -0,0 +1,138 @@
|
|||||||
|
import { css, CSSResultGroup, html, LitElement, PropertyValues } from "lit";
|
||||||
|
import { customElement, property, state } from "lit/decorators";
|
||||||
|
import memoizeOne from "memoize-one";
|
||||||
|
import { LocalizeKeys } from "../../../../common/translations/localize";
|
||||||
|
import "../../../../components/ha-form/ha-form";
|
||||||
|
import { AssistPipeline } from "../../../../data/assist_pipeline";
|
||||||
|
import { HomeAssistant } from "../../../../types";
|
||||||
|
import { fetchWakeWordInfo, WakeWord } from "../../../../data/wake_word";
|
||||||
|
|
||||||
|
@customElement("assist-pipeline-detail-wakeword")
|
||||||
|
export class AssistPipelineDetailWakeWord extends LitElement {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property() public data?: Partial<AssistPipeline>;
|
||||||
|
|
||||||
|
@state() private _wakeWords?: WakeWord[];
|
||||||
|
|
||||||
|
private _schema = memoizeOne(
|
||||||
|
(wakeWords?: WakeWord[]) =>
|
||||||
|
[
|
||||||
|
{
|
||||||
|
name: "",
|
||||||
|
type: "grid",
|
||||||
|
schema: [
|
||||||
|
{
|
||||||
|
name: "wake_word_entity",
|
||||||
|
selector: {
|
||||||
|
entity: {
|
||||||
|
domain: "wake_word",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wakeWords?.length
|
||||||
|
? {
|
||||||
|
name: "wake_word_id",
|
||||||
|
required: true,
|
||||||
|
selector: {
|
||||||
|
select: {
|
||||||
|
options: wakeWords.map((ww) => ({
|
||||||
|
value: ww.id,
|
||||||
|
label: ww.name,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
: { name: "", type: "constant" },
|
||||||
|
] as const,
|
||||||
|
},
|
||||||
|
] as const
|
||||||
|
);
|
||||||
|
|
||||||
|
private _computeLabel = (schema): string =>
|
||||||
|
schema.name
|
||||||
|
? this.hass.localize(
|
||||||
|
`ui.panel.config.voice_assistants.assistants.pipeline.detail.form.${schema.name}` as LocalizeKeys
|
||||||
|
)
|
||||||
|
: "";
|
||||||
|
|
||||||
|
protected willUpdate(changedProps: PropertyValues) {
|
||||||
|
if (
|
||||||
|
changedProps.has("data") &&
|
||||||
|
changedProps.get("data")?.wake_word_entity !== this.data?.wake_word_entity
|
||||||
|
) {
|
||||||
|
this._fetchWakeWords();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
return html`
|
||||||
|
<div class="section">
|
||||||
|
<div class="content">
|
||||||
|
<div class="intro">
|
||||||
|
<h3>
|
||||||
|
${this.hass.localize(
|
||||||
|
`ui.panel.config.voice_assistants.assistants.pipeline.detail.steps.wakeword.title`
|
||||||
|
)}
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
${this.hass.localize(
|
||||||
|
`ui.panel.config.voice_assistants.assistants.pipeline.detail.steps.wakeword.description`
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<ha-form
|
||||||
|
.schema=${this._schema(this._wakeWords)}
|
||||||
|
.data=${this.data}
|
||||||
|
.hass=${this.hass}
|
||||||
|
.computeLabel=${this._computeLabel}
|
||||||
|
></ha-form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _fetchWakeWords() {
|
||||||
|
if (!this.data?.wake_word_entity) {
|
||||||
|
this._wakeWords = undefined;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._wakeWords = (
|
||||||
|
await fetchWakeWordInfo(this.hass, this.data.wake_word_entity)
|
||||||
|
).wake_words;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResultGroup {
|
||||||
|
return css`
|
||||||
|
.section {
|
||||||
|
border: 1px solid var(--divider-color);
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
.intro {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 22px;
|
||||||
|
line-height: 28px;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
color: var(--secondary-text-color);
|
||||||
|
font-size: var(--mdc-typography-body2-font-size, 0.875rem);
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"assist-pipeline-detail-wakeword": AssistPipelineDetailWakeWord;
|
||||||
|
}
|
||||||
|
}
|
@ -25,6 +25,7 @@ import "./assist-pipeline-detail/assist-pipeline-detail-config";
|
|||||||
import "./assist-pipeline-detail/assist-pipeline-detail-conversation";
|
import "./assist-pipeline-detail/assist-pipeline-detail-conversation";
|
||||||
import "./assist-pipeline-detail/assist-pipeline-detail-stt";
|
import "./assist-pipeline-detail/assist-pipeline-detail-stt";
|
||||||
import "./assist-pipeline-detail/assist-pipeline-detail-tts";
|
import "./assist-pipeline-detail/assist-pipeline-detail-tts";
|
||||||
|
import "./assist-pipeline-detail/assist-pipeline-detail-wakeword";
|
||||||
import "./debug/assist-render-pipeline-events";
|
import "./debug/assist-render-pipeline-events";
|
||||||
import { VoiceAssistantPipelineDetailsDialogParams } from "./show-dialog-voice-assistant-pipeline-detail";
|
import { VoiceAssistantPipelineDetailsDialogParams } from "./show-dialog-voice-assistant-pipeline-detail";
|
||||||
|
|
||||||
@ -192,6 +193,12 @@ export class DialogVoiceAssistantPipelineDetail extends LitElement {
|
|||||||
keys="tts_engine,tts_language,tts_voice"
|
keys="tts_engine,tts_language,tts_voice"
|
||||||
@value-changed=${this._valueChanged}
|
@value-changed=${this._valueChanged}
|
||||||
></assist-pipeline-detail-tts>
|
></assist-pipeline-detail-tts>
|
||||||
|
<assist-pipeline-detail-wakeword
|
||||||
|
.hass=${this.hass}
|
||||||
|
.data=${this._data}
|
||||||
|
keys="wake_word_entity,wake_word_id"
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
></assist-pipeline-detail-wakeword>
|
||||||
</div>
|
</div>
|
||||||
${this._params.pipeline?.id
|
${this._params.pipeline?.id
|
||||||
? html`
|
? html`
|
||||||
@ -249,6 +256,8 @@ export class DialogVoiceAssistantPipelineDetail extends LitElement {
|
|||||||
tts_engine: data.tts_engine ?? null,
|
tts_engine: data.tts_engine ?? null,
|
||||||
tts_language: data.tts_language ?? null,
|
tts_language: data.tts_language ?? null,
|
||||||
tts_voice: data.tts_voice ?? null,
|
tts_voice: data.tts_voice ?? null,
|
||||||
|
wake_word_entity: data.wake_word_entity ?? null,
|
||||||
|
wake_word_id: data.wake_word_id ?? null,
|
||||||
};
|
};
|
||||||
if (this._params!.pipeline?.id) {
|
if (this._params!.pipeline?.id) {
|
||||||
await this._params!.updatePipeline(values);
|
await this._params!.updatePipeline(values);
|
||||||
|
@ -2173,7 +2173,9 @@
|
|||||||
"stt_language": "[%key:ui::panel::config::voice_assistants::assistants::pipeline::detail::form::language%]",
|
"stt_language": "[%key:ui::panel::config::voice_assistants::assistants::pipeline::detail::form::language%]",
|
||||||
"tts_engine": "Text-to-speech",
|
"tts_engine": "Text-to-speech",
|
||||||
"tts_language": "[%key:ui::panel::config::voice_assistants::assistants::pipeline::detail::form::language%]",
|
"tts_language": "[%key:ui::panel::config::voice_assistants::assistants::pipeline::detail::form::language%]",
|
||||||
"tts_voice": "Voice"
|
"tts_voice": "Voice",
|
||||||
|
"wake_word_entity": "Wake word engine",
|
||||||
|
"wake_word_id": "Wake word"
|
||||||
},
|
},
|
||||||
"steps": {
|
"steps": {
|
||||||
"config": {
|
"config": {
|
||||||
@ -2191,6 +2193,10 @@
|
|||||||
"tts": {
|
"tts": {
|
||||||
"title": "Text-to-speech",
|
"title": "Text-to-speech",
|
||||||
"description": "When you are controlling your assistant with voice, the text-to-speech engine turns the conversation text responses into audio."
|
"description": "When you are controlling your assistant with voice, the text-to-speech engine turns the conversation text responses into audio."
|
||||||
|
},
|
||||||
|
"wakeword": {
|
||||||
|
"title": "Wake word",
|
||||||
|
"description": "If a device supports wake words, you can activate Assist by saying this word."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"no_cloud_message": "You should have an active cloud subscription to use cloud speech services.",
|
"no_cloud_message": "You should have an active cloud subscription to use cloud speech services.",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user