mirror of
https://github.com/home-assistant/frontend
synced 2024-09-22 18:30:59 +02:00
Use entity registry display api (#15549)
This commit is contained in:
parent
7173b30716
commit
f69ae84cc6
@ -136,7 +136,7 @@ export class DemoAutomationDescribeAction extends LitElement {
|
||||
<div class="action">
|
||||
<span>
|
||||
${this._action
|
||||
? describeAction(this.hass, this._action)
|
||||
? describeAction(this.hass, [], this._action)
|
||||
: "<invalid YAML>"}
|
||||
</span>
|
||||
<ha-yaml-editor
|
||||
@ -149,7 +149,7 @@ export class DemoAutomationDescribeAction extends LitElement {
|
||||
${ACTIONS.map(
|
||||
(conf) => html`
|
||||
<div class="action">
|
||||
<span>${describeAction(this.hass, conf as any)}</span>
|
||||
<span>${describeAction(this.hass, [], conf as any)}</span>
|
||||
<pre>${dump(conf)}</pre>
|
||||
</div>
|
||||
`
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { EntityRegistryEntry } from "../../data/entity_registry";
|
||||
import { EntityRegistryDisplayEntry } from "../../data/entity_registry";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import { LocalizeFunc } from "../translations/localize";
|
||||
import { computeDomain } from "./compute_domain";
|
||||
@ -15,7 +15,7 @@ export const computeAttributeValueDisplay = (
|
||||
const attributeValue =
|
||||
value !== undefined ? value : stateObj.attributes[attribute];
|
||||
const domain = computeDomain(entityId);
|
||||
const entity = entities[entityId] as EntityRegistryEntry | undefined;
|
||||
const entity = entities[entityId] as EntityRegistryDisplayEntry | undefined;
|
||||
const translationKey = entity?.translation_key;
|
||||
|
||||
return (
|
||||
@ -38,7 +38,7 @@ export const computeAttributeNameDisplay = (
|
||||
): string => {
|
||||
const entityId = stateObj.entity_id;
|
||||
const domain = computeDomain(entityId);
|
||||
const entity = entities[entityId] as EntityRegistryEntry | undefined;
|
||||
const entity = entities[entityId] as EntityRegistryDisplayEntry | undefined;
|
||||
const translationKey = entity?.translation_key;
|
||||
|
||||
return (
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { UNAVAILABLE, UNKNOWN } from "../../data/entity";
|
||||
import { EntityRegistryEntry } from "../../data/entity_registry";
|
||||
import { EntityRegistryDisplayEntry } from "../../data/entity_registry";
|
||||
import { FrontendLocaleData } from "../../data/translation";
|
||||
import {
|
||||
updateIsInstallingFromAttributes,
|
||||
@ -49,7 +49,7 @@ export const computeStateDisplayFromEntityAttributes = (
|
||||
return localize(`state.default.${state}`);
|
||||
}
|
||||
|
||||
const entity = entities[entityId] as EntityRegistryEntry | undefined;
|
||||
const entity = entities[entityId] as EntityRegistryDisplayEntry | undefined;
|
||||
|
||||
// Entities with a `unit_of_measurement` or `state_class` are numeric values and should use `formatNumber`
|
||||
if (isNumericFromAttributes(attributes)) {
|
||||
|
@ -2,7 +2,7 @@ import {
|
||||
HassEntity,
|
||||
HassEntityAttributeBase,
|
||||
} from "home-assistant-js-websocket";
|
||||
import { EntityRegistryEntry } from "../../data/entity_registry";
|
||||
import { EntityRegistryDisplayEntry } from "../../data/entity_registry";
|
||||
import { FrontendLocaleData, NumberFormat } from "../../data/translation";
|
||||
import { round } from "./round";
|
||||
|
||||
@ -92,11 +92,9 @@ export const formatNumber = (
|
||||
*/
|
||||
export const getNumberFormatOptions = (
|
||||
entityState: HassEntity,
|
||||
entity?: EntityRegistryEntry
|
||||
entity?: EntityRegistryDisplayEntry
|
||||
): Intl.NumberFormatOptions | undefined => {
|
||||
const precision =
|
||||
entity?.options?.sensor?.display_precision ??
|
||||
entity?.options?.sensor?.suggested_display_precision;
|
||||
const precision = entity?.display_precision;
|
||||
if (precision != null) {
|
||||
return {
|
||||
maximumFractionDigits: precision,
|
||||
|
@ -22,7 +22,7 @@ import {
|
||||
isNumericState,
|
||||
} from "../../common/number/format_number";
|
||||
import { isUnavailableState, UNAVAILABLE, UNKNOWN } from "../../data/entity";
|
||||
import { EntityRegistryEntry } from "../../data/entity_registry";
|
||||
import { EntityRegistryDisplayEntry } from "../../data/entity_registry";
|
||||
import { timerTimeRemaining } from "../../data/timer";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import "../ha-label-badge";
|
||||
@ -160,7 +160,7 @@ export class HaStateLabelBadge extends LitElement {
|
||||
private _computeValue(
|
||||
domain: string,
|
||||
entityState: HassEntity,
|
||||
entry?: EntityRegistryEntry
|
||||
entry?: EntityRegistryDisplayEntry
|
||||
) {
|
||||
switch (domain) {
|
||||
case "alarm_control_panel":
|
||||
@ -200,7 +200,7 @@ export class HaStateLabelBadge extends LitElement {
|
||||
private _computeShowIcon(
|
||||
domain: string,
|
||||
entityState: HassEntity,
|
||||
entry?: EntityRegistryEntry
|
||||
entry?: EntityRegistryDisplayEntry
|
||||
): boolean {
|
||||
if (entityState.state === UNAVAILABLE) {
|
||||
return false;
|
||||
|
@ -12,10 +12,11 @@ import {
|
||||
createAreaRegistryEntry,
|
||||
} from "../data/area_registry";
|
||||
import {
|
||||
DeviceEntityLookup,
|
||||
DeviceEntityDisplayLookup,
|
||||
DeviceRegistryEntry,
|
||||
getDeviceEntityDisplayLookup,
|
||||
} from "../data/device_registry";
|
||||
import { EntityRegistryEntry } from "../data/entity_registry";
|
||||
import { EntityRegistryDisplayEntry } from "../data/entity_registry";
|
||||
import {
|
||||
showAlertDialog,
|
||||
showPromptDialog,
|
||||
@ -113,7 +114,7 @@ export class HaAreaPicker extends LitElement {
|
||||
(
|
||||
areas: AreaRegistryEntry[],
|
||||
devices: DeviceRegistryEntry[],
|
||||
entities: EntityRegistryEntry[],
|
||||
entities: EntityRegistryDisplayEntry[],
|
||||
includeDomains: this["includeDomains"],
|
||||
excludeDomains: this["excludeDomains"],
|
||||
includeDeviceClasses: this["includeDeviceClasses"],
|
||||
@ -133,9 +134,9 @@ export class HaAreaPicker extends LitElement {
|
||||
];
|
||||
}
|
||||
|
||||
const deviceEntityLookup: DeviceEntityLookup = {};
|
||||
let deviceEntityLookup: DeviceEntityDisplayLookup = {};
|
||||
let inputDevices: DeviceRegistryEntry[] | undefined;
|
||||
let inputEntities: EntityRegistryEntry[] | undefined;
|
||||
let inputEntities: EntityRegistryDisplayEntry[] | undefined;
|
||||
|
||||
if (
|
||||
includeDomains ||
|
||||
@ -143,15 +144,7 @@ export class HaAreaPicker extends LitElement {
|
||||
includeDeviceClasses ||
|
||||
entityFilter
|
||||
) {
|
||||
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);
|
||||
}
|
||||
deviceEntityLookup = getDeviceEntityDisplayLookup(entities);
|
||||
}
|
||||
inputDevices = devices;
|
||||
inputEntities = entities.filter((entity) => entity.area_id);
|
||||
|
@ -1,14 +1,10 @@
|
||||
import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { ensureArray } from "../../common/array/ensure-array";
|
||||
import type { DeviceRegistryEntry } from "../../data/device_registry";
|
||||
import { getDeviceIntegrationLookup } from "../../data/device_registry";
|
||||
import {
|
||||
EntityRegistryEntry,
|
||||
subscribeEntityRegistry,
|
||||
} from "../../data/entity_registry";
|
||||
import {
|
||||
EntitySources,
|
||||
fetchEntitySourcesWithCache,
|
||||
@ -18,13 +14,12 @@ import {
|
||||
filterSelectorDevices,
|
||||
filterSelectorEntities,
|
||||
} from "../../data/selector";
|
||||
import { SubscribeMixin } from "../../mixins/subscribe-mixin";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import "../ha-area-picker";
|
||||
import "../ha-areas-picker";
|
||||
|
||||
@customElement("ha-selector-area")
|
||||
export class HaAreaSelector extends SubscribeMixin(LitElement) {
|
||||
export class HaAreaSelector extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
|
||||
@property() public selector!: AreaSelector;
|
||||
@ -41,18 +36,8 @@ export class HaAreaSelector extends SubscribeMixin(LitElement) {
|
||||
|
||||
@state() private _entitySources?: EntitySources;
|
||||
|
||||
@state() private _entities?: EntityRegistryEntry[];
|
||||
|
||||
private _deviceIntegrationLookup = memoizeOne(getDeviceIntegrationLookup);
|
||||
|
||||
public hassSubscribe(): UnsubscribeFunc[] {
|
||||
return [
|
||||
subscribeEntityRegistry(this.hass.connection!, (entities) => {
|
||||
this._entities = entities.filter((entity) => entity.device_id !== null);
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
private _hasIntegration(selector: AreaSelector) {
|
||||
return (
|
||||
(selector.area?.entity &&
|
||||
@ -127,10 +112,12 @@ export class HaAreaSelector extends SubscribeMixin(LitElement) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const deviceIntegrations =
|
||||
this._entitySources && this._entities
|
||||
? this._deviceIntegrationLookup(this._entitySources, this._entities)
|
||||
: undefined;
|
||||
const deviceIntegrations = this._entitySources
|
||||
? this._deviceIntegrationLookup(
|
||||
this._entitySources,
|
||||
Object.values(this.hass.entities)
|
||||
)
|
||||
: undefined;
|
||||
|
||||
return ensureArray(this.selector.area.device).some((filter) =>
|
||||
filterSelectorDevices(filter, device, deviceIntegrations)
|
||||
|
@ -2,12 +2,11 @@ import { html, LitElement, PropertyValues } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { AttributeSelector } from "../../data/selector";
|
||||
import { SubscribeMixin } from "../../mixins/subscribe-mixin";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import "../entity/ha-entity-attribute-picker";
|
||||
|
||||
@customElement("ha-selector-attribute")
|
||||
export class HaSelectorAttribute extends SubscribeMixin(LitElement) {
|
||||
export class HaSelectorAttribute extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public selector!: AttributeSelector;
|
||||
|
@ -1,14 +1,10 @@
|
||||
import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { html, LitElement } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { ensureArray } from "../../common/array/ensure-array";
|
||||
import type { DeviceRegistryEntry } from "../../data/device_registry";
|
||||
import { getDeviceIntegrationLookup } from "../../data/device_registry";
|
||||
import {
|
||||
EntityRegistryEntry,
|
||||
subscribeEntityRegistry,
|
||||
} from "../../data/entity_registry";
|
||||
import {
|
||||
EntitySources,
|
||||
fetchEntitySourcesWithCache,
|
||||
@ -18,21 +14,18 @@ import {
|
||||
filterSelectorDevices,
|
||||
filterSelectorEntities,
|
||||
} from "../../data/selector";
|
||||
import { SubscribeMixin } from "../../mixins/subscribe-mixin";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import "../device/ha-device-picker";
|
||||
import "../device/ha-devices-picker";
|
||||
|
||||
@customElement("ha-selector-device")
|
||||
export class HaDeviceSelector extends SubscribeMixin(LitElement) {
|
||||
export class HaDeviceSelector extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
|
||||
@property() public selector!: DeviceSelector;
|
||||
|
||||
@state() private _entitySources?: EntitySources;
|
||||
|
||||
@state() private _entities?: EntityRegistryEntry[];
|
||||
|
||||
@property() public value?: any;
|
||||
|
||||
@property() public label?: string;
|
||||
@ -45,14 +38,6 @@ export class HaDeviceSelector extends SubscribeMixin(LitElement) {
|
||||
|
||||
private _deviceIntegrationLookup = memoizeOne(getDeviceIntegrationLookup);
|
||||
|
||||
public hassSubscribe(): UnsubscribeFunc[] {
|
||||
return [
|
||||
subscribeEntityRegistry(this.hass.connection!, (entities) => {
|
||||
this._entities = entities.filter((entity) => entity.device_id !== null);
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
private _hasIntegration(selector: DeviceSelector) {
|
||||
return (
|
||||
(selector.device?.filter &&
|
||||
@ -118,10 +103,12 @@ export class HaDeviceSelector extends SubscribeMixin(LitElement) {
|
||||
if (!this.selector.device?.filter) {
|
||||
return true;
|
||||
}
|
||||
const deviceIntegrations =
|
||||
this._entitySources && this._entities
|
||||
? this._deviceIntegrationLookup(this._entitySources, this._entities)
|
||||
: undefined;
|
||||
const deviceIntegrations = this._entitySources
|
||||
? this._deviceIntegrationLookup(
|
||||
this._entitySources,
|
||||
Object.values(this.hass.entities)
|
||||
)
|
||||
: undefined;
|
||||
|
||||
return ensureArray(this.selector.device.filter).some((filter) =>
|
||||
filterSelectorDevices(filter, device, deviceIntegrations)
|
||||
|
@ -1,6 +1,7 @@
|
||||
// @ts-ignore
|
||||
import chipStyles from "@material/chips/dist/mdc.chips.min.css";
|
||||
import "@material/mwc-button/mwc-button";
|
||||
import "@material/mwc-menu/mwc-menu-surface";
|
||||
import {
|
||||
mdiClose,
|
||||
mdiDevices,
|
||||
@ -9,13 +10,14 @@ import {
|
||||
mdiUnfoldMoreVertical,
|
||||
} from "@mdi/js";
|
||||
import "@polymer/paper-tooltip/paper-tooltip";
|
||||
import { ComboBoxLightOpenedChangedEvent } from "@vaadin/combo-box/vaadin-combo-box-light";
|
||||
import { HassEntity, HassServiceTarget } from "home-assistant-js-websocket";
|
||||
import { css, CSSResultGroup, html, LitElement, unsafeCSS } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { ComboBoxLightOpenedChangedEvent } from "@vaadin/combo-box/vaadin-combo-box-light";
|
||||
import { ensureArray } from "../common/array/ensure-array";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import { stopPropagation } from "../common/dom/stop_propagation";
|
||||
import { computeDomain } from "../common/entity/compute_domain";
|
||||
import { computeStateName } from "../common/entity/compute_state_name";
|
||||
import { isValidEntityId } from "../common/entity/valid_entity_id";
|
||||
@ -23,7 +25,7 @@ import {
|
||||
computeDeviceName,
|
||||
DeviceRegistryEntry,
|
||||
} from "../data/device_registry";
|
||||
import { EntityRegistryEntry } from "../data/entity_registry";
|
||||
import { EntityRegistryDisplayEntry } from "../data/entity_registry";
|
||||
import { HomeAssistant } from "../types";
|
||||
import "./device/ha-device-picker";
|
||||
import type { HaDevicePickerDeviceFilterFunc } from "./device/ha-device-picker";
|
||||
@ -33,8 +35,6 @@ import "./ha-area-picker";
|
||||
import "./ha-icon-button";
|
||||
import "./ha-input-helper-text";
|
||||
import "./ha-svg-icon";
|
||||
import { stopPropagation } from "../common/dom/stop_propagation";
|
||||
import "@material/mwc-menu/mwc-menu-surface";
|
||||
|
||||
@customElement("ha-target-picker")
|
||||
export class HaTargetPicker extends LitElement {
|
||||
@ -551,7 +551,7 @@ export class HaTargetPicker extends LitElement {
|
||||
return true;
|
||||
}
|
||||
|
||||
private _entityRegMeetsFilter(entity: EntityRegistryEntry): boolean {
|
||||
private _entityRegMeetsFilter(entity: EntityRegistryDisplayEntry): boolean {
|
||||
if (entity.entity_category) {
|
||||
return false;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
mdiProgressWrench,
|
||||
mdiRecordCircleOutline,
|
||||
} from "@mdi/js";
|
||||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import {
|
||||
css,
|
||||
CSSResultGroup,
|
||||
@ -14,12 +15,16 @@ import {
|
||||
PropertyValues,
|
||||
TemplateResult,
|
||||
} from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { ifDefined } from "lit/directives/if-defined";
|
||||
import { formatDateTimeWithSeconds } from "../../common/datetime/format_date_time";
|
||||
import { relativeTime } from "../../common/datetime/relative_time";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { toggleAttribute } from "../../common/dom/toggle_attribute";
|
||||
import {
|
||||
EntityRegistryEntry,
|
||||
subscribeEntityRegistry,
|
||||
} from "../../data/entity_registry";
|
||||
import { LogbookEntry } from "../../data/logbook";
|
||||
import {
|
||||
ChooseAction,
|
||||
@ -193,6 +198,7 @@ class ActionRenderer {
|
||||
|
||||
constructor(
|
||||
private hass: HomeAssistant,
|
||||
private entityReg: EntityRegistryEntry[],
|
||||
private entries: TemplateResult[],
|
||||
private trace: AutomationTraceExtended,
|
||||
private logbookRenderer: LogbookRenderer,
|
||||
@ -298,7 +304,7 @@ class ActionRenderer {
|
||||
|
||||
this._renderEntry(
|
||||
path,
|
||||
describeAction(this.hass, data, actionType),
|
||||
describeAction(this.hass, this.entityReg, data, actionType),
|
||||
undefined,
|
||||
data.enabled === false
|
||||
);
|
||||
@ -441,7 +447,9 @@ class ActionRenderer {
|
||||
) as RepeatAction;
|
||||
const disabled = repeatConfig.enabled === false;
|
||||
|
||||
const name = repeatConfig.alias || describeAction(this.hass, repeatConfig);
|
||||
const name =
|
||||
repeatConfig.alias ||
|
||||
describeAction(this.hass, this.entityReg, repeatConfig);
|
||||
|
||||
this._renderEntry(repeatPath, name, undefined, disabled);
|
||||
|
||||
@ -577,6 +585,16 @@ export class HaAutomationTracer extends LitElement {
|
||||
|
||||
@property({ type: Boolean }) public allowPick = false;
|
||||
|
||||
@state() private _entityReg: EntityRegistryEntry[] = [];
|
||||
|
||||
public hassSubscribe(): UnsubscribeFunc[] {
|
||||
return [
|
||||
subscribeEntityRegistry(this.hass.connection!, (entities) => {
|
||||
this._entityReg = entities;
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this.trace) {
|
||||
return html``;
|
||||
@ -592,6 +610,7 @@ export class HaAutomationTracer extends LitElement {
|
||||
);
|
||||
const actionRenderer = new ActionRenderer(
|
||||
this.hass,
|
||||
this._entityReg,
|
||||
entries,
|
||||
this.trace,
|
||||
logbookRenderer,
|
||||
|
@ -4,7 +4,10 @@ import { computeStateName } from "../common/entity/compute_state_name";
|
||||
import { caseInsensitiveStringCompare } from "../common/string/compare";
|
||||
import { debounce } from "../common/util/debounce";
|
||||
import type { HomeAssistant } from "../types";
|
||||
import type { EntityRegistryEntry } from "./entity_registry";
|
||||
import type {
|
||||
EntityRegistryDisplayEntry,
|
||||
EntityRegistryEntry,
|
||||
} from "./entity_registry";
|
||||
import type { EntitySources } from "./entity_sources";
|
||||
|
||||
export interface DeviceRegistryEntry {
|
||||
@ -25,6 +28,10 @@ export interface DeviceRegistryEntry {
|
||||
configuration_url: string | null;
|
||||
}
|
||||
|
||||
export interface DeviceEntityDisplayLookup {
|
||||
[deviceId: string]: EntityRegistryDisplayEntry[];
|
||||
}
|
||||
|
||||
export interface DeviceEntityLookup {
|
||||
[deviceId: string]: EntityRegistryEntry[];
|
||||
}
|
||||
@ -147,9 +154,25 @@ export const getDeviceEntityLookup = (
|
||||
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: EntityRegistryEntry[]
|
||||
entities: EntityRegistryDisplayEntry[]
|
||||
): Record<string, string[]> => {
|
||||
const deviceIntegrations: Record<string, string[]> = {};
|
||||
|
||||
|
@ -6,6 +6,35 @@ import { caseInsensitiveStringCompare } from "../common/string/compare";
|
||||
import { debounce } from "../common/util/debounce";
|
||||
import { HomeAssistant } from "../types";
|
||||
|
||||
type entityCategory = "config" | "diagnostic";
|
||||
|
||||
export interface EntityRegistryDisplayEntry {
|
||||
entity_id: string;
|
||||
name?: string;
|
||||
device_id?: string;
|
||||
area_id?: string;
|
||||
hidden?: boolean;
|
||||
entity_category?: entityCategory;
|
||||
translation_key?: string;
|
||||
platform?: string;
|
||||
display_precision?: number;
|
||||
}
|
||||
|
||||
interface EntityRegistryDisplayEntryResponse {
|
||||
entities: {
|
||||
ei: string;
|
||||
di?: string;
|
||||
ai?: string;
|
||||
ec?: number;
|
||||
en?: string;
|
||||
pl?: string;
|
||||
tk?: string;
|
||||
hb?: boolean;
|
||||
dp?: number;
|
||||
}[];
|
||||
entity_categories: Record<number, entityCategory>;
|
||||
}
|
||||
|
||||
export interface EntityRegistryEntry {
|
||||
id: string;
|
||||
entity_id: string;
|
||||
@ -17,7 +46,7 @@ export interface EntityRegistryEntry {
|
||||
area_id: string | null;
|
||||
disabled_by: "user" | "device" | "integration" | "config_entry" | null;
|
||||
hidden_by: Exclude<EntityRegistryEntry["disabled_by"], "config_entry">;
|
||||
entity_category: "config" | "diagnostic" | null;
|
||||
entity_category: entityCategory | null;
|
||||
has_entity_name: boolean;
|
||||
original_name?: string;
|
||||
unique_id: string;
|
||||
@ -154,6 +183,11 @@ export const fetchEntityRegistry = (conn: Connection) =>
|
||||
type: "config/entity_registry/list",
|
||||
});
|
||||
|
||||
export const fetchEntityRegistryDisplay = (conn: Connection) =>
|
||||
conn.sendMessagePromise<EntityRegistryDisplayEntryResponse>({
|
||||
type: "config/entity_registry/list_for_display",
|
||||
});
|
||||
|
||||
const subscribeEntityRegistryUpdates = (
|
||||
conn: Connection,
|
||||
store: Store<EntityRegistryEntry[]>
|
||||
@ -182,6 +216,34 @@ export const subscribeEntityRegistry = (
|
||||
onChange
|
||||
);
|
||||
|
||||
const subscribeEntityRegistryDisplayUpdates = (
|
||||
conn: Connection,
|
||||
store: Store<EntityRegistryDisplayEntryResponse>
|
||||
) =>
|
||||
conn.subscribeEvents(
|
||||
debounce(
|
||||
() =>
|
||||
fetchEntityRegistryDisplay(conn).then((entities) =>
|
||||
store.setState(entities, true)
|
||||
),
|
||||
500,
|
||||
true
|
||||
),
|
||||
"entity_registry_updated"
|
||||
);
|
||||
|
||||
export const subscribeEntityRegistryDisplay = (
|
||||
conn: Connection,
|
||||
onChange: (entities: EntityRegistryDisplayEntryResponse) => void
|
||||
) =>
|
||||
createCollection<EntityRegistryDisplayEntryResponse>(
|
||||
"_entityRegistryDisplay",
|
||||
fetchEntityRegistryDisplay,
|
||||
subscribeEntityRegistryDisplayUpdates,
|
||||
conn,
|
||||
onChange
|
||||
);
|
||||
|
||||
export const sortEntityRegistryByName = (
|
||||
entries: EntityRegistryEntry[],
|
||||
language: string
|
||||
@ -190,10 +252,20 @@ export const sortEntityRegistryByName = (
|
||||
caseInsensitiveStringCompare(entry1.name || "", entry2.name || "", language)
|
||||
);
|
||||
|
||||
export const entityRegistryByEntityId = memoizeOne(
|
||||
(entries: EntityRegistryEntry[]) => {
|
||||
const entities: Record<string, EntityRegistryEntry> = {};
|
||||
for (const entity of entries) {
|
||||
entities[entity.entity_id] = entity;
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
);
|
||||
|
||||
export const entityRegistryById = memoizeOne(
|
||||
(entries: HomeAssistant["entities"]) => {
|
||||
const entities: HomeAssistant["entities"] = {};
|
||||
for (const entity of Object.values(entries)) {
|
||||
(entries: EntityRegistryEntry[]) => {
|
||||
const entities: Record<string, EntityRegistryEntry> = {};
|
||||
for (const entity of entries) {
|
||||
entities[entity.id] = entity;
|
||||
}
|
||||
return entities;
|
||||
|
@ -11,6 +11,7 @@ import { computeDeviceName } from "./device_registry";
|
||||
import {
|
||||
computeEntityRegistryName,
|
||||
entityRegistryById,
|
||||
EntityRegistryEntry,
|
||||
} from "./entity_registry";
|
||||
import { domainToName } from "./integration";
|
||||
import {
|
||||
@ -33,6 +34,7 @@ import {
|
||||
|
||||
export const describeAction = <T extends ActionType>(
|
||||
hass: HomeAssistant,
|
||||
entityRegistry: EntityRegistryEntry[],
|
||||
action: ActionTypes[T],
|
||||
actionType?: T,
|
||||
ignoreAlias = false
|
||||
@ -91,7 +93,7 @@ export const describeAction = <T extends ActionType>(
|
||||
targets.push(targetThing);
|
||||
}
|
||||
} else {
|
||||
const entityReg = entityRegistryById(hass.entities)[targetThing];
|
||||
const entityReg = entityRegistryById(entityRegistry)[targetThing];
|
||||
if (entityReg) {
|
||||
targets.push(
|
||||
computeEntityRegistryName(hass, entityReg) || targetThing
|
||||
|
@ -25,7 +25,11 @@ import "../../components/ha-icon-button";
|
||||
import "../../components/ha-icon-button-prev";
|
||||
import "../../components/ha-list-item";
|
||||
import "../../components/ha-related-items";
|
||||
import { EntityRegistryEntry } from "../../data/entity_registry";
|
||||
import {
|
||||
EntityRegistryEntry,
|
||||
ExtEntityRegistryEntry,
|
||||
getExtendedEntityRegistryEntry,
|
||||
} from "../../data/entity_registry";
|
||||
import { haStyleDialog } from "../../resources/styles";
|
||||
import "../../state-summary/state-card-content";
|
||||
import { HomeAssistant } from "../../types";
|
||||
@ -77,6 +81,8 @@ export class MoreInfoDialog extends LitElement {
|
||||
|
||||
@state() private _childView?: ChildView;
|
||||
|
||||
@state() private _entry?: ExtEntityRegistryEntry;
|
||||
|
||||
public showDialog(params: MoreInfoDialogParams) {
|
||||
this._entityId = params.entityId;
|
||||
if (!this._entityId) {
|
||||
@ -86,10 +92,22 @@ export class MoreInfoDialog extends LitElement {
|
||||
this._currView = params.view || "info";
|
||||
this._childView = undefined;
|
||||
this.large = false;
|
||||
this._loadEntityRegistryEntry();
|
||||
}
|
||||
|
||||
private async _loadEntityRegistryEntry() {
|
||||
if (!this._entityId) {
|
||||
return;
|
||||
}
|
||||
this._entry = await getExtendedEntityRegistryEntry(
|
||||
this.hass,
|
||||
this._entityId
|
||||
);
|
||||
}
|
||||
|
||||
public closeDialog() {
|
||||
this._entityId = undefined;
|
||||
this._entry = undefined;
|
||||
this._childView = undefined;
|
||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||
}
|
||||
@ -172,7 +190,10 @@ export class MoreInfoDialog extends LitElement {
|
||||
idToPassThroughUrl = stateObj.attributes.id;
|
||||
}
|
||||
if (EDITABLE_DOMAINS_WITH_UNIQUE_ID.includes(domain)) {
|
||||
idToPassThroughUrl = this.hass.entities[this._entityId!].unique_id;
|
||||
if (!this._entry) {
|
||||
return;
|
||||
}
|
||||
idToPassThroughUrl = this._entry.unique_id;
|
||||
}
|
||||
|
||||
navigate(`/config/${domain}/edit/${idToPassThroughUrl}`);
|
||||
@ -358,6 +379,8 @@ export class MoreInfoDialog extends LitElement {
|
||||
<ha-more-info-settings
|
||||
.hass=${this.hass}
|
||||
.entityId=${this._entityId}
|
||||
.entry=${this._entry}
|
||||
@entity-entry-updated=${this._entryUpdated}
|
||||
></ha-more-info-settings>
|
||||
`
|
||||
: this._currView === "related"
|
||||
@ -387,6 +410,10 @@ export class MoreInfoDialog extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
private _entryUpdated(ev: CustomEvent<ExtEntityRegistryEntry>) {
|
||||
this._entry = ev.detail;
|
||||
}
|
||||
|
||||
private _enlarge() {
|
||||
this.large = !this.large;
|
||||
}
|
||||
|
@ -6,12 +6,11 @@ import { dynamicElement } from "../../common/dom/dynamic-element-directive";
|
||||
import {
|
||||
EntityRegistryEntry,
|
||||
ExtEntityRegistryEntry,
|
||||
getExtendedEntityRegistryEntry,
|
||||
} from "../../data/entity_registry";
|
||||
import { PLATFORMS_WITH_SETTINGS_TAB } from "../../panels/config/entities/const";
|
||||
import "../../panels/config/entities/entity-registry-settings";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import { documentationUrl } from "../../util/documentation-url";
|
||||
import "../../panels/config/entities/entity-registry-settings";
|
||||
|
||||
@customElement("ha-more-info-settings")
|
||||
export class HaMoreInfoSettings extends LitElement {
|
||||
@ -19,18 +18,18 @@ export class HaMoreInfoSettings extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public entityId!: string;
|
||||
|
||||
@state() private _entry?: EntityRegistryEntry | ExtEntityRegistryEntry | null;
|
||||
@state() private entry?: EntityRegistryEntry | ExtEntityRegistryEntry | null;
|
||||
|
||||
@state() private _settingsElementTag?: string;
|
||||
|
||||
protected render() {
|
||||
// loading.
|
||||
if (this._entry === undefined) {
|
||||
if (this.entry === undefined) {
|
||||
return html``;
|
||||
}
|
||||
|
||||
// No unique ID
|
||||
if (this._entry === null) {
|
||||
if (this.entry === null) {
|
||||
return html`
|
||||
<div class="content">
|
||||
${this.hass.localize(
|
||||
@ -54,53 +53,31 @@ export class HaMoreInfoSettings extends LitElement {
|
||||
}
|
||||
|
||||
return html`
|
||||
<div @entity-entry-updated=${this._entryUpdated}>
|
||||
${dynamicElement(this._settingsElementTag, {
|
||||
hass: this.hass,
|
||||
entry: this._entry,
|
||||
entityId: this.entityId,
|
||||
})}
|
||||
</div>
|
||||
${dynamicElement(this._settingsElementTag, {
|
||||
hass: this.hass,
|
||||
entry: this.entry,
|
||||
entityId: this.entityId,
|
||||
})}
|
||||
`;
|
||||
}
|
||||
|
||||
protected willUpdate(changedProps: PropertyValues) {
|
||||
super.willUpdate(changedProps);
|
||||
if (changedProps.has("entityId")) {
|
||||
this._entry = undefined;
|
||||
if (this.entityId) {
|
||||
this._getEntityReg();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async _getEntityReg() {
|
||||
try {
|
||||
this._entry = await getExtendedEntityRegistryEntry(
|
||||
this.hass,
|
||||
this.entityId
|
||||
);
|
||||
public willUpdate(changedProps: PropertyValues) {
|
||||
if (changedProps.has("entry")) {
|
||||
this._loadPlatformSettingTabs();
|
||||
} catch {
|
||||
this._entry = null;
|
||||
}
|
||||
}
|
||||
|
||||
private _entryUpdated(ev: CustomEvent<ExtEntityRegistryEntry>) {
|
||||
this._entry = ev.detail;
|
||||
}
|
||||
|
||||
private async _loadPlatformSettingTabs(): Promise<void> {
|
||||
if (!this._entry) {
|
||||
if (!this.entry) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
!Object.keys(PLATFORMS_WITH_SETTINGS_TAB).includes(this._entry.platform)
|
||||
!Object.keys(PLATFORMS_WITH_SETTINGS_TAB).includes(this.entry.platform)
|
||||
) {
|
||||
this._settingsElementTag = "entity-registry-settings";
|
||||
return;
|
||||
}
|
||||
const tag = PLATFORMS_WITH_SETTINGS_TAB[this._entry.platform];
|
||||
const tag = PLATFORMS_WITH_SETTINGS_TAB[this.entry.platform];
|
||||
await import(`../../panels/config/entities/editor-tabs/settings/${tag}`);
|
||||
this._settingsElementTag = tag;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import {
|
||||
mdiStopCircleOutline,
|
||||
mdiSort,
|
||||
} from "@mdi/js";
|
||||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import { css, CSSResultGroup, html, LitElement, PropertyValues } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
@ -26,6 +27,10 @@ import "../../../../components/ha-icon-button";
|
||||
import type { HaYamlEditor } from "../../../../components/ha-yaml-editor";
|
||||
import { ACTION_TYPES } from "../../../../data/action";
|
||||
import { validateConfig } from "../../../../data/config";
|
||||
import {
|
||||
EntityRegistryEntry,
|
||||
subscribeEntityRegistry,
|
||||
} from "../../../../data/entity_registry";
|
||||
import { Action, getActionType } from "../../../../data/script";
|
||||
import { describeAction } from "../../../../data/script_i18n";
|
||||
import { callExecuteScript } from "../../../../data/service";
|
||||
@ -107,6 +112,8 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
|
||||
@property({ type: Boolean }) public reOrderMode = false;
|
||||
|
||||
@state() private _entityReg: EntityRegistryEntry[] = [];
|
||||
|
||||
@state() private _warnings?: string[];
|
||||
|
||||
@state() private _uiModeAvailable = true;
|
||||
@ -115,6 +122,14 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
|
||||
@query("ha-yaml-editor") private _yamlEditor?: HaYamlEditor;
|
||||
|
||||
public hassSubscribe(): UnsubscribeFunc[] {
|
||||
return [
|
||||
subscribeEntityRegistry(this.hass.connection!, (entities) => {
|
||||
this._entityReg = entities;
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
protected willUpdate(changedProperties: PropertyValues) {
|
||||
if (!changedProperties.has("action")) {
|
||||
return;
|
||||
@ -156,7 +171,9 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
class="action-icon"
|
||||
.path=${ACTION_TYPES[type!]}
|
||||
></ha-svg-icon>
|
||||
${capitalizeFirstLetter(describeAction(this.hass, this.action))}
|
||||
${capitalizeFirstLetter(
|
||||
describeAction(this.hass, this._entityReg, this.action)
|
||||
)}
|
||||
</h3>
|
||||
|
||||
<slot name="icons" slot="icons"></slot>
|
||||
@ -465,7 +482,7 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
),
|
||||
inputType: "string",
|
||||
placeholder: capitalizeFirstLetter(
|
||||
describeAction(this.hass, this.action, undefined, true)
|
||||
describeAction(this.hass, this._entityReg, this.action, undefined, true)
|
||||
),
|
||||
defaultValue: this.action.alias,
|
||||
confirmText: this.hass.localize("ui.common.submit"),
|
||||
|
@ -49,6 +49,7 @@ import {
|
||||
showAutomationEditor,
|
||||
triggerAutomationActions,
|
||||
} from "../../../data/automation";
|
||||
import { fetchEntityRegistry } from "../../../data/entity_registry";
|
||||
import {
|
||||
showAlertDialog,
|
||||
showConfirmationDialog,
|
||||
@ -479,7 +480,8 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
|
||||
this._readOnly = false;
|
||||
this._config = this._normalizeConfig(config);
|
||||
} catch (err: any) {
|
||||
const entity = Object.values(this.hass.entities).find(
|
||||
const entityRegistry = await fetchEntityRegistry(this.hass.connection);
|
||||
const entity = entityRegistry.find(
|
||||
(ent) =>
|
||||
ent.platform === "automation" && ent.unique_id === this.automationId
|
||||
);
|
||||
|
@ -1,14 +1,19 @@
|
||||
import { HassEntities } from "home-assistant-js-websocket";
|
||||
import { HassEntities, UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import { PropertyValues } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
||||
import { debounce } from "../../../common/util/debounce";
|
||||
import {
|
||||
EntityRegistryEntry,
|
||||
subscribeEntityRegistry,
|
||||
} from "../../../data/entity_registry";
|
||||
import { ScriptEntity } from "../../../data/script";
|
||||
import {
|
||||
HassRouterPage,
|
||||
RouterOptions,
|
||||
} from "../../../layouts/hass-router-page";
|
||||
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import "./ha-script-editor";
|
||||
import "./ha-script-picker";
|
||||
@ -21,7 +26,7 @@ const equal = (a: ScriptEntity[], b: ScriptEntity[]): boolean => {
|
||||
};
|
||||
|
||||
@customElement("ha-config-script")
|
||||
class HaConfigScript extends HassRouterPage {
|
||||
class HaConfigScript extends SubscribeMixin(HassRouterPage) {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property() public narrow!: boolean;
|
||||
@ -32,6 +37,16 @@ class HaConfigScript extends HassRouterPage {
|
||||
|
||||
@property() public scripts: ScriptEntity[] = [];
|
||||
|
||||
@state() private _entityReg: EntityRegistryEntry[] = [];
|
||||
|
||||
public hassSubscribe(): UnsubscribeFunc[] {
|
||||
return [
|
||||
subscribeEntityRegistry(this.hass.connection!, (entities) => {
|
||||
this._entityReg = entities;
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
protected routerOptions: RouterOptions = {
|
||||
defaultPage: "dashboard",
|
||||
routes: {
|
||||
@ -78,6 +93,7 @@ class HaConfigScript extends HassRouterPage {
|
||||
pageEl.isWide = this.isWide;
|
||||
pageEl.route = this.routeTail;
|
||||
pageEl.showAdvanced = this.showAdvanced;
|
||||
pageEl.entityRegistry = this._entityReg;
|
||||
|
||||
if (this.hass) {
|
||||
if (!pageEl.scripts || !changedProps) {
|
||||
|
@ -39,6 +39,7 @@ import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-svg-icon";
|
||||
import "../../../components/ha-yaml-editor";
|
||||
import type { HaYamlEditor } from "../../../components/ha-yaml-editor";
|
||||
import { EntityRegistryEntry } from "../../../data/entity_registry";
|
||||
import {
|
||||
deleteScript,
|
||||
getScriptStateConfig,
|
||||
@ -75,6 +76,8 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) {
|
||||
|
||||
@property({ type: Boolean }) public narrow!: boolean;
|
||||
|
||||
@property({ attribute: false }) public entityRegistry!: EntityRegistryEntry[];
|
||||
|
||||
@state() private _config?: ScriptConfig;
|
||||
|
||||
@state() private _entityId?: string;
|
||||
@ -431,7 +434,7 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) {
|
||||
this._config = this._normalizeConfig(config);
|
||||
},
|
||||
(resp) => {
|
||||
const entity = Object.values(this.hass.entities).find(
|
||||
const entity = this.entityRegistry.find(
|
||||
(ent) =>
|
||||
ent.platform === "script" && ent.unique_id === this.scriptId
|
||||
);
|
||||
@ -477,7 +480,9 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) {
|
||||
getScriptStateConfig(this.hass, this.entityId).then((c) => {
|
||||
this._config = this._normalizeConfig(c.config);
|
||||
});
|
||||
const regEntry = this.hass.entities[this.entityId];
|
||||
const regEntry = this.entityRegistry.find(
|
||||
(ent) => ent.entity_id === this.entityId
|
||||
);
|
||||
if (regEntry?.unique_id) {
|
||||
this.scriptId = regEntry.unique_id;
|
||||
}
|
||||
@ -544,7 +549,7 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) {
|
||||
if (!this.scriptId) {
|
||||
return;
|
||||
}
|
||||
const entity = Object.values(this.hass.entities).find(
|
||||
const entity = this.entityRegistry.find(
|
||||
(entry) => entry.unique_id === this.scriptId
|
||||
);
|
||||
if (!entity) {
|
||||
|
@ -44,6 +44,7 @@ import { HomeAssistant, Route } from "../../../types";
|
||||
import { documentationUrl } from "../../../util/documentation-url";
|
||||
import { showToast } from "../../../util/toast";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
import { EntityRegistryEntry } from "../../../data/entity_registry";
|
||||
|
||||
@customElement("ha-script-picker")
|
||||
class HaScriptPicker extends LitElement {
|
||||
@ -57,7 +58,9 @@ class HaScriptPicker extends LitElement {
|
||||
|
||||
@property() public route!: Route;
|
||||
|
||||
@property() private _activeFilters?: string[];
|
||||
@property({ attribute: false }) public entityRegistry!: EntityRegistryEntry[];
|
||||
|
||||
@state() private _activeFilters?: string[];
|
||||
|
||||
@state() private _filteredScripts?: string[] | null;
|
||||
|
||||
@ -266,7 +269,7 @@ class HaScriptPicker extends LitElement {
|
||||
}
|
||||
|
||||
private _handleRowClicked(ev: HASSDomEvent<RowClickedEvent>) {
|
||||
const entry = this.hass.entities[ev.detail.id];
|
||||
const entry = this.entityRegistry.find((e) => e.entity_id === ev.detail.id);
|
||||
if (entry) {
|
||||
navigate(`/config/script/edit/${entry.unique_id}`);
|
||||
} else {
|
||||
@ -275,7 +278,12 @@ class HaScriptPicker extends LitElement {
|
||||
}
|
||||
|
||||
private _runScript = async (script: any) => {
|
||||
const entry = this.hass.entities[script.entity_id];
|
||||
const entry = this.entityRegistry.find(
|
||||
(e) => e.entity_id === script.entity_id
|
||||
);
|
||||
if (!entry) {
|
||||
return;
|
||||
}
|
||||
await triggerScript(this.hass, entry.unique_id);
|
||||
showToast(this, {
|
||||
message: this.hass.localize(
|
||||
@ -291,7 +299,9 @@ class HaScriptPicker extends LitElement {
|
||||
}
|
||||
|
||||
private _showTrace(script: any) {
|
||||
const entry = this.hass.entities[script.entity_id];
|
||||
const entry = this.entityRegistry.find(
|
||||
(e) => e.entity_id === script.entity_id
|
||||
);
|
||||
if (entry) {
|
||||
navigate(`/config/script/trace/${entry.unique_id}`);
|
||||
}
|
||||
@ -317,7 +327,12 @@ class HaScriptPicker extends LitElement {
|
||||
|
||||
private async _duplicate(script: any) {
|
||||
try {
|
||||
const entry = this.hass.entities[script.entity_id];
|
||||
const entry = this.entityRegistry.find(
|
||||
(e) => e.entity_id === script.entity_id
|
||||
);
|
||||
if (!entry) {
|
||||
return;
|
||||
}
|
||||
const config = await fetchScriptFileConfig(this.hass, entry.unique_id);
|
||||
showScriptEditor({
|
||||
...config,
|
||||
@ -362,8 +377,12 @@ class HaScriptPicker extends LitElement {
|
||||
|
||||
private async _delete(script: any) {
|
||||
try {
|
||||
const entry = this.hass.entities[script.entity_id];
|
||||
await deleteScript(this.hass, entry.unique_id);
|
||||
const entry = this.entityRegistry.find(
|
||||
(e) => e.entity_id === script.entity_id
|
||||
);
|
||||
if (entry) {
|
||||
await deleteScript(this.hass, entry.unique_id);
|
||||
}
|
||||
} catch (err: any) {
|
||||
await showAlertDialog(this, {
|
||||
text:
|
||||
|
@ -39,6 +39,7 @@ import { HomeAssistant, Route } from "../../../types";
|
||||
import "../../../layouts/hass-subpage";
|
||||
import "../../../components/ha-button-menu";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { EntityRegistryEntry } from "../../../data/entity_registry";
|
||||
|
||||
@customElement("ha-script-trace")
|
||||
export class HaScriptTrace extends LitElement {
|
||||
@ -54,6 +55,8 @@ export class HaScriptTrace extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public route!: Route;
|
||||
|
||||
@property({ attribute: false }) public entityRegistry!: EntityRegistryEntry[];
|
||||
|
||||
@state() private _entityId?: string;
|
||||
|
||||
@state() private _traces?: ScriptTrace[];
|
||||
@ -318,7 +321,7 @@ export class HaScriptTrace extends LitElement {
|
||||
const params = new URLSearchParams(location.search);
|
||||
this._loadTraces(params.get("run_id") || undefined);
|
||||
|
||||
this._entityId = Object.values(this.hass.entities).find(
|
||||
this._entityId = this.entityRegistry.find(
|
||||
(entry) => entry.unique_id === this.scriptId
|
||||
)?.entity_id;
|
||||
}
|
||||
@ -335,7 +338,7 @@ export class HaScriptTrace extends LitElement {
|
||||
if (this.scriptId) {
|
||||
this._loadTraces();
|
||||
|
||||
this._entityId = Object.values(this.hass.entities).find(
|
||||
this._entityId = this.entityRegistry.find(
|
||||
(entry) => entry.unique_id === this.scriptId
|
||||
)?.entity_id;
|
||||
}
|
||||
|
@ -130,7 +130,10 @@ class HuiGaugeCard extends LitElement implements LovelaceCard {
|
||||
.min=${this._config.min!}
|
||||
.max=${this._config.max!}
|
||||
.value=${stateObj.state}
|
||||
.formatOptions=${getNumberFormatOptions(stateObj)}
|
||||
.formatOptions=${getNumberFormatOptions(
|
||||
stateObj,
|
||||
this.hass.entities[stateObj.entity_id]
|
||||
)}
|
||||
.locale=${this.hass!.locale}
|
||||
.label=${this._config!.unit ||
|
||||
this.hass?.states[this._config!.entity].attributes
|
||||
|
@ -278,8 +278,8 @@ const computeDefaultViewStates = (
|
||||
.filter(
|
||||
(entry) =>
|
||||
entry.entity_category ||
|
||||
HIDE_PLATFORM.has(entry.platform) ||
|
||||
entry.hidden_by
|
||||
(entry.platform && HIDE_PLATFORM.has(entry.platform)) ||
|
||||
entry.hidden
|
||||
)
|
||||
.map((entry) => entry.entity_id)
|
||||
);
|
||||
|
@ -14,7 +14,7 @@ import { polyfillsLoaded } from "../common/translations/localize";
|
||||
import { subscribeAreaRegistry } from "../data/area_registry";
|
||||
import { broadcastConnectionStatus } from "../data/connection-status";
|
||||
import { subscribeDeviceRegistry } from "../data/device_registry";
|
||||
import { subscribeEntityRegistry } from "../data/entity_registry";
|
||||
import { subscribeEntityRegistryDisplay } from "../data/entity_registry";
|
||||
import { subscribeFrontendUserData } from "../data/frontend";
|
||||
import { forwardHaptic } from "../data/haptics";
|
||||
import { DEFAULT_PANEL } from "../data/panel";
|
||||
@ -188,10 +188,22 @@ export const connectionMixin = <T extends Constructor<HassBaseEl>>(
|
||||
});
|
||||
|
||||
subscribeEntities(conn, (states) => this._updateHass({ states }));
|
||||
subscribeEntityRegistry(conn, (entityReg) => {
|
||||
subscribeEntityRegistryDisplay(conn, (entityReg) => {
|
||||
const entities: HomeAssistant["entities"] = {};
|
||||
for (const entity of entityReg) {
|
||||
entities[entity.entity_id] = entity;
|
||||
for (const entity of entityReg.entities) {
|
||||
entities[entity.ei] = {
|
||||
entity_id: entity.ei,
|
||||
device_id: entity.di,
|
||||
area_id: entity.ai,
|
||||
translation_key: entity.tk,
|
||||
platform: entity.pl,
|
||||
entity_category: entity.ec
|
||||
? entityReg.entity_categories[entity.ec]
|
||||
: undefined,
|
||||
name: entity.en,
|
||||
hidden: entity.hb,
|
||||
display_precision: entity.dp,
|
||||
};
|
||||
}
|
||||
this._updateHass({ entities });
|
||||
});
|
||||
|
@ -10,7 +10,7 @@ import {
|
||||
import { LocalizeFunc } from "./common/translations/localize";
|
||||
import { AreaRegistryEntry } from "./data/area_registry";
|
||||
import { DeviceRegistryEntry } from "./data/device_registry";
|
||||
import { EntityRegistryEntry } from "./data/entity_registry";
|
||||
import { EntityRegistryDisplayEntry } from "./data/entity_registry";
|
||||
import { CoreFrontendUserData } from "./data/frontend";
|
||||
import { FrontendLocaleData, getHassTranslations } from "./data/translation";
|
||||
import { Themes } from "./data/ws-themes";
|
||||
@ -189,7 +189,7 @@ export interface HomeAssistant {
|
||||
connection: Connection;
|
||||
connected: boolean;
|
||||
states: HassEntities;
|
||||
entities: { [id: string]: EntityRegistryEntry };
|
||||
entities: { [id: string]: EntityRegistryDisplayEntry };
|
||||
devices: { [id: string]: DeviceRegistryEntry };
|
||||
areas: { [id: string]: AreaRegistryEntry };
|
||||
services: HassServices;
|
||||
|
Loading…
Reference in New Issue
Block a user