Initial Z-Wave JS Config Panel (#8166)

This commit is contained in:
Charles Garwood 2021-01-16 10:22:27 -05:00 committed by GitHub
parent bb77d34017
commit 40f4c35b42
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 360 additions and 0 deletions

27
src/data/zwave_js.ts Normal file
View File

@ -0,0 +1,27 @@
import { HomeAssistant } from "../types";
export interface ZWaveJSNetwork {
client: ZWaveJSClient;
controller: ZWaveJSController;
}
export interface ZWaveJSClient {
state: string;
ws_server_url: string;
server_version: string;
driver_version: string;
}
export interface ZWaveJSController {
home_id: string;
node_count: number;
}
export const fetchNetworkStatus = (
hass: HomeAssistant,
entry_id: string
): Promise<ZWaveJSNetwork> =>
hass.callWS({
type: "zwave_js/network_status",
entry_id,
});

View File

@ -307,6 +307,13 @@ class HaPanelConfig extends HassRouterPage {
load: () =>
import("./integrations/integration-panels/ozw/ozw-config-router"),
},
zwave_js: {
tag: "zwave_js-config-router",
load: () =>
import(
"./integrations/integration-panels/zwave_js/zwave_js-config-router"
),
},
},
};

View File

@ -66,6 +66,10 @@ const integrationsWithPanel = {
buttonLocalizeKey: "ui.panel.config.zwave.button",
path: "/config/zwave",
},
zwave_js: {
buttonLocalizeKey: "ui.panel.config.zwave_js.button",
path: "/config/zwave_js/dashboard",
},
};
@customElement("ha-integration-card")

View File

@ -0,0 +1,229 @@
import "@material/mwc-button/mwc-button";
import { mdiCheckCircle, mdiCircle } from "@mdi/js";
import {
css,
CSSResultArray,
customElement,
html,
internalProperty,
LitElement,
property,
TemplateResult,
} from "lit-element";
import { classMap } from "lit-html/directives/class-map";
import "../../../../../components/ha-card";
import "../../../../../components/ha-icon-next";
import {
fetchNetworkStatus,
ZWaveJSNetwork,
} from "../../../../../data/zwave_js";
import "../../../../../layouts/hass-tabs-subpage";
import { haStyle } from "../../../../../resources/styles";
import type { HomeAssistant, Route } from "../../../../../types";
import "../../../ha-config-section";
import { configTabs } from "./zwave_js-config-router";
@customElement("zwave_js-config-dashboard")
class ZWaveJSConfigDashboard extends LitElement {
@property({ type: Object }) public hass!: HomeAssistant;
@property({ type: Object }) public route!: Route;
@property({ type: Boolean }) public narrow!: boolean;
@property({ type: Boolean }) public isWide!: boolean;
@property() public configEntryId?: string;
@internalProperty() private _network?: ZWaveJSNetwork;
@internalProperty() private _status = "unknown";
@internalProperty() private _icon = mdiCircle;
protected firstUpdated() {
if (this.hass) {
this._fetchData();
}
}
protected render(): TemplateResult {
return html`
<hass-tabs-subpage
.hass=${this.hass}
.narrow=${this.narrow}
.route=${this.route}
.tabs=${configTabs}
>
<ha-config-section .narrow=${this.narrow} .isWide=${this.isWide}>
<div slot="header">
${this.hass.localize("ui.panel.config.zwave_js.dashboard.header")}
</div>
<div slot="introduction">
${this.hass.localize(
"ui.panel.config.zwave_js.dashboard.introduction"
)}
</div>
${this._network
? html`
<ha-card class="content network-status">
<div class="card-content">
<div class="heading">
<div class="icon">
${this._status === "connecting"
? html`<ha-circular-progress
active
></ha-circular-progress>`
: html`
<ha-svg-icon
.path=${this._icon}
class="network-status-icon ${classMap({
[this._status]: true,
})}"
slot="item-icon"
></ha-svg-icon>
`}
</div>
${this._status !== "connecting"
? html`
<div class="details">
${this.hass.localize(
"ui.panel.config.zwave_js.common.network"
)}
${this.hass.localize(
`ui.panel.config.zwave_js.network_status.${this._status}`
)}<br />
<small
>${this._network.client.ws_server_url}</small
>
</div>
`
: ``}
</div>
<div class="secondary">
${this.hass.localize(
"ui.panel.config.zwave_js.dashboard.driver_version"
)}:
${this._network.client.driver_version}<br />
${this.hass.localize(
"ui.panel.config.zwave_js.dashboard.server_version"
)}:
${this._network.client.server_version}<br />
${this.hass.localize(
"ui.panel.config.zwave_js.dashboard.home_id"
)}:
${this._network.controller.home_id}<br />
${this.hass.localize(
"ui.panel.config.zwave_js.dashboard.node_count"
)}:
${this._network.controller.node_count}
</div>
</div>
<div class="card-actions">
<a
href="${`/config/devices/dashboard?historyBack=1&config_entry=${this.configEntryId}`}"
>
<mwc-button>
${this.hass.localize("ui.panel.config.devices.caption")}
</mwc-button>
</a>
<a
href="${`/config/entities/dashboard?historyBack=1&config_entry=${this.configEntryId}`}"
>
<mwc-button>
${this.hass.localize(
"ui.panel.config.entities.caption"
)}
</mwc-button>
</a>
</div>
</ha-card>
`
: ``}
</ha-config-section>
</hass-tabs-subpage>
`;
}
private async _fetchData() {
if (!this.configEntryId) return;
this._network = await fetchNetworkStatus(this.hass!, this.configEntryId);
this._status = this._network.client.state;
if (this._status === "connected") {
this._icon = mdiCheckCircle;
}
}
static get styles(): CSSResultArray {
return [
haStyle,
css`
.secondary {
color: var(--secondary-text-color);
}
.connected {
color: green;
}
.starting {
color: orange;
}
.offline {
color: red;
}
.content {
margin-top: 24px;
}
.sectionHeader {
position: relative;
padding-right: 40px;
}
.network-status div.heading {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 16px;
}
.network-status {
text-align: center;
}
.network-status div.heading .icon {
width: 48px;
height: 48px;
margin-right: 16px;
}
.network-status div.heading ha-svg-icon {
width: 48px;
height: 48px;
}
.network-status div.heading .details {
font-size: 1.5rem;
}
.network-status small {
font-size: 1rem;
}
ha-card {
margin: 0 auto;
max-width: 600px;
}
[hidden] {
display: none;
}
`,
];
}
}
declare global {
interface HTMLElementTagNameMap {
"zwave_js-config-dashboard": ZWaveJSConfigDashboard;
}
}

View File

@ -0,0 +1,71 @@
import { customElement, property } from "lit-element";
import {
HassRouterPage,
RouterOptions,
} from "../../../../../layouts/hass-router-page";
import { HomeAssistant } from "../../../../../types";
import { navigate } from "../../../../../common/navigate";
import { PageNavigation } from "../../../../../layouts/hass-tabs-subpage";
import { mdiServerNetwork } from "@mdi/js";
export const configTabs: PageNavigation[] = [
{
translationKey: "ui.panel.config.zwave_js.navigation.network",
path: `/config/zwave_js/dashboard`,
iconPath: mdiServerNetwork,
},
];
@customElement("zwave_js-config-router")
class ZWaveJSConfigRouter extends HassRouterPage {
@property({ attribute: false }) public hass!: HomeAssistant;
@property() public isWide!: boolean;
@property() public narrow!: boolean;
private _configEntry = new URLSearchParams(window.location.search).get(
"config_entry"
);
protected routerOptions: RouterOptions = {
defaultPage: "dashboard",
showLoading: true,
routes: {
dashboard: {
tag: "zwave_js-config-dashboard",
load: () => import("./zwave_js-config-dashboard"),
},
},
};
protected updatePageEl(el): void {
el.route = this.routeTail;
el.hass = this.hass;
el.isWide = this.isWide;
el.narrow = this.narrow;
el.configEntryId = this._configEntry;
if (this._currentPage === "node") {
el.nodeId = this.routeTail.path.substr(1);
}
const searchParams = new URLSearchParams(window.location.search);
if (this._configEntry && !searchParams.has("config_entry")) {
searchParams.append("config_entry", this._configEntry);
navigate(
this,
`${this.routeTail.prefix}${
this.routeTail.path
}?${searchParams.toString()}`,
true
);
}
}
}
declare global {
interface HTMLElementTagNameMap {
"zwave_js-config-router": ZWaveJSConfigRouter;
}
}

View File

@ -2378,6 +2378,28 @@
"node_info": "Node Information",
"refresh_entity": "Refresh Entity"
}
},
"zwave_js": {
"button": "Configure",
"navigation": {
"network": "Network"
},
"common": {
"network": "Network"
},
"dashboard": {
"header": "Manage your Z-Wave Network",
"introduction": "Manage your Z-Wave network and Z-Wave nodes",
"driver_version": "Driver Version",
"server_version": "Server Version",
"home_id": "Home ID",
"node_count": "Node Count"
},
"network_status": {
"connected": "Connected",
"connecting": "Connecting",
"unknown": "Unknown"
}
}
},
"history": {