fix: numerical states would not follow HA's format

Fix #662
This commit is contained in:
Jérôme Wiedemann 2023-07-24 23:37:49 +00:00
parent f79aded282
commit 72d7c4133f
3 changed files with 37 additions and 38 deletions

View File

@ -334,7 +334,13 @@ Inside the javascript code, you'll have access to those variables:
- `user`: The user object (equivalent to `hass.user`)
- `hass`: The complete `hass` object
- `variables`: an object containing all your variables defined in the configuration. See [Variables](#variables)
- `localize(entity, state?)`: a function which localizes a state (eg. `localize(entity)`) and returns a string. Takes an entity object as argument (not the state of the entity as we need context) and takes an optional `state` string as argument. If `state` is not provided, it localizes the state of the `entity` (Eg. `localize(entity)` or `localize(states['weather.your_city'])`). If `state` is provided, it localizes `state` in the context of the `entity` (eg. : `localize(states['weather.your_city'], states['weather.your_city'].attributes.forecast[0].condition)`)
- `localize(entity, state?, numeric_precision?, show_units?, units?)`: a function which localizes a state (eg. `localize(entity)`) and returns a string. Takes an entity object as argument (not the state of the entity as we need context) and takes optional arguments.
- If `state` is not provided, it localizes the state of the `entity` (Eg. `localize(entity)` or `localize(states['weather.your_city'])`).
- If `state` is provided, it localizes `state` in the context of the `entity` (eg. : `localize(entity, entity.attributes.forecast[0].condition)` or `localize(states['weather.your_city'], states['weather.your_city'].attributes.forecast[0].condition)`)
- `numeric_precision` (number): For state which are numbers, force the precision instead of letting HA decide for you
- `show_units` (boolean): Will display units or not. Default is to display them.
- `units` (string): Will force the units to be the value of that parameter.
- To skip one or multiple parameter while calling the function, use `undefined`. Eg. `localize(states['sensor.temperature'], undefined, 1, undefined, 'Celcius')`
- `formatDateTime(date)`, `formatShortDateTimeWithYear(date)`, `formatShortDateTime(date)`, `formatDateTimeWithSeconds(date)`, `formatDateTimeNumeric(date)`: Some helper functions to format a date time string or Date object. Name are pretty explicit. Example: `return formatDateTime(entity.attribute.last_changed)`
See [here](#templates-support) for some examples or [here](#custom-fields) for some crazy advanced stuff using templates!

View File

@ -294,7 +294,13 @@ class ButtonCard extends LitElement {
return retval;
}
private _localize(stateObj: HassEntity, state?: string): string {
private _localize(
stateObj: HassEntity,
state?: string,
numeric_precision?: number,
show_units = true,
units?: string,
): string {
// eslint-disable-next-line @typescript-eslint/no-this-alias
return computeStateDisplay(
this._hass!.localize,
@ -302,7 +308,7 @@ class ButtonCard extends LitElement {
this._hass!.locale,
this._hass!.config,
this._hass!.entities,
this._config?.numeric_precision,
{ numeric_precision: numeric_precision || this._config?.numeric_precision, show_units, units },
state,
);
}
@ -543,10 +549,7 @@ class ButtonCard extends LitElement {
private _buildStateString(stateObj: HassEntity | undefined): string | undefined | null {
let stateString: string | undefined | null;
if (this._config!.show_state && stateObj && stateObj.state) {
const units = this._buildUnits(stateObj);
if (units) {
stateString = `${stateObj.state} ${units}`;
} else if (computeDomain(stateObj.entity_id) === 'timer') {
if (computeDomain(stateObj.entity_id) === 'timer') {
if (stateObj.state === 'idle' || this._timeRemaining === 0) {
stateString = computeStateDisplay(
this._hass!.localize,
@ -554,7 +557,7 @@ class ButtonCard extends LitElement {
this._hass!.locale,
this._hass!.config,
this._hass!.entities,
this._config?.numeric_precision,
this._config,
);
} else {
stateString = this._computeTimeDisplay(stateObj);
@ -565,12 +568,10 @@ class ButtonCard extends LitElement {
this._hass!.locale,
this._hass!.config,
this._hass!.entities,
this._config?.numeric_precision,
this._config,
)})`;
}
}
} else if (!this._config?.show_units && computeDomain(stateObj.entity_id) === 'sensor') {
stateString = stateObj.state;
} else {
stateString = computeStateDisplay(
this._hass!.localize,
@ -578,27 +579,13 @@ class ButtonCard extends LitElement {
this._hass!.locale,
this._hass!.config,
this._hass!.entities,
this._config?.numeric_precision,
this._config,
);
}
}
return stateString;
}
private _buildUnits(state: HassEntity | undefined): string | undefined {
let units: string | undefined;
if (state) {
if (this._config!.show_units) {
if (state.attributes?.unit_of_measurement && !this._config!.units) {
units = state.attributes.unit_of_measurement;
} else {
units = this._config!.units ? this._config!.units : undefined;
}
}
}
return units;
}
private _buildLastChanged(state: HassEntity | undefined, style: StyleInfo): TemplateResult | undefined {
return this._config!.show_last_changed && state
? html`

View File

@ -14,6 +14,7 @@ import { formatDate } from './format_date';
import { formatTime } from './format_time';
import { UPDATE_SUPPORT_PROGRESS, updateIsInstallingFromAttributes } from './update';
import { supportsFeatureFromAttributes } from './supports-features';
import { ButtonCardConfig } from '../types/types';
const UNAVAILABLE = 'unavailable';
const UNKNOWN = 'unknown';
@ -24,7 +25,7 @@ export const computeStateDisplaySingleEntity = (
locale: FrontendLocaleData,
config: HassConfig,
entity: EntityRegistryDisplayEntry | undefined,
numeric_precision: number | undefined,
buttonConfig: { numeric_precision?: number; show_units?: boolean; units?: string } | undefined,
state?: string,
): string =>
computeStateDisplayFromEntityAttributes(
@ -34,7 +35,7 @@ export const computeStateDisplaySingleEntity = (
entity,
stateObj.entity_id,
stateObj.attributes,
numeric_precision,
buttonConfig,
state !== undefined ? state : stateObj.state,
);
@ -44,7 +45,7 @@ export const computeStateDisplay = (
locale: FrontendLocaleData,
config: HassConfig,
entities: HomeAssistant['entities'],
numeric_precision: number | undefined,
buttonConfig: { numeric_precision?: number; show_units?: boolean; units?: string } | undefined,
state?: string,
): string => {
const entity = entities[stateObj.entity_id] as EntityRegistryDisplayEntry | undefined;
@ -56,7 +57,7 @@ export const computeStateDisplay = (
entity,
stateObj.entity_id,
stateObj.attributes,
numeric_precision,
buttonConfig,
state !== undefined ? state : stateObj.state,
);
};
@ -68,7 +69,7 @@ export const computeStateDisplayFromEntityAttributes = (
entity: EntityRegistryDisplayEntry | undefined,
entityId: string,
attributes: any,
numeric_precision: number | undefined,
buttonConfig: { numeric_precision?: number; show_units?: boolean; units?: string } | undefined,
state: string,
): string => {
if (state === UNKNOWN || state === UNAVAILABLE) {
@ -93,24 +94,29 @@ export const computeStateDisplayFromEntityAttributes = (
try {
return formatNumber(state, locale, {
style: 'currency',
currency: attributes.unit_of_measurement,
currency: buttonConfig?.units || attributes.unit_of_measurement,
minimumFractionDigits: 2,
// Override monetary options with number format
...getNumberFormatOptions({ state, attributes } as HassEntity, numeric_precision, entity),
...getNumberFormatOptions({ state, attributes } as HassEntity, buttonConfig?.numeric_precision, entity),
});
} catch (_err) {
// fallback to default
}
}
const unit = !attributes.unit_of_measurement
const localOrConfigUnit = buttonConfig?.show_units
? buttonConfig?.units
? buttonConfig?.units
: attributes.unit_of_measurement
: undefined;
const unit = !localOrConfigUnit
? ''
: attributes.unit_of_measurement === '%'
: localOrConfigUnit === '%'
? blankBeforePercent(locale) + '%'
: ` ${attributes.unit_of_measurement}`;
: ` ${localOrConfigUnit}`;
return `${formatNumber(
state,
locale,
getNumberFormatOptions({ state, attributes } as HassEntity, numeric_precision, entity),
getNumberFormatOptions({ state, attributes } as HassEntity, buttonConfig?.numeric_precision, entity),
)}${unit}`;
}
@ -161,7 +167,7 @@ export const computeStateDisplayFromEntityAttributes = (
return formatNumber(
state,
locale,
getNumberFormatOptions({ state, attributes } as HassEntity, numeric_precision, entity),
getNumberFormatOptions({ state, attributes } as HassEntity, buttonConfig?.numeric_precision, entity),
);
}