ZHA device info dialog (#3529)

* zha device info dialog

* cleanup

* quick hack to make this work

* remove hack

* add mixin for zha device info dialog

* fix potential exception

* cleanup

* review comments

* lint

* remove unused import

* lint

* review coments

* review comments

* translations and css
This commit is contained in:
David F. Mulcahey 2019-09-04 12:40:47 -04:00 committed by Paulus Schoutsen
parent c4fca84ded
commit 164e433592
9 changed files with 217 additions and 38 deletions

View File

@ -80,6 +80,15 @@ export const fetchDevices = (hass: HomeAssistant): Promise<ZHADevice[]> =>
type: "zha/devices", type: "zha/devices",
}); });
export const fetchZHADevice = (
hass: HomeAssistant,
ieeeAddress: string
): Promise<ZHADevice> =>
hass.callWS({
type: "zha/device",
ieee: ieeeAddress,
});
export const fetchBindableDevices = ( export const fetchBindableDevices = (
hass: HomeAssistant, hass: HomeAssistant,
ieeeAddress: string ieeeAddress: string

View File

@ -0,0 +1,115 @@
import {
LitElement,
html,
css,
CSSResult,
TemplateResult,
customElement,
property,
} from "lit-element";
import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable";
import "../../components/dialog/ha-paper-dialog";
// Not duplicate, is for typing
// tslint:disable-next-line
import { HaPaperDialog } from "../../components/dialog/ha-paper-dialog";
import "../../panels/config/zha/zha-device-card";
import { PolymerChangedEvent } from "../../polymer-types";
import { haStyleDialog } from "../../resources/styles";
import { HomeAssistant } from "../../types";
import { ZHADeviceInfoDialogParams } from "./show-dialog-zha-device-info";
import { ZHADevice, fetchZHADevice } from "../../data/zha";
@customElement("dialog-zha-device-info")
class DialogZHADeviceInfo extends LitElement {
@property() public hass!: HomeAssistant;
@property() private _params?: ZHADeviceInfoDialogParams;
@property() private _error?: string;
@property() private _device?: ZHADevice;
public async showDialog(params: ZHADeviceInfoDialogParams): Promise<void> {
this._params = params;
this._device = await fetchZHADevice(this.hass, params.ieee);
await this.updateComplete;
this._dialog.open();
}
protected render(): TemplateResult | void {
if (!this._params || !this._device) {
return html``;
}
return html`
<ha-paper-dialog
with-backdrop
opened
@opened-changed=${this._openedChanged}
>
${this._error
? html`
<div class="error">${this._error}</div>
`
: html`
<zha-device-card
class="card"
.hass=${this.hass}
.device=${this._device}
showActions
isJoinPage
@zha-device-removed=${this._onDeviceRemoved}
></zha-device-card>
`}
</ha-paper-dialog>
`;
}
private _openedChanged(ev: PolymerChangedEvent<boolean>): void {
if (!ev.detail.value) {
this._params = undefined;
this._error = undefined;
this._device = undefined;
}
}
private _onDeviceRemoved(): void {
this._closeDialog();
}
private get _dialog(): HaPaperDialog {
return this.shadowRoot!.querySelector("ha-paper-dialog")!;
}
private _closeDialog() {
this._dialog.close();
}
static get styles(): CSSResult[] {
return [
haStyleDialog,
css`
ha-paper-dialog > * {
margin: 0;
display: block;
padding: 0;
}
.card {
box-sizing: border-box;
display: flex;
flex: 1 0 300px;
min-width: 0;
max-width: 600px;
word-wrap: break-word;
}
.error {
color: var(--google-red-500);
}
`,
];
}
}
declare global {
interface HTMLElementTagNameMap {
"dialog-zha-device-info": DialogZHADeviceInfo;
}
}

View File

@ -0,0 +1,19 @@
import { fireEvent } from "../../common/dom/fire_event";
export interface ZHADeviceInfoDialogParams {
ieee: string;
}
export const loadZHADeviceInfoDialog = () =>
import(/* webpackChunkName: "dialog-zha-device-info" */ "./dialog-zha-device-info");
export const showZHADeviceInfoDialog = (
element: HTMLElement,
zhaDeviceInfoParams: ZHADeviceInfoDialogParams
): void => {
fireEvent(element, "show-dialog", {
dialogTag: "dialog-zha-device-info",
dialogImport: loadZHADeviceInfoDialog,
dialogParams: zhaDeviceInfoParams,
});
};

View File

@ -113,12 +113,12 @@ class ZHAAddDevicesPage extends LitElement {
(device) => html` (device) => html`
<zha-device-card <zha-device-card
class="card" class="card"
.hass="${this.hass}" .hass=${this.hass}
.device="${device}" .device=${device}
.narrow="${!this.isWide}" .narrow=${!this.isWide}
.showHelp="${this._showHelp}" .showHelp=${this._showHelp}
.showActions="${!this._active}" .showActions=${!this._active}
.isJoinPage="${true}" isJoinPage
></zha-device-card> ></zha-device-card>
` `
)} )}

View File

@ -55,11 +55,11 @@ declare global {
@customElement("zha-device-card") @customElement("zha-device-card")
class ZHADeviceCard extends LitElement { class ZHADeviceCard extends LitElement {
@property() public hass!: HomeAssistant; @property() public hass!: HomeAssistant;
@property() public narrow?: boolean;
@property() public device?: ZHADevice; @property() public device?: ZHADevice;
@property() public showHelp: boolean = false; @property({ type: Boolean }) public narrow?: boolean;
@property() public showActions?: boolean; @property({ type: Boolean }) public showHelp?: boolean = false;
@property() public isJoinPage?: boolean; @property({ type: Boolean }) public showActions?: boolean;
@property({ type: Boolean }) public isJoinPage?: boolean;
@property() private _serviceData?: NodeServiceData; @property() private _serviceData?: NodeServiceData;
@property() private _areas: AreaRegistryEntry[] = []; @property() private _areas: AreaRegistryEntry[] = [];
@property() private _selectedAreaIndex: number = -1; @property() private _selectedAreaIndex: number = -1;
@ -139,7 +139,7 @@ class ZHADeviceCard extends LitElement {
<div class="model">${this.device!.model}</div> <div class="model">${this.device!.model}</div>
<div class="manuf"> <div class="manuf">
${this.hass!.localize( ${this.hass!.localize(
"ui.panel.config.integrations.config_entry.manuf", "ui.dialogs.zha_device_info.manuf",
"manufacturer", "manufacturer",
this.device!.manufacturer this.device!.manufacturer
)} )}
@ -206,14 +206,14 @@ class ZHADeviceCard extends LitElement {
@change="${this._saveCustomName}" @change="${this._saveCustomName}"
.value="${this._userGivenName}" .value="${this._userGivenName}"
placeholder="${this.hass!.localize( placeholder="${this.hass!.localize(
"ui.panel.config.zha.device_card.device_name_placeholder" "ui.dialogs.zha_device_info.zha_device_card.device_name_placeholder"
)}" )}"
></paper-input> ></paper-input>
</div> </div>
<div class="node-picker"> <div class="node-picker">
<paper-dropdown-menu <paper-dropdown-menu
label="${this.hass!.localize( label="${this.hass!.localize(
"ui.panel.config.zha.device_card.area_picker_label" "ui.dialogs.zha_device_info.zha_device_card.area_picker_label"
)}" )}"
class="flex" class="flex"
> >
@ -223,9 +223,7 @@ class ZHADeviceCard extends LitElement {
@iron-select="${this._selectedAreaChanged}" @iron-select="${this._selectedAreaChanged}"
> >
<paper-item> <paper-item>
${this.hass!.localize( ${this.hass!.localize("ui.dialogs.zha_device_info.no_area")}
"ui.panel.config.integrations.config_entry.no_area"
)}
</paper-item> </paper-item>
${this._areas.map( ${this._areas.map(
@ -247,7 +245,7 @@ class ZHADeviceCard extends LitElement {
? html` ? html`
<div class="help-text"> <div class="help-text">
${this.hass!.localize( ${this.hass!.localize(
"ui.panel.config.zha.services.reconfigure" "ui.dialogs.zha_device_info.services.reconfigure"
)} )}
</div> </div>
` `
@ -264,7 +262,7 @@ class ZHADeviceCard extends LitElement {
? html` ? html`
<div class="help-text"> <div class="help-text">
${this.hass!.localize( ${this.hass!.localize(
"ui.panel.config.zha.services.remove" "ui.dialogs.zha_device_info.services.remove"
)} )}
</div> </div>
` `
@ -381,6 +379,7 @@ class ZHADeviceCard extends LitElement {
} }
.device .manuf { .device .manuf {
color: var(--secondary-text-color); color: var(--secondary-text-color);
margin-bottom: 20px;
} }
.extra-info { .extra-info {
margin-top: 8px; margin-top: 8px;
@ -393,14 +392,17 @@ class ZHADeviceCard extends LitElement {
.info { .info {
margin-left: 16px; margin-left: 16px;
} }
dl {
display: grid;
grid-template-columns: 125px 1fr;
}
dl dt { dl dt {
padding-left: 12px; padding-left: 12px;
float: left; float: left;
width: 100px;
text-align: left; text-align: left;
} }
dt dd { dl dd {
text-align: left; max-width: 200px;
} }
paper-icon-item { paper-icon-item {
cursor: pointer; cursor: pointer;

View File

@ -105,13 +105,12 @@ export class ZHANode extends LitElement {
? html` ? html`
<zha-device-card <zha-device-card
class="card" class="card"
.hass="${this.hass}" .hass=${this.hass}
.device="${this._selectedDevice}" .device=${this._selectedDevice}
.narrow="${!this.isWide}" .narrow=${!this.isWide}
.showHelp="${this._showHelp}" .showHelp=${this._showHelp}
.showActions="${true}" showActions
@zha-device-removed="${this._onDeviceRemoved}" @zha-device-removed=${this._onDeviceRemoved}
.isJoinPage="${false}"
></zha-device-card> ></zha-device-card>
` `
: ""} : ""}

View File

@ -3,6 +3,7 @@ import AuthMixin from "./auth-mixin";
import TranslationsMixin from "./translations-mixin"; import TranslationsMixin from "./translations-mixin";
import ThemesMixin from "./themes-mixin"; import ThemesMixin from "./themes-mixin";
import MoreInfoMixin from "./more-info-mixin"; import MoreInfoMixin from "./more-info-mixin";
import ZHADialogMixin from "./zha-dialog-mixin";
import SidebarMixin from "./sidebar-mixin"; import SidebarMixin from "./sidebar-mixin";
import { dialogManagerMixin } from "./dialog-manager-mixin"; import { dialogManagerMixin } from "./dialog-manager-mixin";
import { connectionMixin } from "./connection-mixin"; import { connectionMixin } from "./connection-mixin";
@ -25,4 +26,5 @@ export class HassElement extends ext(HassBaseMixin(LitElement), [
NotificationMixin, NotificationMixin,
dialogManagerMixin, dialogManagerMixin,
urlSyncMixin, urlSyncMixin,
ZHADialogMixin,
]) {} ]) {}

View File

@ -0,0 +1,29 @@
import { Constructor, LitElement } from "lit-element";
import { HassBaseEl } from "./hass-base-mixin";
import {
showZHADeviceInfoDialog,
ZHADeviceInfoDialogParams,
} from "../dialogs/zha-device-info-dialog/show-dialog-zha-device-info";
import { HASSDomEvent } from "../common/dom/fire_event";
declare global {
// for fire event
interface HASSDomEvents {
"zha-show-device-dialog": {
ieee: string;
};
}
}
export default (superClass: Constructor<LitElement & HassBaseEl>) =>
class extends superClass {
protected firstUpdated(changedProps) {
super.firstUpdated(changedProps);
this.addEventListener("zha-show-device-dialog", (e) =>
showZHADeviceInfoDialog(
e.target as HTMLElement,
(e as HASSDomEvent<ZHADeviceInfoDialogParams>).detail
)
);
}
};

View File

@ -554,6 +554,20 @@
"title": "System Options", "title": "System Options",
"enable_new_entities_label": "Enable newly added entities.", "enable_new_entities_label": "Enable newly added entities.",
"enable_new_entities_description": "If disabled, newly discovered entities will not be automatically added to Home Assistant." "enable_new_entities_description": "If disabled, newly discovered entities will not be automatically added to Home Assistant."
},
"zha_device_info": {
"manuf": "by {manufacturer}",
"no_area": "No Area",
"services": {
"reconfigure": "Reconfigure ZHA device (heal device). Use this if you are having issues with the device. If the device in question is a battery powered device please ensure it is awake and accepting commands when you use this service.",
"updateDeviceName": "Set a custom name for this device in the device registry.",
"remove": "Remove a device from the ZigBee network."
},
"zha_device_card": {
"device_name_placeholder": "User given name",
"area_picker_label": "Area",
"update_name_button": "Update Name"
}
} }
}, },
"duration": { "duration": {
@ -942,16 +956,6 @@
"zha": { "zha": {
"caption": "ZHA", "caption": "ZHA",
"description": "Zigbee Home Automation network management", "description": "Zigbee Home Automation network management",
"services": {
"reconfigure": "Reconfigure ZHA device (heal device). Use this if you are having issues with the device. If the device in question is a battery powered device please ensure it is awake and accepting commands when you use this service.",
"updateDeviceName": "Set a custom name for this device in the device registry.",
"remove": "Remove a device from the ZigBee network."
},
"device_card": {
"device_name_placeholder": "User given name",
"area_picker_label": "Area",
"update_name_button": "Update Name"
},
"add_device_page": { "add_device_page": {
"header": "Zigbee Home Automation - Add Devices", "header": "Zigbee Home Automation - Add Devices",
"spinner": "Searching for ZHA Zigbee devices...", "spinner": "Searching for ZHA Zigbee devices...",