diff --git a/gallery/src/pages/automation/describe-action.ts b/gallery/src/pages/automation/describe-action.ts
index 7deccf6927..3340429dc4 100644
--- a/gallery/src/pages/automation/describe-action.ts
+++ b/gallery/src/pages/automation/describe-action.ts
@@ -136,7 +136,7 @@ export class DemoAutomationDescribeAction extends LitElement {
${this._action
- ? describeAction(this.hass, [], this._action)
+ ? describeAction(this.hass, [], [], [], this._action)
: ""}
html`
-
${describeAction(this.hass, [], conf as any)}
+
${describeAction(this.hass, [], [], [], conf as any)}
${dump(conf)}
`
diff --git a/src/components/trace/hat-trace-timeline.ts b/src/components/trace/hat-trace-timeline.ts
index 78eb1ec8e1..eab5998d1d 100644
--- a/src/components/trace/hat-trace-timeline.ts
+++ b/src/components/trace/hat-trace-timeline.ts
@@ -1,3 +1,4 @@
+import { consume } from "@lit-labs/context";
import {
mdiAlertCircle,
mdiCircle,
@@ -6,14 +7,13 @@ import {
mdiProgressWrench,
mdiRecordCircleOutline,
} from "@mdi/js";
-import { UnsubscribeFunc } from "home-assistant-js-websocket";
import {
- css,
CSSResultGroup,
- html,
LitElement,
PropertyValues,
TemplateResult,
+ css,
+ html,
nothing,
} from "lit";
import { customElement, property, state } from "lit/decorators";
@@ -23,27 +23,31 @@ 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";
+ floorsContext,
+ fullEntitiesContext,
+ labelsContext,
+} from "../../data/context";
+import { EntityRegistryEntry } from "../../data/entity_registry";
+import { FloorRegistryEntry } from "../../data/floor_registry";
+import { LabelRegistryEntry } from "../../data/label_registry";
import { LogbookEntry } from "../../data/logbook";
import {
ChooseAction,
ChooseActionChoice,
- getActionType,
IfAction,
ParallelAction,
RepeatAction,
+ getActionType,
} from "../../data/script";
import { describeAction } from "../../data/script_i18n";
import {
ActionTraceStep,
AutomationTraceExtended,
ChooseActionTraceStep,
- getDataFromPath,
IfActionTraceStep,
- isTriggerPath,
TriggerTraceStep,
+ getDataFromPath,
+ isTriggerPath,
} from "../../data/trace";
import { HomeAssistant } from "../../types";
import "./ha-timeline";
@@ -200,6 +204,8 @@ class ActionRenderer {
constructor(
private hass: HomeAssistant,
private entityReg: EntityRegistryEntry[],
+ private labelReg: LabelRegistryEntry[],
+ private floorReg: FloorRegistryEntry[],
private entries: TemplateResult[],
private trace: AutomationTraceExtended,
private logbookRenderer: LogbookRenderer,
@@ -310,7 +316,14 @@ class ActionRenderer {
this._renderEntry(
path,
- describeAction(this.hass, this.entityReg, data, actionType),
+ describeAction(
+ this.hass,
+ this.entityReg,
+ this.labelReg,
+ this.floorReg,
+ data,
+ actionType
+ ),
undefined,
data.enabled === false
);
@@ -475,7 +488,13 @@ class ActionRenderer {
const name =
repeatConfig.alias ||
- describeAction(this.hass, this.entityReg, repeatConfig);
+ describeAction(
+ this.hass,
+ this.entityReg,
+ this.labelReg,
+ this.floorReg,
+ repeatConfig
+ );
this._renderEntry(repeatPath, name, undefined, disabled);
@@ -631,15 +650,17 @@ export class HaAutomationTracer extends LitElement {
@property({ type: Boolean }) public allowPick = false;
- @state() private _entityReg: EntityRegistryEntry[] = [];
+ @state()
+ @consume({ context: fullEntitiesContext, subscribe: true })
+ _entityReg!: EntityRegistryEntry[];
- public hassSubscribe(): UnsubscribeFunc[] {
- return [
- subscribeEntityRegistry(this.hass.connection!, (entities) => {
- this._entityReg = entities;
- }),
- ];
- }
+ @state()
+ @consume({ context: labelsContext, subscribe: true })
+ _labelReg!: LabelRegistryEntry[];
+
+ @state()
+ @consume({ context: floorsContext, subscribe: true })
+ _floorReg!: FloorRegistryEntry[];
protected render() {
if (!this.trace) {
@@ -657,6 +678,8 @@ export class HaAutomationTracer extends LitElement {
const actionRenderer = new ActionRenderer(
this.hass,
this._entityReg,
+ this._labelReg,
+ this._floorReg,
entries,
this.trace,
logbookRenderer,
diff --git a/src/data/context.ts b/src/data/context.ts
index b5d914522c..75ebe5ae3d 100644
--- a/src/data/context.ts
+++ b/src/data/context.ts
@@ -2,6 +2,8 @@ import { createContext } from "@lit-labs/context";
import { HassConfig } from "home-assistant-js-websocket";
import { HomeAssistant } from "../types";
import { EntityRegistryEntry } from "./entity_registry";
+import { FloorRegistryEntry } from "./floor_registry";
+import { LabelRegistryEntry } from "./label_registry";
export const connectionContext =
createContext("connection");
@@ -25,3 +27,7 @@ export const panelsContext = createContext("panels");
export const fullEntitiesContext =
createContext("extendedEntities");
+
+export const floorsContext = createContext("floors");
+
+export const labelsContext = createContext("labels");
diff --git a/src/data/script_i18n.ts b/src/data/script_i18n.ts
index 22d5e3c0a7..b08cb49c49 100644
--- a/src/data/script_i18n.ts
+++ b/src/data/script_i18n.ts
@@ -14,7 +14,9 @@ import {
computeEntityRegistryName,
entityRegistryById,
} from "./entity_registry";
+import { FloorRegistryEntry } from "./floor_registry";
import { domainToName } from "./integration";
+import { LabelRegistryEntry } from "./label_registry";
import {
ActionType,
ActionTypes,
@@ -40,6 +42,8 @@ const actionTranslationBaseKey =
export const describeAction = (
hass: HomeAssistant,
entityRegistry: EntityRegistryEntry[],
+ labelRegistry: LabelRegistryEntry[],
+ floorRegistry: FloorRegistryEntry[],
action: ActionTypes[T],
actionType?: T,
ignoreAlias = false
@@ -48,6 +52,8 @@ export const describeAction = (
return tryDescribeAction(
hass,
entityRegistry,
+ labelRegistry,
+ floorRegistry,
action,
actionType,
ignoreAlias
@@ -66,6 +72,8 @@ export const describeAction = (
const tryDescribeAction = (
hass: HomeAssistant,
entityRegistry: EntityRegistryEntry[],
+ labelRegistry: LabelRegistryEntry[],
+ floorRegistry: FloorRegistryEntry[],
action: ActionTypes[T],
actionType?: T,
ignoreAlias = false
@@ -82,10 +90,12 @@ const tryDescribeAction = (
const targets: string[] = [];
if (config.target) {
- for (const [key, label] of Object.entries({
+ for (const [key, name] of Object.entries({
area_id: "areas",
device_id: "devices",
entity_id: "entities",
+ floor_id: "floors",
+ label_id: "labels",
})) {
if (!(key in config.target)) {
continue;
@@ -99,7 +109,7 @@ const tryDescribeAction = (
targets.push(
hass.localize(
`${actionTranslationBaseKey}.service.description.target_template`,
- { name: label }
+ { name }
)
);
break;
@@ -147,6 +157,32 @@ const tryDescribeAction = (
)
);
}
+ } else if (key === "floor_id") {
+ const floor = floorRegistry.find(
+ (flr) => flr.floor_id === targetThing
+ );
+ if (floor?.name) {
+ targets.push(floor.name);
+ } else {
+ targets.push(
+ hass.localize(
+ `${actionTranslationBaseKey}.service.description.target_unknown_floor`
+ )
+ );
+ }
+ } else if (key === "label_id") {
+ const label = labelRegistry.find(
+ (lbl) => lbl.label_id === targetThing
+ );
+ if (label?.name) {
+ targets.push(label.name);
+ } else {
+ targets.push(
+ hass.localize(
+ `${actionTranslationBaseKey}.service.description.target_unknown_label`
+ )
+ );
+ }
} else {
targets.push(targetThing);
}
diff --git a/src/panels/config/automation/action/ha-automation-action-row.ts b/src/panels/config/automation/action/ha-automation-action-row.ts
index 6986aba974..bac8c011fb 100644
--- a/src/panels/config/automation/action/ha-automation-action-row.ts
+++ b/src/panels/config/automation/action/ha-automation-action-row.ts
@@ -42,8 +42,14 @@ import type { HaYamlEditor } from "../../../../components/ha-yaml-editor";
import { ACTION_ICONS, YAML_ONLY_ACTION_TYPES } from "../../../../data/action";
import { AutomationClipboard } from "../../../../data/automation";
import { validateConfig } from "../../../../data/config";
-import { fullEntitiesContext } from "../../../../data/context";
+import {
+ floorsContext,
+ fullEntitiesContext,
+ labelsContext,
+} from "../../../../data/context";
import { EntityRegistryEntry } from "../../../../data/entity_registry";
+import { FloorRegistryEntry } from "../../../../data/floor_registry";
+import { LabelRegistryEntry } from "../../../../data/label_registry";
import {
Action,
NonConditionAction,
@@ -146,6 +152,14 @@ export default class HaAutomationActionRow extends LitElement {
@consume({ context: fullEntitiesContext, subscribe: true })
_entityReg!: EntityRegistryEntry[];
+ @state()
+ @consume({ context: labelsContext, subscribe: true })
+ _labelReg!: LabelRegistryEntry[];
+
+ @state()
+ @consume({ context: floorsContext, subscribe: true })
+ _floorReg!: FloorRegistryEntry[];
+
@state() private _warnings?: string[];
@state() private _uiModeAvailable = true;
@@ -210,7 +224,13 @@ export default class HaAutomationActionRow extends LitElement {
.path=${ACTION_ICONS[type!]}
>`}
${capitalizeFirstLetter(
- describeAction(this.hass, this._entityReg, this.action)
+ describeAction(
+ this.hass,
+ this._entityReg,
+ this._labelReg,
+ this._floorReg,
+ this.action
+ )
)}
@@ -573,7 +593,15 @@ export default class HaAutomationActionRow extends LitElement {
),
inputType: "string",
placeholder: capitalizeFirstLetter(
- describeAction(this.hass, this._entityReg, this.action, undefined, true)
+ describeAction(
+ this.hass,
+ this._entityReg,
+ this._labelReg,
+ this._floorReg,
+ this.action,
+ undefined,
+ true
+ )
),
defaultValue: this.action.alias,
confirmText: this.hass.localize("ui.common.submit"),
diff --git a/src/panels/config/ha-panel-config.ts b/src/panels/config/ha-panel-config.ts
index f7fd2fd195..fe3151b260 100644
--- a/src/panels/config/ha-panel-config.ts
+++ b/src/panels/config/ha-panel-config.ts
@@ -35,7 +35,11 @@ import { customElement, property, state } from "lit/decorators";
import { isComponentLoaded } from "../../common/config/is_component_loaded";
import { listenMediaQuery } from "../../common/dom/media_query";
import { CloudStatus, fetchCloudStatus } from "../../data/cloud";
-import { fullEntitiesContext } from "../../data/context";
+import {
+ floorsContext,
+ fullEntitiesContext,
+ labelsContext,
+} from "../../data/context";
import {
entityRegistryByEntityId,
entityRegistryById,
@@ -45,6 +49,8 @@ import { HassRouterPage, RouterOptions } from "../../layouts/hass-router-page";
import { PageNavigation } from "../../layouts/hass-tabs-subpage";
import { SubscribeMixin } from "../../mixins/subscribe-mixin";
import { HomeAssistant, Route } from "../../types";
+import { subscribeLabelRegistry } from "../../data/label_registry";
+import { subscribeFloorRegistry } from "../../data/floor_registry";
declare global {
// for fire event
@@ -379,11 +385,27 @@ class HaPanelConfig extends SubscribeMixin(HassRouterPage) {
initialValue: [],
});
+ private _labelsContext = new ContextProvider(this, {
+ context: labelsContext,
+ initialValue: [],
+ });
+
+ private _floorsContext = new ContextProvider(this, {
+ context: floorsContext,
+ initialValue: [],
+ });
+
public hassSubscribe(): UnsubscribeFunc[] {
return [
subscribeEntityRegistry(this.hass.connection!, (entities) => {
this._entitiesContext.setValue(entities);
}),
+ subscribeLabelRegistry(this.hass.connection!, (labels) => {
+ this._labelsContext.setValue(labels);
+ }),
+ subscribeFloorRegistry(this.hass.connection!, (floors) => {
+ this._floorsContext.setValue(floors);
+ }),
];
}
diff --git a/src/translations/en.json b/src/translations/en.json
index d4e2852c0a..facdbb7080 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -3241,7 +3241,9 @@
"target_template": "templated {name}",
"target_unknown_entity": "unknown entity",
"target_unknown_device": "unknown device",
- "target_unknown_area": "unknown area"
+ "target_unknown_area": "unknown area",
+ "target_unknown_floor": "unknown floor",
+ "target_unknown_label": "unknown label"
}
},
"play_media": {