mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 09:46:36 +00:00
Display device name in bluetooth panel (#23960)
This commit is contained in:
parent
0cd4256c0e
commit
b056ce228b
@ -1,8 +1,9 @@
|
||||
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { html, LitElement } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import { storage } from "../../../../../common/decorators/storage";
|
||||
import type { HASSDomEvent } from "../../../../../common/dom/fire_event";
|
||||
import type { LocalizeFunc } from "../../../../../common/translations/localize";
|
||||
import type {
|
||||
@ -11,9 +12,6 @@ import type {
|
||||
} from "../../../../../components/data-table/ha-data-table";
|
||||
import "../../../../../components/ha-fab";
|
||||
import "../../../../../components/ha-icon-button";
|
||||
import "../../../../../layouts/hass-tabs-subpage-data-table";
|
||||
import { haStyle } from "../../../../../resources/styles";
|
||||
import type { HomeAssistant, Route } from "../../../../../types";
|
||||
import type {
|
||||
BluetoothDeviceData,
|
||||
BluetoothScannersDetails,
|
||||
@ -22,6 +20,10 @@ import {
|
||||
subscribeBluetoothAdvertisements,
|
||||
subscribeBluetoothScannersDetails,
|
||||
} from "../../../../../data/bluetooth";
|
||||
import type { DeviceRegistryEntry } from "../../../../../data/device_registry";
|
||||
import "../../../../../layouts/hass-tabs-subpage-data-table";
|
||||
import { haStyle } from "../../../../../resources/styles";
|
||||
import type { HomeAssistant, Route } from "../../../../../types";
|
||||
import { showBluetoothDeviceInfoDialog } from "./show-dialog-bluetooth-device-info";
|
||||
|
||||
@customElement("bluetooth-advertisement-monitor")
|
||||
@ -38,6 +40,22 @@ export class BluetoothAdvertisementMonitorPanel extends LitElement {
|
||||
|
||||
@state() private _scanners: BluetoothScannersDetails = {};
|
||||
|
||||
@state() private _sourceDevices: Record<string, DeviceRegistryEntry> = {};
|
||||
|
||||
@storage({
|
||||
key: "bluetooth-advertisement-table-grouping",
|
||||
state: false,
|
||||
subscribe: false,
|
||||
})
|
||||
private _activeGrouping?: string = "source";
|
||||
|
||||
@storage({
|
||||
key: "bluetooth-advertisement-table-collapsed",
|
||||
state: false,
|
||||
subscribe: false,
|
||||
})
|
||||
private _activeCollapsed: string[] = [];
|
||||
|
||||
private _unsub_advertisements?: UnsubscribeFunc;
|
||||
|
||||
private _unsub_scanners?: UnsubscribeFunc;
|
||||
@ -57,6 +75,19 @@ export class BluetoothAdvertisementMonitorPanel extends LitElement {
|
||||
this._scanners = scanners;
|
||||
}
|
||||
);
|
||||
|
||||
const devices = Object.values(this.hass.devices);
|
||||
const bluetoothDevices = devices.filter((device) =>
|
||||
device.connections.find((connection) => connection[0] === "bluetooth")
|
||||
);
|
||||
this._sourceDevices = Object.fromEntries(
|
||||
bluetoothDevices.map((device) => {
|
||||
const connection = device.connections.find(
|
||||
(c) => c[0] === "bluetooth"
|
||||
)!;
|
||||
return [connection[1], device];
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,14 +122,28 @@ export class BluetoothAdvertisementMonitorPanel extends LitElement {
|
||||
filterable: true,
|
||||
sortable: true,
|
||||
},
|
||||
device: {
|
||||
title: localize("ui.panel.config.bluetooth.device"),
|
||||
filterable: true,
|
||||
sortable: true,
|
||||
template: (data) => html`${data.device || "-"}`,
|
||||
},
|
||||
source: {
|
||||
title: localize("ui.panel.config.bluetooth.source"),
|
||||
filterable: true,
|
||||
sortable: true,
|
||||
groupable: true,
|
||||
},
|
||||
source_address: {
|
||||
title: localize("ui.panel.config.bluetooth.source_address"),
|
||||
filterable: true,
|
||||
sortable: true,
|
||||
defaultHidden: true,
|
||||
},
|
||||
rssi: {
|
||||
title: localize("ui.panel.config.bluetooth.rssi"),
|
||||
type: "numeric",
|
||||
maxWidth: "60px",
|
||||
sortable: true,
|
||||
},
|
||||
};
|
||||
@ -108,11 +153,22 @@ export class BluetoothAdvertisementMonitorPanel extends LitElement {
|
||||
);
|
||||
|
||||
private _dataWithNamedSourceAndIds = memoizeOne((data) =>
|
||||
data.map((row) => ({
|
||||
...row,
|
||||
id: row.address,
|
||||
source: this._scanners[row.source]?.name || row.source,
|
||||
}))
|
||||
data.map((row) => {
|
||||
const device = this._sourceDevices[row.address];
|
||||
const scannerDevice = this._sourceDevices[row.source];
|
||||
const scanner = this._scanners[row.source];
|
||||
return {
|
||||
...row,
|
||||
id: row.address,
|
||||
source_address: row.source,
|
||||
source:
|
||||
scannerDevice?.name_by_user ||
|
||||
scannerDevice?.name ||
|
||||
scanner?.name ||
|
||||
row.source,
|
||||
device: device?.name_by_user || device?.name || undefined,
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
protected render(): TemplateResult {
|
||||
@ -124,11 +180,23 @@ export class BluetoothAdvertisementMonitorPanel extends LitElement {
|
||||
.columns=${this._columns(this.hass.localize)}
|
||||
.data=${this._dataWithNamedSourceAndIds(this._data)}
|
||||
@row-click=${this._handleRowClicked}
|
||||
.initialGroupColumn=${this._activeGrouping}
|
||||
.initialCollapsedGroups=${this._activeCollapsed}
|
||||
@grouping-changed=${this._handleGroupingChanged}
|
||||
@collapsed-changed=${this._handleCollapseChanged}
|
||||
clickable
|
||||
></hass-tabs-subpage-data-table>
|
||||
`;
|
||||
}
|
||||
|
||||
private _handleGroupingChanged(ev: CustomEvent) {
|
||||
this._activeGrouping = ev.detail.value;
|
||||
}
|
||||
|
||||
private _handleCollapseChanged(ev: CustomEvent) {
|
||||
this._activeCollapsed = ev.detail.value;
|
||||
}
|
||||
|
||||
private _handleRowClicked(ev: HASSDomEvent<RowClickedEvent>) {
|
||||
const entry = this._data.find((ent) => ent.address === ev.detail.id);
|
||||
showBluetoothDeviceInfoDialog(this, {
|
||||
|
@ -53,8 +53,6 @@ class DialogBluetoothDeviceInfo extends LitElement implements HassDialog {
|
||||
return html`
|
||||
<ha-dialog
|
||||
open
|
||||
scrimClickAction
|
||||
escapeKeyAction
|
||||
@closed=${this.closeDialog}
|
||||
.heading=${createCloseHeading(
|
||||
this.hass,
|
||||
|
@ -5330,6 +5330,8 @@
|
||||
"name": "Name",
|
||||
"source": "Source",
|
||||
"rssi": "RSSI",
|
||||
"source_address": "Source address",
|
||||
"device": "Device",
|
||||
"device_information": "Device information",
|
||||
"advertisement_data": "Advertisement data",
|
||||
"manufacturer_data": "Manufacturer data",
|
||||
|
Loading…
x
Reference in New Issue
Block a user