mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 01:06:35 +00:00
ZHA add devices page (#2969)
* zha add device page add device join dialog stub update dialog stub fix spinner add messages and devices to dialog dialog updates update dialog update dialog add debug info fix reference add header update dialog test zha gateway message subscription add device join dialog stub add messages and devices to dialog dialog updates update dialog add debug info update dialog start transitioning to a page instead of a dialog fix import subpage update router remove old dialog handle remove dialog parts make add button call navigate change extract page add devices page cleanup * update device join page * auto scroll log * update css and add device page layout * fix padding * fix missing imports * fix imports * add -> permit * left justify device cards to prevent jumping * conditionally display entity ids * cleanup * fix vertical alignment * review comments * fix manufacturer overrides
This commit is contained in:
parent
435b7d9cee
commit
669358bf1a
@ -16,6 +16,7 @@ export interface ZHADevice {
|
|||||||
manufacturer_code: number;
|
manufacturer_code: number;
|
||||||
device_reg_id: string;
|
device_reg_id: string;
|
||||||
user_given_name: string;
|
user_given_name: string;
|
||||||
|
area_id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Attribute {
|
export interface Attribute {
|
||||||
@ -42,7 +43,7 @@ export interface ReadAttributeServiceData {
|
|||||||
cluster_id: number;
|
cluster_id: number;
|
||||||
cluster_type: string;
|
cluster_type: string;
|
||||||
attribute: number;
|
attribute: number;
|
||||||
manufacturer: number;
|
manufacturer?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const reconfigureNode = (
|
export const reconfigureNode = (
|
||||||
|
@ -73,9 +73,9 @@ class HaPanelConfig extends HassRouterPage {
|
|||||||
import(/* webpackChunkName: "panel-config-users" */ "./users/ha-config-users"),
|
import(/* webpackChunkName: "panel-config-users" */ "./users/ha-config-users"),
|
||||||
},
|
},
|
||||||
zha: {
|
zha: {
|
||||||
tag: "ha-config-zha",
|
tag: "zha-config-panel",
|
||||||
load: () =>
|
load: () =>
|
||||||
import(/* webpackChunkName: "panel-config-zha" */ "./zha/ha-config-zha"),
|
import(/* webpackChunkName: "panel-config-zha" */ "./zha/zha-config-panel"),
|
||||||
},
|
},
|
||||||
zwave: {
|
zwave: {
|
||||||
tag: "ha-config-zwave",
|
tag: "ha-config-zwave",
|
||||||
|
@ -1,26 +1,26 @@
|
|||||||
import "@polymer/app-layout/app-header/app-header";
|
import "../../../components/ha-paper-icon-button-arrow-prev";
|
||||||
import "@polymer/app-layout/app-toolbar/app-toolbar";
|
import "../../../layouts/hass-subpage";
|
||||||
|
import "./zha-binding";
|
||||||
|
import "./zha-cluster-attributes";
|
||||||
|
import "./zha-cluster-commands";
|
||||||
|
import "./zha-network";
|
||||||
|
import "./zha-node";
|
||||||
|
import "@polymer/paper-icon-button/paper-icon-button";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
CSSResult,
|
||||||
html,
|
html,
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
CSSResult,
|
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import "@polymer/paper-icon-button/paper-icon-button";
|
|
||||||
import { HASSDomEvent } from "../../../common/dom/fire_event";
|
import { HASSDomEvent } from "../../../common/dom/fire_event";
|
||||||
import { Cluster, ZHADevice, fetchBindableDevices } from "../../../data/zha";
|
import { Cluster, fetchBindableDevices, ZHADevice } from "../../../data/zha";
|
||||||
import "../../../layouts/ha-app-layout";
|
|
||||||
import "../../../components/ha-paper-icon-button-arrow-prev";
|
|
||||||
import { haStyle } from "../../../resources/styles";
|
import { haStyle } from "../../../resources/styles";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import { ZHAClusterSelectedParams, ZHADeviceSelectedParams } from "./types";
|
import { ZHAClusterSelectedParams, ZHADeviceSelectedParams } from "./types";
|
||||||
import "./zha-cluster-attributes";
|
|
||||||
import "./zha-cluster-commands";
|
|
||||||
import "./zha-network";
|
|
||||||
import "./zha-node";
|
|
||||||
import "./zha-binding";
|
|
||||||
|
|
||||||
export class HaConfigZha extends LitElement {
|
export class HaConfigZha extends LitElement {
|
||||||
@property() public hass?: HomeAssistant;
|
@property() public hass?: HomeAssistant;
|
||||||
@ -38,16 +38,7 @@ export class HaConfigZha extends LitElement {
|
|||||||
|
|
||||||
protected render(): TemplateResult | void {
|
protected render(): TemplateResult | void {
|
||||||
return html`
|
return html`
|
||||||
<ha-app-layout>
|
<hass-subpage header="Zigbee Home Automation">
|
||||||
<app-header slot="header">
|
|
||||||
<app-toolbar>
|
|
||||||
<ha-paper-icon-button-arrow-prev
|
|
||||||
@click="${this._onBackTapped}"
|
|
||||||
></ha-paper-icon-button-arrow-prev>
|
|
||||||
<div main-title>Zigbee Home Automation</div>
|
|
||||||
</app-toolbar>
|
|
||||||
</app-header>
|
|
||||||
|
|
||||||
<zha-network
|
<zha-network
|
||||||
.isWide="${this.isWide}"
|
.isWide="${this.isWide}"
|
||||||
.hass="${this.hass}"
|
.hass="${this.hass}"
|
||||||
@ -86,7 +77,7 @@ export class HaConfigZha extends LitElement {
|
|||||||
></zha-binding-control>
|
></zha-binding-control>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
</ha-app-layout>
|
</hass-subpage>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,10 +108,6 @@ export class HaConfigZha extends LitElement {
|
|||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResult[] {
|
||||||
return [haStyle];
|
return [haStyle];
|
||||||
}
|
}
|
||||||
|
|
||||||
private _onBackTapped(): void {
|
|
||||||
history.back();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
@ -8,6 +8,12 @@ export interface ItemSelectedEvent {
|
|||||||
target?: PickerTarget;
|
target?: PickerTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ZHADeviceRemovedEvent {
|
||||||
|
detail?: {
|
||||||
|
device?: ZHADevice;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export interface ChangeEvent {
|
export interface ChangeEvent {
|
||||||
detail?: {
|
detail?: {
|
||||||
value?: any;
|
value?: any;
|
||||||
@ -22,7 +28,7 @@ export interface SetAttributeServiceData {
|
|||||||
cluster_type: string;
|
cluster_type: string;
|
||||||
attribute: number;
|
attribute: number;
|
||||||
value: any;
|
value: any;
|
||||||
manufacturer: number;
|
manufacturer?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IssueCommandServiceData {
|
export interface IssueCommandServiceData {
|
||||||
|
246
src/panels/config/zha/zha-add-devices-page.ts
Normal file
246
src/panels/config/zha/zha-add-devices-page.ts
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
import "../../../components/ha-service-description";
|
||||||
|
import "../../../components/ha-textarea";
|
||||||
|
import "../../../layouts/hass-subpage";
|
||||||
|
import "./zha-device-card";
|
||||||
|
import "@material/mwc-button";
|
||||||
|
import "@polymer/paper-icon-button/paper-icon-button";
|
||||||
|
import "@polymer/paper-spinner/paper-spinner";
|
||||||
|
|
||||||
|
import {
|
||||||
|
css,
|
||||||
|
CSSResult,
|
||||||
|
customElement,
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
|
property,
|
||||||
|
TemplateResult,
|
||||||
|
} from "lit-element";
|
||||||
|
|
||||||
|
import { ZHADevice } from "../../../data/zha";
|
||||||
|
import { haStyle } from "../../../resources/styles";
|
||||||
|
import { HomeAssistant } from "../../../types";
|
||||||
|
|
||||||
|
@customElement("zha-add-devices-page")
|
||||||
|
class ZHAAddDevicesPage extends LitElement {
|
||||||
|
@property() public hass!: HomeAssistant;
|
||||||
|
@property() public isWide?: boolean;
|
||||||
|
@property() private _error?: string;
|
||||||
|
@property() private _discoveredDevices: ZHADevice[] = [];
|
||||||
|
@property() private _formattedEvents: string = "";
|
||||||
|
@property() private _active: boolean = false;
|
||||||
|
@property() private _showHelp: boolean = false;
|
||||||
|
private _addDevicesTimeoutHandle: any = undefined;
|
||||||
|
private _subscribed?: Promise<() => Promise<void>>;
|
||||||
|
|
||||||
|
public connectedCallback(): void {
|
||||||
|
super.connectedCallback();
|
||||||
|
this._subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
public disconnectedCallback(): void {
|
||||||
|
super.disconnectedCallback();
|
||||||
|
this._unsubscribe();
|
||||||
|
this._error = undefined;
|
||||||
|
this._discoveredDevices = [];
|
||||||
|
this._formattedEvents = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render(): TemplateResult | void {
|
||||||
|
return html`
|
||||||
|
<hass-subpage
|
||||||
|
header="${this.hass!.localize(
|
||||||
|
"ui.panel.config.zha.add_device_page.header"
|
||||||
|
)}"
|
||||||
|
>
|
||||||
|
${this._active
|
||||||
|
? html`
|
||||||
|
<h2>
|
||||||
|
<paper-spinner
|
||||||
|
?active="${this._active}"
|
||||||
|
alt="Searching"
|
||||||
|
></paper-spinner>
|
||||||
|
${this.hass!.localize(
|
||||||
|
"ui.panel.config.zha.add_device_page.spinner"
|
||||||
|
)}
|
||||||
|
</h2>
|
||||||
|
`
|
||||||
|
: html`
|
||||||
|
<div class="card-actions">
|
||||||
|
<mwc-button @click=${this._subscribe} class="search-button">
|
||||||
|
Search again
|
||||||
|
</mwc-button>
|
||||||
|
<paper-icon-button
|
||||||
|
class="toggle-help-icon"
|
||||||
|
@click="${this._onHelpTap}"
|
||||||
|
icon="hass:help-circle"
|
||||||
|
></paper-icon-button>
|
||||||
|
${this._showHelp
|
||||||
|
? html`
|
||||||
|
<ha-service-description
|
||||||
|
.hass="${this.hass}"
|
||||||
|
domain="zha"
|
||||||
|
service="permit"
|
||||||
|
class="help-text"
|
||||||
|
/>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
</div>
|
||||||
|
`}
|
||||||
|
${this._error
|
||||||
|
? html`
|
||||||
|
<div class="error">${this._error}</div>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
<div class="content-header"></div>
|
||||||
|
<div class="content">
|
||||||
|
${this._discoveredDevices.length < 1
|
||||||
|
? html`
|
||||||
|
<div class="discovery-text">
|
||||||
|
<h4>
|
||||||
|
${this.hass!.localize(
|
||||||
|
"ui.panel.config.zha.add_device_page.discovery_text"
|
||||||
|
)}
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: html`
|
||||||
|
${this._discoveredDevices.map(
|
||||||
|
(device) => html`
|
||||||
|
<zha-device-card
|
||||||
|
class="card"
|
||||||
|
.hass="${this.hass}"
|
||||||
|
.device="${device}"
|
||||||
|
.narrow="${!this.isWide}"
|
||||||
|
.showHelp="${this._showHelp}"
|
||||||
|
.showActions="${!this._active}"
|
||||||
|
.isJoinPage="${true}"
|
||||||
|
></zha-device-card>
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
`}
|
||||||
|
</div>
|
||||||
|
<ha-textarea class="events" value="${this._formattedEvents}">
|
||||||
|
</ha-textarea>
|
||||||
|
</hass-subpage>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleMessage(message: any): void {
|
||||||
|
if (message.type === "log_output") {
|
||||||
|
this._formattedEvents += message.log_entry.message + "\n";
|
||||||
|
if (this.shadowRoot) {
|
||||||
|
const textArea = this.shadowRoot.querySelector("ha-textarea");
|
||||||
|
if (textArea) {
|
||||||
|
textArea.scrollTop = textArea.scrollHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (message.type && message.type === "device_fully_initialized") {
|
||||||
|
this._discoveredDevices.push(message.device_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _unsubscribe(): void {
|
||||||
|
this._active = false;
|
||||||
|
if (this._addDevicesTimeoutHandle) {
|
||||||
|
clearTimeout(this._addDevicesTimeoutHandle);
|
||||||
|
}
|
||||||
|
if (this._subscribed) {
|
||||||
|
this._subscribed.then((unsub) => unsub());
|
||||||
|
this._subscribed = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _subscribe(): void {
|
||||||
|
this._subscribed = this.hass!.connection.subscribeMessage(
|
||||||
|
(message) => this._handleMessage(message),
|
||||||
|
{ type: "zha/devices/permit" }
|
||||||
|
);
|
||||||
|
this._active = true;
|
||||||
|
this._addDevicesTimeoutHandle = setTimeout(
|
||||||
|
() => this._unsubscribe(),
|
||||||
|
60000
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _onHelpTap(): void {
|
||||||
|
this._showHelp = !this._showHelp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResult[] {
|
||||||
|
return [
|
||||||
|
haStyle,
|
||||||
|
css`
|
||||||
|
.discovery-text,
|
||||||
|
.content-header {
|
||||||
|
margin: 16px;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
border-top: 1px solid var(--light-primary-color);
|
||||||
|
min-height: 500px;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
padding: 4px;
|
||||||
|
justify-content: left;
|
||||||
|
overflow: scroll;
|
||||||
|
}
|
||||||
|
.error {
|
||||||
|
color: var(--google-red-500);
|
||||||
|
}
|
||||||
|
paper-spinner {
|
||||||
|
display: none;
|
||||||
|
margin-right: 20px;
|
||||||
|
margin-left: 16px;
|
||||||
|
}
|
||||||
|
paper-spinner[active] {
|
||||||
|
display: block;
|
||||||
|
float: left;
|
||||||
|
margin-right: 20px;
|
||||||
|
margin-left: 16px;
|
||||||
|
}
|
||||||
|
.card {
|
||||||
|
margin-left: 16px;
|
||||||
|
margin-right: 16px;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.events {
|
||||||
|
margin: 16px;
|
||||||
|
border-top: 1px solid var(--light-primary-color);
|
||||||
|
padding-top: 16px;
|
||||||
|
min-height: 200px;
|
||||||
|
max-height: 200px;
|
||||||
|
overflow: scroll;
|
||||||
|
}
|
||||||
|
.toggle-help-icon {
|
||||||
|
position: absolute;
|
||||||
|
margin-top: 16px;
|
||||||
|
margin-right: 16px;
|
||||||
|
top: -6px;
|
||||||
|
right: 0;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
ha-service-description {
|
||||||
|
margin-top: 16px;
|
||||||
|
margin-left: 16px;
|
||||||
|
display: block;
|
||||||
|
color: grey;
|
||||||
|
}
|
||||||
|
.search-button {
|
||||||
|
margin-top: 16px;
|
||||||
|
margin-left: 16px;
|
||||||
|
}
|
||||||
|
.help-text {
|
||||||
|
color: grey;
|
||||||
|
padding-left: 16px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"zha-add-devices-page": ZHAAddDevicesPage;
|
||||||
|
}
|
||||||
|
}
|
@ -1,20 +1,26 @@
|
|||||||
|
import "../../../components/buttons/ha-call-service-button";
|
||||||
|
import "../../../components/ha-service-description";
|
||||||
|
import "../ha-config-section";
|
||||||
|
import "@material/mwc-button/mwc-button";
|
||||||
|
import "@polymer/paper-card/paper-card";
|
||||||
|
import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
|
||||||
|
import "@polymer/paper-icon-button/paper-icon-button";
|
||||||
|
import "@polymer/paper-listbox/paper-listbox";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
css,
|
||||||
|
CSSResult,
|
||||||
|
customElement,
|
||||||
html,
|
html,
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
CSSResult,
|
|
||||||
css,
|
|
||||||
customElement,
|
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import "@polymer/paper-card/paper-card";
|
|
||||||
import "../../../components/buttons/ha-call-service-button";
|
import { bindDevices, unbindDevices, ZHADevice } from "../../../data/zha";
|
||||||
import "../../../components/ha-service-description";
|
|
||||||
import { ZHADevice, bindDevices, unbindDevices } from "../../../data/zha";
|
|
||||||
import { haStyle } from "../../../resources/styles";
|
import { haStyle } from "../../../resources/styles";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import "../ha-config-section";
|
|
||||||
import { ItemSelectedEvent } from "./types";
|
import { ItemSelectedEvent } from "./types";
|
||||||
|
|
||||||
@customElement("zha-binding-control")
|
@customElement("zha-binding-control")
|
||||||
|
@ -1,17 +1,24 @@
|
|||||||
|
import "../../../components/buttons/ha-call-service-button";
|
||||||
|
import "../../../components/ha-service-description";
|
||||||
|
import "../ha-config-section";
|
||||||
|
import "@material/mwc-button";
|
||||||
|
import "@polymer/paper-card/paper-card";
|
||||||
|
import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
|
||||||
|
import "@polymer/paper-icon-button/paper-icon-button";
|
||||||
|
import "@polymer/paper-input/paper-input";
|
||||||
|
import "@polymer/paper-item/paper-item";
|
||||||
|
import "@polymer/paper-listbox/paper-listbox";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
css,
|
||||||
|
CSSResult,
|
||||||
html,
|
html,
|
||||||
LitElement,
|
LitElement,
|
||||||
PropertyDeclarations,
|
PropertyDeclarations,
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
CSSResult,
|
|
||||||
css,
|
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import "@material/mwc-button";
|
|
||||||
import "@polymer/paper-card/paper-card";
|
|
||||||
import "@polymer/paper-icon-button/paper-icon-button";
|
|
||||||
import "../../../components/buttons/ha-call-service-button";
|
|
||||||
import "../../../components/ha-service-description";
|
|
||||||
import {
|
import {
|
||||||
Attribute,
|
Attribute,
|
||||||
Cluster,
|
Cluster,
|
||||||
@ -22,13 +29,12 @@ import {
|
|||||||
} from "../../../data/zha";
|
} from "../../../data/zha";
|
||||||
import { haStyle } from "../../../resources/styles";
|
import { haStyle } from "../../../resources/styles";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import "../ha-config-section";
|
import { formatAsPaddedHex } from "./functions";
|
||||||
import {
|
import {
|
||||||
ChangeEvent,
|
ChangeEvent,
|
||||||
ItemSelectedEvent,
|
ItemSelectedEvent,
|
||||||
SetAttributeServiceData,
|
SetAttributeServiceData,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
import { formatAsPaddedHex } from "./functions";
|
|
||||||
|
|
||||||
export class ZHAClusterAttributes extends LitElement {
|
export class ZHAClusterAttributes extends LitElement {
|
||||||
public hass?: HomeAssistant;
|
public hass?: HomeAssistant;
|
||||||
@ -115,7 +121,7 @@ export class ZHAClusterAttributes extends LitElement {
|
|||||||
</div>
|
</div>
|
||||||
${this.showHelp
|
${this.showHelp
|
||||||
? html`
|
? html`
|
||||||
<div style="color: grey; padding: 16px">
|
<div class="help-text">
|
||||||
Select an attribute to view or set its value
|
Select an attribute to view or set its value
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
@ -152,6 +158,13 @@ export class ZHAClusterAttributes extends LitElement {
|
|||||||
<mwc-button @click="${this._onGetZigbeeAttributeClick}"
|
<mwc-button @click="${this._onGetZigbeeAttributeClick}"
|
||||||
>Get Zigbee Attribute</mwc-button
|
>Get Zigbee Attribute</mwc-button
|
||||||
>
|
>
|
||||||
|
${this.showHelp
|
||||||
|
? html`
|
||||||
|
<div class="help-text2">
|
||||||
|
Get the value for the selected attribute
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
<ha-call-service-button
|
<ha-call-service-button
|
||||||
.hass="${this.hass}"
|
.hass="${this.hass}"
|
||||||
domain="zha"
|
domain="zha"
|
||||||
@ -165,6 +178,7 @@ export class ZHAClusterAttributes extends LitElement {
|
|||||||
.hass="${this.hass}"
|
.hass="${this.hass}"
|
||||||
domain="zha"
|
domain="zha"
|
||||||
service="set_zigbee_cluster_attribute"
|
service="set_zigbee_cluster_attribute"
|
||||||
|
class="help-text2"
|
||||||
></ha-service-description>
|
></ha-service-description>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
@ -201,7 +215,7 @@ export class ZHAClusterAttributes extends LitElement {
|
|||||||
attribute: this._attributes[this._selectedAttributeIndex].id,
|
attribute: this._attributes[this._selectedAttributeIndex].id,
|
||||||
manufacturer: this._manufacturerCodeOverride
|
manufacturer: this._manufacturerCodeOverride
|
||||||
? parseInt(this._manufacturerCodeOverride as string, 10)
|
? parseInt(this._manufacturerCodeOverride as string, 10)
|
||||||
: this.selectedNode!.manufacturer_code,
|
: undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,7 +234,7 @@ export class ZHAClusterAttributes extends LitElement {
|
|||||||
value: this._attributeValue,
|
value: this._attributeValue,
|
||||||
manufacturer: this._manufacturerCodeOverride
|
manufacturer: this._manufacturerCodeOverride
|
||||||
? parseInt(this._manufacturerCodeOverride as string, 10)
|
? parseInt(this._manufacturerCodeOverride as string, 10)
|
||||||
: this.selectedNode!.manufacturer_code,
|
: undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,6 +326,16 @@ export class ZHAClusterAttributes extends LitElement {
|
|||||||
[hidden] {
|
[hidden] {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
.help-text {
|
||||||
|
color: grey;
|
||||||
|
padding-left: 28px;
|
||||||
|
padding-right: 28px;
|
||||||
|
padding-bottom: 16px;
|
||||||
|
}
|
||||||
|
.help-text2 {
|
||||||
|
color: grey;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,23 @@
|
|||||||
|
import "../../../components/buttons/ha-call-service-button";
|
||||||
|
import "../../../components/ha-service-description";
|
||||||
|
import "../ha-config-section";
|
||||||
|
import "@polymer/paper-card/paper-card";
|
||||||
|
import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
|
||||||
|
import "@polymer/paper-icon-button/paper-icon-button";
|
||||||
|
import "@polymer/paper-input/paper-input";
|
||||||
|
import "@polymer/paper-item/paper-item";
|
||||||
|
import "@polymer/paper-listbox/paper-listbox";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
css,
|
||||||
|
CSSResult,
|
||||||
html,
|
html,
|
||||||
LitElement,
|
LitElement,
|
||||||
PropertyDeclarations,
|
PropertyDeclarations,
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
CSSResult,
|
|
||||||
css,
|
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import "@polymer/paper-card/paper-card";
|
|
||||||
import "../../../components/buttons/ha-call-service-button";
|
|
||||||
import "../../../components/ha-service-description";
|
|
||||||
import {
|
import {
|
||||||
Cluster,
|
Cluster,
|
||||||
Command,
|
Command,
|
||||||
@ -18,13 +26,12 @@ import {
|
|||||||
} from "../../../data/zha";
|
} from "../../../data/zha";
|
||||||
import { haStyle } from "../../../resources/styles";
|
import { haStyle } from "../../../resources/styles";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import "../ha-config-section";
|
import { formatAsPaddedHex } from "./functions";
|
||||||
import {
|
import {
|
||||||
ChangeEvent,
|
ChangeEvent,
|
||||||
IssueCommandServiceData,
|
IssueCommandServiceData,
|
||||||
ItemSelectedEvent,
|
ItemSelectedEvent,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
import { formatAsPaddedHex } from "./functions";
|
|
||||||
|
|
||||||
export class ZHAClusterCommands extends LitElement {
|
export class ZHAClusterCommands extends LitElement {
|
||||||
public hass?: HomeAssistant;
|
public hass?: HomeAssistant;
|
||||||
@ -107,7 +114,7 @@ export class ZHAClusterCommands extends LitElement {
|
|||||||
</div>
|
</div>
|
||||||
${this._showHelp
|
${this._showHelp
|
||||||
? html`
|
? html`
|
||||||
<div class="helpText">Select a command to interact with</div>
|
<div class="help-text">Select a command to interact with</div>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
${this._selectedCommandIndex !== -1
|
${this._selectedCommandIndex !== -1
|
||||||
@ -135,6 +142,7 @@ export class ZHAClusterCommands extends LitElement {
|
|||||||
.hass="${this.hass}"
|
.hass="${this.hass}"
|
||||||
domain="zha"
|
domain="zha"
|
||||||
service="issue_zigbee_cluster_command"
|
service="issue_zigbee_cluster_command"
|
||||||
|
class="help-text2"
|
||||||
></ha-service-description>
|
></ha-service-description>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
@ -242,7 +250,14 @@ export class ZHAClusterCommands extends LitElement {
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.helpText {
|
.help-text {
|
||||||
|
color: grey;
|
||||||
|
padding-left: 28px;
|
||||||
|
padding-right: 28px;
|
||||||
|
padding-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.help-text2 {
|
||||||
color: grey;
|
color: grey;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,27 @@
|
|||||||
|
import "../../../components/buttons/ha-call-service-button";
|
||||||
|
import "../../../components/ha-service-description";
|
||||||
|
import "../ha-config-section";
|
||||||
|
import "@polymer/paper-card/paper-card";
|
||||||
|
import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
|
||||||
|
import "@polymer/paper-item/paper-item";
|
||||||
|
import "@polymer/paper-listbox/paper-listbox";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
css,
|
||||||
|
CSSResult,
|
||||||
html,
|
html,
|
||||||
LitElement,
|
LitElement,
|
||||||
PropertyDeclarations,
|
PropertyDeclarations,
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
CSSResult,
|
|
||||||
css,
|
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import "@polymer/paper-card/paper-card";
|
|
||||||
import { fireEvent } from "../../../common/dom/fire_event";
|
import { fireEvent } from "../../../common/dom/fire_event";
|
||||||
import "../../../components/buttons/ha-call-service-button";
|
|
||||||
import "../../../components/ha-service-description";
|
|
||||||
import { Cluster, fetchClustersForZhaNode, ZHADevice } from "../../../data/zha";
|
import { Cluster, fetchClustersForZhaNode, ZHADevice } from "../../../data/zha";
|
||||||
import { haStyle } from "../../../resources/styles";
|
import { haStyle } from "../../../resources/styles";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import "../ha-config-section";
|
|
||||||
import { ItemSelectedEvent } from "./types";
|
|
||||||
import { formatAsPaddedHex } from "./functions";
|
import { formatAsPaddedHex } from "./functions";
|
||||||
|
import { ItemSelectedEvent } from "./types";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
// for fire event
|
// for fire event
|
||||||
@ -90,7 +95,7 @@ export class ZHAClusters extends LitElement {
|
|||||||
</div>
|
</div>
|
||||||
${this.showHelp
|
${this.showHelp
|
||||||
? html`
|
? html`
|
||||||
<div class="helpText">
|
<div class="help-text">
|
||||||
Select cluster to view attributes and commands
|
Select cluster to view attributes and commands
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
@ -143,9 +148,11 @@ export class ZHAClusters extends LitElement {
|
|||||||
padding-right: 28px;
|
padding-right: 28px;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
}
|
}
|
||||||
.helpText {
|
.help-text {
|
||||||
color: grey;
|
color: grey;
|
||||||
padding: 16px;
|
padding-left: 28px;
|
||||||
|
padding-right: 28px;
|
||||||
|
padding-bottom: 16px;
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
|
70
src/panels/config/zha/zha-config-panel.ts
Normal file
70
src/panels/config/zha/zha-config-panel.ts
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import "../../../layouts/hass-loading-screen";
|
||||||
|
|
||||||
|
import { customElement, property } from "lit-element";
|
||||||
|
|
||||||
|
import { listenMediaQuery } from "../../../common/dom/media_query";
|
||||||
|
import {
|
||||||
|
HassRouterPage,
|
||||||
|
RouterOptions,
|
||||||
|
} from "../../../layouts/hass-router-page";
|
||||||
|
import { HomeAssistant } from "../../../types";
|
||||||
|
|
||||||
|
@customElement("zha-config-panel")
|
||||||
|
class ZHAConfigPanel extends HassRouterPage {
|
||||||
|
@property() public hass!: HomeAssistant;
|
||||||
|
@property() public _wideSidebar: boolean = false;
|
||||||
|
@property() public _wide: boolean = false;
|
||||||
|
|
||||||
|
protected routerOptions: RouterOptions = {
|
||||||
|
defaultPage: "configuration",
|
||||||
|
cacheAll: true,
|
||||||
|
preloadAll: true,
|
||||||
|
routes: {
|
||||||
|
configuration: {
|
||||||
|
tag: "ha-config-zha",
|
||||||
|
load: () =>
|
||||||
|
import(/* webpackChunkName: "zha-configuration-page" */ "./ha-config-zha"),
|
||||||
|
},
|
||||||
|
add: {
|
||||||
|
tag: "zha-add-devices-page",
|
||||||
|
load: () =>
|
||||||
|
import(/* webpackChunkName: "zha-add-devices-page" */ "./zha-add-devices-page"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
private _listeners: Array<() => void> = [];
|
||||||
|
|
||||||
|
public connectedCallback(): void {
|
||||||
|
super.connectedCallback();
|
||||||
|
this._listeners.push(
|
||||||
|
listenMediaQuery("(min-width: 1040px)", (matches) => {
|
||||||
|
this._wide = matches;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
this._listeners.push(
|
||||||
|
listenMediaQuery("(min-width: 1296px)", (matches) => {
|
||||||
|
this._wideSidebar = matches;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public disconnectedCallback(): void {
|
||||||
|
super.disconnectedCallback();
|
||||||
|
while (this._listeners.length) {
|
||||||
|
this._listeners.pop()!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected updatePageEl(el): void {
|
||||||
|
el.route = this.routeTail;
|
||||||
|
el.hass = this.hass;
|
||||||
|
el.isWide = this.hass.dockedSidebar ? this._wideSidebar : this._wide;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"zha-config-panel": ZHAConfigPanel;
|
||||||
|
}
|
||||||
|
}
|
@ -1,40 +1,123 @@
|
|||||||
|
import "../../../components/buttons/ha-call-service-button";
|
||||||
|
import "../../../components/entity/state-badge";
|
||||||
|
import "@material/mwc-button";
|
||||||
|
import "@polymer/paper-card/paper-card";
|
||||||
|
import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
|
||||||
|
import "@polymer/paper-input/paper-input";
|
||||||
|
import "@polymer/paper-item/paper-icon-item";
|
||||||
|
import "@polymer/paper-item/paper-item";
|
||||||
|
import "@polymer/paper-item/paper-item-body";
|
||||||
|
import "@polymer/paper-listbox/paper-listbox";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
css,
|
||||||
|
CSSResult,
|
||||||
|
customElement,
|
||||||
html,
|
html,
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
|
PropertyValues,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
CSSResult,
|
|
||||||
css,
|
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import "@polymer/paper-item/paper-icon-item";
|
|
||||||
import "@polymer/paper-item/paper-item-body";
|
|
||||||
import "@polymer/paper-card/paper-card";
|
|
||||||
import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
|
|
||||||
import "@polymer/paper-item/paper-item";
|
|
||||||
import "@polymer/paper-listbox/paper-listbox";
|
|
||||||
import { fireEvent } from "../../../common/dom/fire_event";
|
import { fireEvent } from "../../../common/dom/fire_event";
|
||||||
|
import compare from "../../../common/string/compare";
|
||||||
|
import {
|
||||||
|
AreaRegistryEntry,
|
||||||
|
fetchAreaRegistry,
|
||||||
|
} from "../../../data/area_registry";
|
||||||
|
import {
|
||||||
|
DeviceRegistryEntryMutableParams,
|
||||||
|
updateDeviceRegistryEntry,
|
||||||
|
} from "../../../data/device_registry";
|
||||||
|
import { reconfigureNode, ZHADevice } from "../../../data/zha";
|
||||||
import { haStyle } from "../../../resources/styles";
|
import { haStyle } from "../../../resources/styles";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
|
import { ItemSelectedEvent, NodeServiceData } from "./types";
|
||||||
|
|
||||||
import "../../../components/entity/state-badge";
|
declare global {
|
||||||
import { ZHADevice } from "../../../data/zha";
|
// for fire event
|
||||||
|
interface HASSDomEvents {
|
||||||
|
"zha-device-removed": {
|
||||||
|
device?: ZHADevice;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 narrow?: boolean;
|
||||||
@property() public device?: ZHADevice;
|
@property() public device?: ZHADevice;
|
||||||
|
@property() public showHelp: boolean = false;
|
||||||
|
@property() public showActions?: boolean;
|
||||||
|
@property() public isJoinPage?: boolean;
|
||||||
|
@property() private _serviceData?: NodeServiceData;
|
||||||
|
@property() private _areas: AreaRegistryEntry[] = [];
|
||||||
|
@property() private _selectedAreaIndex: number = -1;
|
||||||
|
|
||||||
|
public firstUpdated(changedProperties: PropertyValues): void {
|
||||||
|
super.firstUpdated(changedProperties);
|
||||||
|
this.addEventListener("hass-service-called", (ev) =>
|
||||||
|
this.serviceCalled(ev)
|
||||||
|
);
|
||||||
|
this._serviceData = {
|
||||||
|
ieee_address: this.device!.ieee,
|
||||||
|
};
|
||||||
|
fetchAreaRegistry(this.hass!).then((areas) => {
|
||||||
|
this._areas = areas.sort((a, b) => compare(a.name, b.name));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected updated(changedProperties: PropertyValues): void {
|
||||||
|
if (changedProperties.has("device")) {
|
||||||
|
this._selectedAreaIndex =
|
||||||
|
this._areas.findIndex((area) => area.area_id === this.device!.area_id) +
|
||||||
|
1;
|
||||||
|
}
|
||||||
|
super.update(changedProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected serviceCalled(ev): void {
|
||||||
|
// Check if this is for us
|
||||||
|
if (ev.detail.success && ev.detail.service === "remove") {
|
||||||
|
fireEvent(this, "zha-device-removed", {
|
||||||
|
device: this.device,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected render(): TemplateResult | void {
|
protected render(): TemplateResult | void {
|
||||||
return html`
|
return html`
|
||||||
<paper-card>
|
<paper-card heading="${this.isJoinPage ? this.device!.name : ""}">
|
||||||
|
${
|
||||||
|
this.isJoinPage
|
||||||
|
? html`
|
||||||
|
<div class="info">
|
||||||
|
<div class="model">${this.device!.model}</div>
|
||||||
|
<div class="manuf">
|
||||||
|
${this.hass!.localize(
|
||||||
|
"ui.panel.config.integrations.config_entry.manuf",
|
||||||
|
"manufacturer",
|
||||||
|
this.device!.manufacturer
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: ""
|
||||||
|
}
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<dl>
|
<dl>
|
||||||
<dt class="label">IEEE:</dt>
|
<dt>IEEE:</dt>
|
||||||
<dd class="info">${this.device!.ieee}</dd>
|
<dd class="zha-info">${this.device!.ieee}</dd>
|
||||||
<dt class="label">Quirk applied:</dt>
|
${
|
||||||
<dd class="info">${this.device!.quirk_applied}</dd>
|
this.device!.quirk_applied
|
||||||
<dt class="label">Quirk:</dt>
|
? html`
|
||||||
<dd class="info">${this.device!.quirk_class}</dd>
|
<dt>Quirk:</dt>
|
||||||
|
<dd class="zha-info">${this.device!.quirk_class}</dd>
|
||||||
|
`
|
||||||
|
: ""
|
||||||
|
}
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -49,24 +132,145 @@ class ZHADeviceCard extends LitElement {
|
|||||||
.stateObj="${this.hass!.states[entity.entity_id]}"
|
.stateObj="${this.hass!.states[entity.entity_id]}"
|
||||||
slot="item-icon"
|
slot="item-icon"
|
||||||
></state-badge>
|
></state-badge>
|
||||||
<paper-item-body>
|
${!this.isJoinPage
|
||||||
<div class="name">${entity.name}</div>
|
? html`
|
||||||
<div class="secondary entity-id">${entity.entity_id}</div>
|
<paper-item-body>
|
||||||
</paper-item-body>
|
<div class="name">${entity.name}</div>
|
||||||
|
<div class="secondary entity-id">
|
||||||
|
${entity.entity_id}
|
||||||
|
</div>
|
||||||
|
</paper-item-body>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
</paper-icon-item>
|
</paper-icon-item>
|
||||||
`
|
`
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="editable">
|
||||||
|
<paper-input
|
||||||
|
type="string"
|
||||||
|
@change="${this._saveCustomName}"
|
||||||
|
placeholder="${this.hass!.localize(
|
||||||
|
"ui.panel.config.zha.device_card.device_name_placeholder"
|
||||||
|
)}"
|
||||||
|
></paper-input>
|
||||||
|
</div>
|
||||||
|
<div class="node-picker">
|
||||||
|
<paper-dropdown-menu
|
||||||
|
label="${this.hass!.localize(
|
||||||
|
"ui.panel.config.zha.device_card.area_picker_label"
|
||||||
|
)}"
|
||||||
|
class="flex"
|
||||||
|
>
|
||||||
|
<paper-listbox
|
||||||
|
slot="dropdown-content"
|
||||||
|
.selected="${this._selectedAreaIndex}"
|
||||||
|
@iron-select="${this._selectedAreaChanged}"
|
||||||
|
>
|
||||||
|
<paper-item>
|
||||||
|
${this.hass!.localize(
|
||||||
|
"ui.panel.config.integrations.config_entry.no_area"
|
||||||
|
)}
|
||||||
|
</paper-item>
|
||||||
|
|
||||||
|
${this._areas.map(
|
||||||
|
(entry) => html`
|
||||||
|
<paper-item area="${entry}">${entry.name}</paper-item>
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
</paper-listbox>
|
||||||
|
</paper-dropdown-menu>
|
||||||
|
</div>
|
||||||
|
${
|
||||||
|
this.showActions
|
||||||
|
? html`
|
||||||
|
<div class="card-actions">
|
||||||
|
<mwc-button @click="${this._onReconfigureNodeClick}"
|
||||||
|
>Reconfigure Device</mwc-button
|
||||||
|
>
|
||||||
|
${this.showHelp
|
||||||
|
? html`
|
||||||
|
<div class="help-text">
|
||||||
|
${this.hass!.localize(
|
||||||
|
"ui.panel.config.zha.services.reconfigure"
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
|
||||||
|
<ha-call-service-button
|
||||||
|
.hass="${this.hass}"
|
||||||
|
domain="zha"
|
||||||
|
service="remove"
|
||||||
|
.serviceData="${this._serviceData}"
|
||||||
|
>Remove Device</ha-call-service-button
|
||||||
|
>
|
||||||
|
${this.showHelp
|
||||||
|
? html`
|
||||||
|
<div class="help-text">
|
||||||
|
${this.hass!.localize(
|
||||||
|
"ui.panel.config.zha.services.remove"
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
</div>
|
||||||
</paper-card>
|
</paper-card>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _onReconfigureNodeClick(): Promise<void> {
|
||||||
|
if (this.hass) {
|
||||||
|
await reconfigureNode(this.hass, this.device!.ieee);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _saveCustomName(event): Promise<void> {
|
||||||
|
if (this.hass) {
|
||||||
|
const values: DeviceRegistryEntryMutableParams = {
|
||||||
|
name_by_user: event.target.value,
|
||||||
|
area_id: this.device!.area_id ? this.device!.area_id : undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
await updateDeviceRegistryEntry(
|
||||||
|
this.hass,
|
||||||
|
this.device!.device_reg_id,
|
||||||
|
values
|
||||||
|
);
|
||||||
|
|
||||||
|
this.device!.user_given_name = event.target.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private _openMoreInfo(ev: MouseEvent): void {
|
private _openMoreInfo(ev: MouseEvent): void {
|
||||||
fireEvent(this, "hass-more-info", {
|
fireEvent(this, "hass-more-info", {
|
||||||
entityId: (ev.currentTarget as any).entity.entity_id,
|
entityId: (ev.currentTarget as any).entity.entity_id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _selectedAreaChanged(event: ItemSelectedEvent) {
|
||||||
|
if (!this.device || !this._areas) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._selectedAreaIndex = event!.target!.selected;
|
||||||
|
const area = this._areas[this._selectedAreaIndex - 1]; // account for No Area
|
||||||
|
if (
|
||||||
|
(!area && !this.device.area_id) ||
|
||||||
|
(area && area.area_id === this.device.area_id)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await updateDeviceRegistryEntry(this.hass!, this.device.device_reg_id, {
|
||||||
|
area_id: area ? area.area_id : undefined,
|
||||||
|
name_by_user: this.device!.user_given_name,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResult[] {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
@ -74,29 +278,43 @@ class ZHADeviceCard extends LitElement {
|
|||||||
:host(:not([narrow])) .device-entities {
|
:host(:not([narrow])) .device-entities {
|
||||||
max-height: 225px;
|
max-height: 225px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
padding: 4px;
|
||||||
|
justify-content: left;
|
||||||
}
|
}
|
||||||
paper-card {
|
paper-card {
|
||||||
flex: 1 0 100%;
|
flex: 1 0 100%;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
min-width: 0;
|
min-width: 425px;
|
||||||
}
|
}
|
||||||
.device {
|
.device {
|
||||||
width: 30%;
|
width: 30%;
|
||||||
}
|
}
|
||||||
.label {
|
.device .name {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
.device .manuf {
|
||||||
|
color: var(--secondary-text-color);
|
||||||
|
}
|
||||||
|
.extra-info {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
.manuf,
|
||||||
|
.zha-info,
|
||||||
|
.entity-id {
|
||||||
|
color: var(--secondary-text-color);
|
||||||
|
}
|
||||||
.info {
|
.info {
|
||||||
color: var(--secondary-text-color);
|
margin-left: 16px;
|
||||||
font-weight: bold;
|
|
||||||
}
|
}
|
||||||
dl dt {
|
dl dt {
|
||||||
|
padding-left: 12px;
|
||||||
float: left;
|
float: left;
|
||||||
width: 100px;
|
width: 50px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
dt dd {
|
dt dd {
|
||||||
margin-left: 10px;
|
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
paper-icon-item {
|
paper-icon-item {
|
||||||
@ -104,6 +322,36 @@ class ZHADeviceCard extends LitElement {
|
|||||||
padding-top: 4px;
|
padding-top: 4px;
|
||||||
padding-bottom: 4px;
|
padding-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
.editable {
|
||||||
|
padding-left: 28px;
|
||||||
|
padding-right: 28px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
.help-text {
|
||||||
|
color: grey;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
.flex {
|
||||||
|
-ms-flex: 1 1 0.000000001px;
|
||||||
|
-webkit-flex: 1;
|
||||||
|
flex: 1;
|
||||||
|
-webkit-flex-basis: 0.000000001px;
|
||||||
|
flex-basis: 0.000000001px;
|
||||||
|
}
|
||||||
|
.node-picker {
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: -webkit-flex;
|
||||||
|
display: flex;
|
||||||
|
-ms-flex-direction: row;
|
||||||
|
-webkit-flex-direction: row;
|
||||||
|
flex-direction: row;
|
||||||
|
-ms-flex-align: center;
|
||||||
|
-webkit-align-items: center;
|
||||||
|
align-items: center;
|
||||||
|
padding-left: 28px;
|
||||||
|
padding-right: 28px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -114,5 +362,3 @@ declare global {
|
|||||||
"zha-device-card": ZHADeviceCard;
|
"zha-device-card": ZHADeviceCard;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("zha-device-card", ZHADeviceCard);
|
|
||||||
|
@ -1,19 +1,22 @@
|
|||||||
|
import "../../../components/buttons/ha-call-service-button";
|
||||||
|
import "../../../components/ha-service-description";
|
||||||
|
import "../ha-config-section";
|
||||||
|
import "@material/mwc-button";
|
||||||
|
import "@polymer/paper-card/paper-card";
|
||||||
|
import "@polymer/paper-icon-button/paper-icon-button";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
css,
|
||||||
|
CSSResult,
|
||||||
html,
|
html,
|
||||||
LitElement,
|
LitElement,
|
||||||
PropertyDeclarations,
|
PropertyDeclarations,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
CSSResult,
|
|
||||||
css,
|
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import "@material/mwc-button";
|
|
||||||
import "@polymer/paper-card/paper-card";
|
import { navigate } from "../../../common/navigate";
|
||||||
import "@polymer/paper-icon-button/paper-icon-button";
|
|
||||||
import "../../../components/buttons/ha-call-service-button";
|
|
||||||
import "../../../components/ha-service-description";
|
|
||||||
import { haStyle } from "../../../resources/styles";
|
import { haStyle } from "../../../resources/styles";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import "../ha-config-section";
|
|
||||||
|
|
||||||
export class ZHANetwork extends LitElement {
|
export class ZHANetwork extends LitElement {
|
||||||
public hass?: HomeAssistant;
|
public hass?: HomeAssistant;
|
||||||
@ -30,6 +33,7 @@ export class ZHANetwork extends LitElement {
|
|||||||
hass: {},
|
hass: {},
|
||||||
isWide: {},
|
isWide: {},
|
||||||
_showHelp: {},
|
_showHelp: {},
|
||||||
|
_joinParams: {},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,29 +41,31 @@ export class ZHANetwork extends LitElement {
|
|||||||
return html`
|
return html`
|
||||||
<ha-config-section .isWide="${this.isWide}">
|
<ha-config-section .isWide="${this.isWide}">
|
||||||
<div style="position: relative" slot="header">
|
<div style="position: relative" slot="header">
|
||||||
<span>Network Management</span>
|
<span>Network Management</span>
|
||||||
<paper-icon-button class="toggle-help-icon" @click="${
|
<paper-icon-button
|
||||||
this._onHelpTap
|
class="toggle-help-icon"
|
||||||
}" icon="hass:help-circle"></paper-icon-button>
|
@click="${this._onHelpTap}"
|
||||||
|
icon="hass:help-circle"
|
||||||
|
></paper-icon-button>
|
||||||
</div>
|
</div>
|
||||||
<span slot="introduction">Commands that affect entire network</span>
|
<span slot="introduction">Commands that affect entire network</span>
|
||||||
|
|
||||||
<paper-card class="content">
|
<paper-card class="content">
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<ha-call-service-button .hass="${
|
<mwc-button @click=${this._onAddDevicesClick}>
|
||||||
this.hass
|
Add Devices
|
||||||
}" domain="zha" service="permit">Permit</ha-call-service-button>
|
</mwc-button>
|
||||||
${
|
${this._showHelp
|
||||||
this._showHelp
|
? html`
|
||||||
? html`
|
<ha-service-description
|
||||||
<ha-service-description
|
.hass="${this.hass}"
|
||||||
.hass="${this.hass}"
|
domain="zha"
|
||||||
domain="zha"
|
service="permit"
|
||||||
service="permit"
|
class="help-text2"
|
||||||
/>
|
/>
|
||||||
`
|
`
|
||||||
: ""
|
: ""}
|
||||||
}
|
</div>
|
||||||
</paper-card>
|
</paper-card>
|
||||||
</ha-config-section>
|
</ha-config-section>
|
||||||
`;
|
`;
|
||||||
@ -69,6 +75,10 @@ export class ZHANetwork extends LitElement {
|
|||||||
this._showHelp = !this._showHelp;
|
this._showHelp = !this._showHelp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _onAddDevicesClick() {
|
||||||
|
navigate(this, "add");
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResult[] {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
@ -102,6 +112,11 @@ export class ZHANetwork extends LitElement {
|
|||||||
[hidden] {
|
[hidden] {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.help-text2 {
|
||||||
|
color: grey;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,30 @@
|
|||||||
import {
|
import "../../../components/buttons/ha-call-service-button";
|
||||||
html,
|
import "../../../components/ha-service-description";
|
||||||
LitElement,
|
import "../ha-config-section";
|
||||||
PropertyDeclarations,
|
import "./zha-clusters";
|
||||||
TemplateResult,
|
import "./zha-device-card";
|
||||||
CSSResult,
|
|
||||||
PropertyValues,
|
|
||||||
css,
|
|
||||||
} from "lit-element";
|
|
||||||
import "@material/mwc-button";
|
import "@material/mwc-button";
|
||||||
import "@polymer/paper-card/paper-card";
|
import "@polymer/paper-card/paper-card";
|
||||||
import "@polymer/paper-icon-button/paper-icon-button";
|
import "@polymer/paper-icon-button/paper-icon-button";
|
||||||
import "@polymer/paper-input/paper-input";
|
import "@polymer/paper-input/paper-input";
|
||||||
import "@polymer/paper-item/paper-item";
|
import "@polymer/paper-item/paper-item";
|
||||||
import "@polymer/paper-listbox/paper-listbox";
|
import "@polymer/paper-listbox/paper-listbox";
|
||||||
|
|
||||||
|
import {
|
||||||
|
css,
|
||||||
|
CSSResult,
|
||||||
|
customElement,
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
|
property,
|
||||||
|
TemplateResult,
|
||||||
|
} from "lit-element";
|
||||||
|
|
||||||
import { fireEvent } from "../../../common/dom/fire_event";
|
import { fireEvent } from "../../../common/dom/fire_event";
|
||||||
import "../../../components/buttons/ha-call-service-button";
|
import { fetchDevices, ZHADevice } from "../../../data/zha";
|
||||||
import "../../../components/ha-service-description";
|
|
||||||
import { haStyle } from "../../../resources/styles";
|
import { haStyle } from "../../../resources/styles";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import "../ha-config-section";
|
import { ItemSelectedEvent, ZHADeviceRemovedEvent } from "./types";
|
||||||
import { ItemSelectedEvent, NodeServiceData, ChangeEvent } from "./types";
|
|
||||||
import "./zha-clusters";
|
|
||||||
import "./zha-device-card";
|
|
||||||
import {
|
|
||||||
updateDeviceRegistryEntry,
|
|
||||||
DeviceRegistryEntryMutableParams,
|
|
||||||
} from "../../../data/device_registry";
|
|
||||||
import { reconfigureNode, fetchDevices, ZHADevice } from "../../../data/zha";
|
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
// for fire event
|
// for fire event
|
||||||
@ -37,60 +35,25 @@ declare global {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@customElement("zha-node")
|
||||||
export class ZHANode extends LitElement {
|
export class ZHANode extends LitElement {
|
||||||
public hass?: HomeAssistant;
|
@property() public hass?: HomeAssistant;
|
||||||
public isWide?: boolean;
|
@property() public isWide?: boolean;
|
||||||
private _showHelp: boolean;
|
@property() private _showHelp: boolean = false;
|
||||||
private _selectedNodeIndex: number;
|
@property() private _selectedDeviceIndex: number = -1;
|
||||||
private _selectedNode?: ZHADevice;
|
@property() private _selectedDevice?: ZHADevice;
|
||||||
private _serviceData?: {};
|
@property() private _nodes: ZHADevice[] = [];
|
||||||
private _nodes: ZHADevice[];
|
|
||||||
private _userSelectedName?: string;
|
|
||||||
|
|
||||||
constructor() {
|
public connectedCallback(): void {
|
||||||
super();
|
super.connectedCallback();
|
||||||
this._showHelp = false;
|
this._fetchDevices();
|
||||||
this._selectedNodeIndex = -1;
|
|
||||||
this._nodes = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
static get properties(): PropertyDeclarations {
|
|
||||||
return {
|
|
||||||
hass: {},
|
|
||||||
isWide: {},
|
|
||||||
_showHelp: {},
|
|
||||||
_selectedNodeIndex: {},
|
|
||||||
_selectedNode: {},
|
|
||||||
_entities: {},
|
|
||||||
_serviceData: {},
|
|
||||||
_nodes: {},
|
|
||||||
_userSelectedName: {},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public firstUpdated(changedProperties: PropertyValues): void {
|
|
||||||
super.firstUpdated(changedProperties);
|
|
||||||
if (this._nodes.length === 0) {
|
|
||||||
this._fetchDevices();
|
|
||||||
}
|
|
||||||
this.addEventListener("hass-service-called", (ev) =>
|
|
||||||
this.serviceCalled(ev)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected serviceCalled(ev): void {
|
|
||||||
// Check if this is for us
|
|
||||||
if (ev.detail.success && ev.detail.service === "remove") {
|
|
||||||
this._selectedNodeIndex = -1;
|
|
||||||
this._fetchDevices();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected render(): TemplateResult | void {
|
protected render(): TemplateResult | void {
|
||||||
return html`
|
return html`
|
||||||
<ha-config-section .isWide="${this.isWide}">
|
<ha-config-section .isWide="${this.isWide}">
|
||||||
<div class="sectionHeader" slot="header">
|
<div class="sectionHeader" slot="header">
|
||||||
<span>Node Management</span>
|
<span>Device Management</span>
|
||||||
<paper-icon-button
|
<paper-icon-button
|
||||||
class="toggle-help-icon"
|
class="toggle-help-icon"
|
||||||
@click="${this._onHelpTap}"
|
@click="${this._onHelpTap}"
|
||||||
@ -98,8 +61,8 @@ export class ZHANode extends LitElement {
|
|||||||
></paper-icon-button>
|
></paper-icon-button>
|
||||||
</div>
|
</div>
|
||||||
<span slot="introduction">
|
<span slot="introduction">
|
||||||
Run ZHA commands that affect a single node. Pick a node to see a list
|
Run ZHA commands that affect a single device. Pick a device to see a
|
||||||
of available commands. <br /><br />Note: Sleepy (battery powered)
|
list of available commands. <br /><br />Note: Sleepy (battery powered)
|
||||||
devices need to be awake when executing commands against them. You can
|
devices need to be awake when executing commands against them. You can
|
||||||
generally wake a sleepy device by triggering it. <br /><br />Some
|
generally wake a sleepy device by triggering it. <br /><br />Some
|
||||||
devices such as Xiaomi sensors have a wake up button that you can
|
devices such as Xiaomi sensors have a wake up button that you can
|
||||||
@ -108,11 +71,15 @@ export class ZHANode extends LitElement {
|
|||||||
</span>
|
</span>
|
||||||
<paper-card class="content">
|
<paper-card class="content">
|
||||||
<div class="node-picker">
|
<div class="node-picker">
|
||||||
<paper-dropdown-menu label="Nodes" class="flex">
|
<paper-dropdown-menu
|
||||||
|
label="Devices"
|
||||||
|
class="flex"
|
||||||
|
id="zha-device-selector"
|
||||||
|
>
|
||||||
<paper-listbox
|
<paper-listbox
|
||||||
slot="dropdown-content"
|
slot="dropdown-content"
|
||||||
@iron-select="${this._selectedNodeChanged}"
|
@iron-select="${this._selectedDeviceChanged}"
|
||||||
.selected="${this._selectedNodeIndex}"
|
.selected="${this._selectedDeviceIndex}"
|
||||||
>
|
>
|
||||||
${this._nodes.map(
|
${this._nodes.map(
|
||||||
(entry) => html`
|
(entry) => html`
|
||||||
@ -128,95 +95,36 @@ export class ZHANode extends LitElement {
|
|||||||
</div>
|
</div>
|
||||||
${this._showHelp
|
${this._showHelp
|
||||||
? html`
|
? html`
|
||||||
<div class="helpText">
|
<div class="help-text">
|
||||||
Select node to view per-node options
|
Select device to view per-device options
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
${this._selectedNodeIndex !== -1
|
${this._selectedDeviceIndex !== -1
|
||||||
? html`
|
? html`
|
||||||
<zha-device-card
|
<zha-device-card
|
||||||
class="card"
|
class="card"
|
||||||
.hass="${this.hass}"
|
.hass="${this.hass}"
|
||||||
.device="${this._selectedNode}"
|
.device="${this._selectedDevice}"
|
||||||
.narrow="${!this.isWide}"
|
.narrow="${!this.isWide}"
|
||||||
|
.showHelp="${this._showHelp}"
|
||||||
|
.showActions="${true}"
|
||||||
|
@zha-device-removed="${this._onDeviceRemoved}"
|
||||||
|
.isJoinPage="${false}"
|
||||||
></zha-device-card>
|
></zha-device-card>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
${this._selectedNodeIndex !== -1
|
${this._selectedDevice ? this._renderClusters() : ""}
|
||||||
? html`
|
|
||||||
<div class="input-text">
|
|
||||||
<paper-input
|
|
||||||
type="string"
|
|
||||||
.value="${this._userSelectedName}"
|
|
||||||
@value-changed="${this._onUserSelectedNameChanged}"
|
|
||||||
placeholder="User given name"
|
|
||||||
></paper-input>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
${this._selectedNodeIndex !== -1 ? this._renderNodeActions() : ""}
|
|
||||||
${this._selectedNode ? this._renderClusters() : ""}
|
|
||||||
</paper-card>
|
</paper-card>
|
||||||
</ha-config-section>
|
</ha-config-section>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _renderNodeActions(): TemplateResult {
|
|
||||||
return html`
|
|
||||||
<div class="card-actions">
|
|
||||||
<mwc-button @click="${this._onReconfigureNodeClick}"
|
|
||||||
>Reconfigure Node</mwc-button
|
|
||||||
>
|
|
||||||
${this._showHelp
|
|
||||||
? html`
|
|
||||||
<div class="helpText">
|
|
||||||
${this.hass!.localize(
|
|
||||||
"ui.panel.config.zha.services.reconfigure"
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
<ha-call-service-button
|
|
||||||
.hass="${this.hass}"
|
|
||||||
domain="zha"
|
|
||||||
service="remove"
|
|
||||||
.serviceData="${this._serviceData}"
|
|
||||||
>Remove Node</ha-call-service-button
|
|
||||||
>
|
|
||||||
${this._showHelp
|
|
||||||
? html`
|
|
||||||
<ha-service-description
|
|
||||||
.hass="${this.hass}"
|
|
||||||
domain="zha"
|
|
||||||
service="remove"
|
|
||||||
/>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
<mwc-button
|
|
||||||
@click="${this._onUpdateDeviceNameClick}"
|
|
||||||
.disabled="${!this._userSelectedName ||
|
|
||||||
this._userSelectedName === ""}"
|
|
||||||
>Update Name</mwc-button
|
|
||||||
>
|
|
||||||
${this._showHelp
|
|
||||||
? html`
|
|
||||||
<div class="helpText">
|
|
||||||
${this.hass!.localize(
|
|
||||||
"ui.panel.config.zha.services.updateDeviceName"
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _renderClusters(): TemplateResult {
|
private _renderClusters(): TemplateResult {
|
||||||
return html`
|
return html`
|
||||||
<zha-clusters
|
<zha-clusters
|
||||||
.hass="${this.hass}"
|
.hass="${this.hass}"
|
||||||
.selectedDevice="${this._selectedNode}"
|
.selectedDevice="${this._selectedDevice}"
|
||||||
.showHelp="${this._showHelp}"
|
.showHelp="${this._showHelp}"
|
||||||
></zha-clusters>
|
></zha-clusters>
|
||||||
`;
|
`;
|
||||||
@ -226,45 +134,10 @@ export class ZHANode extends LitElement {
|
|||||||
this._showHelp = !this._showHelp;
|
this._showHelp = !this._showHelp;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _selectedNodeChanged(event: ItemSelectedEvent): void {
|
private _selectedDeviceChanged(event: ItemSelectedEvent): void {
|
||||||
this._selectedNodeIndex = event!.target!.selected;
|
this._selectedDeviceIndex = event!.target!.selected;
|
||||||
this._selectedNode = this._nodes[this._selectedNodeIndex];
|
this._selectedDevice = this._nodes[this._selectedDeviceIndex];
|
||||||
this._userSelectedName = "";
|
fireEvent(this, "zha-node-selected", { node: this._selectedDevice });
|
||||||
fireEvent(this, "zha-node-selected", { node: this._selectedNode });
|
|
||||||
this._serviceData = this._computeNodeServiceData();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _onReconfigureNodeClick(): Promise<void> {
|
|
||||||
if (this.hass) {
|
|
||||||
await reconfigureNode(this.hass, this._selectedNode!.ieee);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private _onUserSelectedNameChanged(value: ChangeEvent): void {
|
|
||||||
this._userSelectedName = value.detail!.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _onUpdateDeviceNameClick(): Promise<void> {
|
|
||||||
if (this.hass) {
|
|
||||||
const values: DeviceRegistryEntryMutableParams = {
|
|
||||||
name_by_user: this._userSelectedName,
|
|
||||||
};
|
|
||||||
|
|
||||||
await updateDeviceRegistryEntry(
|
|
||||||
this.hass,
|
|
||||||
this._selectedNode!.device_reg_id,
|
|
||||||
values
|
|
||||||
);
|
|
||||||
|
|
||||||
this._selectedNode!.user_given_name = this._userSelectedName!;
|
|
||||||
this._userSelectedName = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private _computeNodeServiceData(): NodeServiceData {
|
|
||||||
return {
|
|
||||||
ieee_address: this._selectedNode!.ieee,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _fetchDevices() {
|
private async _fetchDevices() {
|
||||||
@ -273,6 +146,13 @@ export class ZHANode extends LitElement {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _onDeviceRemoved(event: ZHADeviceRemovedEvent): void {
|
||||||
|
this._selectedDeviceIndex = -1;
|
||||||
|
this._nodes.splice(this._nodes.indexOf(event.detail!.device!), 1);
|
||||||
|
this._selectedDevice = undefined;
|
||||||
|
fireEvent(this, "zha-node-selected", { node: this._selectedDevice });
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResult[] {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
@ -298,13 +178,10 @@ export class ZHANode extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.help-text {
|
.help-text {
|
||||||
|
color: grey;
|
||||||
padding-left: 28px;
|
padding-left: 28px;
|
||||||
padding-right: 28px;
|
padding-right: 28px;
|
||||||
}
|
padding-bottom: 16px;
|
||||||
|
|
||||||
.helpText {
|
|
||||||
color: grey;
|
|
||||||
padding: 16px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
paper-card {
|
paper-card {
|
||||||
@ -355,12 +232,6 @@ export class ZHANode extends LitElement {
|
|||||||
right: 0;
|
right: 0;
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-text {
|
|
||||||
padding-left: 28px;
|
|
||||||
padding-right: 28px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -371,5 +242,3 @@ declare global {
|
|||||||
"zha-node": ZHANode;
|
"zha-node": ZHANode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("zha-node", ZHANode);
|
|
||||||
|
@ -877,7 +877,18 @@
|
|||||||
"description": "Zigbee Home Automation network management",
|
"description": "Zigbee Home Automation network management",
|
||||||
"services": {
|
"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.",
|
"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."
|
"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": {
|
||||||
|
"header": "Zigbee Home Automation - Add Devices",
|
||||||
|
"spinner": "Searching for ZHA Zigbee devices...",
|
||||||
|
"discovery_text": "Discovered devices will show up here. Follow the instructions for your device(s) and place the device(s) in pairing mode."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zwave": {
|
"zwave": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user