mirror of
https://github.com/home-assistant/core.git
synced 2025-04-25 09:47:52 +00:00
Calculate attributes when entity information available in Group sensor (#119021)
This commit is contained in:
parent
b84ea1edeb
commit
fc915dc1bf
@ -36,7 +36,14 @@ from homeassistant.const import (
|
|||||||
STATE_UNAVAILABLE,
|
STATE_UNAVAILABLE,
|
||||||
STATE_UNKNOWN,
|
STATE_UNKNOWN,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant, State, callback
|
from homeassistant.core import (
|
||||||
|
CALLBACK_TYPE,
|
||||||
|
Event,
|
||||||
|
EventStateChangedData,
|
||||||
|
HomeAssistant,
|
||||||
|
State,
|
||||||
|
callback,
|
||||||
|
)
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers import config_validation as cv, entity_registry as er
|
from homeassistant.helpers import config_validation as cv, entity_registry as er
|
||||||
from homeassistant.helpers.entity import (
|
from homeassistant.helpers.entity import (
|
||||||
@ -45,6 +52,7 @@ from homeassistant.helpers.entity import (
|
|||||||
get_unit_of_measurement,
|
get_unit_of_measurement,
|
||||||
)
|
)
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
from homeassistant.helpers.event import async_track_state_change_event
|
||||||
from homeassistant.helpers.issue_registry import (
|
from homeassistant.helpers.issue_registry import (
|
||||||
IssueSeverity,
|
IssueSeverity,
|
||||||
async_create_issue,
|
async_create_issue,
|
||||||
@ -329,6 +337,7 @@ class SensorGroup(GroupEntity, SensorEntity):
|
|||||||
self._native_unit_of_measurement = unit_of_measurement
|
self._native_unit_of_measurement = unit_of_measurement
|
||||||
self._valid_units: set[str | None] = set()
|
self._valid_units: set[str | None] = set()
|
||||||
self._can_convert: bool = False
|
self._can_convert: bool = False
|
||||||
|
self.calculate_attributes_later: CALLBACK_TYPE | None = None
|
||||||
self._attr_name = name
|
self._attr_name = name
|
||||||
if name == DEFAULT_NAME:
|
if name == DEFAULT_NAME:
|
||||||
self._attr_name = f"{DEFAULT_NAME} {sensor_type}".capitalize()
|
self._attr_name = f"{DEFAULT_NAME} {sensor_type}".capitalize()
|
||||||
@ -345,13 +354,32 @@ class SensorGroup(GroupEntity, SensorEntity):
|
|||||||
|
|
||||||
async def async_added_to_hass(self) -> None:
|
async def async_added_to_hass(self) -> None:
|
||||||
"""When added to hass."""
|
"""When added to hass."""
|
||||||
|
for entity_id in self._entity_ids:
|
||||||
|
if self.hass.states.get(entity_id) is None:
|
||||||
|
self.calculate_attributes_later = async_track_state_change_event(
|
||||||
|
self.hass, self._entity_ids, self.calculate_state_attributes
|
||||||
|
)
|
||||||
|
break
|
||||||
|
if not self.calculate_attributes_later:
|
||||||
|
await self.calculate_state_attributes()
|
||||||
|
await super().async_added_to_hass()
|
||||||
|
|
||||||
|
async def calculate_state_attributes(
|
||||||
|
self, event: Event[EventStateChangedData] | None = None
|
||||||
|
) -> None:
|
||||||
|
"""Calculate state attributes."""
|
||||||
|
for entity_id in self._entity_ids:
|
||||||
|
if self.hass.states.get(entity_id) is None:
|
||||||
|
return
|
||||||
|
if self.calculate_attributes_later:
|
||||||
|
self.calculate_attributes_later()
|
||||||
|
self.calculate_attributes_later = None
|
||||||
self._attr_state_class = self._calculate_state_class(self._state_class)
|
self._attr_state_class = self._calculate_state_class(self._state_class)
|
||||||
self._attr_device_class = self._calculate_device_class(self._device_class)
|
self._attr_device_class = self._calculate_device_class(self._device_class)
|
||||||
self._attr_native_unit_of_measurement = self._calculate_unit_of_measurement(
|
self._attr_native_unit_of_measurement = self._calculate_unit_of_measurement(
|
||||||
self._native_unit_of_measurement
|
self._native_unit_of_measurement
|
||||||
)
|
)
|
||||||
self._valid_units = self._get_valid_units()
|
self._valid_units = self._get_valid_units()
|
||||||
await super().async_added_to_hass()
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def async_update_group_state(self) -> None:
|
def async_update_group_state(self) -> None:
|
||||||
|
@ -763,3 +763,52 @@ async def test_last_sensor(hass: HomeAssistant) -> None:
|
|||||||
state = hass.states.get("sensor.test_last")
|
state = hass.states.get("sensor.test_last")
|
||||||
assert str(float(value)) == state.state
|
assert str(float(value)) == state.state
|
||||||
assert entity_id == state.attributes.get("last_entity_id")
|
assert entity_id == state.attributes.get("last_entity_id")
|
||||||
|
|
||||||
|
|
||||||
|
async def test_sensors_attributes_added_when_entity_info_available(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
) -> None:
|
||||||
|
"""Test the sensor calculate attributes once all entities attributes are available."""
|
||||||
|
config = {
|
||||||
|
SENSOR_DOMAIN: {
|
||||||
|
"platform": GROUP_DOMAIN,
|
||||||
|
"name": DEFAULT_NAME,
|
||||||
|
"type": "sum",
|
||||||
|
"entities": ["sensor.test_1", "sensor.test_2", "sensor.test_3"],
|
||||||
|
"unique_id": "very_unique_id",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entity_ids = config["sensor"]["entities"]
|
||||||
|
|
||||||
|
assert await async_setup_component(hass, "sensor", config)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.sensor_group_sum")
|
||||||
|
|
||||||
|
assert state.state == STATE_UNAVAILABLE
|
||||||
|
assert state.attributes.get(ATTR_ENTITY_ID) is None
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) is None
|
||||||
|
assert state.attributes.get(ATTR_STATE_CLASS) is None
|
||||||
|
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) is None
|
||||||
|
|
||||||
|
for entity_id, value in dict(zip(entity_ids, VALUES, strict=False)).items():
|
||||||
|
hass.states.async_set(
|
||||||
|
entity_id,
|
||||||
|
value,
|
||||||
|
{
|
||||||
|
ATTR_DEVICE_CLASS: SensorDeviceClass.VOLUME,
|
||||||
|
ATTR_STATE_CLASS: SensorStateClass.TOTAL,
|
||||||
|
ATTR_UNIT_OF_MEASUREMENT: "L",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.sensor_group_sum")
|
||||||
|
|
||||||
|
assert float(state.state) == pytest.approx(float(SUM_VALUE))
|
||||||
|
assert state.attributes.get(ATTR_ENTITY_ID) == entity_ids
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.VOLUME
|
||||||
|
assert state.attributes.get(ATTR_ICON) is None
|
||||||
|
assert state.attributes.get(ATTR_STATE_CLASS) == SensorStateClass.TOTAL
|
||||||
|
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "L"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user