Add not supported warning in entity voice settings (#16336)

* Add not supported warning in entity voice settings

* Add alexa support and improve style

* Only toggle supported

---------

Co-authored-by: Paul Bottein <paul.bottein@gmail.com>
This commit is contained in:
Bram Kragten 2023-04-27 17:11:49 +02:00 committed by GitHub
parent b3b74b8328
commit 29be64a858
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 90 additions and 31 deletions

View File

@ -9,5 +9,11 @@ export interface AlexaEntity {
export const fetchCloudAlexaEntities = (hass: HomeAssistant) => export const fetchCloudAlexaEntities = (hass: HomeAssistant) =>
hass.callWS<AlexaEntity[]>({ type: "cloud/alexa/entities" }); hass.callWS<AlexaEntity[]>({ type: "cloud/alexa/entities" });
export const fetchCloudAlexaEntity = (hass: HomeAssistant, entity_id: string) =>
hass.callWS<AlexaEntity>({
type: "cloud/alexa/entities/get",
entity_id,
});
export const syncCloudAlexaEntities = (hass: HomeAssistant) => export const syncCloudAlexaEntities = (hass: HomeAssistant) =>
hass.callWS({ type: "cloud/alexa/sync" }); hass.callWS({ type: "cloud/alexa/sync" });

View File

@ -19,6 +19,7 @@ import {
import "../../../components/ha-aliases-editor"; import "../../../components/ha-aliases-editor";
import "../../../components/ha-settings-row"; import "../../../components/ha-settings-row";
import "../../../components/ha-switch"; import "../../../components/ha-switch";
import { fetchCloudAlexaEntity } from "../../../data/alexa";
import { import {
CloudStatus, CloudStatus,
CloudStatusLoggedIn, CloudStatusLoggedIn,
@ -53,16 +54,16 @@ export class EntityVoiceSettings extends SubscribeMixin(LitElement) {
@state() private _googleEntity?: GoogleEntity; @state() private _googleEntity?: GoogleEntity;
@state() private _unsupported: Partial<
Record<"cloud.google_assistant" | "cloud.alexa" | "conversation", boolean>
> = {};
protected willUpdate(changedProps: PropertyValues<this>) { protected willUpdate(changedProps: PropertyValues<this>) {
if (!isComponentLoaded(this.hass, "cloud")) { if (!isComponentLoaded(this.hass, "cloud")) {
return; return;
} }
if (changedProps.has("entry") && this.entry) { if (changedProps.has("entry") && this.entry) {
fetchCloudGoogleEntity(this.hass, this.entry.entity_id).then( this._fetchEntities();
(googleEntity) => {
this._googleEntity = googleEntity;
}
);
} }
if (!this.hasUpdated) { if (!this.hasUpdated) {
fetchCloudStatus(this.hass).then((status) => { fetchCloudStatus(this.hass).then((status) => {
@ -71,6 +72,31 @@ export class EntityVoiceSettings extends SubscribeMixin(LitElement) {
} }
} }
private async _fetchEntities() {
try {
const googleEntity = await fetchCloudGoogleEntity(
this.hass,
this.entry.entity_id
);
this._googleEntity = googleEntity;
this.requestUpdate("_googleEntity");
} catch (err: any) {
if (err.code === "not_supported") {
this._unsupported["cloud.google_assistant"] = true;
this.requestUpdate("_unsupported");
}
}
try {
await fetchCloudAlexaEntity(this.hass, this.entry.entity_id);
} catch (err: any) {
if (err.code === "not_supported") {
this._unsupported["cloud.alexa"] = true;
this.requestUpdate("_unsupported");
}
}
}
private _getEntityFilterFuncs = memoizeOne( private _getEntityFilterFuncs = memoizeOne(
(googleFilter: EntityFilter, alexaFilter: EntityFilter) => ({ (googleFilter: EntityFilter, alexaFilter: EntityFilter) => ({
google: generateFilter( google: generateFilter(
@ -163,9 +189,28 @@ export class EntityVoiceSettings extends SubscribeMixin(LitElement) {
></ha-switch> ></ha-switch>
</ha-settings-row> </ha-settings-row>
${anyExposed ${anyExposed
? showAssistants.map( ? showAssistants.map((key) => {
(key) => html` const supported = !this._unsupported[key];
<ha-settings-row>
const exposed =
alexaManual && key === "cloud.alexa"
? manExposedAlexa
: googleManual && key === "cloud.google_assistant"
? manExposedGoogle
: this.entry.options?.[key]?.should_expose;
const manualConfig =
(alexaManual && key === "cloud.alexa") ||
(googleManual && key === "cloud.google_assistant");
const support2fa =
key === "cloud.google_assistant" &&
!googleManual &&
supported &&
this._googleEntity?.might_2fa;
return html`
<ha-settings-row .threeLine=${!supported && manualConfig}>
<img <img
alt="" alt=""
src=${brandsUrl({ src=${brandsUrl({
@ -177,9 +222,23 @@ export class EntityVoiceSettings extends SubscribeMixin(LitElement) {
slot="prefix" slot="prefix"
/> />
<span slot="heading">${voiceAssistants[key].name}</span> <span slot="heading">${voiceAssistants[key].name}</span>
${key === "cloud.google_assistant" && ${!supported
!googleManual && ? html`<div slot="description">
this._googleEntity?.might_2fa ${this.hass.localize(
"ui.dialogs.voice-settings.unsupported"
)}
</div>`
: nothing}
${manualConfig
? html`
<div slot="description">
${this.hass.localize(
"ui.dialogs.voice-settings.manual_config"
)}
</div>
`
: nothing}
${support2fa
? html` ? html`
<ha-formfield <ha-formfield
slot="description" slot="description"
@ -193,30 +252,16 @@ export class EntityVoiceSettings extends SubscribeMixin(LitElement) {
></ha-checkbox> ></ha-checkbox>
</ha-formfield> </ha-formfield>
` `
: (alexaManual && key === "cloud.alexa") ||
(googleManual && key === "cloud.google_assistant")
? html`
<span slot="description">
${this.hass.localize(
"ui.dialogs.voice-settings.manual_config"
)}
</span>
`
: nothing} : nothing}
<ha-switch <ha-switch
.assistant=${key} .assistant=${key}
@change=${this._toggleAssistant} @change=${this._toggleAssistant}
.disabled=${(alexaManual && key === "cloud.alexa") || .disabled=${manualConfig || (!exposed && !supported)}
(googleManual && key === "cloud.google_assistant")} .checked=${exposed}
.checked=${alexaManual && key === "cloud.alexa"
? manExposedAlexa
: googleManual && key === "cloud.google_assistant"
? manExposedGoogle
: this.entry.options?.[key]?.should_expose}
></ha-switch> ></ha-switch>
</ha-settings-row> </ha-settings-row>
` `;
) })
: nothing} : nothing}
<h3 class="header"> <h3 class="header">
@ -283,9 +328,15 @@ export class EntityVoiceSettings extends SubscribeMixin(LitElement) {
} }
private async _toggleAll(ev) { private async _toggleAll(ev) {
const expose = ev.target.checked;
const assistants = expose
? ev.target.assistants.filter((key) => !this._unsupported[key])
: ev.target.assistants;
exposeEntities( exposeEntities(
this.hass, this.hass,
ev.target.assistants, assistants,
[this.entry.entity_id], [this.entry.entity_id],
ev.target.checked ev.target.checked
); );
@ -305,6 +356,7 @@ export class EntityVoiceSettings extends SubscribeMixin(LitElement) {
margin: 32px; margin: 32px;
margin-top: 0; margin-top: 0;
--settings-row-prefix-display: contents; --settings-row-prefix-display: contents;
--settings-row-content-display: contents;
} }
ha-settings-row { ha-settings-row {
padding: 0; padding: 0;

View File

@ -1083,7 +1083,8 @@
"aliases_header": "Aliases", "aliases_header": "Aliases",
"aliases_description": "Aliases are supported by Assist and Google Assistant.", "aliases_description": "Aliases are supported by Assist and Google Assistant.",
"ask_pin": "Ask for PIN", "ask_pin": "Ask for PIN",
"manual_config": "Managed with filters in configuration.yaml" "manual_config": "Managed in configuration.yaml",
"unsupported": "Unsupported"
}, },
"restart": { "restart": {
"heading": "Restart Home Assistant", "heading": "Restart Home Assistant",