diff --git a/src/data/zwave_js.ts b/src/data/zwave_js.ts index 9296ca8990..4940cd2d92 100644 --- a/src/data/zwave_js.ts +++ b/src/data/zwave_js.ts @@ -208,11 +208,11 @@ export const enum NodeStatus { export interface ZwaveJSProvisioningEntry { /** The device specific key (DSK) in the form aaaaa-bbbbb-ccccc-ddddd-eeeee-fffff-11111-22222 */ dsk: string; - securityClasses: SecurityClass[]; - /** - * Additional properties to be stored in this provisioning entry, e.g. the device ID from a scanned QR code - */ - [prop: string]: any; + security_classes: SecurityClass[]; + additional_properties: { + nodeId?: number; + [prop: string]: any; + }; } export interface RequestedGrant { @@ -278,7 +278,7 @@ export const setZwaveDataCollectionPreference = ( export const fetchZwaveProvisioningEntries = ( hass: HomeAssistant, entry_id: string -): Promise => +): Promise => hass.callWS({ type: "zwave_js/get_provisioning_entries", entry_id, diff --git a/src/panels/config/integrations/integration-panels/zwave_js/dialog-zwave_js-add-node.ts b/src/panels/config/integrations/integration-panels/zwave_js/dialog-zwave_js-add-node.ts index b9f846fa09..151350351d 100644 --- a/src/panels/config/integrations/integration-panels/zwave_js/dialog-zwave_js-add-node.ts +++ b/src/panels/config/integrations/integration-panels/zwave_js/dialog-zwave_js-add-node.ts @@ -45,6 +45,8 @@ export interface ZWaveJSAddNodeDevice { class DialogZWaveJSAddNode extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; + @state() private _params?: ZWaveJSAddNodeDialogParams; + @state() private _entryId?: string; @state() private _status?: @@ -91,6 +93,7 @@ class DialogZWaveJSAddNode extends LitElement { } public async showDialog(params: ZWaveJSAddNodeDialogParams): Promise { + this._params = params; this._entryId = params.entry_id; this._status = "loading"; this._checkSmartStartSupport(); @@ -562,6 +565,9 @@ class DialogZWaveJSAddNode extends LitElement { provisioningInfo ); this._status = "provisioned"; + if (this._params?.addedCallback) { + this._params.addedCallback(); + } } catch (err: any) { this._error = err.message; this._status = "failed"; @@ -693,6 +699,9 @@ class DialogZWaveJSAddNode extends LitElement { if (message.event === "interview completed") { this._unsubscribe(); this._status = "finished"; + if (this._params?.addedCallback) { + this._params.addedCallback(); + } } if (message.event === "interview stage completed") { diff --git a/src/panels/config/integrations/integration-panels/zwave_js/show-dialog-zwave_js-add-node.ts b/src/panels/config/integrations/integration-panels/zwave_js/show-dialog-zwave_js-add-node.ts index 702a618fa3..d956d79d78 100644 --- a/src/panels/config/integrations/integration-panels/zwave_js/show-dialog-zwave_js-add-node.ts +++ b/src/panels/config/integrations/integration-panels/zwave_js/show-dialog-zwave_js-add-node.ts @@ -2,6 +2,7 @@ import { fireEvent } from "../../../../../common/dom/fire_event"; export interface ZWaveJSAddNodeDialogParams { entry_id: string; + addedCallback?: () => void; } export const loadAddNodeDialog = () => import("./dialog-zwave_js-add-node"); diff --git a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-config-dashboard.ts b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-config-dashboard.ts index 413e6bd099..afd91be9a4 100644 --- a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-config-dashboard.ts +++ b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-config-dashboard.ts @@ -411,6 +411,7 @@ class ZWaveJSConfigDashboard extends LitElement { private async _addNodeClicked() { showZWaveJSAddNodeDialog(this, { entry_id: this.configEntryId!, + addedCallback: () => this._fetchData(), }); } diff --git a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-provisioned.ts b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-provisioned.ts index cad49415cf..a9a41cdadb 100644 --- a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-provisioned.ts +++ b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-provisioned.ts @@ -1,4 +1,4 @@ -import { mdiDelete } from "@mdi/js"; +import { mdiCheckCircle, mdiCloseCircleOutline, mdiDelete } from "@mdi/js"; import { html, LitElement } from "lit"; import { customElement, property, state } from "lit/decorators"; import memoizeOne from "memoize-one"; @@ -42,17 +42,42 @@ class ZWaveJSProvisioned extends LitElement { private _columns = memoizeOne( (narrow: boolean): DataTableColumnContainer => ({ + included: { + title: this.hass.localize( + "ui.panel.config.zwave_js.provisioned.included" + ), + type: "icon", + width: "100px", + template: (_info, provisioningEntry: any) => + provisioningEntry.additional_properties.nodeId + ? html` + + ` + : html` + + `, + }, dsk: { title: this.hass.localize("ui.panel.config.zwave_js.provisioned.dsk"), sortable: true, filterable: true, grows: true, }, - securityClasses: { + security_classes: { title: this.hass.localize( "ui.panel.config.zwave_js.provisioned.security_classes" ), - width: "15%", + width: "30%", hidden: narrow, filterable: true, sortable: true, @@ -60,7 +85,7 @@ class ZWaveJSProvisioned extends LitElement { securityClasses .map((secClass) => this.hass.localize( - `ui.panel.config.zwave_js.security_classes.${SecurityClass[secClass]}` + `ui.panel.config.zwave_js.security_classes.${SecurityClass[secClass]}.title` ) ) .join(", "), @@ -70,6 +95,7 @@ class ZWaveJSProvisioned extends LitElement { "ui.panel.config.zwave_js.provisioned.unprovison" ), type: "icon-button", + width: "100px", template: (_info, provisioningEntry: any) => html` { + const dsk = ev.currentTarget.provisioningEntry.dsk; + const confirm = await showConfirmationDialog(this, { title: this.hass.localize( "ui.panel.config.zwave_js.provisioned.confirm_unprovision_title" @@ -113,11 +141,8 @@ class ZWaveJSProvisioned extends LitElement { return; } - await unprovisionZwaveSmartStartNode( - this.hass, - this.configEntryId, - ev.currentTarget.provisioningEntry.dsk - ); + await unprovisionZwaveSmartStartNode(this.hass, this.configEntryId, dsk); + this._fetchData(); }; } diff --git a/src/translations/en.json b/src/translations/en.json index 0f7ad0b5ee..ab73f2fc4c 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2897,6 +2897,8 @@ "dsk": "DSK", "security_classes": "Security classes", "unprovison": "Unprovison", + "included": "Included", + "not_included": "Not Included", "confirm_unprovision_title": "Are you sure you want to unprovision the device?", "confirm_unprovision_text": "If you unprovision the device it will not be added to Home Assistant when it is powered on. If it is already added to Home Assistant, removing the provisioned device will not remove it from Home Assistant." },