Allow overriding a sensor's precision (#15176)

* Allow overriding a sensor's precision

* use a dropdown for choosing precision

* Address review comments

* Handle undefined state

* Loose equality FTW

* Apply suggestions from code review
This commit is contained in:
Erik Montnemery 2023-01-25 11:04:03 +01:00 committed by GitHub
parent 8b4b19cc96
commit ddfaa67456
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 81 additions and 1 deletions

View File

@ -30,6 +30,7 @@ export interface ExtEntityRegistryEntry extends EntityRegistryEntry {
device_class?: string;
original_device_class?: string;
aliases: string[];
options: EntityRegistryOptions | null;
}
export interface UpdateEntityRegistryEntryResult {
@ -39,6 +40,7 @@ export interface UpdateEntityRegistryEntryResult {
}
export interface SensorEntityOptions {
precision?: number | null;
unit_of_measurement?: string | null;
}
@ -54,6 +56,12 @@ export interface WeatherEntityOptions {
wind_speed_unit?: string | null;
}
export interface EntityRegistryOptions {
number?: NumberEntityOptions;
sensor?: SensorEntityOptions;
weather?: WeatherEntityOptions;
}
export interface EntityRegistryEntryUpdateParams {
name?: string | null;
icon?: string | null;

View File

@ -62,6 +62,7 @@ import {
EntityRegistryEntry,
EntityRegistryEntryUpdateParams,
ExtEntityRegistryEntry,
SensorEntityOptions,
fetchEntityRegistry,
removeEntityRegistryEntry,
updateEntityRegistryEntry,
@ -125,6 +126,16 @@ const OVERRIDE_WEATHER_UNITS = {
const SWITCH_AS_DOMAINS = ["cover", "fan", "light", "lock", "siren"];
const PRECISIONS = [0, 1, 2, 3, 4, 5, 6];
function precisionLabel(precision: number, _state?: string) {
const state_float =
_state === undefined || isNaN(parseFloat(_state))
? 0.0
: parseFloat(_state);
return state_float.toFixed(precision);
}
@customElement("entity-registry-settings")
export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
@property({ attribute: false }) public hass!: HomeAssistant;
@ -153,6 +164,8 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
@state() private _unit_of_measurement?: string | null;
@state() private _precision?: number | null;
@state() private _precipitation_unit?: string | null;
@state() private _pressure_unit?: string | null;
@ -250,6 +263,10 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
this._unit_of_measurement = stateObj?.attributes?.unit_of_measurement;
}
if (domain === "sensor") {
this._precision = this.entry.options?.sensor?.precision;
}
if (domain === "weather") {
const stateObj: HassEntity | undefined =
this.hass.states[this.entry.entity_id];
@ -467,6 +484,44 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
</ha-select>
`
: ""}
${domain === "sensor" &&
// Allow customizing the precision for a sensor with numerical device class,
// a unit of measurement or state class
((this._deviceClass &&
!["date", "enum", "timestamp"].includes(this._deviceClass)) ||
stateObj?.attributes.unit_of_measurement ||
stateObj?.attributes.state_class)
? html`
<ha-select
.label=${this.hass.localize(
"ui.dialogs.entity_registry.editor.precision"
)}
.value=${this._precision == null
? "default"
: this._precision.toString()}
naturalMenuWidth
fixedMenuPosition
@selected=${this._precisionChanged}
@closed=${stopPropagation}
>
<mwc-list-item .value=${"default"}
>${this.hass.localize(
"ui.dialogs.entity_registry.editor.precision_default"
)}</mwc-list-item
>
${PRECISIONS.map(
(precision) => html`
<mwc-list-item .value=${precision.toString()}>
${precisionLabel(
precision,
this.hass.states[this.entry.entity_id]?.state
)}
</mwc-list-item>
`
)}
</ha-select>
`
: ""}
${domain === "weather"
? html`
<ha-select
@ -892,6 +947,12 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
this._precipitation_unit = ev.target.value;
}
private _precisionChanged(ev): void {
this._error = undefined;
this._precision =
ev.target.value === "default" ? null : Number(ev.target.value);
}
private _pressureUnitChanged(ev): void {
this._error = undefined;
this._pressure_unit = ev.target.value;
@ -1081,7 +1142,16 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
stateObj?.attributes?.unit_of_measurement !== this._unit_of_measurement
) {
params.options_domain = domain;
params.options = { unit_of_measurement: this._unit_of_measurement };
params.options = this.entry.options?.[domain] || {};
params.options.unit_of_measurement = this._unit_of_measurement;
}
if (
domain === "sensor" &&
this.entry.options?.[domain]?.precision !== this._precision
) {
params.options_domain = domain;
params.options = params.options || this.entry.options?.[domain] || {};
(params.options as SensorEntityOptions).precision = this._precision;
}
if (
domain === "weather" &&

View File

@ -905,6 +905,8 @@
"entity_id": "Entity ID",
"unit_of_measurement": "Unit of Measurement",
"precipitation_unit": "Precipitation unit",
"precision": "Precision",
"precision_default": "Use default",
"pressure_unit": "Barometric pressure unit",
"temperature_unit": "Temperature unit",
"visibility_unit": "Visibility unit",