Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suppress log warnings when a sensor group has non numeric members #102828

Merged
merged 8 commits into from
Jan 31, 2024
14 changes: 9 additions & 5 deletions homeassistant/components/group/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ def __init__(
unique_id: str | None,
name: str,
entity_ids: list[str],
mode: bool,
ignore_non_numeric: bool,
sensor_type: str,
unit_of_measurement: str | None,
state_class: SensorStateClass | None,
Expand All @@ -318,7 +318,8 @@ def __init__(
self._attr_name = f"{DEFAULT_NAME} {sensor_type}".capitalize()
self._attr_extra_state_attributes = {ATTR_ENTITY_ID: entity_ids}
self._attr_unique_id = unique_id
self.mode = all if mode is False else any
self._ignore_non_numeric = ignore_non_numeric
mill1000 marked this conversation as resolved.
Show resolved Hide resolved
self.mode = all if ignore_non_numeric is False else any
self._state_calc: Callable[
[list[tuple[str, float, State]]],
tuple[dict[str, str | None], float | None],
Expand Down Expand Up @@ -358,9 +359,14 @@ def async_update_group_state(self) -> None:
sensor_values.append((entity_id, numeric_state, state))
if entity_id in self._state_incorrect:
self._state_incorrect.remove(entity_id)
valid_states.append(True)
mill1000 marked this conversation as resolved.
Show resolved Hide resolved
except ValueError:
valid_states.append(False)
if entity_id not in self._state_incorrect:
# Log invalid states unless ignoring non numeric values
if (
not self._ignore_non_numeric
and entity_id not in self._state_incorrect
):
self._state_incorrect.add(entity_id)
_LOGGER.warning(
"Unable to use state. Only numerical states are supported,"
Expand Down Expand Up @@ -388,8 +394,6 @@ def async_update_group_state(self) -> None:
state.attributes.get("unit_of_measurement"),
self.entity_id,
)
continue
valid_states.append(True)

# Set group as unavailable if all members do not have numeric values
self._attr_available = any(numeric_state for numeric_state in valid_states)
Expand Down
59 changes: 49 additions & 10 deletions tests/components/group/test_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,15 +245,15 @@ async def test_reload(hass: HomeAssistant) -> None:
assert hass.states.get("sensor.second_test")


async def test_sensor_incorrect_state(
async def test_sensor_incorrect_state_with_ignore_non_numeric(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test the min sensor."""
"""Test that non numeric values are ignored in a group."""
config = {
SENSOR_DOMAIN: {
"platform": GROUP_DOMAIN,
"name": "test_failure",
"type": "min",
"name": "test_ignore_non_numeric",
"type": "max",
mill1000 marked this conversation as resolved.
Show resolved Hide resolved
"ignore_non_numeric": True,
"entities": ["sensor.test_1", "sensor.test_2", "sensor.test_3"],
"unique_id": "very_unique_id",
Expand All @@ -266,24 +266,63 @@ async def test_sensor_incorrect_state(

entity_ids = config["sensor"]["entities"]

# Check that the final sensor value ignores the non numeric input
for entity_id, value in dict(zip(entity_ids, VALUES_ERROR)).items():
hass.states.async_set(entity_id, value)
await hass.async_block_till_done()

state = hass.states.get("sensor.test_failure")

assert state.state == "15.3"
state = hass.states.get("sensor.test_ignore_non_numeric")
assert state.state == "17.0"
assert (
"Unable to use state. Only numerical states are supported, entity sensor.test_2 with value string excluded from calculation"
in caplog.text
"Unable to use state. Only numerical states are supported," not in caplog.text
)

mill1000 marked this conversation as resolved.
Show resolved Hide resolved
# Check that the final sensor value with all numeric inputs
for entity_id, value in dict(zip(entity_ids, VALUES)).items():
hass.states.async_set(entity_id, value)
await hass.async_block_till_done()

state = hass.states.get("sensor.test_ignore_non_numeric")
assert state.state == "20.0"


async def test_sensor_incorrect_state_with_not_ignore_non_numeric(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test that non numeric values cause a group to be unknown."""
config = {
SENSOR_DOMAIN: {
"platform": GROUP_DOMAIN,
"name": "test_failure",
"type": "max",
"ignore_non_numeric": False,
"entities": ["sensor.test_1", "sensor.test_2", "sensor.test_3"],
"unique_id": "very_unique_id",
"state_class": SensorStateClass.MEASUREMENT,
}
}

assert await async_setup_component(hass, "sensor", config)
await hass.async_block_till_done()

entity_ids = config["sensor"]["entities"]

# Check that the final sensor value is unavailable if a non numeric input exists
for entity_id, value in dict(zip(entity_ids, VALUES_ERROR)).items():
hass.states.async_set(entity_id, value)
await hass.async_block_till_done()

state = hass.states.get("sensor.test_failure")
assert state.state == "unknown"
assert "Unable to use state. Only numerical states are supported" in caplog.text

# Check that the final sensor value is correct with all numeric inputs
for entity_id, value in dict(zip(entity_ids, VALUES)).items():
hass.states.async_set(entity_id, value)
await hass.async_block_till_done()

state = hass.states.get("sensor.test_failure")
assert state.state == "15.3"
assert state.state == "20.0"


async def test_sensor_require_all_states(hass: HomeAssistant) -> None:
Expand Down
Loading