mirror of
https://github.com/home-assistant/core.git
synced 2025-07-08 22:07:10 +00:00
Implement suggested_display_precision for ESPHome (#147849)
This commit is contained in:
parent
35f0505c7b
commit
9469c6ad1c
@ -81,6 +81,7 @@ class EsphomeSensor(EsphomeEntity[SensorInfo, SensorState], SensorEntity):
|
|||||||
# if the string is empty
|
# if the string is empty
|
||||||
if unit_of_measurement := static_info.unit_of_measurement:
|
if unit_of_measurement := static_info.unit_of_measurement:
|
||||||
self._attr_native_unit_of_measurement = unit_of_measurement
|
self._attr_native_unit_of_measurement = unit_of_measurement
|
||||||
|
self._attr_suggested_display_precision = static_info.accuracy_decimals
|
||||||
self._attr_device_class = try_parse_enum(
|
self._attr_device_class = try_parse_enum(
|
||||||
SensorDeviceClass, static_info.device_class
|
SensorDeviceClass, static_info.device_class
|
||||||
)
|
)
|
||||||
@ -97,7 +98,7 @@ class EsphomeSensor(EsphomeEntity[SensorInfo, SensorState], SensorEntity):
|
|||||||
self._attr_state_class = _STATE_CLASSES.from_esphome(state_class)
|
self._attr_state_class = _STATE_CLASSES.from_esphome(state_class)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_value(self) -> datetime | str | None:
|
def native_value(self) -> datetime | int | float | None:
|
||||||
"""Return the state of the entity."""
|
"""Return the state of the entity."""
|
||||||
if not self._has_state or (state := self._state).missing_state:
|
if not self._has_state or (state := self._state).missing_state:
|
||||||
return None
|
return None
|
||||||
@ -106,7 +107,7 @@ class EsphomeSensor(EsphomeEntity[SensorInfo, SensorState], SensorEntity):
|
|||||||
return None
|
return None
|
||||||
if self.device_class is SensorDeviceClass.TIMESTAMP:
|
if self.device_class is SensorDeviceClass.TIMESTAMP:
|
||||||
return dt_util.utc_from_timestamp(state_float)
|
return dt_util.utc_from_timestamp(state_float)
|
||||||
return f"{state_float:.{self._static_info.accuracy_decimals}f}"
|
return state_float
|
||||||
|
|
||||||
|
|
||||||
class EsphomeTextSensor(EsphomeEntity[TextSensorInfo, TextSensorState], SensorEntity):
|
class EsphomeTextSensor(EsphomeEntity[TextSensorInfo, TextSensorState], SensorEntity):
|
||||||
|
@ -375,7 +375,7 @@ async def test_deep_sleep_device(
|
|||||||
assert state.state == STATE_ON
|
assert state.state == STATE_ON
|
||||||
state = hass.states.get("sensor.test_my_sensor")
|
state = hass.states.get("sensor.test_my_sensor")
|
||||||
assert state is not None
|
assert state is not None
|
||||||
assert state.state == "123"
|
assert state.state == "123.0"
|
||||||
|
|
||||||
await mock_device.mock_disconnect(False)
|
await mock_device.mock_disconnect(False)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
@ -394,7 +394,7 @@ async def test_deep_sleep_device(
|
|||||||
assert state.state == STATE_ON
|
assert state.state == STATE_ON
|
||||||
state = hass.states.get("sensor.test_my_sensor")
|
state = hass.states.get("sensor.test_my_sensor")
|
||||||
assert state is not None
|
assert state is not None
|
||||||
assert state.state == "123"
|
assert state.state == "123.0"
|
||||||
|
|
||||||
await mock_device.mock_disconnect(True)
|
await mock_device.mock_disconnect(True)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
@ -13,18 +13,28 @@ from aioesphomeapi import (
|
|||||||
TextSensorInfo,
|
TextSensorInfo,
|
||||||
TextSensorState,
|
TextSensorState,
|
||||||
)
|
)
|
||||||
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components.sensor import (
|
from homeassistant.components.sensor import (
|
||||||
ATTR_STATE_CLASS,
|
ATTR_STATE_CLASS,
|
||||||
SensorDeviceClass,
|
SensorDeviceClass,
|
||||||
SensorStateClass,
|
SensorStateClass,
|
||||||
|
async_rounded_state,
|
||||||
)
|
)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_DEVICE_CLASS,
|
ATTR_DEVICE_CLASS,
|
||||||
ATTR_ICON,
|
ATTR_ICON,
|
||||||
ATTR_UNIT_OF_MEASUREMENT,
|
ATTR_UNIT_OF_MEASUREMENT,
|
||||||
|
PERCENTAGE,
|
||||||
STATE_UNKNOWN,
|
STATE_UNKNOWN,
|
||||||
EntityCategory,
|
EntityCategory,
|
||||||
|
UnitOfElectricCurrent,
|
||||||
|
UnitOfElectricPotential,
|
||||||
|
UnitOfEnergy,
|
||||||
|
UnitOfPower,
|
||||||
|
UnitOfPressure,
|
||||||
|
UnitOfTemperature,
|
||||||
|
UnitOfVolume,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers import entity_registry as er
|
from homeassistant.helpers import entity_registry as er
|
||||||
@ -441,3 +451,63 @@ async def test_generic_numeric_sensor_empty_string_uom(
|
|||||||
assert state is not None
|
assert state is not None
|
||||||
assert state.state == "123"
|
assert state.state == "123"
|
||||||
assert ATTR_UNIT_OF_MEASUREMENT not in state.attributes
|
assert ATTR_UNIT_OF_MEASUREMENT not in state.attributes
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("device_class", "unit_of_measurement", "state_value", "expected_precision"),
|
||||||
|
[
|
||||||
|
(SensorDeviceClass.TEMPERATURE, UnitOfTemperature.CELSIUS, 23.456, 1),
|
||||||
|
(SensorDeviceClass.TEMPERATURE, UnitOfTemperature.CELSIUS, 0.1, 1),
|
||||||
|
(SensorDeviceClass.TEMPERATURE, UnitOfTemperature.CELSIUS, -25.789, 1),
|
||||||
|
(SensorDeviceClass.POWER, UnitOfPower.WATT, 1234.56, 0),
|
||||||
|
(SensorDeviceClass.POWER, UnitOfPower.WATT, 1.23456, 3),
|
||||||
|
(SensorDeviceClass.POWER, UnitOfPower.WATT, 0.123, 3),
|
||||||
|
(SensorDeviceClass.ENERGY, UnitOfEnergy.WATT_HOUR, 1234.5, 0),
|
||||||
|
(SensorDeviceClass.ENERGY, UnitOfEnergy.WATT_HOUR, 12.3456, 2),
|
||||||
|
(SensorDeviceClass.VOLTAGE, UnitOfElectricPotential.VOLT, 230.45, 1),
|
||||||
|
(SensorDeviceClass.VOLTAGE, UnitOfElectricPotential.VOLT, 3.3, 1),
|
||||||
|
(SensorDeviceClass.CURRENT, UnitOfElectricCurrent.AMPERE, 15.678, 2),
|
||||||
|
(SensorDeviceClass.CURRENT, UnitOfElectricCurrent.AMPERE, 0.015, 3),
|
||||||
|
(SensorDeviceClass.ATMOSPHERIC_PRESSURE, UnitOfPressure.HPA, 1013.25, 1),
|
||||||
|
(SensorDeviceClass.PRESSURE, UnitOfPressure.BAR, 1.01325, 3),
|
||||||
|
(SensorDeviceClass.VOLUME, UnitOfVolume.LITERS, 45.67, 1),
|
||||||
|
(SensorDeviceClass.VOLUME, UnitOfVolume.LITERS, 4567.0, 0),
|
||||||
|
(SensorDeviceClass.HUMIDITY, PERCENTAGE, 87.654, 1),
|
||||||
|
(SensorDeviceClass.HUMIDITY, PERCENTAGE, 45.2, 1),
|
||||||
|
(SensorDeviceClass.BATTERY, PERCENTAGE, 95.2, 1),
|
||||||
|
(SensorDeviceClass.BATTERY, PERCENTAGE, 100.0, 1),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_suggested_display_precision_by_device_class(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_client: APIClient,
|
||||||
|
mock_esphome_device: MockESPHomeDeviceType,
|
||||||
|
device_class: SensorDeviceClass,
|
||||||
|
unit_of_measurement: str,
|
||||||
|
state_value: float,
|
||||||
|
expected_precision: int,
|
||||||
|
) -> None:
|
||||||
|
"""Test suggested display precision for different device classes."""
|
||||||
|
entity_info = [
|
||||||
|
SensorInfo(
|
||||||
|
object_id="mysensor",
|
||||||
|
key=1,
|
||||||
|
name="my sensor",
|
||||||
|
unique_id="my_sensor",
|
||||||
|
accuracy_decimals=expected_precision,
|
||||||
|
device_class=device_class.value,
|
||||||
|
unit_of_measurement=unit_of_measurement,
|
||||||
|
)
|
||||||
|
]
|
||||||
|
states = [SensorState(key=1, state=state_value)]
|
||||||
|
await mock_esphome_device(
|
||||||
|
mock_client=mock_client,
|
||||||
|
entity_info=entity_info,
|
||||||
|
states=states,
|
||||||
|
)
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.test_my_sensor")
|
||||||
|
assert state is not None
|
||||||
|
assert float(
|
||||||
|
async_rounded_state(hass, "sensor.test_my_sensor", state)
|
||||||
|
) == pytest.approx(round(state_value, expected_precision))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user