Add view in visualization button to the device page for ZHA devices (#8090)

This commit is contained in:
David F. Mulcahey 2021-03-01 09:54:49 -05:00 committed by GitHub
parent f31f10cea9
commit 1642c68493
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 109 additions and 19 deletions

View File

@ -89,6 +89,11 @@ export const reconfigureNode = (
ieee: ieeeAddress,
});
export const refreshTopology = (hass: HomeAssistant): Promise<void> =>
hass.callWS({
type: "zha/topology/update",
});
export const fetchAttributesForCluster = (
hass: HomeAssistant,
ieeeAddress: string,

View File

@ -79,6 +79,11 @@ export class HaDeviceActionsZha extends LitElement {
"ui.dialogs.zha_device_info.buttons.clusters"
)}
</mwc-button>
<mwc-button @click=${this._onViewInVisualizationClick}>
${this.hass!.localize(
"ui.dialogs.zha_device_info.buttons.view_in_visualization"
)}
</mwc-button>
<mwc-button class="warning" @click=${this._removeDevice}>
${this.hass!.localize(
"ui.dialogs.zha_device_info.buttons.remove"
@ -104,6 +109,13 @@ export class HaDeviceActionsZha extends LitElement {
navigate(this, "/config/zha/add/" + this._zhaDevice!.ieee);
}
private _onViewInVisualizationClick() {
navigate(
this,
"/config/zha/visualization/" + this._zhaDevice!.device_reg_id
);
}
private async _handleZigbeeInfoClicked() {
showZHADeviceZigbeeInfoDialog(this, { device: this._zhaDevice! });
}

View File

@ -59,6 +59,8 @@ class ZHAConfigDashboardRouter extends HassRouterPage {
el.groupId = this.routeTail.path.substr(1);
} else if (this._currentPage === "device") {
el.ieee = this.routeTail.path.substr(1);
} else if (this._currentPage === "visualization") {
el.zoomedDeviceId = this.routeTail.path.substr(1);
}
const searchParams = new URLSearchParams(window.location.search);

View File

@ -9,23 +9,33 @@ import {
PropertyValues,
query,
} from "lit-element";
import { Edge, EdgeOptions, Network, Node } from "vis-network";
import "@material/mwc-button";
import { navigate } from "../../../../../common/navigate";
import {
fetchDevices,
refreshTopology,
ZHADevice,
} from "../../../../../data/zha";
import "../../../../../layouts/hass-subpage";
import type { HomeAssistant } from "../../../../../types";
import { Network, Edge, Node, EdgeOptions } from "vis-network";
import "../../../../../common/search/search-input";
import "../../../../../components/device/ha-device-picker";
import "../../../../../components/ha-button-menu";
import "../../../../../components/ha-svg-icon";
import { fetchDevices, ZHADevice } from "../../../../../data/zha";
import "../../../../../layouts/hass-subpage";
import { PolymerChangedEvent } from "../../../../../polymer-types";
import type { HomeAssistant } from "../../../../../types";
import { formatAsPaddedHex } from "./functions";
import { DeviceRegistryEntry } from "../../../../../data/device_registry";
@customElement("zha-network-visualization-page")
export class ZHANetworkVisualizationPage extends LitElement {
@property({ type: Object }) public hass!: HomeAssistant;
@property({ type: Boolean }) public narrow!: boolean;
@property({ type: Boolean, reflect: true }) public narrow = false;
@property()
public zoomedDeviceId?: string;
@query("#visualization", true)
private _visualization?: HTMLElement;
@ -45,9 +55,6 @@ export class ZHANetworkVisualizationPage extends LitElement {
@internalProperty()
private _filter?: string;
@internalProperty()
private _zoomedDeviceId?: string;
protected firstUpdated(changedProperties: PropertyValues): void {
super.firstUpdated(changedProperties);
if (this.hass) {
@ -98,6 +105,12 @@ export class ZHANetworkVisualizationPage extends LitElement {
}
}
});
this._network.on("stabilized", () => {
if (this.zoomedDeviceId) {
this._zoomToDevice();
}
});
}
protected render() {
@ -121,13 +134,18 @@ export class ZHANetworkVisualizationPage extends LitElement {
</search-input>
<ha-device-picker
.hass=${this.hass}
.value=${this._zoomedDeviceId}
.value=${this.zoomedDeviceId}
.label=${this.hass.localize(
"ui.panel.config.zha.visualization.zoom_label"
)}
.includeDomains="['zha']"
@value-changed=${this._zoomToDevice}
.deviceFilter=${(device) => this._filterDevices(device)}
@value-changed=${this._onZoomToDevice}
></ha-device-picker>
<mwc-button @click=${this._refreshTopology}
>${this.hass!.localize(
"ui.panel.config.zha.visualization.refresh_topology"
)}</mwc-button
>
</div>
<div id="visualization"></div>
</hass-subpage>
@ -248,7 +266,7 @@ export class ZHANetworkVisualizationPage extends LitElement {
filteredNodeIds.push(node.id!);
}
});
this._zoomedDeviceId = "";
this.zoomedDeviceId = "";
this._zoomOut();
this._network.selectNodes(filteredNodeIds, true);
} else {
@ -256,21 +274,25 @@ export class ZHANetworkVisualizationPage extends LitElement {
}
}
private _zoomToDevice(event: PolymerChangedEvent<string>) {
private _onZoomToDevice(event: PolymerChangedEvent<string>) {
event.stopPropagation();
this._zoomedDeviceId = event.detail.value;
this.zoomedDeviceId = event.detail.value;
if (!this._network) {
return;
}
this._zoomToDevice();
}
private _zoomToDevice() {
this._filter = "";
if (!this._zoomedDeviceId) {
if (!this.zoomedDeviceId) {
this._zoomOut();
} else {
const device: ZHADevice | undefined = this._devicesByDeviceId.get(
this._zoomedDeviceId
this.zoomedDeviceId
);
if (device) {
this._network.fit({
this._network!.fit({
nodes: [device.ieee],
animation: { duration: 500, easingFunction: "easeInQuad" },
});
@ -285,6 +307,24 @@ export class ZHANetworkVisualizationPage extends LitElement {
});
}
private async _refreshTopology(): Promise<void> {
await refreshTopology(this.hass);
}
private _filterDevices(device: DeviceRegistryEntry): boolean {
if (!this.hass) {
return false;
}
for (const parts of device.identifiers) {
for (const part of parts) {
if (part === "zha") {
return true;
}
}
}
return false;
}
static get styles(): CSSResult[] {
return [
css`
@ -299,30 +339,59 @@ export class ZHANetworkVisualizationPage extends LitElement {
line-height: var(--paper-font-display1_-_line-height);
opacity: var(--dark-primary-opacity);
}
.table-header {
border-bottom: 1px solid --divider-color;
padding: 0 16px;
display: flex;
align-items: center;
flex-direction: row;
height: var(--header-height);
}
:host([narrow]) .table-header {
flex-direction: column;
align-items: stretch;
height: var(--header-height) * 3;
}
.search-toolbar {
display: flex;
align-items: center;
color: var(--secondary-text-color);
padding: 0 16px;
}
search-input {
position: relative;
top: 2px;
flex: 1;
}
:host(:not([narrow])) search-input {
margin: 5px;
}
search-input.header {
left: -8px;
}
ha-device-picker {
flex: 1;
}
:host(:not([narrow])) ha-device-picker {
margin: 5px;
}
mwc-button {
font-weight: 500;
color: var(--primary-color);
}
:host(:not([narrow])) mwc-button {
margin: 5px;
}
`,
];
}

View File

@ -745,7 +745,8 @@
"remove": "Remove Device",
"clusters": "Manage Clusters",
"reconfigure": "Reconfigure Device",
"zigbee_information": "Zigbee device signature"
"zigbee_information": "Zigbee device signature",
"view_in_visualization": "View in Visualization"
},
"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.",
@ -2365,7 +2366,8 @@
"header": "Network Visualization",
"caption": "Visualization",
"highlight_label": "Highlight Devices",
"zoom_label": "Zoom To Device"
"zoom_label": "Zoom To Device",
"refresh_topology": "Refresh Topology"
},
"group_binding": {
"header": "Group Binding",