Add Zigbee group viewing to ZHA config panel (#4365)

* add ability to view zigbee groups

* review comments

* remove selectable until used
This commit is contained in:
David F. Mulcahey 2019-12-23 10:46:34 -05:00 committed by GitHub
parent bb41170765
commit de653e1f7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 312 additions and 1 deletions

View File

@ -51,6 +51,12 @@ export interface ReadAttributeServiceData {
manufacturer?: number;
}
export interface ZHAGroup {
name: string;
group_id: number;
members: ZHADevice[];
}
export const reconfigureNode = (
hass: HomeAssistant,
ieeeAddress: string
@ -153,3 +159,8 @@ export const fetchClustersForZhaNode = (
type: "zha/devices/clusters",
ieee: ieeeAddress,
});
export const fetchGroups = (hass: HomeAssistant): Promise<ZHAGroup[]> =>
hass.callWS({
type: "zha/groups",
});

View File

@ -1,4 +1,4 @@
import { ZHADevice } from "../../../data/zha";
import { ZHADevice, ZHAGroup } from "../../../data/zha";
export const formatAsPaddedHex = (value: string | number): string => {
let hex = value;
@ -13,3 +13,9 @@ export const sortZHADevices = (a: ZHADevice, b: ZHADevice): number => {
const nameb = b.user_given_name ? b.user_given_name : b.name;
return nameA.localeCompare(nameb);
};
export const sortZHAGroups = (a: ZHAGroup, b: ZHAGroup): number => {
const nameA = a.name;
const nameb = b.name;
return nameA.localeCompare(nameb);
};

View File

@ -5,6 +5,7 @@ import "./zha-cluster-attributes";
import "./zha-cluster-commands";
import "./zha-network";
import "./zha-node";
import "./zha-groups-tile";
import "@polymer/paper-icon-button/paper-icon-button";
import {
@ -45,6 +46,11 @@ export class HaConfigZha extends LitElement {
.hass="${this.hass}"
></zha-network>
<zha-groups-tile
.isWide="${this.isWide}"
.hass="${this.hass}"
></zha-groups-tile>
<zha-node
.isWide="${this.isWide}"
.hass="${this.hass}"

View File

@ -12,6 +12,7 @@ import { HomeAssistant } from "../../../types";
class ZHAConfigPanel extends HassRouterPage {
@property() public hass!: HomeAssistant;
@property() public isWide!: boolean;
@property() public narrow!: boolean;
protected routerOptions: RouterOptions = {
defaultPage: "configuration",
@ -32,6 +33,13 @@ class ZHAConfigPanel extends HassRouterPage {
/* webpackChunkName: "zha-add-devices-page" */ "./zha-add-devices-page"
),
},
groups: {
tag: "zha-groups-dashboard",
load: () =>
import(
/* webpackChunkName: "zha-groups-dashboard" */ "./zha-groups-dashboard"
),
},
},
};
@ -39,6 +47,7 @@ class ZHAConfigPanel extends HassRouterPage {
el.route = this.routeTail;
el.hass = this.hass;
el.isWide = this.isWide;
el.narrow = this.narrow;
}
}

View File

@ -0,0 +1,77 @@
import "../../../layouts/hass-subpage";
import "./zha-groups-data-table";
import {
LitElement,
html,
TemplateResult,
property,
customElement,
CSSResult,
css,
} from "lit-element";
import { HomeAssistant } from "../../../types";
import { ZHAGroup, fetchGroups } from "../../../data/zha";
import { sortZHAGroups } from "./functions";
@customElement("zha-groups-dashboard")
export class ZHAGroupsDashboard extends LitElement {
@property() public hass!: HomeAssistant;
@property() public narrow = false;
@property() public _groups!: ZHAGroup[];
public connectedCallback(): void {
super.connectedCallback();
this._fetchGroups();
}
protected render(): TemplateResult {
return html`
<hass-subpage
header=${this.hass.localize(
"ui.panel.config.zha.groups.zha_zigbee_groups"
)}
>
<div class="content">
<zha-groups-data-table
.hass=${this.hass}
.narrow=${this.narrow}
.groups=${this._groups}
class="table"
></zha-groups-data-table>
</div>
</hass-subpage>
`;
}
private async _fetchGroups() {
this._groups = (await fetchGroups(this.hass!)).sort(sortZHAGroups);
}
static get styles(): CSSResult[] {
return [
css`
.content {
padding: 4px;
}
zha-groups-data-table {
width: 100%;
}
.button {
float: right;
}
.table {
height: 200px;
overflow: auto;
}
`,
];
}
}
declare global {
interface HTMLElementTagNameMap {
"zha-groups-dashboard": ZHAGroupsDashboard;
}
}

View File

@ -0,0 +1,85 @@
import "../../../components/data-table/ha-data-table";
import "../../../components/entity/ha-state-icon";
import memoizeOne from "memoize-one";
import {
LitElement,
html,
TemplateResult,
property,
customElement,
} from "lit-element";
import { HomeAssistant } from "../../../types";
// tslint:disable-next-line
import { DataTableColumnContainer } from "../../../components/data-table/ha-data-table";
// tslint:disable-next-line
import { ZHAGroup, ZHADevice } from "../../../data/zha";
import { formatAsPaddedHex } from "./functions";
export interface GroupRowData extends ZHAGroup {
group?: GroupRowData;
id?: number;
}
@customElement("zha-groups-data-table")
export class ZHAGroupsDataTable extends LitElement {
@property() public hass!: HomeAssistant;
@property() public narrow = false;
@property() public groups: ZHAGroup[] = [];
private _columns = memoizeOne(
(narrow: boolean): DataTableColumnContainer =>
narrow
? {
name: {
title: "Group",
sortable: true,
filterable: true,
direction: "asc",
},
}
: {
name: {
title: this.hass.localize("ui.panel.config.zha.groups.groups"),
sortable: true,
filterable: true,
direction: "asc",
},
group_id: {
title: this.hass.localize("ui.panel.config.zha.groups.group_id"),
template: (groupId: number) => {
return html`
${formatAsPaddedHex(groupId)}
`;
},
sortable: true,
},
members: {
title: this.hass.localize("ui.panel.config.zha.groups.members"),
template: (members: ZHADevice[]) => {
return html`
${members.length}
`;
},
sortable: true,
},
}
);
protected render(): TemplateResult {
return html`
<ha-data-table
.columns=${this._columns(this.narrow)}
.data=${this.groups}
.id=${"group_id"}
></ha-data-table>
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"zha-groups-data-table": ZHAGroupsDataTable;
}
}

View File

@ -0,0 +1,108 @@
import "../../../components/ha-card";
import "../ha-config-section";
import "@material/mwc-button";
import "@polymer/paper-icon-button/paper-icon-button";
import {
css,
CSSResult,
html,
LitElement,
TemplateResult,
property,
customElement,
} from "lit-element";
import { navigate } from "../../../common/navigate";
import { haStyle } from "../../../resources/styles";
import { HomeAssistant } from "../../../types";
@customElement("zha-groups-tile")
export class ZHAGroupsTile extends LitElement {
@property() public hass?: HomeAssistant;
@property() public isWide?: boolean;
@property() private _showHelp = false;
protected render(): TemplateResult | void {
return html`
<ha-config-section .isWide="${this.isWide}">
<div style="position: relative" slot="header">
<span>
${this.hass!.localize("ui.panel.config.zha.groups.header")}
</span>
<paper-icon-button
class="toggle-help-icon"
@click="${this._onHelpTap}"
icon="hass:help-circle"
></paper-icon-button>
</div>
<span slot="introduction">
${this.hass!.localize("ui.panel.config.zha.groups.introduction")}
</span>
<ha-card class="content">
<div class="card-actions">
<mwc-button @click=${this._onManageGroupsClick}>
${this.hass!.localize("ui.panel.config.zha.groups.manage_groups")}
</mwc-button>
</div>
</ha-card>
</ha-config-section>
`;
}
private _onHelpTap(): void {
this._showHelp = !this._showHelp;
}
private _onManageGroupsClick() {
navigate(this, "groups");
}
static get styles(): CSSResult[] {
return [
haStyle,
css`
.content {
margin-top: 24px;
}
ha-card {
margin: 0 auto;
max-width: 600px;
}
.card-actions.warning ha-call-service-button {
color: var(--google-red-500);
}
.toggle-help-icon {
position: absolute;
top: -6px;
right: 0;
color: var(--primary-color);
}
ha-service-description {
display: block;
color: grey;
}
[hidden] {
display: none;
}
.help-text2 {
color: grey;
padding: 16px;
}
`,
];
}
}
declare global {
interface HTMLElementTagNameMap {
"zha-groups-tile": ZHAGroupsTile;
}
}

View File

@ -1437,6 +1437,15 @@
"commands_of_cluster": "Commands of the selected cluster",
"issue_zigbee_command": "Issue Zigbee Command",
"help_command_dropdown": "Select a command to interact with."
},
"groups": {
"zha_zigbee_groups": "ZHA Zigbee Groups",
"manage_groups": "Manage Zigbee Groups",
"groups": "Groups",
"group_id": "Group ID",
"members": "Members",
"header": "Zigbee Group Management",
"introduction": "Create and modify zigbee groups"
}
},
"zwave": {