Limit precision when stringifying float states (#48822)

* Limit precision when stringifying float states

* Add test

* Fix typing

* Move StateType

* Update

* Move conversion to entity helper

* Address review comments

* Tweak precision

* Tweak

* Make _stringify_state an instance method
This commit is contained in:
Erik Montnemery 2021-04-27 21:48:24 +02:00 committed by GitHub
parent 5e00fdccfd
commit d2fd504442
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 55 additions and 5 deletions

View file

@ -7,6 +7,8 @@ from collections.abc import Awaitable, Iterable, Mapping
from datetime import datetime, timedelta
import functools as ft
import logging
import math
import sys
from timeit import default_timer as timer
from typing import Any
@ -43,6 +45,10 @@ DATA_ENTITY_SOURCE = "entity_info"
SOURCE_CONFIG_ENTRY = "config_entry"
SOURCE_PLATFORM_CONFIG = "platform_config"
# Used when converting float states to string: limit precision according to machine
# epsilon to make the string representation readable
FLOAT_PRECISION = abs(int(math.floor(math.log10(abs(sys.float_info.epsilon))))) - 1
@callback
@bind_hass
@ -327,6 +333,19 @@ class Entity(ABC):
self._async_write_ha_state()
def _stringify_state(self) -> str:
"""Convert state to string."""
if not self.available:
return STATE_UNAVAILABLE
state = self.state
if state is None:
return STATE_UNKNOWN
if isinstance(state, float):
# If the entity's state is a float, limit precision according to machine
# epsilon to make the string representation readable
return f"{state:.{FLOAT_PRECISION}}"
return str(state)
@callback
def _async_write_ha_state(self) -> None:
"""Write the state to the state machine."""
@ -346,11 +365,8 @@ class Entity(ABC):
attr = self.capability_attributes
attr = dict(attr) if attr else {}
if not self.available:
state = STATE_UNAVAILABLE
else:
sstate = self.state
state = STATE_UNKNOWN if sstate is None else str(sstate)
state = self._stringify_state()
if self.available:
attr.update(self.state_attributes or {})
extra_state_attributes = self.extra_state_attributes
# Backwards compatibility for "device_state_attributes" deprecated in 2021.4