From b4dd971829eb811b4b18fb4344f230c7ad2083ff Mon Sep 17 00:00:00 2001 From: Charles Garwood Date: Fri, 12 Jul 2019 16:07:50 -0400 Subject: [PATCH] Z-Wave Config Panel Updates (#3349) * Display network status, hide buttons if network is stopped. * travis/lint updates * Review comments * Add translations * lint * Missed a translation * lint again... * Fix unsubscribe function? * lint again * Remove state_str * Code review comments * fix for lit re-rendering & possible undefined value --- src/data/zwave.ts | 18 ++ src/panels/config/zwave/zwave-network.ts | 347 +++++++++++++---------- src/translations/en.json | 26 +- 3 files changed, 243 insertions(+), 148 deletions(-) create mode 100644 src/data/zwave.ts diff --git a/src/data/zwave.ts b/src/data/zwave.ts new file mode 100644 index 0000000000..f86b11bd28 --- /dev/null +++ b/src/data/zwave.ts @@ -0,0 +1,18 @@ +import { HomeAssistant } from "../types"; + +export interface ZWaveNetworkStatus { + state: number; +} + +export const ZWAVE_NETWORK_STATE_STOPPED = 0; +export const ZWAVE_NETWORK_STATE_FAILED = 1; +export const ZWAVE_NETWORK_STATE_STARTED = 5; +export const ZWAVE_NETWORK_STATE_AWAKED = 7; +export const ZWAVE_NETWORK_STATE_READY = 10; + +export const fetchNetworkStatus = ( + hass: HomeAssistant +): Promise => + hass.callWS({ + type: "zwave/network_status", + }); diff --git a/src/panels/config/zwave/zwave-network.ts b/src/panels/config/zwave/zwave-network.ts index aeed3c23c0..41dd3457f7 100644 --- a/src/panels/config/zwave/zwave-network.ts +++ b/src/panels/config/zwave/zwave-network.ts @@ -1,4 +1,5 @@ import "@polymer/paper-icon-button/paper-icon-button"; +import "@polymer/paper-spinner/paper-spinner"; import { css, @@ -9,14 +10,24 @@ import { property, TemplateResult, } from "lit-element"; +import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { haStyle } from "../../../resources/styles"; import { HomeAssistant } from "../../../types"; +import { + fetchNetworkStatus, + ZWaveNetworkStatus, + ZWAVE_NETWORK_STATE_STOPPED, + ZWAVE_NETWORK_STATE_STARTED, + ZWAVE_NETWORK_STATE_AWAKED, + ZWAVE_NETWORK_STATE_READY, +} from "../../../data/zwave"; import "../../../components/buttons/ha-call-api-button"; import "../../../components/buttons/ha-call-service-button"; import "../../../components/ha-service-description"; import "../../../components/ha-card"; +import "../../../components/ha-icon"; import "../ha-config-section"; @customElement("zwave-network") @@ -24,12 +35,28 @@ export class ZwaveNetwork extends LitElement { @property() public hass!: HomeAssistant; @property() public isWide!: boolean; @property() private _showHelp = false; + @property() private _networkStatus?: ZWaveNetworkStatus; + @property() private _unsubs: Array> = []; + + public disconnectedCallback(): void { + this._unsubscribe(); + } + + protected firstUpdated(changedProps): void { + super.firstUpdated(changedProps); + this._getNetworkStatus(); + this._subscribe(); + } protected render(): TemplateResult | void { return html`
- Z-Wave Network Management + + ${this.hass!.localize( + "ui.panel.config.zwave.network_management.header" + )} +
- Run commands that affect the Z-Wave network. You won't get feedback on - whether the command succeeded, but you can look in the OZW Log to try - to figure out. + ${this.hass!.localize( + "ui.panel.config.zwave.network_management.introduction" + )} - -
- - Add Node Secure - - - - - - Add Node - - - - - - Remove Node - - - -
-
- - Cancel Command - - - -
-
- - Heal Network - - - - - Start Network - - - - - - Stop Network - - - - - - Soft Reset - - - - - - Test Network - - - - - - Save Config - -
-
+ ${this._networkStatus + ? html` + +
+ ${this._networkStatus.state === ZWAVE_NETWORK_STATE_STOPPED + ? html` + + ${this.hass!.localize( + "ui.panel.config.zwave.network_status.network_stopped" + )} + ` + : this._networkStatus.state === ZWAVE_NETWORK_STATE_STARTED + ? html` + + ${this.hass!.localize( + "ui.panel.config.zwave.network_status.network_starting" + )}
+ + ${this.hass!.localize( + "ui.panel.config.zwave.network_status.network_starting_note" + )} + + ` + : this._networkStatus.state === ZWAVE_NETWORK_STATE_AWAKED + ? html` + + ${this.hass!.localize( + "ui.panel.config.zwave.network_status.network_started" + )}
+ + ${this.hass!.localize( + "ui.panel.config.zwave.network_status.network_started_note_some_queried" + )} + + ` + : this._networkStatus.state === ZWAVE_NETWORK_STATE_READY + ? html` + ${this.hass!.localize( + "ui.panel.config.zwave.network_status.network_started" + )}
+ + ${this.hass!.localize( + "ui.panel.config.zwave.network_status.network_started_note_all_queried" + )} + + ` + : ""} +
+
+ ${this._networkStatus.state >= ZWAVE_NETWORK_STATE_AWAKED + ? html` + ${this._generateServiceButton("stop_network")} + ${this._generateServiceButton("heal_network")} + ${this._generateServiceButton("test_network")} + ` + : html` + ${this._generateServiceButton("start_network")} + `} +
+ ${this._networkStatus.state >= ZWAVE_NETWORK_STATE_AWAKED + ? html` +
+ ${this._generateServiceButton("soft_reset")} + + ${this.hass!.localize( + "ui.panel.config.zwave.services.save_config" + )} + +
+ ` + : ""} +
+ ${this._networkStatus.state >= ZWAVE_NETWORK_STATE_AWAKED + ? html` + +
+ ${this._generateServiceButton("add_node_secure")} + ${this._generateServiceButton("add_node")} + ${this._generateServiceButton("remove_node")} +
+
+ ${this._generateServiceButton("cancel_command")} +
+
+ ` + : ""} + ` + : ""}
`; } + private async _getNetworkStatus(): Promise { + this._networkStatus = await fetchNetworkStatus(this.hass!); + } + + private _subscribe(): void { + this._unsubs = [ + "zwave.network_start", + "zwave.network_stop", + "zwave.network_ready", + "zwave.network_complete", + "zwave.network_complete_some_dead", + ].map((e) => + this.hass!.connection.subscribeEvents( + (event) => this._handleEvent(event), + e + ) + ); + } + + private _unsubscribe(): void { + while (this._unsubs.length) { + this._unsubs.pop()!.then((unsub) => unsub()); + } + } + + private _handleEvent(event) { + if (event.event_type === "zwave.network_start") { + // Optimistically set the state, wait 1s and poll the backend + // The backend will still report a state of 0 when the 'network_start' + // event is first fired. + if (this._networkStatus) { + this._networkStatus = { ...this._networkStatus, state: 5 }; + } + setTimeout(() => this._getNetworkStatus, 1000); + } else { + this._getNetworkStatus(); + } + } + private _onHelpTap(): void { this._showHelp = !this._showHelp; } + private _generateServiceButton(service: string) { + return html` + + ${this.hass!.localize("ui.panel.config.zwave.services." + service)} + + + + `; + } + static get styles(): CSSResult[] { return [ haStyle, @@ -201,6 +234,26 @@ export class ZwaveNetwork extends LitElement { margin-top: 24px; } + .network-status { + text-align: center; + } + + .network-status div.details { + font-size: 1.5rem; + padding: 24px; + } + + .network-status ha-icon { + display: block; + margin: 0px auto 16px; + width: 48px; + height: 48px; + } + + .network-status small { + font-size: 1rem; + } + ha-card { margin: 0 auto; max-width: 600px; diff --git a/src/translations/en.json b/src/translations/en.json index c4aa870314..b6e6d7f158 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -921,7 +921,31 @@ }, "zwave": { "caption": "Z-Wave", - "description": "Manage your Z-Wave network" + "description": "Manage your Z-Wave network", + "network_management": { + "header": "Z-Wave Network Management", + "introduction": "Run commands that affect the Z-Wave network. You won't get feedback on whether most commands succeeded, but you can check the OZW Log to try to find out." + }, + "network_status": { + "network_stopped": "Z-Wave Network Stopped", + "network_starting": "Starting Z-Wave Network...", + "network_starting_note": "This may take a while depending on the size of your network.", + "network_started": "Z-Wave Network Started", + "network_started_note_some_queried": "Awake nodes have been queried. Sleeping nodes will be queried when they wake.", + "network_started_note_all_queried": "All nodes have been queried." + }, + "services": { + "start_network": "Start Network", + "stop_network": "Stop Network", + "heal_network": "Heal Network", + "test_network": "Test Network", + "soft_reset": "Soft Reset", + "save_config": "Save Config", + "add_node_secure": "Add Node Secure", + "add_node": "Add Node", + "remove_node": "Remove Node", + "cancel_command": "Cancel Command" + } } }, "history": {