mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-11 11:26:35 +00:00
Translate entity attribute names & attribute states (#15822)
This commit is contained in:
parent
dfd7acd713
commit
0232c11bc2
@ -1,28 +1,119 @@
|
|||||||
import { HassEntity } from "home-assistant-js-websocket";
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
|
import { html, TemplateResult } from "lit";
|
||||||
|
import { until } from "lit/directives/until";
|
||||||
import { EntityRegistryDisplayEntry } from "../../data/entity_registry";
|
import { EntityRegistryDisplayEntry } from "../../data/entity_registry";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
|
import checkValidDate from "../datetime/check_valid_date";
|
||||||
|
import { formatDate } from "../datetime/format_date";
|
||||||
|
import { formatDateTimeWithSeconds } from "../datetime/format_date_time";
|
||||||
|
import { formatNumber } from "../number/format_number";
|
||||||
|
import { capitalizeFirstLetter } from "../string/capitalize-first-letter";
|
||||||
|
import { isDate } from "../string/is_date";
|
||||||
|
import { isTimestamp } from "../string/is_timestamp";
|
||||||
import { LocalizeFunc } from "../translations/localize";
|
import { LocalizeFunc } from "../translations/localize";
|
||||||
import { computeDomain } from "./compute_domain";
|
import { computeDomain } from "./compute_domain";
|
||||||
|
import { FrontendLocaleData } from "../../data/translation";
|
||||||
|
|
||||||
|
let jsYamlPromise: Promise<typeof import("../../resources/js-yaml-dump")>;
|
||||||
|
|
||||||
export const computeAttributeValueDisplay = (
|
export const computeAttributeValueDisplay = (
|
||||||
localize: LocalizeFunc,
|
localize: LocalizeFunc,
|
||||||
stateObj: HassEntity,
|
stateObj: HassEntity,
|
||||||
|
locale: FrontendLocaleData,
|
||||||
entities: HomeAssistant["entities"],
|
entities: HomeAssistant["entities"],
|
||||||
attribute: string,
|
attribute: string,
|
||||||
value?: any
|
value?: any
|
||||||
): string => {
|
): string | TemplateResult => {
|
||||||
const entityId = stateObj.entity_id;
|
|
||||||
const deviceClass = stateObj.attributes.device_class;
|
|
||||||
const attributeValue =
|
const attributeValue =
|
||||||
value !== undefined ? value : stateObj.attributes[attribute];
|
value !== undefined ? value : stateObj.attributes[attribute];
|
||||||
|
|
||||||
|
// Null value, return dash
|
||||||
|
if (attributeValue === null) {
|
||||||
|
return "—";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Number value, return formatted number
|
||||||
|
if (typeof attributeValue === "number") {
|
||||||
|
return formatNumber(attributeValue, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special handling in case this is a string with an known format
|
||||||
|
if (typeof attributeValue === "string") {
|
||||||
|
// URL handling
|
||||||
|
if (attributeValue.startsWith("http")) {
|
||||||
|
try {
|
||||||
|
// If invalid URL, exception will be raised
|
||||||
|
const url = new URL(attributeValue);
|
||||||
|
if (url.protocol === "http:" || url.protocol === "https:")
|
||||||
|
return html`<a target="_blank" rel="noreferrer" href=${value}
|
||||||
|
>${attributeValue}</a
|
||||||
|
>`;
|
||||||
|
} catch (_) {
|
||||||
|
// Nothing to do here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Date handling
|
||||||
|
if (isDate(attributeValue, true)) {
|
||||||
|
// Timestamp handling
|
||||||
|
if (isTimestamp(attributeValue)) {
|
||||||
|
const date = new Date(attributeValue);
|
||||||
|
if (checkValidDate(date)) {
|
||||||
|
return formatDateTimeWithSeconds(date, locale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value was not a timestamp, so only do date formatting
|
||||||
|
const date = new Date(attributeValue);
|
||||||
|
if (checkValidDate(date)) {
|
||||||
|
return formatDate(date, locale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Values are objects, render object
|
||||||
|
if (
|
||||||
|
(Array.isArray(attributeValue) &&
|
||||||
|
attributeValue.some((val) => val instanceof Object)) ||
|
||||||
|
(!Array.isArray(attributeValue) && attributeValue instanceof Object)
|
||||||
|
) {
|
||||||
|
if (!jsYamlPromise) {
|
||||||
|
jsYamlPromise = import("../../resources/js-yaml-dump");
|
||||||
|
}
|
||||||
|
const yaml = jsYamlPromise.then((jsYaml) => jsYaml.dump(attributeValue));
|
||||||
|
return html`<pre>${until(yaml, "")}</pre>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this is an array, try to determine the display value for each item
|
||||||
|
if (Array.isArray(attributeValue)) {
|
||||||
|
return attributeValue
|
||||||
|
.map((item) =>
|
||||||
|
computeAttributeValueDisplay(
|
||||||
|
localize,
|
||||||
|
stateObj,
|
||||||
|
locale,
|
||||||
|
entities,
|
||||||
|
attribute,
|
||||||
|
item
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.join(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
// We've explored all known value handling, so now we'll try to find a
|
||||||
|
// translation for the value.
|
||||||
|
const entityId = stateObj.entity_id;
|
||||||
const domain = computeDomain(entityId);
|
const domain = computeDomain(entityId);
|
||||||
const entity = entities[entityId] as EntityRegistryDisplayEntry | undefined;
|
const deviceClass = stateObj.attributes.device_class;
|
||||||
const translationKey = entity?.translation_key;
|
const registryEntry = entities[entityId] as
|
||||||
|
| EntityRegistryDisplayEntry
|
||||||
|
| undefined;
|
||||||
|
const translationKey = registryEntry?.translation_key;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
(translationKey &&
|
(translationKey &&
|
||||||
localize(
|
localize(
|
||||||
`component.${entity.platform}.entity.${domain}.${translationKey}.state_attributes.${attribute}.state.${attributeValue}`
|
`component.${registryEntry.platform}.entity.${domain}.${translationKey}.state_attributes.${attribute}.state.${attributeValue}`
|
||||||
)) ||
|
)) ||
|
||||||
(deviceClass &&
|
(deviceClass &&
|
||||||
localize(
|
localize(
|
||||||
@ -59,6 +150,13 @@ export const computeAttributeNameDisplay = (
|
|||||||
localize(
|
localize(
|
||||||
`component.${domain}.entity_component._.state_attributes.${attribute}.name`
|
`component.${domain}.entity_component._.state_attributes.${attribute}.name`
|
||||||
) ||
|
) ||
|
||||||
|
capitalizeFirstLetter(
|
||||||
attribute
|
attribute
|
||||||
|
.replace(/_/g, " ")
|
||||||
|
.replace(/\bid\b/g, "ID")
|
||||||
|
.replace(/\bip\b/g, "IP")
|
||||||
|
.replace(/\bmac\b/g, "MAC")
|
||||||
|
.replace(/\bgps\b/g, "GPS")
|
||||||
|
)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { HassEntity } from "home-assistant-js-websocket";
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
import { html, LitElement, PropertyValues, nothing } from "lit";
|
import { html, LitElement, PropertyValues, nothing } from "lit";
|
||||||
import { customElement, property, query } from "lit/decorators";
|
import { customElement, property, query } from "lit/decorators";
|
||||||
import { formatAttributeName } from "../../data/entity_attributes";
|
import { computeAttributeNameDisplay } from "../../common/entity/compute_attribute_display";
|
||||||
import { PolymerChangedEvent } from "../../polymer-types";
|
import { PolymerChangedEvent } from "../../polymer-types";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import "../ha-combo-box";
|
import "../ha-combo-box";
|
||||||
@ -54,7 +54,12 @@ class HaEntityAttributePicker extends LitElement {
|
|||||||
.filter((key) => !this.hideAttributes?.includes(key))
|
.filter((key) => !this.hideAttributes?.includes(key))
|
||||||
.map((key) => ({
|
.map((key) => ({
|
||||||
value: key,
|
value: key,
|
||||||
label: formatAttributeName(key),
|
label: computeAttributeNameDisplay(
|
||||||
|
this.hass.localize,
|
||||||
|
state,
|
||||||
|
this.hass.entities,
|
||||||
|
key
|
||||||
|
),
|
||||||
}))
|
}))
|
||||||
: [];
|
: [];
|
||||||
}
|
}
|
||||||
@ -68,7 +73,14 @@ class HaEntityAttributePicker extends LitElement {
|
|||||||
return html`
|
return html`
|
||||||
<ha-combo-box
|
<ha-combo-box
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.value=${this.value ? formatAttributeName(this.value) : ""}
|
.value=${this.value
|
||||||
|
? computeAttributeNameDisplay(
|
||||||
|
this.hass.localize,
|
||||||
|
this.hass.states[this.entityId!],
|
||||||
|
this.hass.entities,
|
||||||
|
this.value
|
||||||
|
)
|
||||||
|
: ""}
|
||||||
.autofocus=${this.autofocus}
|
.autofocus=${this.autofocus}
|
||||||
.label=${this.label ??
|
.label=${this.label ??
|
||||||
this.hass.localize(
|
this.hass.localize(
|
||||||
|
@ -4,7 +4,7 @@ import { customElement, property, query } from "lit/decorators";
|
|||||||
import { fireEvent } from "../../common/dom/fire_event";
|
import { fireEvent } from "../../common/dom/fire_event";
|
||||||
import { computeStateDisplay } from "../../common/entity/compute_state_display";
|
import { computeStateDisplay } from "../../common/entity/compute_state_display";
|
||||||
import { getStates } from "../../common/entity/get_states";
|
import { getStates } from "../../common/entity/get_states";
|
||||||
import { formatAttributeValue } from "../../data/entity_attributes";
|
import { computeAttributeValueDisplay } from "../../common/entity/compute_attribute_display";
|
||||||
import { PolymerChangedEvent } from "../../polymer-types";
|
import { PolymerChangedEvent } from "../../polymer-types";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import "../ha-combo-box";
|
import "../ha-combo-box";
|
||||||
@ -58,7 +58,14 @@ class HaEntityStatePicker extends LitElement {
|
|||||||
this.hass.entities,
|
this.hass.entities,
|
||||||
key
|
key
|
||||||
)
|
)
|
||||||
: formatAttributeValue(this.hass, key),
|
: computeAttributeValueDisplay(
|
||||||
|
this.hass.localize,
|
||||||
|
state,
|
||||||
|
this.hass.locale,
|
||||||
|
this.hass.entities,
|
||||||
|
this.attribute,
|
||||||
|
key
|
||||||
|
),
|
||||||
}))
|
}))
|
||||||
: [];
|
: [];
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,11 @@
|
|||||||
import { HassEntity } from "home-assistant-js-websocket";
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
import {
|
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
|
||||||
css,
|
|
||||||
CSSResultGroup,
|
|
||||||
html,
|
|
||||||
LitElement,
|
|
||||||
TemplateResult,
|
|
||||||
nothing,
|
|
||||||
} from "lit";
|
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import {
|
import {
|
||||||
formatAttributeName,
|
computeAttributeNameDisplay,
|
||||||
formatAttributeValue,
|
computeAttributeValueDisplay,
|
||||||
STATE_ATTRIBUTES,
|
} from "../common/entity/compute_attribute_display";
|
||||||
} from "../data/entity_attributes";
|
import { STATE_ATTRIBUTES } from "../data/entity_attributes";
|
||||||
import { haStyle } from "../resources/styles";
|
import { haStyle } from "../resources/styles";
|
||||||
import { HomeAssistant } from "../types";
|
import { HomeAssistant } from "../types";
|
||||||
|
|
||||||
@ -56,9 +49,22 @@ class HaAttributes extends LitElement {
|
|||||||
${attributes.map(
|
${attributes.map(
|
||||||
(attribute) => html`
|
(attribute) => html`
|
||||||
<div class="data-entry">
|
<div class="data-entry">
|
||||||
<div class="key">${formatAttributeName(attribute)}</div>
|
<div class="key">
|
||||||
|
${computeAttributeNameDisplay(
|
||||||
|
this.hass.localize,
|
||||||
|
this.stateObj!,
|
||||||
|
this.hass.entities,
|
||||||
|
attribute
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
${this.formatAttribute(attribute)}
|
${computeAttributeValueDisplay(
|
||||||
|
this.hass.localize,
|
||||||
|
this.stateObj!,
|
||||||
|
this.hass.locale,
|
||||||
|
this.hass.entities,
|
||||||
|
attribute
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
@ -128,14 +134,6 @@ class HaAttributes extends LitElement {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private formatAttribute(attribute: string): string | TemplateResult {
|
|
||||||
if (!this.stateObj) {
|
|
||||||
return "—";
|
|
||||||
}
|
|
||||||
const value = this.stateObj.attributes[attribute];
|
|
||||||
return formatAttributeValue(this.hass, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private expandedChanged(ev) {
|
private expandedChanged(ev) {
|
||||||
this._expanded = ev.detail.expanded;
|
this._expanded = ev.detail.expanded;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ class HaClimateState extends LitElement {
|
|||||||
${computeAttributeValueDisplay(
|
${computeAttributeValueDisplay(
|
||||||
this.hass.localize,
|
this.hass.localize,
|
||||||
this.stateObj,
|
this.stateObj,
|
||||||
|
this.hass.locale,
|
||||||
this.hass.entities,
|
this.hass.entities,
|
||||||
"preset_mode"
|
"preset_mode"
|
||||||
)}`
|
)}`
|
||||||
@ -142,6 +143,7 @@ class HaClimateState extends LitElement {
|
|||||||
? `${computeAttributeValueDisplay(
|
? `${computeAttributeValueDisplay(
|
||||||
this.hass.localize,
|
this.hass.localize,
|
||||||
this.stateObj,
|
this.stateObj,
|
||||||
|
this.hass.locale,
|
||||||
this.hass.entities,
|
this.hass.entities,
|
||||||
"hvac_action"
|
"hvac_action"
|
||||||
)} (${stateString})`
|
)} (${stateString})`
|
||||||
|
@ -10,7 +10,7 @@ import {
|
|||||||
localizeDeviceAutomationCondition,
|
localizeDeviceAutomationCondition,
|
||||||
localizeDeviceAutomationTrigger,
|
localizeDeviceAutomationTrigger,
|
||||||
} from "./device_automation";
|
} from "./device_automation";
|
||||||
import { formatAttributeName } from "./entity_attributes";
|
import { computeAttributeNameDisplay } from "../common/entity/compute_attribute_display";
|
||||||
|
|
||||||
const describeDuration = (forTime: number | string | ForDict) => {
|
const describeDuration = (forTime: number | string | ForDict) => {
|
||||||
let duration: string | null;
|
let duration: string | null;
|
||||||
@ -67,7 +67,12 @@ export const describeTrigger = (
|
|||||||
const entity = stateObj ? computeStateName(stateObj) : trigger.entity_id;
|
const entity = stateObj ? computeStateName(stateObj) : trigger.entity_id;
|
||||||
|
|
||||||
if (trigger.attribute) {
|
if (trigger.attribute) {
|
||||||
base += ` ${formatAttributeName(trigger.attribute)} from`;
|
base += ` ${computeAttributeNameDisplay(
|
||||||
|
hass.localize,
|
||||||
|
stateObj,
|
||||||
|
hass.entities,
|
||||||
|
trigger.attribute
|
||||||
|
)} from`;
|
||||||
}
|
}
|
||||||
|
|
||||||
base += ` ${entity} is`;
|
base += ` ${entity} is`;
|
||||||
@ -98,11 +103,18 @@ export const describeTrigger = (
|
|||||||
if (trigger.platform === "state") {
|
if (trigger.platform === "state") {
|
||||||
let base = "When";
|
let base = "When";
|
||||||
let entities = "";
|
let entities = "";
|
||||||
|
|
||||||
const states = hass.states;
|
const states = hass.states;
|
||||||
|
|
||||||
if (trigger.attribute) {
|
if (trigger.attribute) {
|
||||||
base += ` ${formatAttributeName(trigger.attribute)} from`;
|
const stateObj = Array.isArray(trigger.entity_id)
|
||||||
|
? hass.states[trigger.entity_id[0]]
|
||||||
|
: hass.states[trigger.entity_id];
|
||||||
|
base += ` ${computeAttributeNameDisplay(
|
||||||
|
hass.localize,
|
||||||
|
stateObj,
|
||||||
|
hass.entities,
|
||||||
|
trigger.attribute
|
||||||
|
)} from`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Array.isArray(trigger.entity_id)) {
|
if (Array.isArray(trigger.entity_id)) {
|
||||||
|
@ -1,16 +1,3 @@
|
|||||||
import { html, TemplateResult } from "lit";
|
|
||||||
import { until } from "lit/directives/until";
|
|
||||||
import checkValidDate from "../common/datetime/check_valid_date";
|
|
||||||
import { formatDate } from "../common/datetime/format_date";
|
|
||||||
import { formatDateTimeWithSeconds } from "../common/datetime/format_date_time";
|
|
||||||
import { formatNumber } from "../common/number/format_number";
|
|
||||||
import { capitalizeFirstLetter } from "../common/string/capitalize-first-letter";
|
|
||||||
import { isDate } from "../common/string/is_date";
|
|
||||||
import { isTimestamp } from "../common/string/is_timestamp";
|
|
||||||
import { HomeAssistant } from "../types";
|
|
||||||
|
|
||||||
let jsYamlPromise: Promise<typeof import("../resources/js-yaml-dump")>;
|
|
||||||
|
|
||||||
export const STATE_ATTRIBUTES = [
|
export const STATE_ATTRIBUTES = [
|
||||||
"assumed_state",
|
"assumed_state",
|
||||||
"attribution",
|
"attribution",
|
||||||
@ -32,74 +19,3 @@ export const STATE_ATTRIBUTES = [
|
|||||||
"supported_features",
|
"supported_features",
|
||||||
"unit_of_measurement",
|
"unit_of_measurement",
|
||||||
];
|
];
|
||||||
|
|
||||||
// Convert from internal snake_case format to user-friendly format
|
|
||||||
export function formatAttributeName(value: string): string {
|
|
||||||
value = value
|
|
||||||
.replace(/_/g, " ")
|
|
||||||
.replace(/\bid\b/g, "ID")
|
|
||||||
.replace(/\bip\b/g, "IP")
|
|
||||||
.replace(/\bmac\b/g, "MAC")
|
|
||||||
.replace(/\bgps\b/g, "GPS");
|
|
||||||
return capitalizeFirstLetter(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function formatAttributeValue(
|
|
||||||
hass: HomeAssistant,
|
|
||||||
value: any
|
|
||||||
): string | TemplateResult {
|
|
||||||
if (value === null) {
|
|
||||||
return "—";
|
|
||||||
}
|
|
||||||
|
|
||||||
// YAML handling
|
|
||||||
if (
|
|
||||||
(Array.isArray(value) && value.some((val) => val instanceof Object)) ||
|
|
||||||
(!Array.isArray(value) && value instanceof Object)
|
|
||||||
) {
|
|
||||||
if (!jsYamlPromise) {
|
|
||||||
jsYamlPromise = import("../resources/js-yaml-dump");
|
|
||||||
}
|
|
||||||
const yaml = jsYamlPromise.then((jsYaml) => jsYaml.dump(value));
|
|
||||||
return html`<pre>${until(yaml, "")}</pre>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof value === "number") {
|
|
||||||
return formatNumber(value, hass.locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof value === "string") {
|
|
||||||
// URL handling
|
|
||||||
if (value.startsWith("http")) {
|
|
||||||
try {
|
|
||||||
// If invalid URL, exception will be raised
|
|
||||||
const url = new URL(value);
|
|
||||||
if (url.protocol === "http:" || url.protocol === "https:")
|
|
||||||
return html`<a target="_blank" rel="noreferrer" href=${value}
|
|
||||||
>${value}</a
|
|
||||||
>`;
|
|
||||||
} catch (_) {
|
|
||||||
// Nothing to do here
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Date handling
|
|
||||||
if (isDate(value, true)) {
|
|
||||||
// Timestamp handling
|
|
||||||
if (isTimestamp(value)) {
|
|
||||||
const date = new Date(value);
|
|
||||||
if (checkValidDate(date)) {
|
|
||||||
return formatDateTimeWithSeconds(date, hass.locale);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Value was not a timestamp, so only do date formatting
|
|
||||||
const date = new Date(value);
|
|
||||||
if (checkValidDate(date)) {
|
|
||||||
return formatDate(date, hass.locale);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Array.isArray(value) ? value.join(", ") : value;
|
|
||||||
}
|
|
||||||
|
@ -235,6 +235,7 @@ class MoreInfoClimate extends LitElement {
|
|||||||
${computeAttributeValueDisplay(
|
${computeAttributeValueDisplay(
|
||||||
hass.localize,
|
hass.localize,
|
||||||
stateObj,
|
stateObj,
|
||||||
|
hass.locale,
|
||||||
hass.entities,
|
hass.entities,
|
||||||
"preset_mode",
|
"preset_mode",
|
||||||
mode
|
mode
|
||||||
@ -268,6 +269,7 @@ class MoreInfoClimate extends LitElement {
|
|||||||
${computeAttributeValueDisplay(
|
${computeAttributeValueDisplay(
|
||||||
hass.localize,
|
hass.localize,
|
||||||
stateObj,
|
stateObj,
|
||||||
|
hass.locale,
|
||||||
hass.entities,
|
hass.entities,
|
||||||
"fan_mode",
|
"fan_mode",
|
||||||
mode
|
mode
|
||||||
@ -301,6 +303,7 @@ class MoreInfoClimate extends LitElement {
|
|||||||
${computeAttributeValueDisplay(
|
${computeAttributeValueDisplay(
|
||||||
hass.localize,
|
hass.localize,
|
||||||
stateObj,
|
stateObj,
|
||||||
|
hass.locale,
|
||||||
hass.entities,
|
hass.entities,
|
||||||
"swing_mode",
|
"swing_mode",
|
||||||
mode
|
mode
|
||||||
|
@ -27,7 +27,7 @@ import "../../../components/ha-card";
|
|||||||
import "../../../components/ha-icon";
|
import "../../../components/ha-icon";
|
||||||
import { HVAC_ACTION_TO_MODE } from "../../../data/climate";
|
import { HVAC_ACTION_TO_MODE } from "../../../data/climate";
|
||||||
import { isUnavailableState } from "../../../data/entity";
|
import { isUnavailableState } from "../../../data/entity";
|
||||||
import { formatAttributeValue } from "../../../data/entity_attributes";
|
import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display";
|
||||||
import { LightEntity } from "../../../data/light";
|
import { LightEntity } from "../../../data/light";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import { computeCardSize } from "../common/compute-card-size";
|
import { computeCardSize } from "../common/compute-card-size";
|
||||||
@ -159,9 +159,12 @@ export class HuiEntityCard extends LitElement implements LovelaceCard {
|
|||||||
<span class="value"
|
<span class="value"
|
||||||
>${"attribute" in this._config
|
>${"attribute" in this._config
|
||||||
? stateObj.attributes[this._config.attribute!] !== undefined
|
? stateObj.attributes[this._config.attribute!] !== undefined
|
||||||
? formatAttributeValue(
|
? computeAttributeValueDisplay(
|
||||||
this.hass,
|
this.hass.localize,
|
||||||
stateObj.attributes[this._config.attribute!]
|
stateObj,
|
||||||
|
this.hass.locale,
|
||||||
|
this.hass.entities,
|
||||||
|
this._config.attribute!
|
||||||
)
|
)
|
||||||
: this.hass.localize("state.default.unknown")
|
: this.hass.localize("state.default.unknown")
|
||||||
: isNumericState(stateObj) || this._config.unit
|
: isNumericState(stateObj) || this._config.unit
|
||||||
|
@ -234,6 +234,7 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard {
|
|||||||
? computeAttributeValueDisplay(
|
? computeAttributeValueDisplay(
|
||||||
this.hass.localize,
|
this.hass.localize,
|
||||||
stateObj,
|
stateObj,
|
||||||
|
this.hass.locale,
|
||||||
this.hass.entities,
|
this.hass.entities,
|
||||||
"hvac_action"
|
"hvac_action"
|
||||||
)
|
)
|
||||||
@ -252,6 +253,7 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard {
|
|||||||
${computeAttributeValueDisplay(
|
${computeAttributeValueDisplay(
|
||||||
this.hass.localize,
|
this.hass.localize,
|
||||||
stateObj,
|
stateObj,
|
||||||
|
this.hass.locale,
|
||||||
this.hass.entities,
|
this.hass.entities,
|
||||||
"preset_mode"
|
"preset_mode"
|
||||||
)}
|
)}
|
||||||
|
@ -8,14 +8,13 @@ import {
|
|||||||
} from "lit";
|
} from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import checkValidDate from "../../../common/datetime/check_valid_date";
|
import checkValidDate from "../../../common/datetime/check_valid_date";
|
||||||
import { formatNumber } from "../../../common/number/format_number";
|
|
||||||
import { formatAttributeValue } from "../../../data/entity_attributes";
|
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||||
import "../components/hui-generic-entity-row";
|
import "../components/hui-generic-entity-row";
|
||||||
import "../components/hui-timestamp-display";
|
import "../components/hui-timestamp-display";
|
||||||
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
||||||
import { AttributeRowConfig, LovelaceRow } from "../entity-rows/types";
|
import { AttributeRowConfig, LovelaceRow } from "../entity-rows/types";
|
||||||
|
import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display";
|
||||||
|
|
||||||
@customElement("hui-attribute-row")
|
@customElement("hui-attribute-row")
|
||||||
class HuiAttributeRow extends LitElement implements LovelaceRow {
|
class HuiAttributeRow extends LitElement implements LovelaceRow {
|
||||||
@ -71,10 +70,15 @@ class HuiAttributeRow extends LitElement implements LovelaceRow {
|
|||||||
.format=${this._config.format}
|
.format=${this._config.format}
|
||||||
capitalize
|
capitalize
|
||||||
></hui-timestamp-display>`
|
></hui-timestamp-display>`
|
||||||
: typeof attribute === "number"
|
|
||||||
? formatNumber(attribute, this.hass.locale)
|
|
||||||
: attribute !== undefined
|
: attribute !== undefined
|
||||||
? formatAttributeValue(this.hass, attribute)
|
? computeAttributeValueDisplay(
|
||||||
|
this.hass.localize,
|
||||||
|
stateObj,
|
||||||
|
this.hass.locale,
|
||||||
|
this.hass.entities,
|
||||||
|
this._config.attribute,
|
||||||
|
attribute
|
||||||
|
)
|
||||||
: "—"}
|
: "—"}
|
||||||
${this._config.suffix}
|
${this._config.suffix}
|
||||||
</hui-generic-entity-row>
|
</hui-generic-entity-row>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user