mirror of
https://github.com/home-assistant/core.git
synced 2026-05-03 19:41:15 +02:00
Adjust sensor group behavior (#152167)
This commit is contained in:
@@ -374,7 +374,7 @@ class SensorGroup(GroupEntity, SensorEntity):
|
||||
def async_update_group_state(self) -> None:
|
||||
"""Query all members and determine the sensor group state."""
|
||||
self.calculate_state_attributes(self._get_valid_entities())
|
||||
states: list[str] = []
|
||||
states: list[str | None] = []
|
||||
valid_units = self._valid_units
|
||||
valid_states: list[bool] = []
|
||||
sensor_values: list[tuple[str, float, State]] = []
|
||||
@@ -435,9 +435,12 @@ class SensorGroup(GroupEntity, SensorEntity):
|
||||
state.attributes.get("unit_of_measurement"),
|
||||
self.entity_id,
|
||||
)
|
||||
else:
|
||||
states.append(None)
|
||||
valid_states.append(False)
|
||||
|
||||
# Set group as unavailable if all members do not have numeric values
|
||||
self._attr_available = any(numeric_state for numeric_state in valid_states)
|
||||
# Set group as unavailable if all members are unavailable or missing
|
||||
self._attr_available = not all(s in (STATE_UNAVAILABLE, None) for s in states)
|
||||
|
||||
valid_state = self.mode(
|
||||
state not in (STATE_UNKNOWN, STATE_UNAVAILABLE) for state in states
|
||||
@@ -446,6 +449,7 @@ class SensorGroup(GroupEntity, SensorEntity):
|
||||
|
||||
if not valid_state or not valid_state_numeric:
|
||||
self._attr_native_value = None
|
||||
self._extra_state_attribute = {}
|
||||
return
|
||||
|
||||
# Calculate values
|
||||
|
||||
@@ -206,7 +206,7 @@ async def test_not_enough_sensor_value(hass: HomeAssistant) -> None:
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("sensor.test_max")
|
||||
assert state.state == STATE_UNAVAILABLE
|
||||
assert state.state == STATE_UNKNOWN
|
||||
assert state.attributes.get("min_entity_id") is None
|
||||
assert state.attributes.get("max_entity_id") is None
|
||||
|
||||
@@ -228,7 +228,7 @@ async def test_not_enough_sensor_value(hass: HomeAssistant) -> None:
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("sensor.test_max")
|
||||
assert state.state == STATE_UNAVAILABLE
|
||||
assert state.state == STATE_UNKNOWN
|
||||
assert state.attributes.get("min_entity_id") is None
|
||||
assert state.attributes.get("max_entity_id") is None
|
||||
|
||||
@@ -281,14 +281,14 @@ async def test_reload(hass: HomeAssistant) -> None:
|
||||
(STATES_ONE_MISSING, "17.0"),
|
||||
(STATES_ONE_UNKNOWN, "17.0"),
|
||||
(STATES_ONE_UNAVAILABLE, "17.0"),
|
||||
(STATES_ALL_ERROR, STATE_UNAVAILABLE),
|
||||
(STATES_ALL_ERROR, STATE_UNKNOWN),
|
||||
(STATES_ALL_MISSING, STATE_UNAVAILABLE),
|
||||
(STATES_ALL_UNKNOWN, STATE_UNAVAILABLE),
|
||||
(STATES_ALL_UNKNOWN, STATE_UNKNOWN),
|
||||
(STATES_ALL_UNAVAILABLE, STATE_UNAVAILABLE),
|
||||
(STATES_MIX_MISSING_UNAVAILABLE, STATE_UNAVAILABLE),
|
||||
(STATES_MIX_MISSING_UNKNOWN, STATE_UNAVAILABLE),
|
||||
(STATES_MIX_UNAVAILABLE_UNKNOWN, STATE_UNAVAILABLE),
|
||||
(STATES_MIX_MISSING_UNAVAILABLE_UNKNOWN, STATE_UNAVAILABLE),
|
||||
(STATES_MIX_MISSING_UNKNOWN, STATE_UNKNOWN),
|
||||
(STATES_MIX_UNAVAILABLE_UNKNOWN, STATE_UNKNOWN),
|
||||
(STATES_MIX_MISSING_UNAVAILABLE_UNKNOWN, STATE_UNKNOWN),
|
||||
],
|
||||
)
|
||||
async def test_sensor_incorrect_state_with_ignore_non_numeric(
|
||||
@@ -339,17 +339,17 @@ async def test_sensor_incorrect_state_with_ignore_non_numeric(
|
||||
("states_list", "expected_group_state", "error_count"),
|
||||
[
|
||||
(STATES_ONE_ERROR, STATE_UNKNOWN, 1),
|
||||
(STATES_ONE_MISSING, "17.0", 0),
|
||||
(STATES_ONE_MISSING, STATE_UNKNOWN, 0),
|
||||
(STATES_ONE_UNKNOWN, STATE_UNKNOWN, 1),
|
||||
(STATES_ONE_UNAVAILABLE, STATE_UNKNOWN, 1),
|
||||
(STATES_ALL_ERROR, STATE_UNAVAILABLE, 3),
|
||||
(STATES_ALL_ERROR, STATE_UNKNOWN, 3),
|
||||
(STATES_ALL_MISSING, STATE_UNAVAILABLE, 0),
|
||||
(STATES_ALL_UNKNOWN, STATE_UNAVAILABLE, 3),
|
||||
(STATES_ALL_UNKNOWN, STATE_UNKNOWN, 3),
|
||||
(STATES_ALL_UNAVAILABLE, STATE_UNAVAILABLE, 3),
|
||||
(STATES_MIX_MISSING_UNKNOWN, STATE_UNAVAILABLE, 2),
|
||||
(STATES_MIX_UNAVAILABLE_UNKNOWN, STATE_UNAVAILABLE, 3),
|
||||
(STATES_MIX_MISSING_UNAVAILABLE, STATE_UNAVAILABLE, 2),
|
||||
(STATES_MIX_MISSING_UNAVAILABLE_UNKNOWN, STATE_UNAVAILABLE, 2),
|
||||
(STATES_MIX_MISSING_UNKNOWN, STATE_UNKNOWN, 2),
|
||||
(STATES_MIX_UNAVAILABLE_UNKNOWN, STATE_UNKNOWN, 3),
|
||||
(STATES_MIX_MISSING_UNAVAILABLE_UNKNOWN, STATE_UNKNOWN, 2),
|
||||
],
|
||||
)
|
||||
async def test_sensor_incorrect_state_with_not_ignore_non_numeric(
|
||||
@@ -402,17 +402,17 @@ async def test_sensor_incorrect_state_with_not_ignore_non_numeric(
|
||||
("states_list", "expected_group_state"),
|
||||
[
|
||||
(STATES_ONE_ERROR, STATE_UNKNOWN),
|
||||
(STATES_ONE_MISSING, "32.3"),
|
||||
(STATES_ONE_MISSING, STATE_UNKNOWN),
|
||||
(STATES_ONE_UNKNOWN, STATE_UNKNOWN),
|
||||
(STATES_ONE_UNAVAILABLE, STATE_UNKNOWN),
|
||||
(STATES_ALL_ERROR, STATE_UNAVAILABLE),
|
||||
(STATES_ALL_ERROR, STATE_UNKNOWN),
|
||||
(STATES_ALL_MISSING, STATE_UNAVAILABLE),
|
||||
(STATES_ALL_UNKNOWN, STATE_UNAVAILABLE),
|
||||
(STATES_ALL_UNKNOWN, STATE_UNKNOWN),
|
||||
(STATES_ALL_UNAVAILABLE, STATE_UNAVAILABLE),
|
||||
(STATES_MIX_MISSING_UNAVAILABLE, STATE_UNAVAILABLE),
|
||||
(STATES_MIX_MISSING_UNKNOWN, STATE_UNAVAILABLE),
|
||||
(STATES_MIX_UNAVAILABLE_UNKNOWN, STATE_UNAVAILABLE),
|
||||
(STATES_MIX_MISSING_UNAVAILABLE_UNKNOWN, STATE_UNAVAILABLE),
|
||||
(STATES_MIX_MISSING_UNKNOWN, STATE_UNKNOWN),
|
||||
(STATES_MIX_UNAVAILABLE_UNKNOWN, STATE_UNKNOWN),
|
||||
(STATES_MIX_MISSING_UNAVAILABLE_UNKNOWN, STATE_UNKNOWN),
|
||||
],
|
||||
)
|
||||
async def test_sensor_require_all_states(
|
||||
@@ -740,7 +740,7 @@ async def test_sensor_calculated_result_fails_on_uom(hass: HomeAssistant) -> Non
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("sensor.test_sum")
|
||||
assert state.state == STATE_UNAVAILABLE
|
||||
assert state.state == STATE_UNKNOWN
|
||||
assert state.attributes.get("device_class") == "energy"
|
||||
assert state.attributes.get("state_class") == "total"
|
||||
assert state.attributes.get("unit_of_measurement") is None
|
||||
@@ -847,6 +847,12 @@ async def test_last_sensor(hass: HomeAssistant) -> None:
|
||||
|
||||
entity_ids = config["sensor"]["entities"]
|
||||
|
||||
for entity_id in entity_ids[1:]:
|
||||
hass.states.async_set(entity_id, "0.0")
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("sensor.test_last")
|
||||
assert state.state == STATE_UNKNOWN
|
||||
|
||||
for entity_id, value in dict(zip(entity_ids, VALUES, strict=False)).items():
|
||||
hass.states.async_set(entity_id, str(value))
|
||||
await hass.async_block_till_done()
|
||||
|
||||
Reference in New Issue
Block a user