From 35d9b2ac3cf92c639a427bdd1330315967a2b871 Mon Sep 17 00:00:00 2001 From: "David F. Mulcahey" Date: Mon, 6 Jan 2020 07:02:47 -0500 Subject: [PATCH] Add the ability to create new Zigbee groups to the ZHA config panel (#4384) * add group page * Update src/panels/config/zha/zha-add-group-page.ts Co-Authored-By: Bram Kragten * fix group name handling * Update src/panels/config/zha/zha-add-group-page.ts Co-Authored-By: Bram Kragten Co-authored-by: Bram Kragten --- src/data/zha.ts | 11 + src/panels/config/zha/zha-add-group-page.ts | 197 ++++++++++++++++++ src/panels/config/zha/zha-config-panel.ts | 7 + src/panels/config/zha/zha-groups-dashboard.ts | 12 ++ src/translations/en.json | 7 +- 5 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 src/panels/config/zha/zha-add-group-page.ts diff --git a/src/data/zha.ts b/src/data/zha.ts index fb227d52fd..d0d57d38d8 100644 --- a/src/data/zha.ts +++ b/src/data/zha.ts @@ -211,3 +211,14 @@ export const removeMembersFromGroup = ( group_id: groupId, members: membersToRemove, }); + +export const addGroup = ( + hass: HomeAssistant, + groupName: string, + membersToAdd?: string[] +): Promise => + hass.callWS({ + type: "zha/group/add", + group_name: groupName, + members: membersToAdd, + }); diff --git a/src/panels/config/zha/zha-add-group-page.ts b/src/panels/config/zha/zha-add-group-page.ts new file mode 100644 index 0000000000..076cddce50 --- /dev/null +++ b/src/panels/config/zha/zha-add-group-page.ts @@ -0,0 +1,197 @@ +import { + property, + LitElement, + html, + customElement, + css, + CSSResult, + PropertyValues, +} from "lit-element"; + +import "../../../layouts/hass-subpage"; +import "../../../layouts/hass-error-screen"; +import "../ha-config-section"; +import { HomeAssistant } from "../../../types"; +import { + ZHADevice, + fetchGroupableDevices, + addGroup, + ZHAGroup, +} from "../../../data/zha"; +import "./zha-devices-data-table"; +import { SelectionChangedEvent } from "../../../components/data-table/ha-data-table"; +import { navigate } from "../../../common/navigate"; +import { PolymerChangedEvent } from "../../../polymer-types"; +import "@polymer/paper-spinner/paper-spinner"; +import "@material/mwc-button"; +import { PaperInputElement } from "@polymer/paper-input/paper-input"; + +@customElement("zha-add-group-page") +export class ZHAAddGroupPage extends LitElement { + @property() public hass!: HomeAssistant; + @property() public narrow!: boolean; + @property() public devices: ZHADevice[] = []; + @property() private _processingAdd: boolean = false; + @property() private _groupName: string = ""; + + private _firstUpdatedCalled: boolean = false; + private _selectedDevicesToAdd: string[] = []; + + public connectedCallback(): void { + super.connectedCallback(); + if (this.hass && this._firstUpdatedCalled) { + this._fetchData(); + } + } + + protected firstUpdated(changedProperties: PropertyValues): void { + super.firstUpdated(changedProperties); + if (this.hass) { + this._fetchData(); + } + this._firstUpdatedCalled = true; + } + + protected render() { + return html` + + +

+ ${this.hass.localize( + "ui.panel.config.zha.groups.create_group_details" + )} +

+ + +
+ ${this.hass.localize("ui.panel.config.zha.groups.add_members")} +
+ + + + +
+ + + ${this.hass!.localize( + "ui.panel.config.zha.groups.create" + )} +
+
+
+ `; + } + + private async _fetchData() { + this.devices = await fetchGroupableDevices(this.hass!); + } + + private _handleAddSelectionChanged(ev: CustomEvent): void { + const changedSelection = ev.detail as SelectionChangedEvent; + const entity = changedSelection.id; + if (changedSelection.selected) { + this._selectedDevicesToAdd.push(entity); + } else { + const index = this._selectedDevicesToAdd.indexOf(entity); + if (index !== -1) { + this._selectedDevicesToAdd.splice(index, 1); + } + } + this._selectedDevicesToAdd = [...this._selectedDevicesToAdd]; + } + + private async _createGroup(): Promise { + this._processingAdd = true; + const group: ZHAGroup = await addGroup( + this.hass, + this._groupName, + this._selectedDevicesToAdd + ); + this._selectedDevicesToAdd = []; + this._processingAdd = false; + this._groupName = ""; + navigate(this, `/config/zha/group/${group.group_id}`, true); + } + + private _handleNameChange(ev: PolymerChangedEvent) { + const target = ev.currentTarget as PaperInputElement; + this._groupName = target.value || ""; + } + + static get styles(): CSSResult[] { + return [ + css` + .header { + font-family: var(--paper-font-display1_-_font-family); + -webkit-font-smoothing: var( + --paper-font-display1_-_-webkit-font-smoothing + ); + font-size: var(--paper-font-display1_-_font-size); + font-weight: var(--paper-font-display1_-_font-weight); + letter-spacing: var(--paper-font-display1_-_letter-spacing); + line-height: var(--paper-font-display1_-_line-height); + opacity: var(--dark-primary-opacity); + } + + .button { + float: right; + } + + .table { + height: 400px; + overflow: auto; + } + + ha-config-section *:last-child { + padding-bottom: 24px; + } + mwc-button paper-spinner { + width: 14px; + height: 14px; + margin-right: 20px; + } + paper-spinner { + display: none; + } + paper-spinner[active] { + display: block; + } + .paper-dialog-buttons { + align-items: flex-end; + padding: 8px; + } + .paper-dialog-buttons .warning { + --mdc-theme-primary: var(--google-red-500); + } + `, + ]; + } +} diff --git a/src/panels/config/zha/zha-config-panel.ts b/src/panels/config/zha/zha-config-panel.ts index c383ba2a2b..f0c0124fc2 100644 --- a/src/panels/config/zha/zha-config-panel.ts +++ b/src/panels/config/zha/zha-config-panel.ts @@ -45,6 +45,13 @@ class ZHAConfigPanel extends HassRouterPage { load: () => import(/* webpackChunkName: "zha-group-page" */ "./zha-group-page"), }, + "group-add": { + tag: "zha-add-group-page", + load: () => + import( + /* webpackChunkName: "zha-add-group-page" */ "./zha-add-group-page" + ), + }, }, }; diff --git a/src/panels/config/zha/zha-groups-dashboard.ts b/src/panels/config/zha/zha-groups-dashboard.ts index 547a3c7b20..9b9f8e60a5 100644 --- a/src/panels/config/zha/zha-groups-dashboard.ts +++ b/src/panels/config/zha/zha-groups-dashboard.ts @@ -17,6 +17,8 @@ import { sortZHAGroups } from "./functions"; import { SelectionChangedEvent } from "../../../components/data-table/ha-data-table"; import "@material/mwc-button"; import "@polymer/paper-spinner/paper-spinner"; +import "@polymer/paper-icon-button/paper-icon-button"; +import { navigate } from "../../../common/navigate"; @customElement("zha-groups-dashboard") export class ZHAGroupsDashboard extends LitElement { @@ -49,6 +51,12 @@ export class ZHAGroupsDashboard extends LitElement { "ui.panel.config.zha.groups.zha_zigbee_groups" )} > + +
${this._groups ? html` @@ -115,6 +123,10 @@ export class ZHAGroupsDashboard extends LitElement { this._processingRemove = false; } + private async _addGroup(): Promise { + navigate(this, `/config/zha/group-add`); + } + static get styles(): CSSResult[] { return [ css` diff --git a/src/translations/en.json b/src/translations/en.json index 8b08f4624f..8e8a008cf0 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1461,7 +1461,12 @@ "add_members": "Add Members", "remove_members": "Remove Members", "adding_members": "Adding Members", - "removing_members": "Removing Members" + "removing_members": "Removing Members", + "create_group_details": "Enter the required details to create a new zigbee group", + "group_name_placeholder": "Group Name", + "create_group": "Create New ZHA Zigbee Group", + "create": "Create Group", + "creating_group": "Creating Group" } }, "zwave": {