ha-frontend/src/data/device_registry.ts

162 lines
4.5 KiB
TypeScript

import { computeStateName } from "../common/entity/compute_state_name";
import { caseInsensitiveStringCompare } from "../common/string/compare";
import type { HomeAssistant } from "../types";
import type {
EntityRegistryDisplayEntry,
EntityRegistryEntry,
} from "./entity_registry";
import type { EntitySources } from "./entity_sources";
export {
fetchDeviceRegistry,
subscribeDeviceRegistry,
} from "./ws-device_registry";
export interface DeviceRegistryEntry {
id: string;
config_entries: string[];
connections: Array<[string, string]>;
identifiers: Array<[string, string]>;
manufacturer: string | null;
model: string | null;
name: string | null;
labels: string[];
sw_version: string | null;
hw_version: string | null;
serial_number: string | null;
via_device_id: string | null;
area_id: string | null;
name_by_user: string | null;
entry_type: "service" | null;
disabled_by: "user" | "integration" | "config_entry" | null;
configuration_url: string | null;
}
export interface DeviceEntityDisplayLookup {
[deviceId: string]: EntityRegistryDisplayEntry[];
}
export interface DeviceEntityLookup {
[deviceId: string]: EntityRegistryEntry[];
}
export interface DeviceRegistryEntryMutableParams {
area_id?: string | null;
name_by_user?: string | null;
disabled_by?: string | null;
labels?: string[];
}
export const fallbackDeviceName = (
hass: HomeAssistant,
entities: EntityRegistryEntry[] | EntityRegistryDisplayEntry[] | string[]
) => {
for (const entity of entities || []) {
const entityId = typeof entity === "string" ? entity : entity.entity_id;
const stateObj = hass.states[entityId];
if (stateObj) {
return computeStateName(stateObj);
}
}
return undefined;
};
export const computeDeviceName = (
device: DeviceRegistryEntry,
hass: HomeAssistant,
entities?: EntityRegistryEntry[] | EntityRegistryDisplayEntry[] | string[]
) =>
device.name_by_user ||
device.name ||
(entities && fallbackDeviceName(hass, entities)) ||
hass.localize("ui.panel.config.devices.unnamed_device", {
type: hass.localize(
`ui.panel.config.devices.type.${device.entry_type || "device"}`
),
});
export const devicesInArea = (devices: DeviceRegistryEntry[], areaId: string) =>
devices.filter((device) => device.area_id === areaId);
export const updateDeviceRegistryEntry = (
hass: HomeAssistant,
deviceId: string,
updates: Partial<DeviceRegistryEntryMutableParams>
) =>
hass.callWS<DeviceRegistryEntry>({
type: "config/device_registry/update",
device_id: deviceId,
...updates,
});
export const removeConfigEntryFromDevice = (
hass: HomeAssistant,
deviceId: string,
configEntryId: string
) =>
hass.callWS<DeviceRegistryEntry>({
type: "config/device_registry/remove_config_entry",
device_id: deviceId,
config_entry_id: configEntryId,
});
export const sortDeviceRegistryByName = (
entries: DeviceRegistryEntry[],
language: string
) =>
entries.sort((entry1, entry2) =>
caseInsensitiveStringCompare(entry1.name || "", entry2.name || "", language)
);
export const getDeviceEntityLookup = (
entities: EntityRegistryEntry[]
): DeviceEntityLookup => {
const deviceEntityLookup: DeviceEntityLookup = {};
for (const entity of entities) {
if (!entity.device_id) {
continue;
}
if (!(entity.device_id in deviceEntityLookup)) {
deviceEntityLookup[entity.device_id] = [];
}
deviceEntityLookup[entity.device_id].push(entity);
}
return deviceEntityLookup;
};
export const getDeviceEntityDisplayLookup = (
entities: EntityRegistryDisplayEntry[]
): DeviceEntityDisplayLookup => {
const deviceEntityLookup: DeviceEntityDisplayLookup = {};
for (const entity of entities) {
if (!entity.device_id) {
continue;
}
if (!(entity.device_id in deviceEntityLookup)) {
deviceEntityLookup[entity.device_id] = [];
}
deviceEntityLookup[entity.device_id].push(entity);
}
return deviceEntityLookup;
};
export const getDeviceIntegrationLookup = (
entitySources: EntitySources,
entities: EntityRegistryDisplayEntry[] | EntityRegistryEntry[]
): Record<string, string[]> => {
const deviceIntegrations: Record<string, string[]> = {};
for (const entity of entities) {
const source = entitySources[entity.entity_id];
if (!source?.domain || entity.device_id === null) {
continue;
}
if (!deviceIntegrations[entity.device_id!]) {
deviceIntegrations[entity.device_id!] = [];
}
deviceIntegrations[entity.device_id!].push(source.domain);
}
return deviceIntegrations;
};