From fc86a66c33b2768f13aa73d4369f1b6c60d1030f Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Wed, 28 Sep 2022 11:27:09 +0200 Subject: [PATCH] Use unique id for script (#13817) Co-authored-by: Bram Kragten --- src/data/script.ts | 5 +- src/panels/config/script/ha-config-script.ts | 4 +- src/panels/config/script/ha-script-editor.ts | 105 ++++++++++--------- src/panels/config/script/ha-script-picker.ts | 23 ++-- src/panels/config/script/ha-script-trace.ts | 50 +++++---- src/panels/logbook/ha-logbook-renderer.ts | 6 +- 6 files changed, 100 insertions(+), 93 deletions(-) diff --git a/src/data/script.ts b/src/data/script.ts index 1f925cffe3..ec13344714 100644 --- a/src/data/script.ts +++ b/src/data/script.ts @@ -15,7 +15,6 @@ import { Describe, boolean, } from "superstruct"; -import { computeObjectId } from "../common/entity/compute_object_id"; import { navigate } from "../common/navigate"; import { HomeAssistant } from "../types"; import { @@ -278,9 +277,9 @@ export type ActionType = keyof ActionTypes; export const triggerScript = ( hass: HomeAssistant, - entityId: string, + scriptId: string, variables?: Record -) => hass.callService("script", computeObjectId(entityId), variables); +) => hass.callService("script", scriptId, variables); export const canRun = (state: ScriptEntity) => { if (state.state === "off") { diff --git a/src/panels/config/script/ha-config-script.ts b/src/panels/config/script/ha-config-script.ts index 4b8f9aefa8..6aabf90bf4 100644 --- a/src/panels/config/script/ha-config-script.ts +++ b/src/panels/config/script/ha-config-script.ts @@ -88,8 +88,8 @@ class HaConfigScript extends HassRouterPage { this._currentPage !== "dashboard" ) { pageEl.creatingNew = undefined; - const scriptEntityId = this.routeTail.path.substr(1); - pageEl.scriptEntityId = scriptEntityId === "new" ? null : scriptEntityId; + const scriptId = this.routeTail.path.substr(1); + pageEl.scriptId = scriptId === "new" ? null : scriptId; } } } diff --git a/src/panels/config/script/ha-script-editor.ts b/src/panels/config/script/ha-script-editor.ts index 629cff5412..34eb30b46d 100644 --- a/src/panels/config/script/ha-script-editor.ts +++ b/src/panels/config/script/ha-script-editor.ts @@ -24,7 +24,6 @@ import { property, query, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import memoizeOne from "memoize-one"; import { fireEvent } from "../../../common/dom/fire_event"; -import { computeObjectId } from "../../../common/entity/compute_object_id"; import { navigate } from "../../../common/navigate"; import { slugify } from "../../../common/string/slugify"; import { computeRTL } from "../../../common/util/compute_rtl"; @@ -68,7 +67,7 @@ import type { HaManualScriptEditor } from "./manual-script-editor"; export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { @property({ attribute: false }) public hass!: HomeAssistant; - @property() public scriptEntityId: string | null = null; + @property() public scriptId: string | null = null; @property({ attribute: false }) public route!: Route; @@ -162,7 +161,7 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { } const schema = this._schema( - !!this.scriptEntityId, + !!this.scriptId, "use_blueprint" in this._config, this._config.mode ); @@ -183,7 +182,7 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { .backCallback=${this._backTapped} .header=${!this._config?.alias ? "" : this._config.alias} > - ${this.scriptEntityId && !this.narrow + ${this.scriptId && !this.narrow ? html` ${this.hass.localize( @@ -201,7 +200,7 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { ${this.hass.localize("ui.panel.config.script.editor.show_info")} @@ -213,16 +212,16 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { ${this.hass.localize("ui.panel.config.script.picker.run_script")} - ${this.scriptEntityId && this.narrow + ${this.scriptId && this.narrow ? html` - + ${this.hass.localize( "ui.panel.config.script.editor.show_trace" @@ -295,7 +294,7 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) {
  • ${this.hass.localize("ui.panel.config.script.picker.delete")} @@ -430,15 +429,15 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { protected updated(changedProps: PropertyValues): void { super.updated(changedProps); - const oldScript = changedProps.get("scriptEntityId"); + const oldScript = changedProps.get("scriptId"); if ( - changedProps.has("scriptEntityId") && - this.scriptEntityId && + changedProps.has("scriptId") && + this.scriptId && this.hass && // Only refresh config if we picked a new script. If same ID, don't fetch it. - (!oldScript || oldScript !== this.scriptEntityId) + (!oldScript || oldScript !== this.scriptId) ) { - getScriptConfig(this.hass, computeObjectId(this.scriptEntityId)).then( + getScriptConfig(this.hass, this.scriptId).then( (config) => { // Normalize data: ensure sequence is a list // Happens when people copy paste their scripts into the config @@ -458,7 +457,7 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { : this.hass.localize( "ui.panel.config.script.editor.load_error_unknown", "err_no", - resp.status_code + resp.status_code || resp.code ) ); history.back(); @@ -466,11 +465,7 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { ); } - if ( - changedProps.has("scriptEntityId") && - !this.scriptEntityId && - this.hass - ) { + if (changedProps.has("scriptId") && !this.scriptId && this.hass) { const initData = getScriptEditorInitData(); this._dirty = !!initData; const baseConfig: Partial = { @@ -530,24 +525,30 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { }; private async _showInfo() { - if (!this.scriptEntityId) { + if (!this.scriptId) { return; } - fireEvent(this, "hass-more-info", { entityId: this.scriptEntityId }); + const entity = Object.values(this.hass.entities).find( + (entry) => entry.unique_id === this.scriptId + ); + if (!entity) { + return; + } + fireEvent(this, "hass-more-info", { entityId: entity.entity_id }); } private async _showTrace() { - if (this.scriptEntityId) { + if (this.scriptId) { const result = await this.confirmUnsavedChanged(); if (result) { - navigate(`/config/script/trace/${this.scriptEntityId}`); + navigate(`/config/script/trace/${this.scriptId}`); } } } private async _runScript(ev: CustomEvent) { ev.stopPropagation(); - await triggerScript(this.hass, this.scriptEntityId as string); + await triggerScript(this.hass, this.scriptId!); showToast(this, { message: this.hass.localize( "ui.notification_toast.triggered", @@ -613,7 +614,7 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { max: isMaxMode(values.mode) ? values.max : undefined, }; - if (!this.scriptEntityId) { + if (!this.scriptId) { this.updateEntityId(values.id, values.alias); } @@ -720,10 +721,7 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { } private async _delete() { - await deleteScript( - this.hass, - computeObjectId(this.scriptEntityId as string) - ); + await deleteScript(this.hass, this.scriptId!); history.back(); } @@ -741,7 +739,7 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { } } - private _saveScript(): void { + private async _saveScript(): Promise { if (this._idError) { showToast(this, { message: this.hass.localize( @@ -756,24 +754,27 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { }); return; } - const id = this.scriptEntityId - ? computeObjectId(this.scriptEntityId) - : this._entityId || Date.now(); - this.hass!.callApi("POST", "config/script/config/" + id, this._config).then( - () => { - this._dirty = false; - if (!this.scriptEntityId) { - navigate(`/config/script/edit/${id}`, { replace: true }); - } - }, - (errors) => { - this._errors = errors.body.message || errors.error || errors.body; - showToast(this, { - message: errors.body.message || errors.error || errors.body, - }); - throw errors; - } - ); + + const id = this.scriptId || this._entityId || Date.now(); + try { + await this.hass!.callApi( + "POST", + "config/script/config/" + id, + this._config + ); + } catch (errors: any) { + this._errors = errors.body.message || errors.error || errors.body; + showToast(this, { + message: errors.body.message || errors.error || errors.body, + }); + throw errors; + } + + this._dirty = false; + + if (!this.scriptId) { + navigate(`/config/script/edit/${id}`, { replace: true }); + } } protected handleKeyboardSave() { diff --git a/src/panels/config/script/ha-script-picker.ts b/src/panels/config/script/ha-script-picker.ts index 8aaa8a02f4..ef55423c10 100644 --- a/src/panels/config/script/ha-script-picker.ts +++ b/src/panels/config/script/ha-script-picker.ts @@ -13,7 +13,6 @@ import { customElement, property, state } from "lit/decorators"; import memoizeOne from "memoize-one"; import { formatDateTime } from "../../../common/datetime/format_date_time"; import { fireEvent, HASSDomEvent } from "../../../common/dom/fire_event"; -import { computeObjectId } from "../../../common/entity/compute_object_id"; import { computeStateName } from "../../../common/entity/compute_state_name"; import { navigate } from "../../../common/navigate"; import { computeRTL } from "../../../common/util/compute_rtl"; @@ -252,11 +251,15 @@ class HaScriptPicker extends LitElement { } private _handleRowClicked(ev: HASSDomEvent) { - navigate(`/config/script/edit/${ev.detail.id}`); + const entry = this.hass.entities[ev.detail.id]; + if (entry) { + navigate(`/config/script/edit/${entry.unique_id}`); + } } private _runScript = async (script: any) => { - await triggerScript(this.hass, script.entity_id); + const entry = this.hass.entities[script.entity_id]; + await triggerScript(this.hass, entry.unique_id); showToast(this, { message: this.hass.localize( "ui.notification_toast.triggered", @@ -271,7 +274,10 @@ class HaScriptPicker extends LitElement { } private _showTrace(script: any) { - navigate(`/config/script/trace/${script.entity_id}`); + const entry = this.hass.entities[script.entity_id]; + if (entry) { + navigate(`/config/script/trace/${entry.unique_id}`); + } } private _showHelp() { @@ -294,10 +300,8 @@ class HaScriptPicker extends LitElement { private async _duplicate(script: any) { try { - const config = await getScriptConfig( - this.hass, - computeObjectId(script.entity_id) - ); + const entry = this.hass.entities[script.entity_id]; + const config = await getScriptConfig(this.hass, entry.unique_id); showScriptEditor({ ...config, alias: `${config?.alias} (${this.hass.localize( @@ -338,7 +342,8 @@ class HaScriptPicker extends LitElement { private async _delete(script: any) { try { - await deleteScript(this.hass, computeObjectId(script.entity_id)); + const entry = this.hass.entities[script.entity_id]; + await deleteScript(this.hass, entry.unique_id); } catch (err: any) { await showAlertDialog(this, { text: diff --git a/src/panels/config/script/ha-script-trace.ts b/src/panels/config/script/ha-script-trace.ts index ab35977cb1..ae001665ca 100644 --- a/src/panels/config/script/ha-script-trace.ts +++ b/src/panels/config/script/ha-script-trace.ts @@ -44,7 +44,7 @@ import { fireEvent } from "../../../common/dom/fire_event"; export class HaScriptTrace extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; - @property() public scriptEntityId!: string; + @property() public scriptId!: string; @property({ attribute: false }) public scripts!: ScriptEntity[]; @@ -54,6 +54,8 @@ export class HaScriptTrace extends LitElement { @property({ attribute: false }) public route!: Route; + @state() private _entityId?: string; + @state() private _traces?: ScriptTrace[]; @state() private _runId?: string; @@ -74,15 +76,15 @@ export class HaScriptTrace extends LitElement { @query("hat-script-graph") private _graph?: HatScriptGraph; protected render(): TemplateResult { - const stateObj = this.scriptEntityId - ? this.hass.states[this.scriptEntityId] + const stateObj = this._entityId + ? this.hass.states[this._entityId] : undefined; const graph = this._graph; const trackedNodes = graph?.trackedNodes; const renderedNodes = graph?.renderedNodes; - const title = stateObj?.attributes.friendly_name || this.scriptEntityId; + const title = stateObj?.attributes.friendly_name || this._entityId; let devButtons: TemplateResult | string = ""; if (__DEV__) { @@ -95,11 +97,11 @@ export class HaScriptTrace extends LitElement { return html` ${devButtons} - ${!this.narrow && this.scriptEntityId + ${!this.narrow && this.scriptId ? html`
    @@ -120,7 +122,7 @@ export class HaScriptTrace extends LitElement { ${this.hass.localize("ui.panel.config.script.editor.show_info")} @@ -130,11 +132,11 @@ export class HaScriptTrace extends LitElement { > - ${this.narrow && this.scriptEntityId + ${this.narrow && this.scriptId ? html` ${this.hass.localize( @@ -309,25 +311,33 @@ export class HaScriptTrace extends LitElement { protected firstUpdated(changedProps) { super.firstUpdated(changedProps); - if (!this.scriptEntityId) { + if (!this.scriptId) { return; } const params = new URLSearchParams(location.search); this._loadTraces(params.get("run_id") || undefined); + + this._entityId = Object.values(this.hass.entities).find( + (entry) => entry.unique_id === this.scriptId + )?.entity_id; } public willUpdate(changedProps) { super.willUpdate(changedProps); - // Only reset if scriptEntityId has changed and we had one before. - if (changedProps.get("scriptEntityId")) { + // Only reset if scriptId has changed and we had one before. + if (changedProps.get("scriptId")) { this._traces = undefined; this._runId = undefined; this._trace = undefined; this._logbookEntries = undefined; - if (this.scriptEntityId) { + if (this.scriptId) { this._loadTraces(); + + this._entityId = Object.values(this.hass.entities).find( + (entry) => entry.unique_id === this.scriptId + )?.entity_id; } } @@ -364,11 +374,7 @@ export class HaScriptTrace extends LitElement { } private async _loadTraces(runId?: string) { - this._traces = await loadTraces( - this.hass, - "script", - this.scriptEntityId.split(".")[1] - ); + this._traces = await loadTraces(this.hass, "script", this.scriptId); // Newest will be on top. this._traces.reverse(); @@ -410,7 +416,7 @@ export class HaScriptTrace extends LitElement { const trace = await loadTrace( this.hass, "script", - this.scriptEntityId.split(".")[1], + this.scriptId, this._runId! ); this._logbookEntries = isComponentLoaded(this.hass, "logbook") @@ -426,7 +432,7 @@ export class HaScriptTrace extends LitElement { private _downloadTrace() { const aEl = document.createElement("a"); - aEl.download = `trace ${this.scriptEntityId} ${ + aEl.download = `trace ${this._entityId} ${ this._trace!.timestamp.start }.json`; aEl.href = `data:application/json;charset=utf-8,${encodeURI( @@ -476,10 +482,10 @@ export class HaScriptTrace extends LitElement { } private async _showInfo() { - if (!this.scriptEntityId) { + if (!this._entityId) { return; } - fireEvent(this, "hass-more-info", { entityId: this.scriptEntityId }); + fireEvent(this, "hass-more-info", { entityId: this._entityId }); } static get styles(): CSSResultGroup { diff --git a/src/panels/logbook/ha-logbook-renderer.ts b/src/panels/logbook/ha-logbook-renderer.ts index c79bdc9e34..74321e70bc 100644 --- a/src/panels/logbook/ha-logbook-renderer.ts +++ b/src/panels/logbook/ha-logbook-renderer.ts @@ -170,11 +170,7 @@ class HaLogbookRenderer extends LitElement {