mirror of
https://github.com/home-assistant/frontend.git
synced 2025-04-26 14:27:20 +00:00
Add Z-Wave JS Heal Node wizard (#9562)
This commit is contained in:
parent
07d7fa26fe
commit
e12b194d41
@ -178,6 +178,17 @@ export const reinterviewNode = (
|
||||
}
|
||||
);
|
||||
|
||||
export const healNode = (
|
||||
hass: HomeAssistant,
|
||||
entry_id: string,
|
||||
node_id: number
|
||||
): Promise<boolean> =>
|
||||
hass.callWS({
|
||||
type: "zwave_js/heal_node",
|
||||
entry_id: entry_id,
|
||||
node_id: node_id,
|
||||
});
|
||||
|
||||
export const healNetwork = (
|
||||
hass: HomeAssistant,
|
||||
entry_id: string
|
||||
|
@ -16,6 +16,7 @@ import {
|
||||
import { haStyle } from "../../../../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../../../../types";
|
||||
import { showZWaveJSReinterviewNodeDialog } from "../../../../integrations/integration-panels/zwave_js/show-dialog-zwave_js-reinterview-node";
|
||||
import { showZWaveJSHealNodeDialog } from "../../../../integrations/integration-panels/zwave_js/show-dialog-zwave_js-heal-node";
|
||||
|
||||
@customElement("ha-device-actions-zwave_js")
|
||||
export class HaDeviceActionsZWaveJS extends LitElement {
|
||||
@ -56,6 +57,9 @@ export class HaDeviceActionsZWaveJS extends LitElement {
|
||||
"ui.panel.config.zwave_js.device_info.reinterview_device"
|
||||
)}
|
||||
</mwc-button>
|
||||
<mwc-button @click=${this._healNodeClicked}>
|
||||
${this.hass.localize("ui.panel.config.zwave_js.device_info.heal_node")}
|
||||
</mwc-button>
|
||||
`;
|
||||
}
|
||||
|
||||
@ -69,6 +73,17 @@ export class HaDeviceActionsZWaveJS extends LitElement {
|
||||
});
|
||||
}
|
||||
|
||||
private async _healNodeClicked() {
|
||||
if (!this._nodeId || !this._entryId) {
|
||||
return;
|
||||
}
|
||||
showZWaveJSHealNodeDialog(this, {
|
||||
entry_id: this._entryId,
|
||||
node_id: this._nodeId,
|
||||
device: this.device,
|
||||
});
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
|
@ -0,0 +1,273 @@
|
||||
import "../../../../../components/ha-circular-progress";
|
||||
import "@material/mwc-button/mwc-button";
|
||||
import "@material/mwc-linear-progress/mwc-linear-progress";
|
||||
import { mdiStethoscope, mdiCheckCircle, mdiCloseCircle } from "@mdi/js";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||
import { createCloseHeading } from "../../../../../components/ha-dialog";
|
||||
import {
|
||||
DeviceRegistryEntry,
|
||||
computeDeviceName,
|
||||
} from "../../../../../data/device_registry";
|
||||
import {
|
||||
fetchNetworkStatus,
|
||||
healNode,
|
||||
ZWaveJSNetwork,
|
||||
} from "../../../../../data/zwave_js";
|
||||
import { haStyleDialog } from "../../../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../../../types";
|
||||
import { ZWaveJSHealNodeDialogParams } from "./show-dialog-zwave_js-heal-node";
|
||||
|
||||
@customElement("dialog-zwave_js-heal-node")
|
||||
class DialogZWaveJSHealNode extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@state() private entry_id?: string;
|
||||
|
||||
@state() private node_id?: number;
|
||||
|
||||
@state() private device?: DeviceRegistryEntry;
|
||||
|
||||
@state() private _status?: string;
|
||||
|
||||
@state() private _error?: string;
|
||||
|
||||
public showDialog(params: ZWaveJSHealNodeDialogParams): void {
|
||||
this.entry_id = params.entry_id;
|
||||
this.device = params.device;
|
||||
this.node_id = params.node_id;
|
||||
this._fetchData();
|
||||
}
|
||||
|
||||
public closeDialog(): void {
|
||||
this.entry_id = undefined;
|
||||
this._status = undefined;
|
||||
this.node_id = undefined;
|
||||
this.device = undefined;
|
||||
this._error = undefined;
|
||||
|
||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this.entry_id || !this.device) {
|
||||
return html``;
|
||||
}
|
||||
|
||||
return html`
|
||||
<ha-dialog
|
||||
open
|
||||
@closed=${this.closeDialog}
|
||||
.heading=${createCloseHeading(
|
||||
this.hass,
|
||||
this.hass.localize("ui.panel.config.zwave_js.heal_node.title")
|
||||
)}
|
||||
>
|
||||
${!this._status
|
||||
? html`
|
||||
<div class="flex-container">
|
||||
<ha-svg-icon
|
||||
.path=${mdiStethoscope}
|
||||
class="introduction"
|
||||
></ha-svg-icon>
|
||||
<div class="status">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.heal_node.introduction",
|
||||
{
|
||||
device: html`<em
|
||||
>${computeDeviceName(this.device, this.hass!)}</em
|
||||
>`,
|
||||
}
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
<em>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.heal_node.traffic_warning"
|
||||
)}
|
||||
</em>
|
||||
</p>
|
||||
<mwc-button slot="primaryAction" @click=${this._startHeal}>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.heal_node.start_heal"
|
||||
)}
|
||||
</mwc-button>
|
||||
`
|
||||
: ``}
|
||||
${this._status === "started"
|
||||
? html`
|
||||
<div class="flex-container">
|
||||
<ha-circular-progress active></ha-circular-progress>
|
||||
<div class="status">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.heal_node.in_progress",
|
||||
{
|
||||
device: html`<em
|
||||
>${computeDeviceName(this.device, this.hass!)}</em
|
||||
>`,
|
||||
}
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<mwc-button slot="primaryAction" @click=${this.closeDialog}>
|
||||
${this.hass.localize("ui.common.close")}
|
||||
</mwc-button>
|
||||
`
|
||||
: ``}
|
||||
${this._status === "failed"
|
||||
? html`
|
||||
<div class="flex-container">
|
||||
<ha-svg-icon
|
||||
.path=${mdiCloseCircle}
|
||||
class="failed"
|
||||
></ha-svg-icon>
|
||||
<div class="status">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.heal_node.healing_failed",
|
||||
{
|
||||
device: html`<em
|
||||
>${computeDeviceName(this.device, this.hass!)}</em
|
||||
>`,
|
||||
}
|
||||
)}
|
||||
</p>
|
||||
<p>
|
||||
${this._error
|
||||
? html` <em>${this._error}</em> `
|
||||
: `
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.heal_node.healing_failed_check_logs"
|
||||
)}
|
||||
`}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<mwc-button slot="primaryAction" @click=${this.closeDialog}>
|
||||
${this.hass.localize("ui.common.close")}
|
||||
</mwc-button>
|
||||
`
|
||||
: ``}
|
||||
${this._status === "finished"
|
||||
? html`
|
||||
<div class="flex-container">
|
||||
<ha-svg-icon
|
||||
.path=${mdiCheckCircle}
|
||||
class="success"
|
||||
></ha-svg-icon>
|
||||
<div class="status">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.heal_node.healing_complete",
|
||||
{
|
||||
device: html`<em
|
||||
>${computeDeviceName(this.device, this.hass!)}</em
|
||||
>`,
|
||||
}
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<mwc-button slot="primaryAction" @click=${this.closeDialog}>
|
||||
${this.hass.localize("ui.panel.config.zwave_js.common.close")}
|
||||
</mwc-button>
|
||||
`
|
||||
: ``}
|
||||
${this._status === "network-healing"
|
||||
? html`
|
||||
<div class="flex-container">
|
||||
<ha-svg-icon
|
||||
.path=${mdiCloseCircle}
|
||||
class="failed"
|
||||
></ha-svg-icon>
|
||||
<div class="status">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.heal_node.network_heal_in_progress"
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<mwc-button slot="primaryAction" @click=${this.closeDialog}>
|
||||
${this.hass.localize("ui.panel.config.zwave_js.common.close")}
|
||||
</mwc-button>
|
||||
`
|
||||
: ``}
|
||||
</ha-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
private async _fetchData(): Promise<void> {
|
||||
if (!this.hass) {
|
||||
return;
|
||||
}
|
||||
const network: ZWaveJSNetwork = await fetchNetworkStatus(
|
||||
this.hass!,
|
||||
this.entry_id!
|
||||
);
|
||||
if (network.controller.is_heal_network_active) {
|
||||
this._status = "network-healing";
|
||||
}
|
||||
}
|
||||
|
||||
private async _startHeal(): Promise<void> {
|
||||
if (!this.hass) {
|
||||
return;
|
||||
}
|
||||
this._status = "started";
|
||||
try {
|
||||
this._status = (await healNode(this.hass, this.entry_id!, this.node_id!))
|
||||
? "finished"
|
||||
: "failed";
|
||||
} catch (error) {
|
||||
this._error = error.message;
|
||||
this._status = "failed";
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyleDialog,
|
||||
css`
|
||||
.success {
|
||||
color: var(--success-color);
|
||||
}
|
||||
|
||||
.failed {
|
||||
color: var(--error-color);
|
||||
}
|
||||
|
||||
.flex-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
ha-svg-icon {
|
||||
width: 68px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
ha-svg-icon.introduction {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.flex-container ha-svg-icon,
|
||||
.flex-container ha-circular-progress {
|
||||
margin-right: 20px;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"dialog-zwave_js-heal-node": DialogZWaveJSHealNode;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||
import { DeviceRegistryEntry } from "../../../../../data/device_registry";
|
||||
|
||||
export interface ZWaveJSHealNodeDialogParams {
|
||||
entry_id: string;
|
||||
node_id: number;
|
||||
device: DeviceRegistryEntry;
|
||||
}
|
||||
|
||||
export const loadHealNodeDialog = () => import("./dialog-zwave_js-heal-node");
|
||||
|
||||
export const showZWaveJSHealNodeDialog = (
|
||||
element: HTMLElement,
|
||||
healNodeDialogParams: ZWaveJSHealNodeDialogParams
|
||||
): void => {
|
||||
fireEvent(element, "show-dialog", {
|
||||
dialogTag: "dialog-zwave_js-heal-node",
|
||||
dialogImport: loadHealNodeDialog,
|
||||
dialogParams: healNodeDialogParams,
|
||||
});
|
||||
};
|
@ -2688,7 +2688,8 @@
|
||||
"node_status": "Node Status",
|
||||
"node_ready": "Node Ready",
|
||||
"device_config": "Configure Device",
|
||||
"reinterview_device": "Re-interview Device"
|
||||
"reinterview_device": "Re-interview Device",
|
||||
"heal_node": "Heal Node"
|
||||
},
|
||||
"node_config": {
|
||||
"header": "Z-Wave Device Configuration",
|
||||
@ -2763,6 +2764,17 @@
|
||||
"healing_failed": "Healing failed. Additional information may be available in the logs.",
|
||||
"healing_cancelled": "Network healing has been cancelled."
|
||||
},
|
||||
"heal_node": {
|
||||
"title": "Heal a Z-Wave Device",
|
||||
"introduction": "Tell {device} to update its routes back to the controller. This can help with communication issues if you have recently moved the device or your controller.",
|
||||
"traffic_warning": "The healing process generates a large amount of traffic on the Z-Wave network. This may cause devices to respond slowly (or not at all) while the heal is in progress.",
|
||||
"start_heal": "Heal Device",
|
||||
"healing_failed": "{device} could not be healed.",
|
||||
"healing_failed_check_logs": "Additional information may be available in the logs.",
|
||||
"healing_complete": "{device} has been healed.",
|
||||
"in_progress": "{device} healing is in progress.",
|
||||
"network_heal_in_progress": "A Z-Wave network heal is already in progress. Please wait for it to finish before healing an individual device."
|
||||
},
|
||||
"logs": {
|
||||
"title": "Z-Wave JS Logs",
|
||||
"log_level": "Log Level",
|
||||
|
Loading…
x
Reference in New Issue
Block a user