mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-27 11:16:35 +00:00
Add format state/attribute to hass (#17249)
This commit is contained in:
parent
023f13cd12
commit
ebee8f670e
@ -1,7 +1,6 @@
|
|||||||
import { HassConfig, HassEntity } from "home-assistant-js-websocket";
|
import { HassConfig, 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 { FrontendLocaleData } from "../../data/translation";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import checkValidDate from "../datetime/check_valid_date";
|
import checkValidDate from "../datetime/check_valid_date";
|
||||||
import { formatDate } from "../datetime/format_date";
|
import { formatDate } from "../datetime/format_date";
|
||||||
@ -12,9 +11,6 @@ import { isDate } from "../string/is_date";
|
|||||||
import { isTimestamp } from "../string/is_timestamp";
|
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,
|
||||||
@ -24,7 +20,7 @@ export const computeAttributeValueDisplay = (
|
|||||||
entities: HomeAssistant["entities"],
|
entities: HomeAssistant["entities"],
|
||||||
attribute: string,
|
attribute: string,
|
||||||
value?: any
|
value?: any
|
||||||
): string | TemplateResult => {
|
): string => {
|
||||||
const attributeValue =
|
const attributeValue =
|
||||||
value !== undefined ? value : stateObj.attributes[attribute];
|
value !== undefined ? value : stateObj.attributes[attribute];
|
||||||
|
|
||||||
@ -40,23 +36,6 @@ export const computeAttributeValueDisplay = (
|
|||||||
|
|
||||||
// Special handling in case this is a string with an known format
|
// Special handling in case this is a string with an known format
|
||||||
if (typeof attributeValue === "string") {
|
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="noopener noreferrer"
|
|
||||||
href=${attributeValue}
|
|
||||||
>${attributeValue}</a
|
|
||||||
>`;
|
|
||||||
} catch (_) {
|
|
||||||
// Nothing to do here
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Date handling
|
// Date handling
|
||||||
if (isDate(attributeValue, true)) {
|
if (isDate(attributeValue, true)) {
|
||||||
// Timestamp handling
|
// Timestamp handling
|
||||||
@ -81,13 +60,8 @@ export const computeAttributeValueDisplay = (
|
|||||||
attributeValue.some((val) => val instanceof Object)) ||
|
attributeValue.some((val) => val instanceof Object)) ||
|
||||||
(!Array.isArray(attributeValue) && attributeValue instanceof Object)
|
(!Array.isArray(attributeValue) && attributeValue instanceof Object)
|
||||||
) {
|
) {
|
||||||
if (!jsYamlPromise) {
|
return JSON.stringify(attributeValue);
|
||||||
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 this is an array, try to determine the display value for each item
|
||||||
if (Array.isArray(attributeValue)) {
|
if (Array.isArray(attributeValue)) {
|
||||||
return attributeValue
|
return attributeValue
|
||||||
|
47
src/common/translations/entity-state.ts
Normal file
47
src/common/translations/entity-state.ts
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import type { HassConfig, HassEntity } from "home-assistant-js-websocket";
|
||||||
|
import type { FrontendLocaleData } from "../../data/translation";
|
||||||
|
import type { HomeAssistant } from "../../types";
|
||||||
|
import type { LocalizeFunc } from "./localize";
|
||||||
|
|
||||||
|
export type FormatEntityStateFunc = {
|
||||||
|
formatEntityState: (stateObj: HassEntity, state?: string) => string;
|
||||||
|
formatEntityAttributeValue: (
|
||||||
|
stateObj: HassEntity,
|
||||||
|
attribute: string,
|
||||||
|
value?: any
|
||||||
|
) => string;
|
||||||
|
formatEntityAttributeName: (
|
||||||
|
stateObj: HassEntity,
|
||||||
|
attribute: string
|
||||||
|
) => string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const computeFormatFunctions = async (
|
||||||
|
localize: LocalizeFunc,
|
||||||
|
locale: FrontendLocaleData,
|
||||||
|
config: HassConfig,
|
||||||
|
entities: HomeAssistant["entities"]
|
||||||
|
): Promise<FormatEntityStateFunc> => {
|
||||||
|
const { computeStateDisplay } = await import(
|
||||||
|
"../entity/compute_state_display"
|
||||||
|
);
|
||||||
|
const { computeAttributeValueDisplay, computeAttributeNameDisplay } =
|
||||||
|
await import("../entity/compute_attribute_display");
|
||||||
|
|
||||||
|
return {
|
||||||
|
formatEntityState: (stateObj, state) =>
|
||||||
|
computeStateDisplay(localize, stateObj, locale, config, entities, state),
|
||||||
|
formatEntityAttributeValue: (stateObj, attribute, value) =>
|
||||||
|
computeAttributeValueDisplay(
|
||||||
|
localize,
|
||||||
|
stateObj,
|
||||||
|
locale,
|
||||||
|
config,
|
||||||
|
entities,
|
||||||
|
attribute,
|
||||||
|
value
|
||||||
|
),
|
||||||
|
formatEntityAttributeName: (stateObj, attribute) =>
|
||||||
|
computeAttributeNameDisplay(localize, stateObj, entities, attribute),
|
||||||
|
};
|
||||||
|
};
|
64
src/components/ha-attribute-value.ts
Normal file
64
src/components/ha-attribute-value.ts
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
|
import { html, LitElement, nothing } from "lit";
|
||||||
|
import { customElement, property } from "lit/decorators";
|
||||||
|
import { until } from "lit/directives/until";
|
||||||
|
import { HomeAssistant } from "../types";
|
||||||
|
|
||||||
|
let jsYamlPromise: Promise<typeof import("../resources/js-yaml-dump")>;
|
||||||
|
|
||||||
|
@customElement("ha-attribute-value")
|
||||||
|
class HaAttributeValue extends LitElement {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property() public stateObj?: HassEntity;
|
||||||
|
|
||||||
|
@property() public attribute!: string;
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
if (!this.stateObj) {
|
||||||
|
return nothing;
|
||||||
|
}
|
||||||
|
const attributeValue = this.stateObj.attributes[this.attribute];
|
||||||
|
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="noopener noreferrer"
|
||||||
|
href=${attributeValue}
|
||||||
|
>
|
||||||
|
${attributeValue}
|
||||||
|
</a>
|
||||||
|
`;
|
||||||
|
} catch (_) {
|
||||||
|
// Nothing to do here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.hass.formatEntityAttributeValue(this.stateObj!, this.attribute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-attribute-value": HaAttributeValue;
|
||||||
|
}
|
||||||
|
}
|
@ -1,15 +1,12 @@
|
|||||||
import { HassEntity } from "home-assistant-js-websocket";
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
|
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import {
|
import { computeAttributeNameDisplay } from "../common/entity/compute_attribute_display";
|
||||||
computeAttributeNameDisplay,
|
|
||||||
computeAttributeValueDisplay,
|
|
||||||
} from "../common/entity/compute_attribute_display";
|
|
||||||
import { STATE_ATTRIBUTES } 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";
|
||||||
|
|
||||||
import "./ha-expansion-panel";
|
import "./ha-expansion-panel";
|
||||||
|
import "./ha-attribute-value";
|
||||||
|
|
||||||
@customElement("ha-attributes")
|
@customElement("ha-attributes")
|
||||||
class HaAttributes extends LitElement {
|
class HaAttributes extends LitElement {
|
||||||
@ -58,14 +55,11 @@ class HaAttributes extends LitElement {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
${computeAttributeValueDisplay(
|
<ha-attribute-value
|
||||||
this.hass.localize,
|
.hass=${this.hass}
|
||||||
this.stateObj!,
|
.attribute=${attribute}
|
||||||
this.hass.locale,
|
.stateObj=${this.stateObj}
|
||||||
this.hass.config,
|
></ha-attribute-value>
|
||||||
this.hass.entities,
|
|
||||||
attribute
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
|
@ -68,7 +68,8 @@ export class HomeAssistantAppEl extends QuickBarMixin(HassElement) {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
willUpdate(changedProps: PropertyValues<this>) {
|
protected willUpdate(changedProps: PropertyValues<this>) {
|
||||||
|
super.willUpdate(changedProps);
|
||||||
if (
|
if (
|
||||||
this._databaseMigration === undefined &&
|
this._databaseMigration === undefined &&
|
||||||
changedProps.has("hass") &&
|
changedProps.has("hass") &&
|
||||||
@ -79,7 +80,7 @@ export class HomeAssistantAppEl extends QuickBarMixin(HassElement) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
update(changedProps: PropertyValues<this>) {
|
protected update(changedProps: PropertyValues<this>) {
|
||||||
if (
|
if (
|
||||||
this.hass?.states &&
|
this.hass?.states &&
|
||||||
this.hass.config &&
|
this.hass.config &&
|
||||||
|
@ -12,13 +12,12 @@ import { ifDefined } from "lit/directives/if-defined";
|
|||||||
import { styleMap } from "lit/directives/style-map";
|
import { styleMap } from "lit/directives/style-map";
|
||||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||||
import { fireEvent } from "../../../common/dom/fire_event";
|
import { fireEvent } from "../../../common/dom/fire_event";
|
||||||
import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display";
|
|
||||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||||
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
||||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||||
import {
|
import {
|
||||||
stateColorCss,
|
|
||||||
stateColorBrightness,
|
stateColorBrightness,
|
||||||
|
stateColorCss,
|
||||||
} from "../../../common/entity/state_color";
|
} from "../../../common/entity/state_color";
|
||||||
import { isValidEntityId } from "../../../common/entity/valid_entity_id";
|
import { isValidEntityId } from "../../../common/entity/valid_entity_id";
|
||||||
import {
|
import {
|
||||||
@ -27,6 +26,7 @@ import {
|
|||||||
isNumericState,
|
isNumericState,
|
||||||
} from "../../../common/number/format_number";
|
} from "../../../common/number/format_number";
|
||||||
import { iconColorCSS } from "../../../common/style/icon_color_css";
|
import { iconColorCSS } from "../../../common/style/icon_color_css";
|
||||||
|
import "../../../components/ha-attribute-value";
|
||||||
import "../../../components/ha-card";
|
import "../../../components/ha-card";
|
||||||
import "../../../components/ha-icon";
|
import "../../../components/ha-icon";
|
||||||
import { CLIMATE_HVAC_ACTION_TO_MODE } from "../../../data/climate";
|
import { CLIMATE_HVAC_ACTION_TO_MODE } from "../../../data/climate";
|
||||||
@ -157,14 +157,14 @@ 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
|
||||||
? computeAttributeValueDisplay(
|
? html`
|
||||||
this.hass.localize,
|
<ha-attribute-value
|
||||||
stateObj,
|
.hass=${this.hass}
|
||||||
this.hass.locale,
|
.stateObj=${stateObj}
|
||||||
this.hass.config,
|
.attribute=${this._config.attribute!}
|
||||||
this.hass.entities,
|
>
|
||||||
this._config.attribute!
|
</ha-attribute-value>
|
||||||
)
|
`
|
||||||
: this.hass.localize("state.default.unknown")
|
: this.hass.localize("state.default.unknown")
|
||||||
: isNumericState(stateObj) || this._config.unit
|
: isNumericState(stateObj) || this._config.unit
|
||||||
? formatNumber(
|
? formatNumber(
|
||||||
|
@ -25,7 +25,6 @@ import { computeCssColor } from "../../../common/color/compute-color";
|
|||||||
import { hsv2rgb, rgb2hex, rgb2hsv } from "../../../common/color/convert-color";
|
import { hsv2rgb, rgb2hex, rgb2hsv } from "../../../common/color/convert-color";
|
||||||
import { DOMAINS_TOGGLE } from "../../../common/const";
|
import { DOMAINS_TOGGLE } from "../../../common/const";
|
||||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
|
||||||
import { stateActive } from "../../../common/entity/state_active";
|
import { stateActive } from "../../../common/entity/state_active";
|
||||||
import { stateColorCss } from "../../../common/entity/state_color";
|
import { stateColorCss } from "../../../common/entity/state_color";
|
||||||
import { stateIconPath } from "../../../common/entity/state_icon_path";
|
import { stateIconPath } from "../../../common/entity/state_icon_path";
|
||||||
@ -234,13 +233,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const stateDisplay = computeStateDisplay(
|
const stateDisplay = this.hass!.formatEntityState(stateObj);
|
||||||
this.hass!.localize,
|
|
||||||
stateObj,
|
|
||||||
this.hass!.locale,
|
|
||||||
this.hass!.config,
|
|
||||||
this.hass!.entities
|
|
||||||
);
|
|
||||||
|
|
||||||
if (domain === "cover") {
|
if (domain === "cover") {
|
||||||
const positionStateDisplay = computeCoverPositionStateDisplay(
|
const positionStateDisplay = computeCoverPositionStateDisplay(
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
import {
|
import {
|
||||||
css,
|
|
||||||
CSSResultGroup,
|
CSSResultGroup,
|
||||||
html,
|
|
||||||
LitElement,
|
LitElement,
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
|
css,
|
||||||
|
html,
|
||||||
nothing,
|
nothing,
|
||||||
} 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 "../../../components/ha-attribute-value";
|
||||||
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,15 +71,14 @@ class HuiAttributeRow extends LitElement implements LovelaceRow {
|
|||||||
capitalize
|
capitalize
|
||||||
></hui-timestamp-display>`
|
></hui-timestamp-display>`
|
||||||
: attribute !== undefined
|
: attribute !== undefined
|
||||||
? computeAttributeValueDisplay(
|
? html`
|
||||||
this.hass.localize,
|
<ha-attribute-value
|
||||||
stateObj,
|
.hass=${this.hass}
|
||||||
this.hass.locale,
|
.stateObj=${stateObj}
|
||||||
this.hass.config,
|
.attribute=${this._config.attribute}
|
||||||
this.hass.entities,
|
>
|
||||||
this._config.attribute,
|
</ha-attribute-value>
|
||||||
attribute
|
`
|
||||||
)
|
|
||||||
: "—"}
|
: "—"}
|
||||||
${this._config.suffix}
|
${this._config.suffix}
|
||||||
</hui-generic-entity-row>
|
</hui-generic-entity-row>
|
||||||
|
@ -19,9 +19,9 @@ import { forwardHaptic } from "../data/haptics";
|
|||||||
import { DEFAULT_PANEL } from "../data/panel";
|
import { DEFAULT_PANEL } from "../data/panel";
|
||||||
import { serviceCallWillDisconnect } from "../data/service";
|
import { serviceCallWillDisconnect } from "../data/service";
|
||||||
import {
|
import {
|
||||||
|
DateFormat,
|
||||||
FirstWeekday,
|
FirstWeekday,
|
||||||
NumberFormat,
|
NumberFormat,
|
||||||
DateFormat,
|
|
||||||
TimeFormat,
|
TimeFormat,
|
||||||
TimeZone,
|
TimeZone,
|
||||||
} from "../data/translation";
|
} from "../data/translation";
|
||||||
@ -176,6 +176,11 @@ export const connectionMixin = <T extends Constructor<HassBaseEl>>(
|
|||||||
loadFragmentTranslation: (fragment) =>
|
loadFragmentTranslation: (fragment) =>
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
this._loadFragmentTranslations(this.hass?.language, fragment),
|
this._loadFragmentTranslations(this.hass?.language, fragment),
|
||||||
|
formatEntityState: (stateObj, state) =>
|
||||||
|
(state !== null ? state : stateObj.state) ?? "",
|
||||||
|
formatEntityAttributeName: (_stateObj, attribute) => attribute,
|
||||||
|
formatEntityAttributeValue: (stateObj, attribute, value) =>
|
||||||
|
value !== null ? value : stateObj.attributes[attribute] ?? "",
|
||||||
...getState(),
|
...getState(),
|
||||||
...this._pendingHass,
|
...this._pendingHass,
|
||||||
};
|
};
|
||||||
|
@ -14,6 +14,7 @@ import { panelTitleMixin } from "./panel-title-mixin";
|
|||||||
import SidebarMixin from "./sidebar-mixin";
|
import SidebarMixin from "./sidebar-mixin";
|
||||||
import ThemesMixin from "./themes-mixin";
|
import ThemesMixin from "./themes-mixin";
|
||||||
import TranslationsMixin from "./translations-mixin";
|
import TranslationsMixin from "./translations-mixin";
|
||||||
|
import StateDisplayMixin from "./state-display-mixin";
|
||||||
import { urlSyncMixin } from "./url-sync-mixin";
|
import { urlSyncMixin } from "./url-sync-mixin";
|
||||||
|
|
||||||
const ext = <T extends Constructor>(baseClass: T, mixins): T =>
|
const ext = <T extends Constructor>(baseClass: T, mixins): T =>
|
||||||
@ -23,6 +24,7 @@ export class HassElement extends ext(HassBaseEl, [
|
|||||||
AuthMixin,
|
AuthMixin,
|
||||||
ThemesMixin,
|
ThemesMixin,
|
||||||
TranslationsMixin,
|
TranslationsMixin,
|
||||||
|
StateDisplayMixin,
|
||||||
MoreInfoMixin,
|
MoreInfoMixin,
|
||||||
ActionMixin,
|
ActionMixin,
|
||||||
SidebarMixin,
|
SidebarMixin,
|
||||||
|
52
src/state/state-display-mixin.ts
Normal file
52
src/state/state-display-mixin.ts
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import { computeFormatFunctions } from "../common/translations/entity-state";
|
||||||
|
import { Constructor, HomeAssistant } from "../types";
|
||||||
|
import { HassBaseEl } from "./hass-base-mixin";
|
||||||
|
|
||||||
|
export default <T extends Constructor<HassBaseEl>>(superClass: T) => {
|
||||||
|
class StateDisplayMixin extends superClass {
|
||||||
|
protected hassConnected() {
|
||||||
|
super.hassConnected();
|
||||||
|
this._updateStateDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected willUpdate(changedProps) {
|
||||||
|
super.willUpdate(changedProps);
|
||||||
|
|
||||||
|
if (!changedProps.has("hass")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
||||||
|
|
||||||
|
if (this.hass) {
|
||||||
|
if (
|
||||||
|
this.hass.localize !== oldHass?.localize ||
|
||||||
|
this.hass.locale !== oldHass.locale ||
|
||||||
|
this.hass.config !== oldHass.config ||
|
||||||
|
this.hass.entities !== oldHass.entities
|
||||||
|
) {
|
||||||
|
this._updateStateDisplay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _updateStateDisplay = async () => {
|
||||||
|
if (!this.hass) return;
|
||||||
|
const {
|
||||||
|
formatEntityState,
|
||||||
|
formatEntityAttributeName,
|
||||||
|
formatEntityAttributeValue,
|
||||||
|
} = await computeFormatFunctions(
|
||||||
|
this.hass.localize,
|
||||||
|
this.hass.locale,
|
||||||
|
this.hass.config,
|
||||||
|
this.hass.entities
|
||||||
|
);
|
||||||
|
this._updateHass({
|
||||||
|
formatEntityState,
|
||||||
|
formatEntityAttributeName,
|
||||||
|
formatEntityAttributeValue,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return StateDisplayMixin;
|
||||||
|
};
|
@ -3,6 +3,7 @@ import {
|
|||||||
Connection,
|
Connection,
|
||||||
HassConfig,
|
HassConfig,
|
||||||
HassEntities,
|
HassEntities,
|
||||||
|
HassEntity,
|
||||||
HassServices,
|
HassServices,
|
||||||
HassServiceTarget,
|
HassServiceTarget,
|
||||||
MessageBase,
|
MessageBase,
|
||||||
@ -256,6 +257,13 @@ export interface HomeAssistant {
|
|||||||
configFlow?: Parameters<typeof getHassTranslations>[4]
|
configFlow?: Parameters<typeof getHassTranslations>[4]
|
||||||
): Promise<LocalizeFunc>;
|
): Promise<LocalizeFunc>;
|
||||||
loadFragmentTranslation(fragment: string): Promise<LocalizeFunc | undefined>;
|
loadFragmentTranslation(fragment: string): Promise<LocalizeFunc | undefined>;
|
||||||
|
formatEntityState(stateObj: HassEntity, state?: string): string;
|
||||||
|
formatEntityAttributeValue(
|
||||||
|
stateObj: HassEntity,
|
||||||
|
attribute: string,
|
||||||
|
value?: string
|
||||||
|
): string;
|
||||||
|
formatEntityAttributeName(stateObj: HassEntity, attribute: string): string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Route {
|
export interface Route {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user