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:
parent
5e00fdccfd
commit
d2fd504442
3 changed files with 55 additions and 5 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue