From 2550bff4e9954510e11f74b734cf9996d30228e4 Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Mon, 2 Dec 2024 02:18:03 -0800 Subject: [PATCH 1/7] Init new scenes in live edit mode (#23051) * Init new scenes in live edit mode * Update src/panels/config/scene/ha-scene-editor.ts Co-authored-by: Simon Lamon <32477463+silamon@users.noreply.github.com> * imports --------- Co-authored-by: Simon Lamon <32477463+silamon@users.noreply.github.com> --- src/panels/config/scene/ha-scene-editor.ts | 23 +++++++++++++++++++--- src/translations/en.json | 8 ++++---- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/panels/config/scene/ha-scene-editor.ts b/src/panels/config/scene/ha-scene-editor.ts index 80b6a97918a7..5dce2d45777d 100644 --- a/src/panels/config/scene/ha-scene-editor.ts +++ b/src/panels/config/scene/ha-scene-editor.ts @@ -7,7 +7,9 @@ import { mdiContentSave, mdiDelete, mdiDotsVertical, + mdiEye, mdiInformationOutline, + mdiMotionPlayOutline, mdiPlay, mdiTag, } from "@mdi/js"; @@ -204,6 +206,14 @@ export class HaSceneEditor extends SubscribeMixin( } ); + public connectedCallback() { + super.connectedCallback(); + if (!this.sceneId) { + this._mode = "live"; + this._subscribeEvents(); + } + } + public disconnectedCallback() { super.disconnectedCallback(); if (this._unsubscribeEvents) { @@ -387,15 +397,22 @@ export class HaSceneEditor extends SubscribeMixin( alert-type="info" .narrow=${this.narrow} .title=${this.hass.localize( - `ui.panel.config.scene.editor.${this._mode === "live" ? "live_preview" : "review_mode"}` + `ui.panel.config.scene.editor.${this._mode === "live" ? "live_edit" : "review_mode"}` )} > ${this.hass.localize( - `ui.panel.config.scene.editor.${this._mode === "live" ? "live_preview_detail" : "review_mode_detail"}` + `ui.panel.config.scene.editor.${this._mode === "live" ? "live_edit_detail" : "review_mode_detail"}` )} + + + ${this.hass.localize( - `ui.panel.config.scene.editor.${this._mode === "live" ? "back_to_review_mode" : "live_preview"}` + `ui.panel.config.scene.editor.${this._mode === "live" ? "switch_to_review_mode" : "live_edit"}` )} diff --git a/src/translations/en.json b/src/translations/en.json index 8069cf58ad32..20018575bdc7 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -3878,11 +3878,11 @@ }, "editor": { "review_mode": "Review Mode", - "review_mode_detail": "You can adjust the scene's details and remove devices or entities. To fully edit, switch to Live Preview, which will apply the scene.", - "live_preview": "Live Preview", - "live_preview_detail": "In Live Preview, all changes to this scene are applied in real-time to your devices and entities.", + "review_mode_detail": "You can adjust the scene's details and remove devices or entities. To fully edit, switch to Live Edit, which will apply the scene.", + "live_edit": "Live Edit", + "live_edit_detail": "In Live Edit, all changes to this scene are applied in real-time to your devices and entities.", "enter_live_mode_unsaved": "You have unsaved changes to this scene. Continuing to live preview will apply the saved scene, which may overwrite your unsaved changes. Consider if you would like to save the scene first before activating it.", - "back_to_review_mode": "Back to review mode", + "switch_to_review_mode": "Switch to review mode", "default_name": "New scene", "load_error_not_editable": "Only scenes in scenes.yaml are editable.", "load_error_unknown": "Error loading scene ({err_no}).", From 6d01728d54268bf6833a802b825ca850b74ad6f0 Mon Sep 17 00:00:00 2001 From: Alex Jurkiewicz Date: Mon, 2 Dec 2024 18:48:12 +0800 Subject: [PATCH 2/7] `history-graph-card-editor`: Correct `hours_to_show` validation (#23090) history-graph-card-editor: Correct hours_to_show validation Allow all floating point numbers from 0 up. Fixes #15933. --- .../editor/config-elements/hui-history-graph-card-editor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/panels/lovelace/editor/config-elements/hui-history-graph-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-history-graph-card-editor.ts index 2b76aa30a97e..81ce443d72ab 100644 --- a/src/panels/lovelace/editor/config-elements/hui-history-graph-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-history-graph-card-editor.ts @@ -68,7 +68,7 @@ export class HuiHistoryGraphCardEditor { name: "hours_to_show", default: DEFAULT_HOURS_TO_SHOW, - selector: { number: { min: 1, mode: "box" } }, + selector: { number: { min: 0, step: "any", mode: "box" } }, }, ], }, From 05eb6e15a546ba96ec2215d1d80780b77f08c383 Mon Sep 17 00:00:00 2001 From: Wendelin <12148533+wendevlin@users.noreply.github.com> Date: Mon, 2 Dec 2024 14:24:03 +0100 Subject: [PATCH 3/7] Save scene before switching to live edit (#23094) Save scene changes before live edit, align delete icons for entities. --- src/panels/config/scene/ha-scene-editor.ts | 10 ++++++++-- src/translations/en.json | 3 ++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/panels/config/scene/ha-scene-editor.ts b/src/panels/config/scene/ha-scene-editor.ts index 5dce2d45777d..410aff18f97a 100644 --- a/src/panels/config/scene/ha-scene-editor.ts +++ b/src/panels/config/scene/ha-scene-editor.ts @@ -559,6 +559,7 @@ export class HaSceneEditor extends SubscribeMixin( } return html` this._storeState(entity)); @@ -1326,6 +1329,9 @@ export class HaSceneEditor extends SubscribeMixin( li[role="separator"] { border-bottom-color: var(--divider-color); } + ha-list-item.entity { + padding-right: 28px; + } `, ]; } diff --git a/src/translations/en.json b/src/translations/en.json index 20018575bdc7..193d38ce1a94 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -3881,7 +3881,8 @@ "review_mode_detail": "You can adjust the scene's details and remove devices or entities. To fully edit, switch to Live Edit, which will apply the scene.", "live_edit": "Live Edit", "live_edit_detail": "In Live Edit, all changes to this scene are applied in real-time to your devices and entities.", - "enter_live_mode_unsaved": "You have unsaved changes to this scene. Continuing to live preview will apply the saved scene, which may overwrite your unsaved changes. Consider if you would like to save the scene first before activating it.", + "enter_live_mode_unsaved": "Before proceeding to Live Edit, please save your current changes.", + "save_before_live": "Save and Live Edit", "switch_to_review_mode": "Switch to review mode", "default_name": "New scene", "load_error_not_editable": "Only scenes in scenes.yaml are editable.", From 6ff1a6feccaf7d309ec2194f06ee72b3ebc25d8f Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Mon, 2 Dec 2024 14:35:41 +0100 Subject: [PATCH 4/7] Don't show alert in voice assistant dialog (#23097) --- .../voice-command-dialog/ha-voice-command-dialog.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/dialogs/voice-command-dialog/ha-voice-command-dialog.ts b/src/dialogs/voice-command-dialog/ha-voice-command-dialog.ts index 4b7d02013459..42c311bef2de 100644 --- a/src/dialogs/voice-command-dialog/ha-voice-command-dialog.ts +++ b/src/dialogs/voice-command-dialog/ha-voice-command-dialog.ts @@ -134,12 +134,13 @@ export class HaVoiceCommandDialog extends LitElement { const controlHA = !this._pipeline ? false - : this.hass.states[this._pipeline?.conversation_engine] - ? supportsFeature( - this.hass.states[this._pipeline?.conversation_engine], - ConversationEntityFeature.CONTROL - ) - : true; + : this._pipeline.prefer_local_intents || + (this.hass.states[this._pipeline.conversation_engine] + ? supportsFeature( + this.hass.states[this._pipeline.conversation_engine], + ConversationEntityFeature.CONTROL + ) + : true); const supportsMicrophone = AudioRecorder.isSupported; const supportsSTT = this._pipeline?.stt_engine; From 41924d8ec67ddbfa177f02e542fe7dec9df25863 Mon Sep 17 00:00:00 2001 From: Wendelin <12148533+wendevlin@users.noreply.github.com> Date: Mon, 2 Dec 2024 21:30:51 +0100 Subject: [PATCH 5/7] Add automatic retry to stream logs (#23098) --- src/data/hassio/supervisor.ts | 19 +++++ src/panels/config/logs/error-log-card.ts | 90 ++++++++++++++++-------- 2 files changed, 80 insertions(+), 29 deletions(-) diff --git a/src/data/hassio/supervisor.ts b/src/data/hassio/supervisor.ts index b14ffd8e56c0..a013aab07d8c 100644 --- a/src/data/hassio/supervisor.ts +++ b/src/data/hassio/supervisor.ts @@ -226,6 +226,25 @@ export const fetchHassioLogsFollow = async ( signal ); +export const fetchHassioLogsFollowSkip = async ( + hass: HomeAssistant, + provider: string, + signal: AbortSignal, + cursor: string, + skipLines: number, + lines = 100, + boot = 0 +) => + hass.callApiRaw( + "GET", + `hassio/${provider.includes("_") ? `addons/${provider}` : provider}/logs${boot !== 0 ? `/boots/${boot}` : ""}/follow`, + undefined, + { + Range: `entries=${cursor}:${skipLines}:${lines}`, + }, + signal + ); + export const getHassioLogDownloadUrl = (provider: string) => `/api/hassio/${ provider.includes("_") ? `addons/${provider}` : provider diff --git a/src/panels/config/logs/error-log-card.ts b/src/panels/config/logs/error-log-card.ts index a5bd9e0b5f5c..0f551df687dd 100644 --- a/src/panels/config/logs/error-log-card.ts +++ b/src/panels/config/logs/error-log-card.ts @@ -50,6 +50,7 @@ import { fetchHassioBoots, fetchHassioLogs, fetchHassioLogsFollow, + fetchHassioLogsFollowSkip, fetchHassioLogsLegacy, getHassioLogDownloadLinesUrl, getHassioLogDownloadUrl, @@ -428,13 +429,21 @@ class ErrorLogCard extends LitElement { } } - private async _loadLogs(): Promise { + private async _loadLogs(retry = false): Promise { this._error = undefined; this._loadingState = "loading"; - this._loadingPrevState = undefined; - this._firstCursor = undefined; - this._numberOfLines = 0; - this._ansiToHtmlElement?.clear(); + this._numberOfLines = retry ? (this._numberOfLines ?? 0) : 0; + + if (!retry) { + this._loadingPrevState = undefined; + this._firstCursor = undefined; + this._ansiToHtmlElement?.clear(); + } + + const streamLogs = + this._streamSupported && + isComponentLoaded(this.hass, "hassio") && + this.provider; try { if (this._logStreamAborter) { @@ -442,32 +451,44 @@ class ErrorLogCard extends LitElement { this._logStreamAborter = undefined; } - if ( - this._streamSupported && - isComponentLoaded(this.hass, "hassio") && - this.provider - ) { + if (streamLogs) { this._logStreamAborter = new AbortController(); - // check if there are any logs at all - const testResponse = await fetchHassioLogs( - this.hass, - this.provider, - `entries=:-1:`, - this._boot - ); - const testLogs = await testResponse.text(); - if (!testLogs.trim()) { - this._loadingState = "empty"; + if (!retry) { + // check if there are any logs at all + const testResponse = await fetchHassioLogs( + this.hass, + this.provider!, + `entries=:-1:`, + this._boot + ); + const testLogs = await testResponse.text(); + if (!testLogs.trim()) { + this._loadingState = "empty"; + } } - const response = await fetchHassioLogsFollow( - this.hass, - this.provider, - this._logStreamAborter.signal, - NUMBER_OF_LINES, - this._boot - ); + let response: Response; + + if (retry && this._firstCursor) { + response = await fetchHassioLogsFollowSkip( + this.hass, + this.provider!, + this._logStreamAborter.signal, + this._firstCursor, + this._numberOfLines, + NUMBER_OF_LINES, + this._boot + ); + } else { + response = await fetchHassioLogsFollow( + this.hass, + this.provider!, + this._logStreamAborter.signal, + NUMBER_OF_LINES, + this._boot + ); + } if (response.headers.has("X-First-Cursor")) { this._firstCursor = response.headers.get("X-First-Cursor")!; @@ -524,7 +545,7 @@ class ErrorLogCard extends LitElement { if (!this._downloadSupported) { const downloadUrl = getHassioLogDownloadLinesUrl( - this.provider, + this.provider!, this._numberOfLines, this._boot ); @@ -532,6 +553,9 @@ class ErrorLogCard extends LitElement { this._logsFileLink = signedUrl.path; }); } + + // first chunk loads successfully, reset retry param + retry = false; } } } else { @@ -554,6 +578,13 @@ class ErrorLogCard extends LitElement { if (err.name === "AbortError") { return; } + + // The stream can fail if the connection is lost or firefox service worker intercept the connection + if (!retry && streamLogs) { + this._loadLogs(true); + return; + } + this._error = (this.localizeFunc || this.hass.localize)( "ui.panel.config.logs.failed_get_logs", { @@ -590,9 +621,10 @@ class ErrorLogCard extends LitElement { private _handleConnectionStatus = (ev: HASSDomEvent) => { if (ev.detail === "disconnected" && this._logStreamAborter) { this._logStreamAborter.abort(); + this._loadingState = "loading"; } if (ev.detail === "connected") { - this._loadLogs(); + this._loadLogs(true); } }; From 0a578c5847f53ceb832a120e1c0824e349cb8fa2 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Mon, 2 Dec 2024 20:48:24 +0100 Subject: [PATCH 6/7] Voice wizard local: Add error message, fix hostname (#23103) Add error message, fix hostname --- .../voice-assistant-setup-step-local.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/dialogs/voice-assistant-setup/voice-assistant-setup-step-local.ts b/src/dialogs/voice-assistant-setup/voice-assistant-setup-step-local.ts index 1fb690601f9d..69c50ef57192 100644 --- a/src/dialogs/voice-assistant-setup/voice-assistant-setup-step-local.ts +++ b/src/dialogs/voice-assistant-setup/voice-assistant-setup-step-local.ts @@ -37,6 +37,8 @@ export class HaVoiceAssistantSetupStepLocal extends LitElement { @state() private _detailState?: string; + @state() private _error?: string; + @state() private _localTts?: EntityRegistryDisplayEntry[]; @state() private _localStt?: EntityRegistryDisplayEntry[]; @@ -62,6 +64,7 @@ export class HaVoiceAssistantSetupStepLocal extends LitElement { alt="Casita Home Assistant error logo" />

Failed to install add-ons

+

${this._error}

We could not automatically install a local TTS and STT provider for you. Read the documentation to learn how to install them. @@ -179,8 +182,9 @@ export class HaVoiceAssistantSetupStepLocal extends LitElement { } this._detailState = "Creating assistant"; await this._findEntitiesAndCreatePipeline(); - } catch (e) { + } catch (e: any) { this._state = "ERROR"; + this._error = e.message; } } @@ -199,11 +203,13 @@ export class HaVoiceAssistantSetupStepLocal extends LitElement { private async _setupConfigEntry(addon: string) { const configFlow = await createConfigFlow(this.hass, "wyoming"); const step = await handleConfigFlowStep(this.hass, configFlow.flow_id, { - host: `core_${addon}`, + host: `core-${addon}`, port: addon === "piper" ? 10200 : 10300, }); if (step.type !== "create_entry") { - throw new Error("Failed to create entry"); + throw new Error( + `Failed to create entry for ${addon}${"errors" in step ? `: ${step.errors.base}` : ""}` + ); } } @@ -321,7 +327,7 @@ export class HaVoiceAssistantSetupStepLocal extends LitElement { this._findLocalEntities(); if (!this._localTts?.length || !this._localStt?.length) { if (tryNo > 3) { - throw new Error("Timeout searching for local TTS and STT entities"); + throw new Error("Could not find local TTS and STT entities"); } await new Promise((resolve) => { setTimeout(resolve, 2000); From 04beef5e3677fa778b73d021f2210a74202157ad Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Mon, 2 Dec 2024 21:31:47 +0100 Subject: [PATCH 7/7] Bumped version to 20241127.2 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d373f50e27d8..1803d94af103 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "home-assistant-frontend" -version = "20241127.1" +version = "20241127.2" license = {text = "Apache-2.0"} description = "The Home Assistant frontend" readme = "README.md"