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": {