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
This commit is contained in:
Charles Garwood 2019-07-12 16:07:50 -04:00 committed by Paulus Schoutsen
parent e99d6f8e6a
commit b4dd971829
3 changed files with 243 additions and 148 deletions

18
src/data/zwave.ts Normal file
View File

@ -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<ZWaveNetworkStatus> =>
hass.callWS({
type: "zwave/network_status",
});

View File

@ -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<Promise<UnsubscribeFunc>> = [];
public disconnectedCallback(): void {
this._unsubscribe();
}
protected firstUpdated(changedProps): void {
super.firstUpdated(changedProps);
this._getNetworkStatus();
this._subscribe();
}
protected render(): TemplateResult | void {
return html`
<ha-config-section .isWide="${this.isWide}">
<div style="position: relative" slot="header">
<span>Z-Wave Network Management</span>
<span>
${this.hass!.localize(
"ui.panel.config.zwave.network_management.header"
)}
</span>
<paper-icon-button
class="toggle-help-icon"
@click="${this._onHelpTap}"
@ -37,162 +64,168 @@ export class ZwaveNetwork extends LitElement {
></paper-icon-button>
</div>
<span slot="introduction">
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"
)}
</span>
<ha-card class="content">
<div class="card-actions">
<ha-call-service-button
.hass=${this.hass}
domain="zwave"
service="add_node_secure"
>
Add Node Secure
</ha-call-service-button>
<ha-service-description
.hass=${this.hass}
domain="zwave"
service="add_node_secure"
?hidden=${!this._showHelp}
>
</ha-service-description>
<ha-call-service-button
.hass=${this.hass}
domain="zwave"
service="add_node"
>
Add Node
</ha-call-service-button>
<ha-service-description
.hass=${this.hass}
domain="zwave"
service="add_node"
?hidden=${!this._showHelp}
>
</ha-service-description>
<ha-call-service-button
.hass=${this.hass}
domain="zwave"
service="remove_node"
>
Remove Node
</ha-call-service-button>
<ha-service-description
.hass=${this.hass}
domain="zwave"
service="remove_node"
?hidden=${!this._showHelp}
>
</ha-service-description>
</div>
<div class="card-actions warning">
<ha-call-service-button
.hass=${this.hass}
domain="zwave"
service="cancel_command"
>
Cancel Command
</ha-call-service-button>
<ha-service-description
.hass=${this.hass}
domain="zwave"
service="cancel_command"
?hidden=${!this._showHelp}
>
</ha-service-description>
</div>
<div class="card-actions">
<ha-call-service-button
.hass=${this.hass}
domain="zwave"
service="heal_network"
>
Heal Network
</ha-call-service-button>
<ha-service-description
.hass=${this.hass}
domain="zwave"
service="heal_network"
?hidden=${!this._showHelp}
></ha-service-description>
<ha-call-service-button
.hass=${this.hass}
domain="zwave"
service="start_network"
>
Start Network
</ha-call-service-button>
<ha-service-description
.hass=${this.hass}
domain="zwave"
service="start_network"
?hidden=${!this._showHelp}
>
</ha-service-description>
<ha-call-service-button
.hass=${this.hass}
domain="zwave"
service="stop_network"
>
Stop Network
</ha-call-service-button>
<ha-service-description
.hass=${this.hass}
domain="zwave"
service="stop_network"
?hidden=${!this._showHelp}
>
</ha-service-description>
<ha-call-service-button
.hass=${this.hass}
domain="zwave"
service="soft_reset"
>
Soft Reset
</ha-call-service-button>
<ha-service-description
.hass=${this.hass}
domain="zwave"
service="soft_reset"
?hidden=${!this._showHelp}
>
</ha-service-description>
<ha-call-service-button
.hass=${this.hass}
domain="zwave"
service="test_network"
>
Test Network
</ha-call-service-button>
<ha-service-description
.hass=${this.hass}
domain="zwave"
service="test_network"
?hidden=${!this._showHelp}
>
</ha-service-description>
<ha-call-api-button .hass=${this.hass} path="zwave/saveconfig">
Save Config
</ha-call-api-button>
</div>
</ha-card>
${this._networkStatus
? html`
<ha-card class="content network-status">
<div class="details">
${this._networkStatus.state === ZWAVE_NETWORK_STATE_STOPPED
? html`
<ha-icon icon="hass:close"></ha-icon>
${this.hass!.localize(
"ui.panel.config.zwave.network_status.network_stopped"
)}
`
: this._networkStatus.state === ZWAVE_NETWORK_STATE_STARTED
? html`
<paper-spinner active></paper-spinner>
${this.hass!.localize(
"ui.panel.config.zwave.network_status.network_starting"
)}<br />
<small>
${this.hass!.localize(
"ui.panel.config.zwave.network_status.network_starting_note"
)}
</small>
`
: this._networkStatus.state === ZWAVE_NETWORK_STATE_AWAKED
? html`
<ha-icon icon="hass:checkbox-marked-circle"> </ha-icon>
${this.hass!.localize(
"ui.panel.config.zwave.network_status.network_started"
)}<br />
<small>
${this.hass!.localize(
"ui.panel.config.zwave.network_status.network_started_note_some_queried"
)}
</small>
`
: this._networkStatus.state === ZWAVE_NETWORK_STATE_READY
? html`
${this.hass!.localize(
"ui.panel.config.zwave.network_status.network_started"
)}<br />
<small>
${this.hass!.localize(
"ui.panel.config.zwave.network_status.network_started_note_all_queried"
)}
</small>
`
: ""}
</div>
<div class="card-actions">
${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")}
`}
</div>
${this._networkStatus.state >= ZWAVE_NETWORK_STATE_AWAKED
? html`
<div class="card-actions">
${this._generateServiceButton("soft_reset")}
<ha-call-api-button
.hass=${this.hass}
path="zwave/saveconfig"
>
${this.hass!.localize(
"ui.panel.config.zwave.services.save_config"
)}
</ha-call-api-button>
</div>
`
: ""}
</ha-card>
${this._networkStatus.state >= ZWAVE_NETWORK_STATE_AWAKED
? html`
<ha-card class="content">
<div class="card-actions">
${this._generateServiceButton("add_node_secure")}
${this._generateServiceButton("add_node")}
${this._generateServiceButton("remove_node")}
</div>
<div class="card-actions">
${this._generateServiceButton("cancel_command")}
</div>
</ha-card>
`
: ""}
`
: ""}
</ha-config-section>
`;
}
private async _getNetworkStatus(): Promise<void> {
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`
<ha-call-service-button
.hass=${this.hass}
domain="zwave"
service="${service}"
>
${this.hass!.localize("ui.panel.config.zwave.services." + service)}
</ha-call-service-button>
<ha-service-description
.hass=${this.hass}
domain="zwave"
service="${service}"
?hidden=${!this._showHelp}
>
</ha-service-description>
`;
}
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;

View File

@ -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": {