Add bluetooth advertisement manufacturer to bluetooth panel
parent
634e1dbde8
commit
eaf6eaa31f
File diff suppressed because it is too large
Load Diff
|
@ -1,16 +1,17 @@
|
||||||
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
|
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||||
import type { CSSResultGroup, TemplateResult, PropertyValues } from "lit";
|
import { load } from "js-yaml";
|
||||||
|
import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
|
||||||
import { html, LitElement } from "lit";
|
import { html, LitElement } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { storage } from "../../../../../common/decorators/storage";
|
import { storage } from "../../../../../common/decorators/storage";
|
||||||
import type { HASSDomEvent } from "../../../../../common/dom/fire_event";
|
import type { HASSDomEvent } from "../../../../../common/dom/fire_event";
|
||||||
import type { LocalizeFunc } from "../../../../../common/translations/localize";
|
import type { LocalizeFunc } from "../../../../../common/translations/localize";
|
||||||
|
import { extractSearchParamsObject } from "../../../../../common/url/search-params";
|
||||||
import type {
|
import type {
|
||||||
DataTableColumnContainer,
|
DataTableColumnContainer,
|
||||||
RowClickedEvent,
|
RowClickedEvent,
|
||||||
} from "../../../../../components/data-table/ha-data-table";
|
} from "../../../../../components/data-table/ha-data-table";
|
||||||
import { extractSearchParamsObject } from "../../../../../common/url/search-params";
|
|
||||||
import "../../../../../components/ha-fab";
|
import "../../../../../components/ha-fab";
|
||||||
import "../../../../../components/ha-icon-button";
|
import "../../../../../components/ha-icon-button";
|
||||||
import "../../../../../components/ha-relative-time";
|
import "../../../../../components/ha-relative-time";
|
||||||
|
@ -23,11 +24,11 @@ import {
|
||||||
subscribeBluetoothScannersDetails,
|
subscribeBluetoothScannersDetails,
|
||||||
} from "../../../../../data/bluetooth";
|
} from "../../../../../data/bluetooth";
|
||||||
import type { DeviceRegistryEntry } from "../../../../../data/device_registry";
|
import type { DeviceRegistryEntry } from "../../../../../data/device_registry";
|
||||||
|
import type { PageNavigation } from "../../../../../layouts/hass-tabs-subpage";
|
||||||
import "../../../../../layouts/hass-tabs-subpage-data-table";
|
import "../../../../../layouts/hass-tabs-subpage-data-table";
|
||||||
import { haStyle } from "../../../../../resources/styles";
|
import { haStyle } from "../../../../../resources/styles";
|
||||||
import type { HomeAssistant, Route } from "../../../../../types";
|
import type { HomeAssistant, Route } from "../../../../../types";
|
||||||
import { showBluetoothDeviceInfoDialog } from "./show-dialog-bluetooth-device-info";
|
import { showBluetoothDeviceInfoDialog } from "./show-dialog-bluetooth-device-info";
|
||||||
import type { PageNavigation } from "../../../../../layouts/hass-tabs-subpage";
|
|
||||||
|
|
||||||
export const bluetoothAdvertisementMonitorTabs: PageNavigation[] = [
|
export const bluetoothAdvertisementMonitorTabs: PageNavigation[] = [
|
||||||
{
|
{
|
||||||
|
@ -58,6 +59,8 @@ export class BluetoothAdvertisementMonitorPanel extends LitElement {
|
||||||
|
|
||||||
@state() private _sourceDevices: Record<string, DeviceRegistryEntry> = {};
|
@state() private _sourceDevices: Record<string, DeviceRegistryEntry> = {};
|
||||||
|
|
||||||
|
@state() private _manufacturers: Record<string, string> = {};
|
||||||
|
|
||||||
@storage({
|
@storage({
|
||||||
key: "bluetooth-advertisement-table-grouping",
|
key: "bluetooth-advertisement-table-grouping",
|
||||||
state: false,
|
state: false,
|
||||||
|
@ -76,6 +79,24 @@ export class BluetoothAdvertisementMonitorPanel extends LitElement {
|
||||||
|
|
||||||
private _unsub_scanners?: UnsubscribeFunc;
|
private _unsub_scanners?: UnsubscribeFunc;
|
||||||
|
|
||||||
|
public firstUpdated(_changedProperties: PropertyValues): void {
|
||||||
|
this._fetchManufacturers();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _fetchManufacturers() {
|
||||||
|
const response = await fetch("/static/bluetooth_company_identifiers.yaml");
|
||||||
|
const yamlText = await response.text();
|
||||||
|
const data = load(yamlText) as any;
|
||||||
|
|
||||||
|
this._manufacturers = (data.company_identifiers || []).reduce(
|
||||||
|
(acc, entry) => {
|
||||||
|
acc[parseInt(entry.value).toString()] = entry.name;
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public connectedCallback(): void {
|
public connectedCallback(): void {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
if (this.hass) {
|
if (this.hass) {
|
||||||
|
@ -188,17 +209,25 @@ export class BluetoothAdvertisementMonitorPanel extends LitElement {
|
||||||
maxWidth: "60px",
|
maxWidth: "60px",
|
||||||
sortable: true,
|
sortable: true,
|
||||||
},
|
},
|
||||||
|
manufacturer: {
|
||||||
|
title: localize("ui.panel.config.bluetooth.manufacturer"),
|
||||||
|
filterable: true,
|
||||||
|
sortable: true,
|
||||||
|
defaultHidden: true,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return columns;
|
return columns;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
private _dataWithNamedSourceAndIds = memoizeOne((data) =>
|
private _dataWithNamedSourceAndIds = memoizeOne((data, manufacturers) =>
|
||||||
data.map((row) => {
|
data.map((row) => {
|
||||||
const device = this._sourceDevices[row.address];
|
const device = this._sourceDevices[row.address];
|
||||||
const scannerDevice = this._sourceDevices[row.source];
|
const scannerDevice = this._sourceDevices[row.source];
|
||||||
const scanner = this._scanners[row.source];
|
const scanner = this._scanners[row.source];
|
||||||
|
const manufacturerCode = Object.keys(row.manufacturer_data)?.[0];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...row,
|
...row,
|
||||||
id: row.address,
|
id: row.address,
|
||||||
|
@ -210,6 +239,9 @@ export class BluetoothAdvertisementMonitorPanel extends LitElement {
|
||||||
row.source,
|
row.source,
|
||||||
device: device?.name_by_user || device?.name || undefined,
|
device: device?.name_by_user || device?.name || undefined,
|
||||||
datetime: new Date(row.time * 1000),
|
datetime: new Date(row.time * 1000),
|
||||||
|
manufacturer: manufacturerCode
|
||||||
|
? manufacturers[manufacturerCode]
|
||||||
|
: undefined,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -221,7 +253,10 @@ export class BluetoothAdvertisementMonitorPanel extends LitElement {
|
||||||
.narrow=${this.narrow}
|
.narrow=${this.narrow}
|
||||||
.route=${this.route}
|
.route=${this.route}
|
||||||
.columns=${this._columns(this.hass.localize)}
|
.columns=${this._columns(this.hass.localize)}
|
||||||
.data=${this._dataWithNamedSourceAndIds(this._data)}
|
.data=${this._dataWithNamedSourceAndIds(
|
||||||
|
this._data,
|
||||||
|
this._manufacturers
|
||||||
|
)}
|
||||||
.noDataText=${this.hass.localize(
|
.noDataText=${this.hass.localize(
|
||||||
"ui.panel.config.bluetooth.no_advertisements_found"
|
"ui.panel.config.bluetooth.no_advertisements_found"
|
||||||
)}
|
)}
|
||||||
|
@ -249,6 +284,7 @@ export class BluetoothAdvertisementMonitorPanel extends LitElement {
|
||||||
const entry = this._data.find((ent) => ent.address === ev.detail.id);
|
const entry = this._data.find((ent) => ent.address === ev.detail.id);
|
||||||
showBluetoothDeviceInfoDialog(this, {
|
showBluetoothDeviceInfoDialog(this, {
|
||||||
entry: entry!,
|
entry: entry!,
|
||||||
|
manufacturers: this._manufacturers,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,15 @@ class DialogBluetoothDeviceInfo extends LitElement implements HassDialog {
|
||||||
return nothing;
|
return nothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const manufacturerCode = this._params.entry.manufacturer_data
|
||||||
|
? Object.keys(this._params.entry.manufacturer_data)[0]
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
const manufacturerName =
|
||||||
|
manufacturerCode && this._params.manufacturers[manufacturerCode]
|
||||||
|
? this._params.manufacturers[manufacturerCode]
|
||||||
|
: undefined;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-dialog
|
<ha-dialog
|
||||||
open
|
open
|
||||||
|
@ -67,6 +76,16 @@ class DialogBluetoothDeviceInfo extends LitElement implements HassDialog {
|
||||||
<br />
|
<br />
|
||||||
<b>${this.hass.localize("ui.panel.config.bluetooth.source")}</b>:
|
<b>${this.hass.localize("ui.panel.config.bluetooth.source")}</b>:
|
||||||
${this._params.entry.source}
|
${this._params.entry.source}
|
||||||
|
${manufacturerName
|
||||||
|
? html`
|
||||||
|
<br />
|
||||||
|
<b>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.bluetooth.manufacturer"
|
||||||
|
)}</b
|
||||||
|
>: ${manufacturerName}
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3>
|
<h3>
|
||||||
|
|
|
@ -3,6 +3,7 @@ import type { BluetoothDeviceData } from "../../../../../data/bluetooth";
|
||||||
|
|
||||||
export interface BluetoothDeviceInfoDialogParams {
|
export interface BluetoothDeviceInfoDialogParams {
|
||||||
entry: BluetoothDeviceData;
|
entry: BluetoothDeviceData;
|
||||||
|
manufacturers: Record<string, string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const loadBluetoothDeviceInfoDialog = () =>
|
export const loadBluetoothDeviceInfoDialog = () =>
|
||||||
|
|
|
@ -5575,6 +5575,7 @@
|
||||||
"source_address": "Source address",
|
"source_address": "Source address",
|
||||||
"updated": "Updated",
|
"updated": "Updated",
|
||||||
"device": "Device",
|
"device": "Device",
|
||||||
|
"manufacturer": "Manufacturer",
|
||||||
"device_information": "Device information",
|
"device_information": "Device information",
|
||||||
"advertisement_data": "Advertisement data",
|
"advertisement_data": "Advertisement data",
|
||||||
"manufacturer_data": "Manufacturer data",
|
"manufacturer_data": "Manufacturer data",
|
||||||
|
|
Loading…
Reference in New Issue