Skip to content

Commit

Permalink
Add Z-Wave controller hard reset device action (certification req) (#…
Browse files Browse the repository at this point in the history
…18216)

Co-authored-by: Bram Kragten <[email protected]>
  • Loading branch information
raman325 and bramkragten authored Oct 24, 2023
1 parent 1cb238e commit d8d16c4
Show file tree
Hide file tree
Showing 6 changed files with 198 additions and 3 deletions.
9 changes: 9 additions & 0 deletions src/data/zwave_js.ts
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,15 @@ export const fetchZwaveNodeFirmwareUpdateCapabilities = (
device_id,
});

export const hardResetController = (
hass: HomeAssistant,
entry_id: string
): Promise<string> =>
hass.callWS({
type: "zwave_js/hard_reset_controller",
entry_id,
});

export const uploadFirmwareAndBeginUpdate = async (
hass: HomeAssistant,
device_id: string,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ import { showZWaveJSRebuildNodeRoutesDialog } from "../../../../integrations/int
import { showZWaveJSNodeStatisticsDialog } from "../../../../integrations/integration-panels/zwave_js/show-dialog-zwave_js-node-statistics";
import { showZWaveJSReinterviewNodeDialog } from "../../../../integrations/integration-panels/zwave_js/show-dialog-zwave_js-reinterview-node";
import { showZWaveJSRemoveFailedNodeDialog } from "../../../../integrations/integration-panels/zwave_js/show-dialog-zwave_js-remove-failed-node";
import { showZWaveJUpdateFirmwareNodeDialog } from "../../../../integrations/integration-panels/zwave_js/show-dialog-zwave_js-update-firmware-node";
import { showZWaveJSUpdateFirmwareNodeDialog } from "../../../../integrations/integration-panels/zwave_js/show-dialog-zwave_js-update-firmware-node";
import type { DeviceAction } from "../../../ha-config-device-page";
import { showZWaveJSHardResetControllerDialog } from "../../../../integrations/integration-panels/zwave_js/show-dialog-zwave_js-hard-reset-controller";

export const getZwaveDeviceActions = async (
el: HTMLElement,
Expand Down Expand Up @@ -136,13 +137,27 @@ export const getZwaveDeviceActions = async (
confirmText: hass.localize("ui.common.yes"),
}))
) {
showZWaveJUpdateFirmwareNodeDialog(el, {
showZWaveJSUpdateFirmwareNodeDialog(el, {
device,
});
}
},
});
}

if (nodeStatus.is_controller_node) {
actions.push({
label: hass.localize(
"ui.panel.config.zwave_js.device_info.hard_reset_controller"
),
icon: mdiDeleteForever,
action: async () => {
showZWaveJSHardResetControllerDialog(el, {
entryId,
});
},
});
}

return actions;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import { mdiCheckCircle, mdiDeleteForever, mdiRestore } from "@mdi/js";
import "@material/mwc-button/mwc-button";
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../../../../common/dom/fire_event";
import { createCloseHeading } from "../../../../../components/ha-dialog";
import "../../../../../components/ha-svg-icon";
import { hardResetController } from "../../../../../data/zwave_js";
import { haStyleDialog } from "../../../../../resources/styles";
import { HomeAssistant } from "../../../../../types";
import { ZWaveJSHardResetControllerDialogParams } from "./show-dialog-zwave_js-hard-reset-controller";
import { showConfirmationDialog } from "../../../../../dialogs/generic/show-dialog-box";
import { navigate } from "../../../../../common/navigate";

enum ResetStatus {
NotStarted,
InProgress,
Done,
}

const iconMap = {
[ResetStatus.NotStarted]: mdiDeleteForever,
[ResetStatus.InProgress]: mdiRestore,
[ResetStatus.Done]: mdiCheckCircle,
};

@customElement("dialog-zwave_js-hard-reset-controller")
class DialogZWaveJSHardResetController extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;

@state() private _entryId?: string;

@state() private _resetStatus = ResetStatus.NotStarted;

public showDialog(params: ZWaveJSHardResetControllerDialogParams): void {
this._entryId = params.entryId;
}

public closeDialog(): void {
this._entryId = undefined;
this._resetStatus = ResetStatus.NotStarted;

fireEvent(this, "dialog-closed", { dialog: this.localName });
}

protected render() {
if (!this._entryId) {
return nothing;
}

return html`<ha-dialog
open
@closed=${this.closeDialog}
.heading=${createCloseHeading(
this.hass,
this.hass.localize(
`ui.panel.config.zwave_js.hard_reset_controller.${
ResetStatus[this._resetStatus]
}.title`
)
)}
>
<div class="flex-container">
<div>
<ha-svg-icon
.path=${iconMap[this._resetStatus]}
.class="icon"
></ha-svg-icon>
</div>
<p>
${this.hass.localize(
`ui.panel.config.zwave_js.hard_reset_controller.${
ResetStatus[this._resetStatus]
}.body`
)}
</p>
</div>
${this._resetStatus === ResetStatus.NotStarted
? html`<mwc-button
slot="primaryAction"
@click=${this._hardResetController}
>
${this.hass.localize("ui.common.continue")}
</mwc-button>
<mwc-button slot="secondaryAction" @click=${this.closeDialog}>
${this.hass.localize("ui.common.cancel")}
</mwc-button>`
: nothing}
</ha-dialog>`;
}

private async _hardResetController(): Promise<void> {
if (
await showConfirmationDialog(this, {
text: this.hass.localize(
`ui.panel.config.zwave_js.hard_reset_controller.confirmation`
),
dismissText: this.hass.localize("ui.common.cancel"),
confirmText: this.hass.localize("ui.common.continue"),
destructive: true,
})
) {
this._resetStatus = ResetStatus.InProgress;
const deviceId = await hardResetController(this.hass, this._entryId!);
setTimeout(() => navigate(`/config/devices/device/${deviceId}`), 0);
this._resetStatus = ResetStatus.Done;
}
}

static get styles(): CSSResultGroup {
return [
haStyleDialog,
css`
.icon {
color: var(--label-badge-red);
}
.flex-container {
display: flex;
align-items: center;
margin-bottom: 5px;
}
ha-svg-icon {
width: 68px;
height: 48px;
}
`,
];
}
}

declare global {
interface HTMLElementTagNameMap {
"dialog-zwave_js-hard-reset-controller": DialogZWaveJSHardResetController;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { fireEvent } from "../../../../../common/dom/fire_event";

export interface ZWaveJSHardResetControllerDialogParams {
entryId: string;
}

export const loadHardResetControllerDialog = () =>
import("./dialog-zwave_js-hard-reset-controller");

export const showZWaveJSHardResetControllerDialog = (
element: HTMLElement,
hardResetControllerDialogParams: ZWaveJSHardResetControllerDialogParams
): void => {
fireEvent(element, "show-dialog", {
dialogTag: "dialog-zwave_js-hard-reset-controller",
dialogImport: loadHardResetControllerDialog,
dialogParams: hardResetControllerDialogParams,
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export interface ZWaveJSUpdateFirmwareNodeDialogParams {
export const loadUpdateFirmwareNodeDialog = () =>
import("./dialog-zwave_js-update-firmware-node");

export const showZWaveJUpdateFirmwareNodeDialog = (
export const showZWaveJSUpdateFirmwareNodeDialog = (
element: HTMLElement,
updateFirmwareNodeDialogParams: ZWaveJSUpdateFirmwareNodeDialogParams
): void => {
Expand Down
16 changes: 16 additions & 0 deletions src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -4030,11 +4030,27 @@
"remove_failed": "Remove failed",
"update_firmware": "Update",
"highest_security": "Highest security",
"hard_reset_controller": "Factory reset",
"unknown": "Unknown",
"zwave_plus": "Z-Wave Plus",
"zwave_plus_version": "Version {version}",
"node_statistics": "Statistics"
},
"hard_reset_controller": {
"NotStarted": {
"title": "Reset Controller to Factory Settings",
"body": "If you decide to move forward, you will reset your controller to factory settings. As a result, the controller will forget all devices it is paired with and all Z-Wave devices for this network will be removed from Home Assistant. If there are any devices still paired with the controller when it is reset, they will have to go through the exclusion process before they can be re-paired. Would you like to continue?"
},
"InProgress": {
"title": "Resetting Controller",
"body": "Your controller is being reset and restarted. Wait until the process is complete before closing this dialog"
},
"Done": {
"title": "Controller Reset Complete",
"body": "Your controller has been reset to factory settings and has been restarted! You can now close this dialog."
},
"confirmation": "This action cannot be undone unless you have an NVM backup from your controller."
},
"node_statistics": {
"title": "Device statistics",
"commands_tx": {
Expand Down

0 comments on commit d8d16c4

Please sign in to comment.